Skip to content

Commit 889701d

Browse files
committed
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)))] | ^^^^^^^^^^ ```
2 parents c23f07d + 4b24c4b commit 889701d

24 files changed

+281
-161
lines changed

compiler/rustc_expand/src/expand.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,9 +1411,8 @@ impl InvocationCollectorNode for P<ast::Item> {
14111411
}
14121412
}
14131413
}
1414-
14151414
let mut idents = Vec::new();
1416-
collect_use_tree_leaves(ut, &mut idents);
1415+
collect_use_tree_leaves(&ut, &mut idents);
14171416
idents
14181417
} else {
14191418
self.kind.ident().into_iter().collect()

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -801,10 +801,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
801801
}
802802
err.multipart_suggestion(msg, suggestions, applicability);
803803
}
804-
if let Some(ModuleOrUniformRoot::Module(module)) = module
805-
&& let Some(module) = module.opt_def_id()
806-
&& let Some(segment) = segment
807-
{
804+
805+
if let Some(segment) = segment {
806+
let module = match module {
807+
Some(ModuleOrUniformRoot::Module(m)) if let Some(id) = m.opt_def_id() => id,
808+
_ => CRATE_DEF_ID.to_def_id(),
809+
};
808810
self.find_cfg_stripped(&mut err, &segment, module);
809811
}
810812

@@ -2839,16 +2841,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
28392841
continue;
28402842
}
28412843

2842-
let note = errors::FoundItemConfigureOut { span: ident.span };
2843-
err.subdiagnostic(note);
2844-
2845-
if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 {
2846-
let note = errors::ItemWasBehindFeature { feature, span: cfg.1 };
2847-
err.subdiagnostic(note);
2844+
let item_was = if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 {
2845+
errors::ItemWas::BehindFeature { feature, span: cfg.1 }
28482846
} else {
2849-
let note = errors::ItemWasCfgOut { span: cfg.1 };
2850-
err.subdiagnostic(note);
2851-
}
2847+
errors::ItemWas::CfgOut { span: cfg.1 }
2848+
};
2849+
let note = errors::FoundItemConfigureOut { span: ident.span, item_was };
2850+
err.subdiagnostic(note);
28522851
}
28532852
}
28542853
}

compiler/rustc_resolve/src/errors.rs

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
use rustc_errors::codes::*;
2-
use rustc_errors::{Applicability, ElidedLifetimeInPathSubdiag, MultiSpan};
2+
use rustc_errors::{
3+
Applicability, Diag, ElidedLifetimeInPathSubdiag, EmissionGuarantee, IntoDiagArg, MultiSpan,
4+
Subdiagnostic,
5+
};
36
use rustc_macros::{Diagnostic, Subdiagnostic};
47
use rustc_span::{Ident, Span, Symbol};
58

6-
use crate::Res;
79
use crate::late::PatternSource;
10+
use crate::{Res, fluent_generated as fluent};
811

912
#[derive(Diagnostic)]
1013
#[diag(resolve_generic_params_from_outer_item, code = E0401)]
@@ -1201,26 +1204,35 @@ pub(crate) struct IdentInScopeButItIsDesc<'a> {
12011204
pub(crate) imported_ident_desc: &'a str,
12021205
}
12031206

1204-
#[derive(Subdiagnostic)]
1205-
#[note(resolve_found_an_item_configured_out)]
12061207
pub(crate) struct FoundItemConfigureOut {
1207-
#[primary_span]
1208-
pub(crate) span: Span,
1209-
}
1210-
1211-
#[derive(Subdiagnostic)]
1212-
#[note(resolve_item_was_behind_feature)]
1213-
pub(crate) struct ItemWasBehindFeature {
1214-
pub(crate) feature: Symbol,
1215-
#[primary_span]
1216-
pub(crate) span: Span,
1217-
}
1218-
1219-
#[derive(Subdiagnostic)]
1220-
#[note(resolve_item_was_cfg_out)]
1221-
pub(crate) struct ItemWasCfgOut {
1222-
#[primary_span]
12231208
pub(crate) span: Span,
1209+
pub(crate) item_was: ItemWas,
1210+
}
1211+
1212+
pub(crate) enum ItemWas {
1213+
BehindFeature { feature: Symbol, span: Span },
1214+
CfgOut { span: Span },
1215+
}
1216+
1217+
impl Subdiagnostic for FoundItemConfigureOut {
1218+
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1219+
let mut multispan: MultiSpan = self.span.into();
1220+
match self.item_was {
1221+
ItemWas::BehindFeature { feature, span } => {
1222+
let key = "feature".into();
1223+
let value = feature.into_diag_arg(&mut None);
1224+
let msg = diag.dcx.eagerly_translate_to_string(
1225+
fluent::resolve_item_was_behind_feature,
1226+
[(&key, &value)].into_iter(),
1227+
);
1228+
multispan.push_span_label(span, msg);
1229+
}
1230+
ItemWas::CfgOut { span } => {
1231+
multispan.push_span_label(span, fluent::resolve_item_was_cfg_out);
1232+
}
1233+
}
1234+
diag.span_note(multispan, fluent::resolve_found_an_item_configured_out);
1235+
}
12241236
}
12251237

12261238
#[derive(Diagnostic)]

compiler/rustc_resolve/src/late.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4231,13 +4231,21 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
42314231
//
42324232
// And that's what happens below - we're just mixing both messages
42334233
// into a single one.
4234+
let failed_to_resolve = match parent_err.node {
4235+
ResolutionError::FailedToResolve { .. } => true,
4236+
_ => false,
4237+
};
42344238
let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
42354239

42364240
// overwrite all properties with the parent's error message
42374241
err.messages = take(&mut parent_err.messages);
42384242
err.code = take(&mut parent_err.code);
42394243
swap(&mut err.span, &mut parent_err.span);
4240-
err.children = take(&mut parent_err.children);
4244+
if failed_to_resolve {
4245+
err.children = take(&mut parent_err.children);
4246+
} else {
4247+
err.children.append(&mut parent_err.children);
4248+
}
42414249
err.sort_span = parent_err.sort_span;
42424250
err.is_lint = parent_err.is_lint.clone();
42434251

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
525525
}
526526
self.err_code_special_cases(&mut err, source, path, span);
527527

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

532531
(err, candidates)
533532
}

tests/ui/cfg/both-true-false.stderr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@ error[E0425]: cannot find function `foo` in this scope
33
|
44
LL | foo();
55
| ^^^ not found in this scope
6+
|
7+
note: found an item that was configured out
8+
--> $DIR/both-true-false.rs:6:4
9+
|
10+
LL | #[cfg(false)]
11+
| ----- the item is gated here
12+
LL | #[cfg(true)]
13+
LL | fn foo() {}
14+
| ^^^
15+
note: found an item that was configured out
16+
--> $DIR/both-true-false.rs:10:4
17+
|
18+
LL | #[cfg(false)]
19+
| ----- the item is gated here
20+
LL | fn foo() {}
21+
| ^^^
622

723
error: aborting due to 1 previous error
824

tests/ui/cfg/cfg-version/syntax.stderr

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,60 +128,150 @@ error[E0425]: cannot find function `key_value_form` in this scope
128128
|
129129
LL | key_value_form();
130130
| ^^^^^^^^^^^^^^ not found in this scope
131+
|
132+
note: found an item that was configured out
133+
--> $DIR/syntax.rs:32:4
134+
|
135+
LL | #[cfg(version = "1.43")]
136+
| ---------------- the item is gated behind the `1.43` feature
137+
LL |
138+
LL | fn key_value_form() {}
139+
| ^^^^^^^^^^^^^^
131140

132141
error[E0425]: cannot find function `not_numbers_or_periods` in this scope
133142
--> $DIR/syntax.rs:143:5
134143
|
135144
LL | not_numbers_or_periods();
136145
| ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
146+
|
147+
note: found an item that was configured out
148+
--> $DIR/syntax.rs:53:4
149+
|
150+
LL | #[cfg(version("foo"))]
151+
| ------- the item is gated here
152+
LL |
153+
LL | fn not_numbers_or_periods() {}
154+
| ^^^^^^^^^^^^^^^^^^^^^^
137155

138156
error[E0425]: cannot find function `complex_semver_with_metadata` in this scope
139157
--> $DIR/syntax.rs:144:5
140158
|
141159
LL | complex_semver_with_metadata();
142160
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
161+
|
162+
note: found an item that was configured out
163+
--> $DIR/syntax.rs:57:4
164+
|
165+
LL | #[cfg(version("1.20.0-stable"))]
166+
| ----------------- the item is gated here
167+
LL |
168+
LL | fn complex_semver_with_metadata() {}
169+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
143170

144171
error[E0425]: cannot find function `invalid_major_only` in this scope
145172
--> $DIR/syntax.rs:145:5
146173
|
147174
LL | invalid_major_only();
148175
| ^^^^^^^^^^^^^^^^^^ not found in this scope
176+
|
177+
note: found an item that was configured out
178+
--> $DIR/syntax.rs:80:4
179+
|
180+
LL | #[cfg(version("1"))]
181+
| ----- the item is gated here
182+
LL |
183+
LL | fn invalid_major_only() {}
184+
| ^^^^^^^^^^^^^^^^^^
149185

150186
error[E0425]: cannot find function `invalid_major_only_zero` in this scope
151187
--> $DIR/syntax.rs:146:5
152188
|
153189
LL | invalid_major_only_zero();
154190
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
191+
|
192+
note: found an item that was configured out
193+
--> $DIR/syntax.rs:84:4
194+
|
195+
LL | #[cfg(version("0"))]
196+
| ----- the item is gated here
197+
LL |
198+
LL | fn invalid_major_only_zero() {}
199+
| ^^^^^^^^^^^^^^^^^^^^^^^
155200

156201
error[E0425]: cannot find function `invalid_major_only_negative` in this scope
157202
--> $DIR/syntax.rs:147:5
158203
|
159204
LL | invalid_major_only_negative();
160205
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
206+
|
207+
note: found an item that was configured out
208+
--> $DIR/syntax.rs:97:4
209+
|
210+
LL | #[cfg(version("-1"))]
211+
| ------ the item is gated here
212+
LL |
213+
LL | fn invalid_major_only_negative() {}
214+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
161215

162216
error[E0425]: cannot find function `exceed_u16_major` in this scope
163217
--> $DIR/syntax.rs:148:5
164218
|
165219
LL | exceed_u16_major();
166220
| ^^^^^^^^^^^^^^^^ not found in this scope
221+
|
222+
note: found an item that was configured out
223+
--> $DIR/syntax.rs:103:4
224+
|
225+
LL | #[cfg(version("65536"))]
226+
| --------- the item is gated here
227+
LL |
228+
LL | fn exceed_u16_major() {}
229+
| ^^^^^^^^^^^^^^^^
167230

168231
error[E0425]: cannot find function `exceed_u16_minor` in this scope
169232
--> $DIR/syntax.rs:149:5
170233
|
171234
LL | exceed_u16_minor();
172235
| ^^^^^^^^^^^^^^^^ not found in this scope
236+
|
237+
note: found an item that was configured out
238+
--> $DIR/syntax.rs:107:4
239+
|
240+
LL | #[cfg(version("1.65536.0"))]
241+
| ------------- the item is gated here
242+
LL |
243+
LL | fn exceed_u16_minor() {}
244+
| ^^^^^^^^^^^^^^^^
173245

174246
error[E0425]: cannot find function `exceed_u16_patch` in this scope
175247
--> $DIR/syntax.rs:150:5
176248
|
177249
LL | exceed_u16_patch();
178250
| ^^^^^^^^^^^^^^^^ not found in this scope
251+
|
252+
note: found an item that was configured out
253+
--> $DIR/syntax.rs:111:4
254+
|
255+
LL | #[cfg(version("1.0.65536"))]
256+
| ------------- the item is gated here
257+
LL |
258+
LL | fn exceed_u16_patch() {}
259+
| ^^^^^^^^^^^^^^^^
179260

180261
error[E0425]: cannot find function `exceed_u16_mixed` in this scope
181262
--> $DIR/syntax.rs:151:5
182263
|
183264
LL | exceed_u16_mixed();
184265
| ^^^^^^^^^^^^^^^^ not found in this scope
266+
|
267+
note: found an item that was configured out
268+
--> $DIR/syntax.rs:115:4
269+
|
270+
LL | #[cfg(version("65536.0.65536"))]
271+
| ----------------- the item is gated here
272+
LL |
273+
LL | fn exceed_u16_mixed() {}
274+
| ^^^^^^^^^^^^^^^^
185275

186276
error: aborting due to 14 previous errors; 14 warnings emitted
187277

tests/ui/cfg/cmdline-false.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ error[E0425]: cannot find function `foo` in this scope
33
|
44
LL | foo();
55
| ^^^ not found in this scope
6+
|
7+
note: found an item that was configured out
8+
--> $DIR/cmdline-false.rs:5:4
9+
|
10+
LL | #[cfg(false)]
11+
| ----- the item is gated here
12+
LL | fn foo() {}
13+
| ^^^
614

715
error: aborting due to 1 previous error
816

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,20 @@ fn main() {
1111
cfged_out::inner::uwu(); //~ ERROR cannot find function
1212
//~^ NOTE found an item that was configured out
1313
//~| NOTE not found in `cfged_out::inner`
14-
//~| NOTE the item is gated here
1514

1615
// The module isn't found - we would like to get a diagnostic, but currently don't due to
1716
// the awkward way the resolver diagnostics are currently implemented.
1817
cfged_out::inner::doesnt_exist::hello(); //~ ERROR failed to resolve
1918
//~^ NOTE could not find `doesnt_exist` in `inner`
2019
//~| NOTE found an item that was configured out
21-
//~| NOTE the item is gated here
2220

2321
// It should find the one in the right module, not the wrong one.
2422
cfged_out::inner::right::meow(); //~ ERROR cannot find function
2523
//~^ NOTE found an item that was configured out
2624
//~| NOTE not found in `cfged_out::inner::right
27-
//~| NOTE the item is gated behind the `what-a-cool-feature` feature
2825

2926
// Exists in the crate root - diagnostic.
3027
cfged_out::vanished(); //~ ERROR cannot find function
3128
//~^ NOTE found an item that was configured out
3229
//~| NOTE not found in `cfged_out`
33-
//~| NOTE the item is gated here
3430
}

0 commit comments

Comments
 (0)