Tweak some suggestions in rustc_resolve

This commit is contained in:
Esteban Küber 2020-04-22 11:58:21 -07:00
parent 82e90d6426
commit 6e3ba6f40f
7 changed files with 56 additions and 25 deletions

View file

@ -383,7 +383,7 @@ fn call_has_self_arg(&self, source: PathSource<'_>) -> Option<(Span, Option<Span
has_self_arg
}
fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) {
fn followed_by_brace(&self, span: Span) -> (bool, Option<Span>) {
// HACK(estebank): find a better way to figure out that this was a
// parser issue where a struct literal is being used on an expression
// where a brace being opened means a block is being started. Look
@ -406,7 +406,7 @@ fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) {
_ => false,
};
// In case this could be a struct literal that needs to be surrounded
// by parenthesis, find the appropriate span.
// by parentheses, find the appropriate span.
let mut i = 0;
let mut closing_brace = None;
loop {
@ -414,10 +414,7 @@ fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) {
match sm.span_to_snippet(sp) {
Ok(ref snippet) => {
if snippet == "}" {
let sp = span.to(sp);
if let Ok(snippet) = sm.span_to_snippet(sp) {
closing_brace = Some((sp, snippet));
}
closing_brace = Some(span.to(sp));
break;
}
}
@ -479,17 +476,23 @@ fn smart_resolve_context_dependent_help(
suggested = path_sep(err, &parent);
}
PathSource::Expr(None) if followed_by_brace => {
if let Some((sp, snippet)) = closing_brace {
err.span_suggestion(
sp,
"surround the struct literal with parenthesis",
format!("({})", snippet),
if let Some(sp) = closing_brace {
err.multipart_suggestion(
"surround the struct literal with parentheses",
vec![
(sp.shrink_to_lo(), "(".to_string()),
(sp.shrink_to_hi(), ")".to_string()),
],
Applicability::MaybeIncorrect,
);
} else {
err.span_label(
span, // Note the parenthesis surrounding the suggestion below
format!("did you mean `({} {{ /* fields */ }})`?", path_str),
span, // Note the parentheses surrounding the suggestion below
format!(
"you might want to surround a struct literal with parentheses: \
`({} {{ /* fields */ }})`?",
path_str
),
);
}
suggested = true;
@ -516,10 +519,16 @@ fn smart_resolve_context_dependent_help(
err.note("if you want the `try` keyword, you need to be in the 2018 edition");
}
}
(Res::Def(DefKind::TyAlias, _), PathSource::Trait(_)) => {
(Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => {
err.span_label(span, "type aliases cannot be used as traits");
if nightly_options::is_nightly_build() {
err.note("did you mean to use a trait alias?");
let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \
`type` alias";
if let Some(span) = self.r.definitions.opt_span(def_id) {
err.span_help(span, msg);
} else {
err.help(msg);
}
}
}
(Res::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {

View file

@ -4,7 +4,11 @@ error[E0404]: expected trait, found type alias `Bar`
LL | impl Bar for Baz { }
| ^^^ type aliases cannot be used as traits
|
= note: did you mean to use a trait alias?
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
--> $DIR/two_files_data.rs:5:1
|
LL | type Bar = dyn Foo;
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View file

@ -45,9 +45,12 @@ error[E0423]: expected value, found struct `T`
--> $DIR/E0423.rs:14:8
|
LL | if T {} == T {} { println!("Ok"); }
| ^---
| |
| help: surround the struct literal with parenthesis: `(T {})`
| ^
|
help: surround the struct literal with parentheses
|
LL | if (T {}) == T {} { println!("Ok"); }
| ^ ^
error: aborting due to 5 previous errors

View file

@ -4,7 +4,11 @@ error[E0404]: expected trait, found type alias `Foo`
LL | impl Foo for S {
| ^^^ type aliases cannot be used as traits
|
= note: did you mean to use a trait alias?
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
--> $DIR/issue-3907.rs:5:1
|
LL | type Foo = dyn issue_3907::Foo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: possible better candidate is found in another module, you can import it into scope
|
LL | use issue_3907::Foo;

View file

@ -16,7 +16,11 @@ LL | impl K for isize {}
| type aliases cannot be used as traits
| help: a trait with a similar name exists: `I`
|
= note: did you mean to use a trait alias?
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
--> $DIR/issue-5035.rs:2:1
|
LL | type K = dyn I;
| ^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -10,7 +10,11 @@ error[E0404]: expected trait, found type alias `Typedef`
LL | fn g<F:Typedef(isize) -> isize>(x: F) {}
| ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used as traits
|
= note: did you mean to use a trait alias?
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
--> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:4:1
|
LL | type Typedef = isize;
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -46,9 +46,12 @@ error[E0423]: expected value, found struct variant `E::V`
--> $DIR/struct-literal-variant-in-if.rs:10:13
|
LL | if x == E::V { field } {}
| ^^^^----------
| |
| help: surround the struct literal with parenthesis: `(E::V { field })`
| ^^^^
|
help: surround the struct literal with parentheses
|
LL | if x == (E::V { field }) {}
| ^ ^
error[E0308]: mismatched types
--> $DIR/struct-literal-variant-in-if.rs:10:20