Skip to content

Commit 95c2b46

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 13a5289 commit 95c2b46

15 files changed

+133
-42
lines changed

compiler/rustc_expand/src/expand.rs

+21-13
Original file line numberDiff line numberDiff line change
@@ -1260,25 +1260,33 @@ impl InvocationCollectorNode for P<ast::Item> {
12601260
res
12611261
}
12621262
fn declared_names(&self) -> Vec<Ident> {
1263-
if let ItemKind::Use(ut) = &self.kind {
1264-
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
1265-
match &ut.kind {
1266-
ast::UseTreeKind::Glob => {}
1267-
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
1268-
ast::UseTreeKind::Nested { items, .. } => {
1269-
for (ut, _) in items {
1270-
collect_use_tree_leaves(ut, idents);
1263+
struct ItemNameVisitor(Vec<Ident>);
1264+
impl Visitor<'_> for ItemNameVisitor {
1265+
fn visit_item(&mut self, i: &ast::Item) {
1266+
if let ItemKind::Use(ut) = &i.kind {
1267+
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
1268+
match &ut.kind {
1269+
ast::UseTreeKind::Glob => {}
1270+
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
1271+
ast::UseTreeKind::Nested { items, .. } => {
1272+
for (ut, _) in items {
1273+
collect_use_tree_leaves(ut, idents);
1274+
}
1275+
}
12711276
}
12721277
}
1278+
1279+
collect_use_tree_leaves(ut, &mut self.0);
1280+
} else {
1281+
self.0.push(i.ident);
12731282
}
1283+
visit::walk_item(self, i);
12741284
}
1275-
1276-
let mut idents = Vec::new();
1277-
collect_use_tree_leaves(ut, &mut idents);
1278-
return idents;
12791285
}
12801286

1281-
vec![self.ident]
1287+
let mut v = ItemNameVisitor(vec![]);
1288+
v.visit_item(self);
1289+
v.0
12821290
}
12831291
}
12841292

compiler/rustc_resolve/src/diagnostics.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -813,11 +813,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
813813
err.multipart_suggestion(msg, suggestions, applicability);
814814
}
815815

816-
if let Some(ModuleOrUniformRoot::Module(module)) = module
817-
&& let Some(module) = module.opt_def_id()
818-
&& let Some(segment) = segment
819-
{
820-
self.find_cfg_stripped(&mut err, &segment, module);
816+
if let Some(segment) = segment {
817+
if let Some(ModuleOrUniformRoot::Module(module)) = module {
818+
let module =
819+
module.opt_def_id().unwrap_or_else(|| CRATE_DEF_ID.to_def_id());
820+
self.find_cfg_stripped(&mut err, &segment, module);
821+
} else {
822+
let module = CRATE_DEF_ID.to_def_id();
823+
self.find_cfg_stripped(&mut err, &segment, module);
824+
}
821825
}
822826

823827
err

compiler/rustc_resolve/src/late.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -3980,13 +3980,21 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
39803980
//
39813981
// And that's what happens below - we're just mixing both messages
39823982
// into a single one.
3983+
let failed_to_resolve = match parent_err.node {
3984+
ResolutionError::FailedToResolve { .. } => true,
3985+
_ => false,
3986+
};
39833987
let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
39843988

39853989
// overwrite all properties with the parent's error message
39863990
err.messages = take(&mut parent_err.messages);
39873991
err.code = take(&mut parent_err.code);
39883992
swap(&mut err.span, &mut parent_err.span);
3989-
err.children = take(&mut parent_err.children);
3993+
if failed_to_resolve {
3994+
err.children = take(&mut parent_err.children);
3995+
} else {
3996+
err.children.append(&mut parent_err.children);
3997+
}
39903998
err.sort_span = parent_err.sort_span;
39913999
err.is_lint = parent_err.is_lint.clone();
39924000

compiler/rustc_resolve/src/late/diagnostics.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -478,9 +478,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
478478
}
479479
self.err_code_special_cases(&mut err, source, path, span);
480480

481-
if let Some(module) = base_error.module {
482-
self.r.find_cfg_stripped(&mut err, &path.last().unwrap().ident.name, module);
483-
}
481+
let module = base_error.module.unwrap_or_else(|| CRATE_DEF_ID.to_def_id());
482+
self.r.find_cfg_stripped(&mut err, &path.last().unwrap().ident.name, module);
484483

485484
(err, candidates)
486485
}

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)