-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Tweak diagnostic for use
suggestion to blank text surrounding span.
#90941
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,63 @@ | ||||||||||||||||||
// aux-build:amputate-span.rs | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we make it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding #[amputate_span::drop_first_token]
/* what the
hey */ async use std::process::Command;
fn main() {
Command::new("git"); //~ ERROR [E0433]
} and #[amputate_span::drop_first_token]
/* what the
hey */ async use std::process::Command;
fn main() {
Command::new("git"); //~ ERROR [E0433]
} I'm guessing that's because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may be somewhat related to this FIXME from PR #85427 that originally stems from PR #44215. Fixing that might serve as an argument for moving away from the "infer the span from the given item's span" strategy, and using the span of the containing mod/crate instead, as discussed in my other comment rust/src/test/ui/resolve/use_suggestion_placement.fixed Lines 17 to 24 in 934624f
|
||||||||||||||||||
// edition:2018 | ||||||||||||||||||
// compile-flags: --extern amputate_span | ||||||||||||||||||
|
||||||||||||||||||
// This test has been crafted to ensure the following things: | ||||||||||||||||||
// | ||||||||||||||||||
// 1. There's a resolution error that prompts the compiler to suggest | ||||||||||||||||||
// adding a `use` item. | ||||||||||||||||||
// | ||||||||||||||||||
// 2. There are no `use` or `extern crate` items in the source | ||||||||||||||||||
// code. In fact, there is only one item, the `fn main` | ||||||||||||||||||
// declaration. | ||||||||||||||||||
// | ||||||||||||||||||
// 3. The single `fn main` declaration has an attribute attached to it | ||||||||||||||||||
// that just deletes the first token from the given item. | ||||||||||||||||||
// | ||||||||||||||||||
// You need all of these conditions to hold in order to replicate the | ||||||||||||||||||
// scenario that yielded issue 87613, where the compiler's suggestion | ||||||||||||||||||
// looks like: | ||||||||||||||||||
// | ||||||||||||||||||
// ``` | ||||||||||||||||||
// help: consider importing this struct | ||||||||||||||||||
// | | ||||||||||||||||||
// 47 | hey */ async use std::process::Command; | ||||||||||||||||||
// | ++++++++++++++++++++++++++ | ||||||||||||||||||
// ``` | ||||||||||||||||||
// | ||||||||||||||||||
// The first condition is necessary to force the compiler issue a | ||||||||||||||||||
// suggestion. The second condition is necessary to force the | ||||||||||||||||||
// suggestion to be issued at a span associated with the sole | ||||||||||||||||||
// `fn`-item of this crate. The third condition is necessary in order | ||||||||||||||||||
// to yield the weird state where the associated span of the `fn`-item | ||||||||||||||||||
// does not actually cover all of the original source code of the | ||||||||||||||||||
// `fn`-item (which is why we are calling it an "amputated" span | ||||||||||||||||||
// here). | ||||||||||||||||||
// | ||||||||||||||||||
// Note that satisfying conditions 2 and 3 requires the use of the | ||||||||||||||||||
// `--extern` compile flag. | ||||||||||||||||||
// | ||||||||||||||||||
// You might ask yourself: What code would do such a thing? The | ||||||||||||||||||
// answer is: the #[tokio::main] attribute does *exactly* this (as | ||||||||||||||||||
// well as injecting some other code into the `fn main` that it | ||||||||||||||||||
// constructs). | ||||||||||||||||||
|
||||||||||||||||||
#[amputate_span::drop_first_token] | ||||||||||||||||||
/* what the | ||||||||||||||||||
hey */ async fn main() { | ||||||||||||||||||
Command::new("git"); //~ ERROR [E0433] | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
// (The /* ... */ comment in the above is not part of the original | ||||||||||||||||||
// bug. It is just meant to illustrate one particular facet of the | ||||||||||||||||||
// original non-ideal behavior, where we were transcribing the | ||||||||||||||||||
// trailing comment as part of the emitted suggestion, for better or | ||||||||||||||||||
// for worse.) | ||||||||||||||||||
|
||||||||||||||||||
mod inner { | ||||||||||||||||||
#[amputate_span::drop_first_token] | ||||||||||||||||||
/* another interesting | ||||||||||||||||||
case */ async fn foo() { | ||||||||||||||||||
Command::new("git"); //~ ERROR [E0433] | ||||||||||||||||||
} | ||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
error[E0433]: failed to resolve: use of undeclared type `Command` | ||
--> $DIR/amputate-span.rs:48:5 | ||
| | ||
LL | Command::new("git"); | ||
| ^^^^^^^ not found in this scope | ||
| | ||
help: consider importing this struct | ||
| | ||
LL | use std::process::Command; | ||
| | ||
|
||
error[E0433]: failed to resolve: use of undeclared type `Command` | ||
--> $DIR/amputate-span.rs:61:2 | ||
| | ||
LL | Command::new("git"); | ||
| ^^^^^^^ not found in this scope | ||
| | ||
help: consider importing this struct | ||
| | ||
LL | use std::process::Command; | ||
| | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0433`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// force-host | ||
// no-prefer-dynamic | ||
|
||
#![crate_type = "proc-macro"] | ||
|
||
extern crate proc_macro; | ||
|
||
use proc_macro::TokenStream; | ||
|
||
#[proc_macro_attribute] | ||
pub fn drop_first_token(attr: TokenStream, input: TokenStream) -> TokenStream { | ||
assert!(attr.is_empty()); | ||
input.into_iter().skip(1).collect() | ||
} |
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.
If the goal is to preserve indentation, I think removing any non-whitespace characters may be better? For example, in the
async fn
case, you probably wantuse
aligned withasync
, not indented to thefn
.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.
Well, then trailing
... */
comments (which would likewise get removed under your suggestion) end up messing up the indentation?And I guess if the item is on the same line as its containing module, we might likewise have a problem:
But I freely admit, both of these cases sound much more rare than
#[tokio::main]
. :)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 think I'm gradually talking myself into going back and looking at deriving the span from the span of the containing mod/crate again, despite my earlier frustrations with that approach.)