Skip to content

Commit adcda6c

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 e5e79f8 commit adcda6c

18 files changed

+273
-43
lines changed

compiler/rustc_expand/src/expand.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,25 +1399,35 @@ impl InvocationCollectorNode for P<ast::Item> {
13991399
}
14001400

14011401
fn declared_idents(&self) -> Vec<Ident> {
1402-
if let ItemKind::Use(ut) = &self.kind {
1403-
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
1404-
match &ut.kind {
1405-
ast::UseTreeKind::Glob => {}
1406-
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
1407-
ast::UseTreeKind::Nested { items, .. } => {
1408-
for (ut, _) in items {
1409-
collect_use_tree_leaves(ut, idents);
1402+
struct ItemNameVisitor(Vec<Ident>);
1403+
impl Visitor<'_> for ItemNameVisitor {
1404+
fn visit_item(&mut self, i: &ast::Item) {
1405+
if let ItemKind::Use(ut) = &i.kind {
1406+
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
1407+
match &ut.kind {
1408+
ast::UseTreeKind::Glob => {}
1409+
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
1410+
ast::UseTreeKind::Nested { items, .. } => {
1411+
for (ut, _) in items {
1412+
collect_use_tree_leaves(ut, idents);
1413+
}
1414+
}
14101415
}
14111416
}
1417+
1418+
collect_use_tree_leaves(ut, &mut self.0);
1419+
} else {
1420+
if let Some(ident) = i.kind.ident() {
1421+
self.0.push(ident);
1422+
}
14121423
}
1424+
visit::walk_item(self, i);
14131425
}
1414-
1415-
let mut idents = Vec::new();
1416-
collect_use_tree_leaves(ut, &mut idents);
1417-
idents
1418-
} else {
1419-
self.kind.ident().into_iter().collect()
14201426
}
1427+
1428+
let mut v = ItemNameVisitor(vec![]);
1429+
v.visit_item(self);
1430+
v.0
14211431
}
14221432
}
14231433

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -803,11 +803,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
803803
}
804804
err.multipart_suggestion(msg, suggestions, applicability);
805805
}
806-
if let Some(ModuleOrUniformRoot::Module(module)) = module
807-
&& let Some(module) = module.opt_def_id()
808-
&& let Some(segment) = segment
809-
{
810-
self.find_cfg_stripped(&mut err, &segment, module);
806+
807+
if let Some(segment) = segment {
808+
if let Some(ModuleOrUniformRoot::Module(module)) = module {
809+
let module =
810+
module.opt_def_id().unwrap_or_else(|| CRATE_DEF_ID.to_def_id());
811+
self.find_cfg_stripped(&mut err, &segment, module);
812+
} else {
813+
let module = CRATE_DEF_ID.to_def_id();
814+
self.find_cfg_stripped(&mut err, &segment, module);
815+
}
811816
}
812817

813818
err

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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,27 @@ 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 | fn foo() {}
11+
| ^^^
12+
note: the item is gated here
13+
--> $DIR/both-true-false.rs:4:7
14+
|
15+
LL | #[cfg(false)]
16+
| ^^^^^
17+
note: found an item that was configured out
18+
--> $DIR/both-true-false.rs:10:4
19+
|
20+
LL | fn foo() {}
21+
| ^^^
22+
note: the item is gated here
23+
--> $DIR/both-true-false.rs:9:7
24+
|
25+
LL | #[cfg(false)]
26+
| ^^^^^
627

728
error: aborting due to 1 previous error
829

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

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,60 +128,170 @@ 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 | fn key_value_form() {}
136+
| ^^^^^^^^^^^^^^
137+
note: the item is gated behind the `1.43` feature
138+
--> $DIR/syntax.rs:30:7
139+
|
140+
LL | #[cfg(version = "1.43")]
141+
| ^^^^^^^^^^^^^^^^
131142

132143
error[E0425]: cannot find function `not_numbers_or_periods` in this scope
133144
--> $DIR/syntax.rs:143:5
134145
|
135146
LL | not_numbers_or_periods();
136147
| ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
148+
|
149+
note: found an item that was configured out
150+
--> $DIR/syntax.rs:53:4
151+
|
152+
LL | fn not_numbers_or_periods() {}
153+
| ^^^^^^^^^^^^^^^^^^^^^^
154+
note: the item is gated here
155+
--> $DIR/syntax.rs:51:14
156+
|
157+
LL | #[cfg(version("foo"))]
158+
| ^^^^^^^
137159

138160
error[E0425]: cannot find function `complex_semver_with_metadata` in this scope
139161
--> $DIR/syntax.rs:144:5
140162
|
141163
LL | complex_semver_with_metadata();
142164
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
165+
|
166+
note: found an item that was configured out
167+
--> $DIR/syntax.rs:57:4
168+
|
169+
LL | fn complex_semver_with_metadata() {}
170+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171+
note: the item is gated here
172+
--> $DIR/syntax.rs:55:14
173+
|
174+
LL | #[cfg(version("1.20.0-stable"))]
175+
| ^^^^^^^^^^^^^^^^^
143176

144177
error[E0425]: cannot find function `invalid_major_only` in this scope
145178
--> $DIR/syntax.rs:145:5
146179
|
147180
LL | invalid_major_only();
148181
| ^^^^^^^^^^^^^^^^^^ not found in this scope
182+
|
183+
note: found an item that was configured out
184+
--> $DIR/syntax.rs:80:4
185+
|
186+
LL | fn invalid_major_only() {}
187+
| ^^^^^^^^^^^^^^^^^^
188+
note: the item is gated here
189+
--> $DIR/syntax.rs:78:14
190+
|
191+
LL | #[cfg(version("1"))]
192+
| ^^^^^
149193

150194
error[E0425]: cannot find function `invalid_major_only_zero` in this scope
151195
--> $DIR/syntax.rs:146:5
152196
|
153197
LL | invalid_major_only_zero();
154198
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
199+
|
200+
note: found an item that was configured out
201+
--> $DIR/syntax.rs:84:4
202+
|
203+
LL | fn invalid_major_only_zero() {}
204+
| ^^^^^^^^^^^^^^^^^^^^^^^
205+
note: the item is gated here
206+
--> $DIR/syntax.rs:82:14
207+
|
208+
LL | #[cfg(version("0"))]
209+
| ^^^^^
155210

156211
error[E0425]: cannot find function `invalid_major_only_negative` in this scope
157212
--> $DIR/syntax.rs:147:5
158213
|
159214
LL | invalid_major_only_negative();
160215
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
216+
|
217+
note: found an item that was configured out
218+
--> $DIR/syntax.rs:97:4
219+
|
220+
LL | fn invalid_major_only_negative() {}
221+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
222+
note: the item is gated here
223+
--> $DIR/syntax.rs:95:14
224+
|
225+
LL | #[cfg(version("-1"))]
226+
| ^^^^^^
161227

162228
error[E0425]: cannot find function `exceed_u16_major` in this scope
163229
--> $DIR/syntax.rs:148:5
164230
|
165231
LL | exceed_u16_major();
166232
| ^^^^^^^^^^^^^^^^ not found in this scope
233+
|
234+
note: found an item that was configured out
235+
--> $DIR/syntax.rs:103:4
236+
|
237+
LL | fn exceed_u16_major() {}
238+
| ^^^^^^^^^^^^^^^^
239+
note: the item is gated here
240+
--> $DIR/syntax.rs:101:14
241+
|
242+
LL | #[cfg(version("65536"))]
243+
| ^^^^^^^^^
167244

168245
error[E0425]: cannot find function `exceed_u16_minor` in this scope
169246
--> $DIR/syntax.rs:149:5
170247
|
171248
LL | exceed_u16_minor();
172249
| ^^^^^^^^^^^^^^^^ not found in this scope
250+
|
251+
note: found an item that was configured out
252+
--> $DIR/syntax.rs:107:4
253+
|
254+
LL | fn exceed_u16_minor() {}
255+
| ^^^^^^^^^^^^^^^^
256+
note: the item is gated here
257+
--> $DIR/syntax.rs:105:14
258+
|
259+
LL | #[cfg(version("1.65536.0"))]
260+
| ^^^^^^^^^^^^^
173261

174262
error[E0425]: cannot find function `exceed_u16_patch` in this scope
175263
--> $DIR/syntax.rs:150:5
176264
|
177265
LL | exceed_u16_patch();
178266
| ^^^^^^^^^^^^^^^^ not found in this scope
267+
|
268+
note: found an item that was configured out
269+
--> $DIR/syntax.rs:111:4
270+
|
271+
LL | fn exceed_u16_patch() {}
272+
| ^^^^^^^^^^^^^^^^
273+
note: the item is gated here
274+
--> $DIR/syntax.rs:109:14
275+
|
276+
LL | #[cfg(version("1.0.65536"))]
277+
| ^^^^^^^^^^^^^
179278

180279
error[E0425]: cannot find function `exceed_u16_mixed` in this scope
181280
--> $DIR/syntax.rs:151:5
182281
|
183282
LL | exceed_u16_mixed();
184283
| ^^^^^^^^^^^^^^^^ not found in this scope
284+
|
285+
note: found an item that was configured out
286+
--> $DIR/syntax.rs:115:4
287+
|
288+
LL | fn exceed_u16_mixed() {}
289+
| ^^^^^^^^^^^^^^^^
290+
note: the item is gated here
291+
--> $DIR/syntax.rs:113:14
292+
|
293+
LL | #[cfg(version("65536.0.65536"))]
294+
| ^^^^^^^^^^^^^^^^^
185295

186296
error: aborting due to 14 previous errors; 14 warnings emitted
187297

tests/ui/cfg/cmdline-false.stderr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ 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 | fn foo() {}
11+
| ^^^
12+
note: the item is gated here
13+
--> $DIR/cmdline-false.rs:4:7
14+
|
15+
LL | #[cfg(false)]
16+
| ^^^^^
617

718
error: aborting due to 1 previous error
819

tests/ui/cfg/diagnostics-reexport.rs

Lines changed: 3 additions & 3 deletions
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

Lines changed: 10 additions & 0 deletions
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:11
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

Lines changed: 5 additions & 7 deletions
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
}

0 commit comments

Comments
 (0)