Skip to content

Commit

Permalink
Auto merge of rust-lang#129183 - estebank:cfg-visitor, r=<try>
Browse files Browse the repository at this point in the history
Detect more `cfg`d 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)))]
   |                                   ^^^^^^^^^^
```
  • Loading branch information
bors committed Aug 20, 2024
2 parents a971212 + 95c2b46 commit 623e6c7
Show file tree
Hide file tree
Showing 15 changed files with 133 additions and 42 deletions.
34 changes: 21 additions & 13 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1260,25 +1260,33 @@ impl InvocationCollectorNode for P<ast::Item> {
res
}
fn declared_names(&self) -> Vec<Ident> {
if let ItemKind::Use(ut) = &self.kind {
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
match &ut.kind {
ast::UseTreeKind::Glob => {}
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
ast::UseTreeKind::Nested { items, .. } => {
for (ut, _) in items {
collect_use_tree_leaves(ut, idents);
struct ItemNameVisitor(Vec<Ident>);
impl Visitor<'_> for ItemNameVisitor {
fn visit_item(&mut self, i: &ast::Item) {
if let ItemKind::Use(ut) = &i.kind {
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
match &ut.kind {
ast::UseTreeKind::Glob => {}
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
ast::UseTreeKind::Nested { items, .. } => {
for (ut, _) in items {
collect_use_tree_leaves(ut, idents);
}
}
}
}

collect_use_tree_leaves(ut, &mut self.0);
} else {
self.0.push(i.ident);
}
visit::walk_item(self, i);
}

let mut idents = Vec::new();
collect_use_tree_leaves(ut, &mut idents);
return idents;
}

vec![self.ident]
let mut v = ItemNameVisitor(vec![]);
v.visit_item(self);
v.0
}
}

Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,11 +813,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
err.multipart_suggestion(msg, suggestions, applicability);
}

if let Some(ModuleOrUniformRoot::Module(module)) = module
&& let Some(module) = module.opt_def_id()
&& let Some(segment) = segment
{
self.find_cfg_stripped(&mut err, &segment, module);
if let Some(segment) = segment {
if let Some(ModuleOrUniformRoot::Module(module)) = module {
let module =
module.opt_def_id().unwrap_or_else(|| CRATE_DEF_ID.to_def_id());
self.find_cfg_stripped(&mut err, &segment, module);
} else {
let module = CRATE_DEF_ID.to_def_id();
self.find_cfg_stripped(&mut err, &segment, module);
}
}

err
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3980,13 +3980,21 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
//
// And that's what happens below - we're just mixing both messages
// into a single one.
let failed_to_resolve = match parent_err.node {
ResolutionError::FailedToResolve { .. } => true,
_ => false,
};
let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);

// overwrite all properties with the parent's error message
err.messages = take(&mut parent_err.messages);
err.code = take(&mut parent_err.code);
swap(&mut err.span, &mut parent_err.span);
err.children = take(&mut parent_err.children);
if failed_to_resolve {
err.children = take(&mut parent_err.children);
} else {
err.children.append(&mut parent_err.children);
}
err.sort_span = parent_err.sort_span;
err.is_lint = parent_err.is_lint.clone();

Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
self.err_code_special_cases(&mut err, source, path, span);

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

(err, candidates)
}
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/cfg/diagnostics-reexport.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod inner {
#[cfg(FALSE)]
#[cfg(FALSE)] //~ NOTE the item is gated here
mod gone {
pub fn uwu() {}
pub fn uwu() {} //~ NOTE found an item that was configured out
}

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

fn main() {
// There is no uwu at this path - no diagnostic.
// There is no uwu at this path, but there's one in a cgfd out sub-module, so we mention it.
inner::uwu(); //~ ERROR cannot find function
//~^ NOTE not found in `inner`
}
10 changes: 10 additions & 0 deletions tests/ui/cfg/diagnostics-reexport.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ error[E0425]: cannot find function `uwu` in module `inner`
LL | inner::uwu();
| ^^^ not found in `inner`
|
note: found an item that was configured out
--> $DIR/diagnostics-reexport.rs:4:16
|
LL | pub fn uwu() {}
| ^^^
note: the item is gated here
--> $DIR/diagnostics-reexport.rs:2:5
|
LL | #[cfg(FALSE)]
| ^^^^^^^^^^^^^
note: found an item that was configured out
--> $DIR/diagnostics-reexport.rs:8:20
|
Expand Down
12 changes: 5 additions & 7 deletions tests/ui/cfg/diagnostics-same-crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ mod placeholder {
//~| NOTE could not find `doesnt_exist` in `inner`
}

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

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

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

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

// Exists in the crate root - we would generally want a diagnostic,
// but currently don't have one.
// Not that it matters much though, this is highly unlikely to confuse anyone.
// Exists in the crate root - we show a diagnostic because we treat "no module DefId" as "crate
// root DefId".
vanished(); //~ ERROR cannot find function
//~^ NOTE not found in this scope
}
17 changes: 14 additions & 3 deletions tests/ui/cfg/diagnostics-same-crate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ LL | #[cfg(FALSE)]
| ^^^^^^^^^^^^^

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

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

error[E0425]: cannot find function `vanished` in this scope
--> $DIR/diagnostics-same-crate.rs:64:5
--> $DIR/diagnostics-same-crate.rs:62:5
|
LL | vanished();
| ^^^^^^^^ not found in this scope
|
note: found an item that was configured out
--> $DIR/diagnostics-same-crate.rs:41:8
|
LL | pub fn vanished() {}
| ^^^^^^^^
note: the item is gated here
--> $DIR/diagnostics-same-crate.rs:40:1
|
LL | #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 7 previous errors

Expand Down
4 changes: 3 additions & 1 deletion tests/ui/conditional-compilation/test-cfg.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//@ compile-flags: --cfg foo --check-cfg=cfg(foo,bar)

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

fn main() {
foo(); //~ ERROR cannot find function `foo` in this scope
//~^ NOTE not found in this scope
}
13 changes: 12 additions & 1 deletion tests/ui/conditional-compilation/test-cfg.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
error[E0425]: cannot find function `foo` in this scope
--> $DIR/test-cfg.rs:7:5
--> $DIR/test-cfg.rs:8:5
|
LL | foo();
| ^^^ not found in this scope
|
note: found an item that was configured out
--> $DIR/test-cfg.rs:5:4
|
LL | fn foo() {}
| ^^^
note: the item is gated here
--> $DIR/test-cfg.rs:3:1
|
LL | #[cfg(all(foo, bar))] // foo AND bar
| ^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
16 changes: 16 additions & 0 deletions tests/ui/macros/macro-inner-attributes.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ error[E0433]: failed to resolve: use of undeclared crate or module `a`
LL | a::bar();
| ^ use of undeclared crate or module `a`
|
note: found an item that was configured out
--> $DIR/macro-inner-attributes.rs:7:7
|
LL | test!(a,
| ^
note: the item is gated here
--> $DIR/macro-inner-attributes.rs:5:45
|
LL | $i:item) => (mod $nm { #![$a] $i }); }
| ^^^^^^
LL |
LL | / test!(a,
LL | | #[cfg(FALSE)],
LL | | pub fn bar() { });
| |_______________________- in this macro invocation
= note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
help: there is a crate or module with a similar name
|
LL | b::bar();
Expand Down
5 changes: 3 additions & 2 deletions tests/ui/nested-cfg-attrs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))]
fn f() {}
#[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))] //~ NOTE the item is gated here
fn f() {} //~ NOTE found an item that was configured out

fn main() { f() } //~ ERROR cannot find function `f` in this scope
//~^ NOTE not found in this scope
11 changes: 11 additions & 0 deletions tests/ui/nested-cfg-attrs.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ error[E0425]: cannot find function `f` in this scope
|
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)))]
| ^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
7 changes: 4 additions & 3 deletions tests/ui/rustdoc/cfg-rustdoc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(doc)]
pub struct Foo;
#[cfg(doc)] //~ NOTE the item is gated here
pub struct Foo; //~ NOTE found an item that was configured out

fn main() {
let f = Foo; //~ ERROR
let f = Foo; //~ ERROR cannot find value `Foo` in this scope
//~^ NOTE not found in this scope
}
11 changes: 11 additions & 0 deletions tests/ui/rustdoc/cfg-rustdoc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ error[E0425]: cannot find value `Foo` in this scope
|
LL | let f = Foo;
| ^^^ not found in this scope
|
note: found an item that was configured out
--> $DIR/cfg-rustdoc.rs:2:12
|
LL | pub struct Foo;
| ^^^
note: the item is gated here
--> $DIR/cfg-rustdoc.rs:1:1
|
LL | #[cfg(doc)]
| ^^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down

0 comments on commit 623e6c7

Please sign in to comment.