diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index e7fa88bff97d5..8727e280bcb9d 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -383,7 +383,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { has_self_arg } - fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) { + fn followed_by_brace(&self, span: Span) -> (bool, Option) { // 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 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { _ => 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 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { 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 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { 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 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { 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))) => { diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index 5027b78b38e34..de2ffc2e5dc1d 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -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 diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index a985e963e5726..d4860394259b7 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -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 diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index 384df571e2a80..16436a9accc85 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -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; diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr index 622f0dfcda4cb..41dff2fe54205 100644 --- a/src/test/ui/resolve/issue-5035.stderr +++ b/src/test/ui/resolve/issue-5035.stderr @@ -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 diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr index c86a6d70344cc..2974d08eb23b1 100644 --- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -10,7 +10,11 @@ error[E0404]: expected trait, found type alias `Typedef` LL | fn g 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 diff --git a/src/test/ui/struct-literal-variant-in-if.stderr b/src/test/ui/struct-literal-variant-in-if.stderr index d232a46f8ec29..4cd1169cc1bb8 100644 --- a/src/test/ui/struct-literal-variant-in-if.stderr +++ b/src/test/ui/struct-literal-variant-in-if.stderr @@ -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