Skip to content

Commit e03a0ad

Browse files
committed
Tie inner attributes to the correct #[cfg(..)] mod
It's possible that multiple modules could have the same name. E.g.: #[cfg(linux)] mod foo; #[cfg(not(linux))] mod foo; Previously, we would just assign attributes to the first module we found with the same name as the one we were trying to associate inner attributes with.This lead to a situation where we assigned all inner sub module attributes to the first module we found. Now we also ensure the spans for each item match so that we know we're associating the inner attributes with the correct mod item.
1 parent 4ca13b1 commit e03a0ad

File tree

5 files changed

+35
-2
lines changed

5 files changed

+35
-2
lines changed

src/modules.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
294294
.to_mut()
295295
.iter_mut()
296296
.filter(|i| matches!(i.kind, ast::ItemKind::Mod(..)))
297-
.find(|i| i.ident == item.ident)
297+
.find(|i| {
298+
// The module names need to be the same, and to account for multiple modules
299+
// with the same name (e.g. those annotated with `#[cfg(..)]` we also check
300+
// the spans to make sure we're adding attributes to the correct item.
301+
i.ident == item.ident && i.span == item.span
302+
})
298303
{
299304
mod_item.attrs.extend(sub_mod_kind.attrs())
300305
}

src/modules/test.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,19 @@ fn validate_file_mod_map<F: Fn(&FileModMap<'_>)>(mod_path: &PathBuf, recursive:
2929
}
3030

3131
fn get_submodule<'a>(module: &'a Module<'_>, mod_name: &str) -> &'a rustc_ast::ast::Item {
32+
get_nth_submodule(module, mod_name, 0)
33+
}
34+
35+
fn get_nth_submodule<'a>(
36+
module: &'a Module<'_>,
37+
mod_name: &str,
38+
position: usize,
39+
) -> &'a rustc_ast::ast::Item {
3240
module
3341
.items
3442
.iter()
35-
.find(|i| i.ident == Ident::from_str(mod_name))
43+
.filter(|i| i.ident == Ident::from_str(mod_name))
44+
.nth(position)
3645
.unwrap()
3746
}
3847

@@ -63,5 +72,15 @@ fn external_sub_module_inner_attrs_are_present_in_mod_item_attrs_list() {
6372
// mod d is annotated with an inner `#![rustfmt::skip]` attribute.
6473
let mod_d = get_submodule(module, "d");
6574
assert!(contains_skip(&mod_d.attrs));
75+
76+
// mod e is defined in both e1.rs and e2.rs depending on the operating system.
77+
// We should ensure that attributes from one path aren't added to the other.
78+
let mod_e1 = get_nth_submodule(module, "e", 0);
79+
assert!(contains_name(&mod_e1.attrs, sym::no_std));
80+
assert!(!contains_name(&mod_e1.attrs, sym::no_implicit_prelude));
81+
82+
let mod_e2 = get_nth_submodule(module, "e", 1);
83+
assert!(contains_name(&mod_e2.attrs, sym::no_implicit_prelude));
84+
assert!(!contains_name(&mod_e2.attrs, sym::no_std));
6685
});
6786
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#![no_std]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#![no_implicit_prelude]

tests/mod-resolver/issue-4959-sub-mod-inner-attr/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ mod a;
33
#[rustfmt::skip]
44
mod c;
55
mod d;
6+
7+
#[cfg(linux)]
8+
#[path ="e1.rs"]
9+
mod e;
10+
#[cfg(not(linux))]
11+
#[path ="e2.rs"]
12+
mod e;

0 commit comments

Comments
 (0)