Skip to content

Commit fac84e8

Browse files
authored
Rollup merge of rust-lang#100228 - luqmana:suggestion-ice, r=estebank
Don't ICE while suggesting updating item path. When an item isn't found, we may suggest an appropriate import to `use`. Along with that, we also suggest updating the path to work with the `use`. Unfortunately, if the code in question originates from a macro, the span used to indicate which part of the path needs updating may not be suitable and cause an ICE (*). Since, such code is not adjustable directly by the user without modifying the macro, just skip the suggestion in such cases. (*) The ICE happens because the emitter want to indicate to the user what code to delete by referencing a certain span. But in this case, said span has `lo == hi == 0` which means it thinks it's a dummy span. Adding a space before the proc macro attribute is enough to stop it from ICE'ing but even then the suggestion doesn't really make any sense: ``` help: if you import `DataStore`, refer to it directly | 1 - #[dbstruct::dbstruct] 1 + #[dbstruct::dbstruct] ``` Since suggestions are best-effort, I just gated this one on `can_be_used_for_suggestions` which catches cases like this. Fixes rust-lang#100199
2 parents d910e53 + 15b1daa commit fac84e8

File tree

4 files changed

+58
-6
lines changed

4 files changed

+58
-6
lines changed

compiler/rustc_resolve/src/diagnostics.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -2544,12 +2544,15 @@ fn show_candidates(
25442544
Applicability::MaybeIncorrect,
25452545
);
25462546
if let [first, .., last] = &path[..] {
2547-
err.span_suggestion_verbose(
2548-
first.ident.span.until(last.ident.span),
2549-
&format!("if you import `{}`, refer to it directly", last.ident),
2550-
"",
2551-
Applicability::Unspecified,
2552-
);
2547+
let sp = first.ident.span.until(last.ident.span);
2548+
if sp.can_be_used_for_suggestions() {
2549+
err.span_suggestion_verbose(
2550+
sp,
2551+
&format!("if you import `{}`, refer to it directly", last.ident),
2552+
"",
2553+
Applicability::Unspecified,
2554+
);
2555+
}
25532556
}
25542557
} else {
25552558
msg.push(':');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
#![feature(proc_macro_quote)]
6+
7+
extern crate proc_macro;
8+
9+
use proc_macro::{quote, Ident, Span, TokenStream, TokenTree};
10+
11+
#[proc_macro_attribute]
12+
pub fn struct_with_bound(_: TokenStream, _: TokenStream) -> TokenStream {
13+
let crate_ident = TokenTree::Ident(Ident::new("crate", Span::call_site()));
14+
let trait_ident = TokenTree::Ident(Ident::new("MyTrait", Span::call_site()));
15+
quote!(
16+
struct Foo<T: $crate_ident::$trait_ident> {}
17+
)
18+
}

src/test/ui/macros/issue-100199.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#[issue_100199::struct_with_bound] //~ ERROR cannot find trait `MyTrait` in the crate root
2+
struct Foo {}
3+
// The above must be on the first line so that it's span points to pos 0.
4+
// This used to trigger an ICE because the diagnostic emitter would get
5+
// an unexpected dummy span (lo == 0 == hi) while attempting to print a
6+
// suggestion.
7+
8+
// aux-build: issue-100199.rs
9+
10+
extern crate issue_100199;
11+
12+
mod traits {
13+
pub trait MyTrait {}
14+
}
15+
16+
fn main() {}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0405]: cannot find trait `MyTrait` in the crate root
2+
--> $DIR/issue-100199.rs:1:1
3+
|
4+
LL | #[issue_100199::struct_with_bound]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in the crate root
6+
|
7+
= note: this error originates in the attribute macro `issue_100199::struct_with_bound` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
help: consider importing this trait
9+
|
10+
LL | use traits::MyTrait;
11+
|
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0405`.

0 commit comments

Comments
 (0)