about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2024-08-17 05:45:10 +0000
committerEsteban Küber <esteban@kuber.com.ar>2025-08-01 21:50:36 +0000
commitadcda6ca9a6d27c04399e3efe1c67fc6ff04d997 (patch)
tree15c6ab8c0c8f03ff178999ee76e0865189e62288 /compiler
parente5e79f8bd428d0b8d26e8240d718b134ef297459 (diff)
downloadrust-adcda6ca9a6d27c04399e3efe1c67fc6ff04d997.tar.gz
rust-adcda6ca9a6d27c04399e3efe1c67fc6ff04d997.zip
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)))]
   |                                   ^^^^^^^^^^
```
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_expand/src/expand.rs38
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs15
-rw-r--r--compiler/rustc_resolve/src/late.rs10
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs5
4 files changed, 45 insertions, 23 deletions
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 0517fd0419d..6174984e3be 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1399,25 +1399,35 @@ impl InvocationCollectorNode for P<ast::Item> {
     }
 
     fn declared_idents(&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 {
+                    if let Some(ident) = i.kind.ident() {
+                        self.0.push(ident);
+                    }
                 }
+                visit::walk_item(self, i);
             }
-
-            let mut idents = Vec::new();
-            collect_use_tree_leaves(ut, &mut idents);
-            idents
-        } else {
-            self.kind.ident().into_iter().collect()
         }
+
+        let mut v = ItemNameVisitor(vec![]);
+        v.visit_item(self);
+        v.0
     }
 }
 
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 3af69b28780..d0a95e6b2ad 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -803,11 +803,16 @@ impl<'ra, 'tcx> Resolver<'ra, '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
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 261d099abdc..163e4b5b7a9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -4231,13 +4231,21 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, '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();
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 98e48664e68..236b1404eeb 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -525,9 +525,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, '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)
     }