@@ -251,7 +251,10 @@ fn generic_interface_transitive_use() { |
| 251 | 251 | |
| 252 | 252 | #[test] |
| 253 | 253 | fn module_private_default() { |
| 254 | | - // priv_val should not be accessible; only pub_val. |
| 254 | + // F2008 §12.2.3.2: submodules of a module see *all* parent entities, |
| 255 | + // including the privates. The .amod must therefore round-trip private |
| 256 | + // module variables — but tagged `private` so module-level USE |
| 257 | + // associations reject them while submodule host association accepts. |
| 255 | 258 | let compiler = find_compiler(); |
| 256 | 259 | let dir = unique_dir(); |
| 257 | 260 | let mod_f90 = dir.join("mod.f90"); |
@@ -262,12 +265,22 @@ fn module_private_default() { |
| 262 | 265 | ).unwrap(); |
| 263 | 266 | compile_file(&compiler, &mod_f90, &mod_o, None); |
| 264 | 267 | |
| 265 | | - // Check .amod only has pub_val. |
| 266 | 268 | let amod = std::fs::read_to_string(dir.join("priv_mod.amod")).unwrap(); |
| 267 | | - assert!(amod.contains("pub_val"), "pub_val should be in .amod"); |
| 269 | + let pub_line = amod |
| 270 | + .lines() |
| 271 | + .find(|l| l.contains("pub_val")) |
| 272 | + .expect("pub_val should appear in .amod"); |
| 268 | 273 | assert!( |
| 269 | | - !amod.contains("priv_val"), |
| 270 | | - "priv_val should NOT be in .amod" |
| 274 | + !pub_line.contains("private"), |
| 275 | + "pub_val should not carry the `private` annotation: {pub_line}" |
| 276 | + ); |
| 277 | + let priv_line = amod |
| 278 | + .lines() |
| 279 | + .find(|l| l.contains("priv_val")) |
| 280 | + .expect("priv_val should appear in .amod (with `private` annotation) so submodule host association can resolve it"); |
| 281 | + assert!( |
| 282 | + priv_line.contains("private"), |
| 283 | + "priv_val must be tagged `private` in the .amod: {priv_line}" |
| 271 | 284 | ); |
| 272 | 285 | |
| 273 | 286 | let _ = std::fs::remove_dir_all(&dir); |