Skip to content

Commit ab5d199

Browse files
committed
Detect more cfgd out items in resolution errors
Use a visitor to collect *all* items (including those nested) that were stripped behind a `cfg` condition. ``` error[E0425]: cannot find function `f` in this scope --> $DIR/nested-cfg-attrs.rs:4:13 | LL | fn main() { f() } | ^ not found in this scope | note: found an item that was configured out --> $DIR/nested-cfg-attrs.rs:2:4 | LL | fn f() {} | ^ note: the item is gated here --> $DIR/nested-cfg-attrs.rs:1:35 | LL | #[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))] | ^^^^^^^^^^ ```
1 parent 7a0cde9 commit ab5d199

15 files changed

+133
-42
lines changed

compiler/rustc_expand/src/expand.rs

+21-13
Original file line numberDiff line numberDiff line change
@@ -1274,25 +1274,33 @@ impl InvocationCollectorNode for P<ast::Item> {
12741274
res
12751275
}
12761276
fn declared_names(&self) -> Vec<Ident> {
1277-
if let ItemKind::Use(ut) = &self.kind {
1278-
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
1279-
match &ut.kind {
1280-
ast::UseTreeKind::Glob => {}
1281-
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
1282-
ast::UseTreeKind::Nested { items, .. } => {
1283-
for (ut, _) in items {
1284-
collect_use_tree_leaves(ut, idents);
1277+
struct ItemNameVisitor(Vec<Ident>);
1278+
impl Visitor<'_> for ItemNameVisitor {
1279+
fn visit_item(&mut self, i: &ast::Item) {
1280+
if let ItemKind::Use(ut) = &i.kind {
1281+
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
1282+
match &ut.kind {
1283+
ast::UseTreeKind::Glob => {}
1284+
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
1285+
ast::UseTreeKind::Nested { items, .. } => {
1286+
for (ut, _) in items {
1287+
collect_use_tree_leaves(ut, idents);
1288+
}
1289+
}
12851290
}
12861291
}
1292+
1293+
collect_use_tree_leaves(ut, &mut self.0);
1294+
} else {
1295+
self.0.push(i.ident);
12871296
}
1297+
visit::walk_item(self, i);
12881298
}
1289-
1290-
let mut idents = Vec::new();
1291-
collect_use_tree_leaves(ut, &mut idents);
1292-
return idents;
12931299
}
12941300

1295-
vec![self.ident]
1301+
let mut v = ItemNameVisitor(vec![]);
1302+
v.visit_item(self);
1303+
v.0
12961304
}
12971305
}
12981306

compiler/rustc_resolve/src/diagnostics.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -810,11 +810,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
810810
err.multipart_suggestion(msg, suggestions, applicability);
811811
}
812812

813-
if let Some(ModuleOrUniformRoot::Module(module)) = module
814-
&& let Some(module) = module.opt_def_id()
815-
&& let Some(segment) = segment
816-
{
817-
self.find_cfg_stripped(&mut err, &segment, module);
813+
if let Some(segment) = segment {
814+
if let Some(ModuleOrUniformRoot::Module(module)) = module {
815+
let module =
816+
module.opt_def_id().unwrap_or_else(|| CRATE_DEF_ID.to_def_id());
817+
self.find_cfg_stripped(&mut err, &segment, module);
818+
} else {
819+
let module = CRATE_DEF_ID.to_def_id();
820+
self.find_cfg_stripped(&mut err, &segment, module);
821+
}
818822
}
819823

820824
err

compiler/rustc_resolve/src/late.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -4147,13 +4147,21 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
41474147
//
41484148
// And that's what happens below - we're just mixing both messages
41494149
// into a single one.
4150+
let failed_to_resolve = match parent_err.node {
4151+
ResolutionError::FailedToResolve { .. } => true,
4152+
_ => false,
4153+
};
41504154
let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
41514155

41524156
// overwrite all properties with the parent's error message
41534157
err.messages = take(&mut parent_err.messages);
41544158
err.code = take(&mut parent_err.code);
41554159
swap(&mut err.span, &mut parent_err.span);
4156-
err.children = take(&mut parent_err.children);
4160+
if failed_to_resolve {
4161+
err.children = take(&mut parent_err.children);
4162+
} else {
4163+
err.children.append(&mut parent_err.children);
4164+
}
41574165
err.sort_span = parent_err.sort_span;
41584166
err.is_lint = parent_err.is_lint.clone();
41594167

compiler/rustc_resolve/src/late/diagnostics.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
494494
}
495495
self.err_code_special_cases(&mut err, source, path, span);
496496

497-
if let Some(module) = base_error.module {
498-
self.r.find_cfg_stripped(&mut err, &path.last().unwrap().ident.name, module);
499-
}
497+
let module = base_error.module.unwrap_or_else(|| CRATE_DEF_ID.to_def_id());
498+
self.r.find_cfg_stripped(&mut err, &path.last().unwrap().ident.name, module);
500499

501500
(err, candidates)
502501
}

tests/ui/cfg/diagnostics-reexport.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pub mod inner {
2-
#[cfg(FALSE)]
2+
#[cfg(FALSE)] //~ NOTE the item is gated here
33
mod gone {
4-
pub fn uwu() {}
4+
pub fn uwu() {} //~ NOTE found an item that was configured out
55
}
66

77
#[cfg(FALSE)] //~ NOTE the item is gated here
@@ -34,7 +34,7 @@ mod b {
3434
}
3535

3636
fn main() {
37-
// There is no uwu at this path - no diagnostic.
37+
// There is no uwu at this path, but there's one in a cgfd out sub-module, so we mention it.
3838
inner::uwu(); //~ ERROR cannot find function
3939
//~^ NOTE not found in `inner`
4040
}

tests/ui/cfg/diagnostics-reexport.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ error[E0425]: cannot find function `uwu` in module `inner`
5050
LL | inner::uwu();
5151
| ^^^ not found in `inner`
5252
|
53+
note: found an item that was configured out
54+
--> $DIR/diagnostics-reexport.rs:4:16
55+
|
56+
LL | pub fn uwu() {}
57+
| ^^^
58+
note: the item is gated here
59+
--> $DIR/diagnostics-reexport.rs:2:5
60+
|
61+
LL | #[cfg(FALSE)]
62+
| ^^^^^^^^^^^^^
5363
note: found an item that was configured out
5464
--> $DIR/diagnostics-reexport.rs:8:20
5565
|

tests/ui/cfg/diagnostics-same-crate.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ mod placeholder {
3737
//~| NOTE could not find `doesnt_exist` in `inner`
3838
}
3939

40-
#[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
41-
pub fn vanished() {}
40+
#[cfg(i_dont_exist_and_you_can_do_nothing_about_it)] //~ NOTE the item is gated here
41+
pub fn vanished() {} //~ NOTE found an item that was configured out
4242

4343
fn main() {
4444
// There is no uwu at this path - no diagnostic.
@@ -49,18 +49,16 @@ fn main() {
4949
inner::uwu(); //~ ERROR cannot find function
5050
//~| NOTE not found in `inner`
5151

52-
// The module isn't found - we would like to get a diagnostic, but currently don't due to
53-
// the awkward way the resolver diagnostics are currently implemented.
52+
// The module isn't found - we get a diagnostic.
5453
inner::doesnt_exist::hello(); //~ ERROR failed to resolve
5554
//~| NOTE could not find `doesnt_exist` in `inner`
5655

5756
// It should find the one in the right module, not the wrong one.
5857
inner::right::meow(); //~ ERROR cannot find function
5958
//~| NOTE not found in `inner::right
6059

61-
// Exists in the crate root - we would generally want a diagnostic,
62-
// but currently don't have one.
63-
// Not that it matters much though, this is highly unlikely to confuse anyone.
60+
// Exists in the crate root - we show a diagnostic because we treat "no module DefId" as "crate
61+
// root DefId".
6462
vanished(); //~ ERROR cannot find function
6563
//~^ NOTE not found in this scope
6664
}

tests/ui/cfg/diagnostics-same-crate.stderr

+14-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ LL | #[cfg(FALSE)]
3333
| ^^^^^^^^^^^^^
3434

3535
error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
36-
--> $DIR/diagnostics-same-crate.rs:54:12
36+
--> $DIR/diagnostics-same-crate.rs:53:12
3737
|
3838
LL | inner::doesnt_exist::hello();
3939
| ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
@@ -67,7 +67,7 @@ LL | #[cfg(FALSE)]
6767
| ^^^^^^^^^^^^^
6868

6969
error[E0425]: cannot find function `meow` in module `inner::right`
70-
--> $DIR/diagnostics-same-crate.rs:58:19
70+
--> $DIR/diagnostics-same-crate.rs:57:19
7171
|
7272
LL | inner::right::meow();
7373
| ^^^^ not found in `inner::right`
@@ -90,10 +90,21 @@ LL | uwu();
9090
| ^^^ not found in this scope
9191

9292
error[E0425]: cannot find function `vanished` in this scope
93-
--> $DIR/diagnostics-same-crate.rs:64:5
93+
--> $DIR/diagnostics-same-crate.rs:62:5
9494
|
9595
LL | vanished();
9696
| ^^^^^^^^ not found in this scope
97+
|
98+
note: found an item that was configured out
99+
--> $DIR/diagnostics-same-crate.rs:41:8
100+
|
101+
LL | pub fn vanished() {}
102+
| ^^^^^^^^
103+
note: the item is gated here
104+
--> $DIR/diagnostics-same-crate.rs:40:1
105+
|
106+
LL | #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
107+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
97108

98109
error: aborting due to 7 previous errors
99110

Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
//@ compile-flags: --cfg foo --check-cfg=cfg(foo,bar)
22

33
#[cfg(all(foo, bar))] // foo AND bar
4-
fn foo() {}
4+
//~^ NOTE the item is gated here
5+
fn foo() {} //~ NOTE found an item that was configured out
56

67
fn main() {
78
foo(); //~ ERROR cannot find function `foo` in this scope
9+
//~^ NOTE not found in this scope
810
}

tests/ui/conditional-compilation/test-cfg.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
error[E0425]: cannot find function `foo` in this scope
2-
--> $DIR/test-cfg.rs:7:5
2+
--> $DIR/test-cfg.rs:8:5
33
|
44
LL | foo();
55
| ^^^ not found in this scope
6+
|
7+
note: found an item that was configured out
8+
--> $DIR/test-cfg.rs:5:4
9+
|
10+
LL | fn foo() {}
11+
| ^^^
12+
note: the item is gated here
13+
--> $DIR/test-cfg.rs:3:1
14+
|
15+
LL | #[cfg(all(foo, bar))] // foo AND bar
16+
| ^^^^^^^^^^^^^^^^^^^^^
617

718
error: aborting due to 1 previous error
819

tests/ui/macros/macro-inner-attributes.stderr

+16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ error[E0433]: failed to resolve: use of undeclared crate or module `a`
44
LL | a::bar();
55
| ^ use of undeclared crate or module `a`
66
|
7+
note: found an item that was configured out
8+
--> $DIR/macro-inner-attributes.rs:7:7
9+
|
10+
LL | test!(a,
11+
| ^
12+
note: the item is gated here
13+
--> $DIR/macro-inner-attributes.rs:5:45
14+
|
15+
LL | $i:item) => (mod $nm { #![$a] $i }); }
16+
| ^^^^^^
17+
LL |
18+
LL | / test!(a,
19+
LL | | #[cfg(FALSE)],
20+
LL | | pub fn bar() { });
21+
| |_______________________- in this macro invocation
22+
= note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
723
help: there is a crate or module with a similar name
824
|
925
LL | b::bar();

tests/ui/nested-cfg-attrs.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))]
2-
fn f() {}
1+
#[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))] //~ NOTE the item is gated here
2+
fn f() {} //~ NOTE found an item that was configured out
33

44
fn main() { f() } //~ ERROR cannot find function `f` in this scope
5+
//~^ NOTE not found in this scope

tests/ui/nested-cfg-attrs.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ error[E0425]: cannot find function `f` in this scope
33
|
44
LL | fn main() { f() }
55
| ^ not found in this scope
6+
|
7+
note: found an item that was configured out
8+
--> $DIR/nested-cfg-attrs.rs:2:4
9+
|
10+
LL | fn f() {}
11+
| ^
12+
note: the item is gated here
13+
--> $DIR/nested-cfg-attrs.rs:1:35
14+
|
15+
LL | #[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))]
16+
| ^^^^^^^^^^
617

718
error: aborting due to 1 previous error
819

tests/ui/rustdoc/cfg-rustdoc.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
#[cfg(doc)]
2-
pub struct Foo;
1+
#[cfg(doc)] //~ NOTE the item is gated here
2+
pub struct Foo; //~ NOTE found an item that was configured out
33

44
fn main() {
5-
let f = Foo; //~ ERROR
5+
let f = Foo; //~ ERROR cannot find value `Foo` in this scope
6+
//~^ NOTE not found in this scope
67
}

tests/ui/rustdoc/cfg-rustdoc.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ error[E0425]: cannot find value `Foo` in this scope
33
|
44
LL | let f = Foo;
55
| ^^^ not found in this scope
6+
|
7+
note: found an item that was configured out
8+
--> $DIR/cfg-rustdoc.rs:2:12
9+
|
10+
LL | pub struct Foo;
11+
| ^^^
12+
note: the item is gated here
13+
--> $DIR/cfg-rustdoc.rs:1:1
14+
|
15+
LL | #[cfg(doc)]
16+
| ^^^^^^^^^^^
617

718
error: aborting due to 1 previous error
819

0 commit comments

Comments
 (0)