-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Detect more cfg
d out items in resolution errors
#129183
base: master
Are you sure you want to change the base?
Conversation
compiler/rustc_expand/src/expand.rs
Outdated
ast::UseTreeKind::Nested { items, .. } => { | ||
for (ut, _) in items { | ||
collect_use_tree_leaves(ut, idents); | ||
struct ItemNameVisitor(Vec<Ident>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens in the case of a double or more stripped items? Won't this visitor and method record them twice?
#![allow(unexpected_cfgs)]
#[cfg(foo)]
mod fs {
#[cfg(bar)]
mod unix {
fn fchown() {}
)
}
fn main() {
fs::unix::chown();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gives you
error[E0433]: failed to resolve: use of undeclared crate or module `fs`
--> f72.rs:13:5
|
13 | fs::unix::chown();
| ^^ use of undeclared crate or module `fs`
|
note: found an item that was configured out
--> f72.rs:4:5
|
4 | mod fs {
| ^^
note: the item is gated here
--> f72.rs:3:1
|
3 | #[cfg(foo)]
| ^^^^^^^^^^^
because fs
is not found so that's the only one that would be checked for (not unix
or chown
).
If you check for unix
, it will point at cfg(foo)
, which is not enough to get unix
back, but gets you on the way to it:
error[E0433]: failed to resolve: use of undeclared crate or module `unix`
--> f72.rs:14:5
|
14 | unix::chown();
| ^^^^ use of undeclared crate or module `unix`
|
note: found an item that was configured out
--> f72.rs:6:9
|
6 | mod unix {
| ^^^^
note: the item is gated here
--> f72.rs:3:1
|
3 | #[cfg(foo)]
| ^^^^^^^^^^^
In testing, I noticed that we don't point at fs::unix
when trying unix
directly and it is behind a cfg
(the second error):
error[E0433]: failed to resolve: could not find `unix` in `fs`
--> f72.rs:13:9
|
13 | fs::unix::chown();
| ^^^^ could not find `unix` in `fs`
|
note: found an item that was configured out
--> f72.rs:6:9
|
6 | mod unix {
| ^^^^
note: the item is gated here
--> f72.rs:5:5
|
5 | #[cfg(bar)]
| ^^^^^^^^^^^
error[E0433]: failed to resolve: use of undeclared crate or module `unix`
--> f72.rs:14:5
|
14 | unix::chown();
| ^^^^ use of undeclared crate or module `unix`
If it isn't cfg
d out and it's public, we do provide this suggestion:
error[E0433]: failed to resolve: use of undeclared crate or module `unix`
--> f72.rs:14:5
|
14 | unix::chown();
| ^^^^ use of undeclared crate or module `unix`
|
help: consider importing this module
|
4 + use fs::unix;
|
but if it is private and crate local maybe we should at least point at it (we don't):
error[E0433]: failed to resolve: use of undeclared crate or module `unix`
--> f72.rs:14:5
|
14 | unix::chown();
| ^^^^ use of undeclared crate or module `unix`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to behave as you expected.
tests/ui/cfg/diagnostics-reexport.rs
Outdated
@@ -1,7 +1,7 @@ | |||
pub mod inner { | |||
#[cfg(FALSE)] | |||
#[cfg(FALSE)] //~ NOTE the item is gated here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is correct? no one ever references this item.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because uwu
under inner::gone
now gets included for inner
(because gone
is cfg
d out) when trying to access inner::uwu
. I believe this is the right thing to do. If the user had written inner::gone::uwu
, the output is:
error[E0433]: failed to resolve: could not find `gone` in `inner`
--> tests/ui/cfg/diagnostics-reexport.rs:38:12
|
38 | inner::gone::uwu(); //~ ERROR cannot find function
| ^^^^ could not find `gone` in `inner`
|
note: found an item that was configured out
--> tests/ui/cfg/diagnostics-reexport.rs:3:9
|
3 | mod gone {
| ^^^^
note: the item is gated here
--> tests/ui/cfg/diagnostics-reexport.rs:2:5
|
2 | #[cfg(FALSE)] //~ NOTE the item is gated here
| ^^^^^^^^^^^^^
but if it is inner::gon::uwu
then the output is
error[E0433]: failed to resolve: could not find `gon` in `inner`
--> tests/ui/cfg/diagnostics-reexport.rs:38:12
|
38 | inner::gon::uwu(); //~ ERROR cannot find function
| ^^^ could not find `gon` in `inner`
We might actually want to still search for cfg
d out items both with levenshtein distance (but the signal there is much weaker) and by looking at the very last path segment (to find the cfg
d out uwu
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tend to agree with @Noratrieb: the user wrote inner::uwu
, which refers to the use super::uwu
below, which already failed to resolve without suggesting gone
. Either both suggest gone::uwu
, or none of them.
We are doing more work on a good path here. |
This comment has been minimized.
This comment has been minimized.
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)))] | ^^^^^^^^^^ ```
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (623e6c7): comparison URL. Overall result: ❌✅ regressions and improvements - ACTION NEEDEDBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)Results (primary 2.6%, secondary 1.5%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (secondary -2.9%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeResults (primary 0.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Bootstrap: 749.153s -> 748.829s (-0.04%) |
It might make sense to limit the visitor to two levels of nesting at most, as a way to attempt to reduce the impact on crates that have large modules |
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
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)))] | ^^^^^^^^^^ ```
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (811a696): comparison URL. Overall result: ❌✅ regressions and improvements - ACTION NEEDEDBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)Results (primary 1.6%, secondary 2.3%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (secondary -2.9%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeResults (primary 0.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Bootstrap: 753.9s -> 754.227s (0.04%) |
I suspect that the regressions on incr-comp for html5ever-0.26 are caused by this gated macro expansion. clap-3.1.6 is quite feature heavy. I leave it to you whether the impact on incr-comp of munching through more nodes is worth it. I believe it it is, as when items are |
Possibly related enough to consider as part of this (if it's not already). #134448 |
// 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". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is correct? it should be the current module def id instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been a while since I last looked at this code, but I think this was referring to https://github.com/rust-lang/rust/pull/129183/files#diff-0e459b4cbb41dd93274d7c68b18a2a3eab7152e9aea107839a7bddff0b4e9195R819
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah I didn't clarify, the comment matches the implementation but I think the implementation is wrong
@estebank can you explain why this nesting is necessary? I fail to see a case where nesting is necessary, as resolution will always fail at the outermost missing item, making the inner ones physically inaccessible. |
0e22c73
to
1b7a0f3
Compare
Removed the recursive search. My logic was "the user already thinks an item exists, they might have both used the wrong path and have it disabled behind a cfg flag" where knowing the item is somewhere but not seeing the cfg would be confusing. But left with a single level as I think we should land at least the simpler version. |
1b7a0f3
to
d4e2623
Compare
☔ The latest upstream changes (presumably #133154) made this pull request unmergeable. Please resolve the merge conflicts. |
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)))] | ^^^^^^^^^^ ```
Use a visitor to collect all items (including those nested) that were stripped behind a
cfg
condition.