diff options
| author | bors <bors@rust-lang.org> | 2025-08-02 05:09:31 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-08-02 05:09:31 +0000 |
| commit | 889701db1ff614160314734fe4138c2f820a95bb (patch) | |
| tree | 73cf71993bf2f50f9f20e0013c86c41a969d947b /compiler/rustc_resolve/src | |
| parent | c23f07d8c56c51b5e634bda55daca2b073306340 (diff) | |
| parent | 4b24c4bf23df8ae5c53669e3209b9f3074769b69 (diff) | |
| download | rust-889701db1ff614160314734fe4138c2f820a95bb.tar.gz rust-889701db1ff614160314734fe4138c2f820a95bb.zip | |
Auto merge of #129183 - estebank:cfg-visitor, r=davidtwco
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/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 52 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 5 |
4 files changed, 55 insertions, 37 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index b14a6edb791..3b57f6e883a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -801,10 +801,12 @@ 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 - { + + if let Some(segment) = segment { + let module = match module { + Some(ModuleOrUniformRoot::Module(m)) if let Some(id) = m.opt_def_id() => id, + _ => CRATE_DEF_ID.to_def_id(), + }; self.find_cfg_stripped(&mut err, &segment, module); } @@ -2839,16 +2841,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { continue; } - let note = errors::FoundItemConfigureOut { span: ident.span }; - err.subdiagnostic(note); - - if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 { - let note = errors::ItemWasBehindFeature { feature, span: cfg.1 }; - err.subdiagnostic(note); + let item_was = if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 { + errors::ItemWas::BehindFeature { feature, span: cfg.1 } } else { - let note = errors::ItemWasCfgOut { span: cfg.1 }; - err.subdiagnostic(note); - } + errors::ItemWas::CfgOut { span: cfg.1 } + }; + let note = errors::FoundItemConfigureOut { span: ident.span, item_was }; + err.subdiagnostic(note); } } } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index d6b1e4de6ea..2747ba135ed 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1,10 +1,13 @@ use rustc_errors::codes::*; -use rustc_errors::{Applicability, ElidedLifetimeInPathSubdiag, MultiSpan}; +use rustc_errors::{ + Applicability, Diag, ElidedLifetimeInPathSubdiag, EmissionGuarantee, IntoDiagArg, MultiSpan, + Subdiagnostic, +}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Ident, Span, Symbol}; -use crate::Res; use crate::late::PatternSource; +use crate::{Res, fluent_generated as fluent}; #[derive(Diagnostic)] #[diag(resolve_generic_params_from_outer_item, code = E0401)] @@ -1201,26 +1204,35 @@ pub(crate) struct IdentInScopeButItIsDesc<'a> { pub(crate) imported_ident_desc: &'a str, } -#[derive(Subdiagnostic)] -#[note(resolve_found_an_item_configured_out)] pub(crate) struct FoundItemConfigureOut { - #[primary_span] - pub(crate) span: Span, -} - -#[derive(Subdiagnostic)] -#[note(resolve_item_was_behind_feature)] -pub(crate) struct ItemWasBehindFeature { - pub(crate) feature: Symbol, - #[primary_span] - pub(crate) span: Span, -} - -#[derive(Subdiagnostic)] -#[note(resolve_item_was_cfg_out)] -pub(crate) struct ItemWasCfgOut { - #[primary_span] pub(crate) span: Span, + pub(crate) item_was: ItemWas, +} + +pub(crate) enum ItemWas { + BehindFeature { feature: Symbol, span: Span }, + CfgOut { span: Span }, +} + +impl Subdiagnostic for FoundItemConfigureOut { + fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { + let mut multispan: MultiSpan = self.span.into(); + match self.item_was { + ItemWas::BehindFeature { feature, span } => { + let key = "feature".into(); + let value = feature.into_diag_arg(&mut None); + let msg = diag.dcx.eagerly_translate_to_string( + fluent::resolve_item_was_behind_feature, + [(&key, &value)].into_iter(), + ); + multispan.push_span_label(span, msg); + } + ItemWas::CfgOut { span } => { + multispan.push_span_label(span, fluent::resolve_item_was_cfg_out); + } + } + diag.span_note(multispan, fluent::resolve_found_an_item_configured_out); + } } #[derive(Diagnostic)] 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) } |
