From eef284be59bbbe50e4d5369542a80e1ccd2ba7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 9 Aug 2020 20:29:39 -0700 Subject: [PATCH 1/4] Tweak ordering of suggestions Modify logic to make it easier to follow and recover labels that would otherwise be lost. --- src/librustc_resolve/late/diagnostics.rs | 16 ++++--- .../ui/empty/empty-struct-braces-expr.stderr | 38 ++++++++++------ .../ui/empty/empty-struct-braces-pat-1.stderr | 8 ++-- .../ui/empty/empty-struct-braces-pat-2.stderr | 44 ++++++++++++++----- .../ui/empty/empty-struct-braces-pat-3.stderr | 22 +++++++--- src/test/ui/error-codes/E0423.stderr | 11 +++-- .../issue-64792-bad-unicode-ctor.stderr | 10 ++--- src/test/ui/namespace/namespace-mix.stderr | 16 +++---- src/test/ui/resolve/issue-39226.stderr | 8 ++-- src/test/ui/resolve/privacy-enum-ctor.stderr | 16 +++---- ...uggest-path-instead-of-mod-dot-item.stderr | 16 +++---- .../fn-or-tuple-struct-without-args.stderr | 8 ++-- .../type/type-ascription-with-fn-call.stderr | 5 +-- 13 files changed, 131 insertions(+), 87 deletions(-) diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index ec6dbb070df..1ea0a6ff218 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -339,8 +339,6 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { // Try Levenshtein algorithm. let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected, span); - let levenshtein_worked = self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span); - // Try context-dependent help if relaxed lookup didn't work. if let Some(res) = res { if self.smart_resolve_context_dependent_help( @@ -351,14 +349,18 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { &path_str, &fallback_label, ) { + // We do this to avoid losing a secondary span when we override the main error span. + self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span); return (err, candidates); } } - // Fallback label. - if !levenshtein_worked { + if !self.type_ascription_suggestion(&mut err, base_span) + && !self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span) + { + // Fallback label. err.span_label(base_span, fallback_label); - self.type_ascription_suggestion(&mut err, base_span); + match self.diagnostic_metadata.current_let_binding { Some((pat_sp, Some(ty_sp), None)) if ty_sp.contains(base_span) && could_be_expr => { err.span_suggestion_short( @@ -869,7 +871,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { start.to(sm.next_point(start)) } - fn type_ascription_suggestion(&self, err: &mut DiagnosticBuilder<'_>, base_span: Span) { + fn type_ascription_suggestion(&self, err: &mut DiagnosticBuilder<'_>, base_span: Span) -> bool { let sm = self.r.session.source_map(); let base_snippet = sm.span_to_snippet(base_span); if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() { @@ -939,9 +941,11 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { "expecting a type here because of type ascription", ); } + return show_label; } } } + false } fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> { diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index c0ba9716fb0..af783996f76 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -12,14 +12,14 @@ LL | let e1 = Empty1; LL | pub struct XEmpty2; | ------------------- similarly named unit struct `XEmpty2` defined here | -help: a unit struct with a similar name exists - | -LL | let e1 = XEmpty2; - | ^^^^^^^ help: use struct literal syntax instead | LL | let e1 = Empty1 {}; | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL | let e1 = XEmpty2; + | ^^^^^^^ error[E0423]: expected function, tuple struct or tuple variant, found struct `Empty1` --> $DIR/empty-struct-braces-expr.rs:16:14 @@ -29,15 +29,20 @@ LL | struct Empty1 {} ... LL | let e1 = Empty1(); | ^^^^^^^^ + | + ::: $DIR/auxiliary/empty-struct.rs:2:1 | -help: a unit struct with a similar name exists +LL | pub struct XEmpty2; + | ------------------- similarly named unit struct `XEmpty2` defined here | -LL | let e1 = XEmpty2(); - | ^^^^^^^ help: use struct literal syntax instead | LL | let e1 = Empty1 {}; | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL | let e1 = XEmpty2(); + | ^^^^^^^ error[E0423]: expected value, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-expr.rs:18:14 @@ -68,29 +73,34 @@ LL | let xe1 = XEmpty1; LL | pub struct XEmpty2; | ------------------- similarly named unit struct `XEmpty2` defined here | -help: a unit struct with a similar name exists - | -LL | let xe1 = XEmpty2; - | ^^^^^^^ help: use struct literal syntax instead | LL | let xe1 = XEmpty1 {}; | ^^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL | let xe1 = XEmpty2; + | ^^^^^^^ error[E0423]: expected function, tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-expr.rs:23:15 | LL | let xe1 = XEmpty1(); | ^^^^^^^^^ + | + ::: $DIR/auxiliary/empty-struct.rs:2:1 | -help: a unit struct with a similar name exists +LL | pub struct XEmpty2; + | ------------------- similarly named unit struct `XEmpty2` defined here | -LL | let xe1 = XEmpty2(); - | ^^^^^^^ help: use struct literal syntax instead | LL | let xe1 = XEmpty1 {}; | ^^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL | let xe1 = XEmpty2(); + | ^^^^^^^ error[E0599]: no variant or associated item named `Empty3` found for enum `empty_struct::XE` in the current scope --> $DIR/empty-struct-braces-expr.rs:25:19 diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr index b027c82f7dd..70847ca45d0 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr @@ -18,14 +18,14 @@ LL | XE::XEmpty3 => () LL | XEmpty4, | ------- similarly named unit variant `XEmpty4` defined here | -help: a unit variant with a similar name exists - | -LL | XE::XEmpty4 => () - | ^^^^^^^ help: use struct pattern syntax instead | LL | XE::XEmpty3 { /* fields */ } => () | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: a unit variant with a similar name exists + | +LL | XE::XEmpty4 => () + | ^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/empty/empty-struct-braces-pat-2.stderr b/src/test/ui/empty/empty-struct-braces-pat-2.stderr index a53b88db7d1..19792bc9fc5 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-2.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-2.stderr @@ -6,30 +6,40 @@ LL | struct Empty1 {} ... LL | Empty1() => () | ^^^^^^^^ + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 | -help: a tuple struct with a similar name exists +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here | -LL | XEmpty6() => () - | ^^^^^^^ help: use struct pattern syntax instead | LL | Empty1 {} => () | ^^^^^^^^^ +help: a tuple struct with a similar name exists + | +LL | XEmpty6() => () + | ^^^^^^^ error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-pat-2.rs:18:9 | LL | XEmpty1() => () | ^^^^^^^^^ + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 | -help: a tuple struct with a similar name exists +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here | -LL | XEmpty6() => () - | ^^^^^^^ help: use struct pattern syntax instead | LL | XEmpty1 {} => () | ^^^^^^^^^^ +help: a tuple struct with a similar name exists + | +LL | XEmpty6() => () + | ^^^^^^^ error[E0532]: expected tuple struct or tuple variant, found struct `Empty1` --> $DIR/empty-struct-braces-pat-2.rs:21:9 @@ -39,30 +49,40 @@ LL | struct Empty1 {} ... LL | Empty1(..) => () | ^^^^^^^^^^ + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 | -help: a tuple struct with a similar name exists +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here | -LL | XEmpty6(..) => () - | ^^^^^^^ help: use struct pattern syntax instead | LL | Empty1 {} => () | ^^^^^^^^^ +help: a tuple struct with a similar name exists + | +LL | XEmpty6(..) => () + | ^^^^^^^ error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-pat-2.rs:24:9 | LL | XEmpty1(..) => () | ^^^^^^^^^^^ + | + ::: $DIR/auxiliary/empty-struct.rs:3:1 | -help: a tuple struct with a similar name exists +LL | pub struct XEmpty6(); + | --------------------- similarly named tuple struct `XEmpty6` defined here | -LL | XEmpty6(..) => () - | ^^^^^^^ help: use struct pattern syntax instead | LL | XEmpty1 {} => () | ^^^^^^^^^^ +help: a tuple struct with a similar name exists + | +LL | XEmpty6(..) => () + | ^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr index 93ace3eccef..066c42d8181 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr @@ -12,15 +12,20 @@ error[E0532]: expected tuple struct or tuple variant, found struct variant `XE:: | LL | XE::XEmpty3() => () | ^^^^^^^^^^^^^ + | + ::: $DIR/auxiliary/empty-struct.rs:8:5 | -help: a tuple variant with a similar name exists +LL | XEmpty5(), + | --------- similarly named tuple variant `XEmpty5` defined here | -LL | XE::XEmpty5() => () - | ^^^^^^^ help: use struct pattern syntax instead | LL | XE::XEmpty3 { /* fields */ } => () | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: a tuple variant with a similar name exists + | +LL | XE::XEmpty5() => () + | ^^^^^^^ error[E0532]: expected tuple struct or tuple variant, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-pat-3.rs:25:9 @@ -36,15 +41,20 @@ error[E0532]: expected tuple struct or tuple variant, found struct variant `XE:: | LL | XE::XEmpty3(..) => () | ^^^^^^^^^^^^^^^ + | + ::: $DIR/auxiliary/empty-struct.rs:8:5 | -help: a tuple variant with a similar name exists +LL | XEmpty5(), + | --------- similarly named tuple variant `XEmpty5` defined here | -LL | XE::XEmpty5(..) => () - | ^^^^^^^ help: use struct pattern syntax instead | LL | XE::XEmpty3 { /* fields */ } => () | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: a tuple variant with a similar name exists + | +LL | XE::XEmpty5(..) => () + | ^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index 077367de9d8..e43b3c3546b 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -34,15 +34,18 @@ LL | struct Foo { a: bool }; LL | LL | let f = Foo(); | ^^^^^ +... +LL | fn foo() { + | -------- similarly named function `foo` defined here | -help: a function with a similar name exists - | -LL | let f = foo(); - | ^^^ help: use struct literal syntax instead | LL | let f = Foo { a: val }; | ^^^^^^^^^^^^^^ +help: a function with a similar name exists + | +LL | let f = foo(); + | ^^^ error[E0423]: expected value, found struct `T` --> $DIR/E0423.rs:14:8 diff --git a/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr b/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr index 12053d8a129..aa30a7e0d64 100644 --- a/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr +++ b/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr @@ -5,16 +5,16 @@ LL | struct X {} | ----------- `X` defined here LL | LL | const Y: X = X("ö"); - | ^^^^^^ + | -------------^^^^^^- similarly named constant `Y` defined here | -help: a constant with a similar name exists - | -LL | const Y: X = Y("ö"); - | ^ help: use struct literal syntax instead | LL | const Y: X = X {}; | ^^^^ +help: a constant with a similar name exists + | +LL | const Y: X = Y("ö"); + | ^ error: aborting due to previous error diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index 636789c9cc3..2e25ffa168f 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -53,14 +53,14 @@ LL | TV(), LL | check(m7::V); | ^^^^^ | -help: a tuple variant with a similar name exists - | -LL | check(m7::TV); - | ^^ help: use struct literal syntax instead | LL | check(m7::V {}); | ^^^^^^^^ +help: a tuple variant with a similar name exists + | +LL | check(m7::TV); + | ^^ help: consider importing one of these items instead | LL | use m8::V; @@ -79,14 +79,14 @@ LL | check(xm7::V); LL | TV(), | ---- similarly named tuple variant `TV` defined here | -help: a tuple variant with a similar name exists - | -LL | check(xm7::TV); - | ^^ help: use struct literal syntax instead | LL | check(xm7::V { /* fields */ }); | ^^^^^^^^^^^^^^^^^^^^^^^ +help: a tuple variant with a similar name exists + | +LL | check(xm7::TV); + | ^^ help: consider importing one of these items instead | LL | use m8::V; diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr index c9b9aeb45ba..72d66b0f6a2 100644 --- a/src/test/ui/resolve/issue-39226.stderr +++ b/src/test/ui/resolve/issue-39226.stderr @@ -7,14 +7,14 @@ LL | struct Handle {} LL | handle: Handle | ^^^^^^ | -help: a local variable with a similar name exists - | -LL | handle: handle - | ^^^^^^ help: use struct literal syntax instead | LL | handle: Handle {} | ^^^^^^^^^ +help: a local variable with a similar name exists + | +LL | handle: handle + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index 3904a00dde1..f3cc338f13c 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -22,10 +22,6 @@ LL | fn f() { LL | Z; | ^ | -help: a function with a similar name exists - | -LL | f; - | ^ help: try using one of the enum's variants | LL | m::Z::Fn; @@ -34,6 +30,10 @@ LL | m::Z::Struct; | ^^^^^^^^^^^^ LL | m::Z::Unit; | ^^^^^^^^^^ +help: a function with a similar name exists + | +LL | f; + | ^ error[E0423]: expected value, found struct variant `Z::Struct` --> $DIR/privacy-enum-ctor.rs:29:20 @@ -55,10 +55,6 @@ LL | fn f() { LL | let _: E = m::E; | ^^^^ | -help: a function with a similar name exists - | -LL | let _: E = m::f; - | ^ help: try using one of the enum's variants | LL | let _: E = E::Fn; @@ -67,6 +63,10 @@ LL | let _: E = E::Struct; | ^^^^^^^^^ LL | let _: E = E::Unit; | ^^^^^^^ +help: a function with a similar name exists + | +LL | let _: E = m::f; + | ^ help: consider importing one of these items instead | LL | use std::f32::consts::E; diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr index 33080340cb6..2d35159ec9a 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -31,14 +31,14 @@ LL | pub const I: i32 = 1; LL | a::b.J | ^^^^ | -help: a constant with a similar name exists - | -LL | a::I.J - | ^ help: use the path separator to refer to an item | LL | a::b::J | +help: a constant with a similar name exists + | +LL | a::I.J + | ^ error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:37:5 @@ -68,14 +68,14 @@ LL | pub const I: i32 = 1; LL | a::b.f() | ^^^^ | -help: a constant with a similar name exists - | -LL | a::I.f() - | ^ help: use the path separator to refer to an item | LL | a::b::f() | ^^^^^^^ +help: a constant with a similar name exists + | +LL | a::I.f() + | ^ error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5 diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr index 45309486db4..9b2febb1393 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -9,14 +9,14 @@ LL | B { a: usize }, LL | let _: E = E::B; | ^^^^ | -help: a tuple variant with a similar name exists - | -LL | let _: E = E::A; - | ^ help: use struct literal syntax instead | LL | let _: E = E::B { a: val }; | ^^^^^^^^^^^^^^^ +help: a tuple variant with a similar name exists + | +LL | let _: E = E::A; + | ^ error[E0308]: mismatched types --> $DIR/fn-or-tuple-struct-without-args.rs:29:20 diff --git a/src/test/ui/type/type-ascription-with-fn-call.stderr b/src/test/ui/type/type-ascription-with-fn-call.stderr index 5f74724b59e..d78fd08fd60 100644 --- a/src/test/ui/type/type-ascription-with-fn-call.stderr +++ b/src/test/ui/type/type-ascription-with-fn-call.stderr @@ -4,10 +4,7 @@ error[E0573]: expected type, found function `f` LL | f() : | - help: maybe you meant to write `;` here LL | f(); - | ^^^ - | | - | not a type - | expecting a type here because of type ascription + | ^^^ expecting a type here because of type ascription error: aborting due to previous error From 089810a1cb28cfb0262b62f1d36c75ea790b0739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 9 Aug 2020 21:02:58 -0700 Subject: [PATCH 2/4] Do not suggest similarly named enclosing item --- src/librustc_resolve/diagnostics.rs | 57 +++++++++++++------ .../struct-with-invalid-const-param.stderr | 5 +- src/test/ui/issues/issue-31845.stderr | 4 +- .../issue-64792-bad-unicode-ctor.stderr | 11 +--- .../ui/privacy/legacy-ctor-visibility.stderr | 4 +- .../attributes-on-modules-fail.stderr | 12 +--- src/test/ui/resolve/privacy-enum-ctor.stderr | 7 --- src/test/ui/ui-testing-optout.stderr | 5 +- 8 files changed, 46 insertions(+), 59 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 9502be728de..de92204a7c2 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -942,6 +942,45 @@ impl<'a> Resolver<'a> { Some(suggestion) if suggestion.candidate == kw::Underscore => return false, Some(suggestion) => suggestion, }; + let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate { + LOCAL_CRATE => self.opt_span(def_id), + _ => Some( + self.session + .source_map() + .guess_head_span(self.cstore().get_span_untracked(def_id, self.session)), + ), + }); + if let Some(def_span) = def_span { + if span.overlaps(def_span) { + // Don't suggest typo suggestion for itself like in the followoing: + // error[E0423]: expected function, tuple struct or tuple variant, found struct `X` + // --> $DIR/issue-64792-bad-unicode-ctor.rs:3:14 + // | + // LL | struct X {} + // | ----------- `X` defined here + // LL | + // LL | const Y: X = X("ö"); + // | -------------^^^^^^- similarly named constant `Y` defined here + // | + // help: use struct literal syntax instead + // | + // LL | const Y: X = X {}; + // | ^^^^ + // help: a constant with a similar name exists + // | + // LL | const Y: X = Y("ö"); + // | ^ + return false; + } + err.span_label( + self.session.source_map().guess_head_span(def_span), + &format!( + "similarly named {} `{}` defined here", + suggestion.res.descr(), + suggestion.candidate.as_str(), + ), + ); + } let msg = format!( "{} {} with a similar name exists", suggestion.res.article(), @@ -953,24 +992,6 @@ impl<'a> Resolver<'a> { suggestion.candidate.to_string(), Applicability::MaybeIncorrect, ); - let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate { - LOCAL_CRATE => self.opt_span(def_id), - _ => Some( - self.session - .source_map() - .guess_head_span(self.cstore().get_span_untracked(def_id, self.session)), - ), - }); - if let Some(span) = def_span { - err.span_label( - self.session.source_map().guess_head_span(span), - &format!( - "similarly named {} `{}` defined here", - suggestion.res.descr(), - suggestion.candidate.as_str(), - ), - ); - } true } diff --git a/src/test/ui/const-generics/struct-with-invalid-const-param.stderr b/src/test/ui/const-generics/struct-with-invalid-const-param.stderr index a968b26bc26..47617c7849f 100644 --- a/src/test/ui/const-generics/struct-with-invalid-const-param.stderr +++ b/src/test/ui/const-generics/struct-with-invalid-const-param.stderr @@ -2,10 +2,7 @@ error[E0573]: expected type, found const parameter `C` --> $DIR/struct-with-invalid-const-param.rs:4:23 | LL | struct S(C); - | ----------------------^-- - | | | - | | help: a struct with a similar name exists: `S` - | similarly named struct `S` defined here + | ^ not a type warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/struct-with-invalid-const-param.rs:1:12 diff --git a/src/test/ui/issues/issue-31845.stderr b/src/test/ui/issues/issue-31845.stderr index fe51fa0699f..56281938559 100644 --- a/src/test/ui/issues/issue-31845.stderr +++ b/src/test/ui/issues/issue-31845.stderr @@ -1,10 +1,8 @@ error[E0425]: cannot find function `g` in this scope --> $DIR/issue-31845.rs:7:12 | -LL | fn h() { - | ------ similarly named function `h` defined here LL | g(); - | ^ help: a function with a similar name exists: `h` + | ^ not found in this scope error: aborting due to previous error diff --git a/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr b/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr index aa30a7e0d64..c3dda704b0e 100644 --- a/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr +++ b/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr @@ -5,16 +5,7 @@ LL | struct X {} | ----------- `X` defined here LL | LL | const Y: X = X("ö"); - | -------------^^^^^^- similarly named constant `Y` defined here - | -help: use struct literal syntax instead - | -LL | const Y: X = X {}; - | ^^^^ -help: a constant with a similar name exists - | -LL | const Y: X = Y("ö"); - | ^ + | ^^^^^^ help: use struct literal syntax instead: `X {}` error: aborting due to previous error diff --git a/src/test/ui/privacy/legacy-ctor-visibility.stderr b/src/test/ui/privacy/legacy-ctor-visibility.stderr index 4f0d72de6f1..c8057d85ed1 100644 --- a/src/test/ui/privacy/legacy-ctor-visibility.stderr +++ b/src/test/ui/privacy/legacy-ctor-visibility.stderr @@ -1,10 +1,8 @@ error[E0423]: expected function, tuple struct or tuple variant, found struct `S` --> $DIR/legacy-ctor-visibility.rs:9:13 | -LL | fn f() { - | ------ similarly named function `f` defined here LL | S(10); - | ^ help: a function with a similar name exists: `f` + | ^ error: aborting due to previous error diff --git a/src/test/ui/proc-macro/attributes-on-modules-fail.stderr b/src/test/ui/proc-macro/attributes-on-modules-fail.stderr index b37f1bd393c..97b2f22e161 100644 --- a/src/test/ui/proc-macro/attributes-on-modules-fail.stderr +++ b/src/test/ui/proc-macro/attributes-on-modules-fail.stderr @@ -44,12 +44,8 @@ error[E0412]: cannot find type `Y` in this scope --> $DIR/attributes-on-modules-fail.rs:10:14 | LL | type A = Y; - | ---------^- similarly named type alias `A` defined here + | ^ not found in this scope | -help: a type alias with a similar name exists - | -LL | type A = A; - | ^ help: consider importing this struct | LL | use Y; @@ -59,12 +55,8 @@ error[E0412]: cannot find type `X` in this scope --> $DIR/attributes-on-modules-fail.rs:14:10 | LL | type A = X; - | ---------^- similarly named type alias `A` defined here + | ^ not found in this scope | -help: a type alias with a similar name exists - | -LL | type A = A; - | ^ help: consider importing this struct | LL | use m::X; diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index f3cc338f13c..f1ed7aaa867 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -16,9 +16,6 @@ LL | m::Z::Unit; error[E0423]: expected value, found enum `Z` --> $DIR/privacy-enum-ctor.rs:25:9 | -LL | fn f() { - | ------ similarly named function `f` defined here -... LL | Z; | ^ | @@ -30,10 +27,6 @@ LL | m::Z::Struct; | ^^^^^^^^^^^^ LL | m::Z::Unit; | ^^^^^^^^^^ -help: a function with a similar name exists - | -LL | f; - | ^ error[E0423]: expected value, found struct variant `Z::Struct` --> $DIR/privacy-enum-ctor.rs:29:20 diff --git a/src/test/ui/ui-testing-optout.stderr b/src/test/ui/ui-testing-optout.stderr index f562bb74c11..652c472c0bc 100644 --- a/src/test/ui/ui-testing-optout.stderr +++ b/src/test/ui/ui-testing-optout.stderr @@ -2,10 +2,7 @@ error[E0412]: cannot find type `B` in this scope --> $DIR/ui-testing-optout.rs:4:10 | 4 | type A = B; - | ---------^- - | | | - | | help: a type alias with a similar name exists: `A` - | similarly named type alias `A` defined here + | ^ not found in this scope error[E0412]: cannot find type `D` in this scope --> $DIR/ui-testing-optout.rs:7:10 From 6c0755a7dcbc087309035cb53893dd478bd3b8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 9 Aug 2020 21:14:59 -0700 Subject: [PATCH 3/4] Point at item definition in foreign crates --- src/librustc_resolve/late/diagnostics.rs | 20 +++++++++++++++---- .../ui/empty/empty-struct-braces-expr.stderr | 8 ++++++-- .../ui/empty/empty-struct-braces-pat-1.stderr | 4 +++- .../ui/empty/empty-struct-braces-pat-2.stderr | 10 ++++++++-- .../ui/empty/empty-struct-braces-pat-3.stderr | 10 ++++++++-- .../ui/empty/empty-struct-tuple-pat.stderr | 2 ++ src/test/ui/namespace/namespace-mix.stderr | 4 +++- src/test/ui/resolve/issue-19452.stderr | 5 +++++ src/test/ui/xcrate/xcrate-unit-struct.stderr | 5 +++++ 9 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 1ea0a6ff218..38bbbb1db1b 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -12,7 +12,7 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder} use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind}; -use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::PrimTy; use rustc_session::config::nightly_options; use rustc_span::hygiene::MacroKind; @@ -88,6 +88,18 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str } impl<'a> LateResolutionVisitor<'a, '_, '_> { + fn def_span(&self, def_id: DefId) -> Option { + match def_id.krate { + LOCAL_CRATE => self.r.opt_span(def_id), + _ => Some( + self.r + .session + .source_map() + .guess_head_span(self.r.cstore().get_span_untracked(def_id, self.r.session)), + ), + } + } + /// Handles error reporting for `smart_resolve_path_fragment` function. /// Creates base error and amends it with one short label and possibly some longer helps/notes. pub(crate) fn smart_resolve_report_errors( @@ -552,7 +564,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { } _ => span, }; - if let Some(span) = self.r.opt_span(def_id) { + if let Some(span) = self.def_span(def_id) { err.span_label(span, &format!("`{}` defined here", path_str)); } let (tail, descr, applicability) = match source { @@ -604,7 +616,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { if nightly_options::is_nightly_build() { let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \ `type` alias"; - if let Some(span) = self.r.opt_span(def_id) { + if let Some(span) = self.def_span(def_id) { err.span_help(span, msg); } else { err.help(msg); @@ -682,7 +694,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { bad_struct_syntax_suggestion(def_id); } (Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => { - if let Some(span) = self.r.opt_span(def_id) { + if let Some(span) = self.def_span(def_id) { err.span_label(span, &format!("`{}` defined here", path_str)); } err.span_label(span, format!("did you mean `{}( /* fields */ )`?", path_str)); diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index af783996f76..6292ed44697 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -68,8 +68,10 @@ error[E0423]: expected value, found struct `XEmpty1` LL | let xe1 = XEmpty1; | ^^^^^^^ | - ::: $DIR/auxiliary/empty-struct.rs:2:1 + ::: $DIR/auxiliary/empty-struct.rs:1:1 | +LL | pub struct XEmpty1 {} + | ------------------ `XEmpty1` defined here LL | pub struct XEmpty2; | ------------------- similarly named unit struct `XEmpty2` defined here | @@ -88,8 +90,10 @@ error[E0423]: expected function, tuple struct or tuple variant, found struct `XE LL | let xe1 = XEmpty1(); | ^^^^^^^^^ | - ::: $DIR/auxiliary/empty-struct.rs:2:1 + ::: $DIR/auxiliary/empty-struct.rs:1:1 | +LL | pub struct XEmpty1 {} + | ------------------ `XEmpty1` defined here LL | pub struct XEmpty2; | ------------------- similarly named unit struct `XEmpty2` defined here | diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr index 70847ca45d0..3570012fc37 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr @@ -13,8 +13,10 @@ error[E0532]: expected unit struct, unit variant or constant, found struct varia LL | XE::XEmpty3 => () | ^^^^^^^^^^^ | - ::: $DIR/auxiliary/empty-struct.rs:7:5 + ::: $DIR/auxiliary/empty-struct.rs:6:5 | +LL | XEmpty3 {}, + | ------- `XE::XEmpty3` defined here LL | XEmpty4, | ------- similarly named unit variant `XEmpty4` defined here | diff --git a/src/test/ui/empty/empty-struct-braces-pat-2.stderr b/src/test/ui/empty/empty-struct-braces-pat-2.stderr index 19792bc9fc5..3bd3f6a9644 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-2.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-2.stderr @@ -27,8 +27,11 @@ error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` LL | XEmpty1() => () | ^^^^^^^^^ | - ::: $DIR/auxiliary/empty-struct.rs:3:1 + ::: $DIR/auxiliary/empty-struct.rs:1:1 | +LL | pub struct XEmpty1 {} + | ------------------ `XEmpty1` defined here +LL | pub struct XEmpty2; LL | pub struct XEmpty6(); | --------------------- similarly named tuple struct `XEmpty6` defined here | @@ -70,8 +73,11 @@ error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` LL | XEmpty1(..) => () | ^^^^^^^^^^^ | - ::: $DIR/auxiliary/empty-struct.rs:3:1 + ::: $DIR/auxiliary/empty-struct.rs:1:1 | +LL | pub struct XEmpty1 {} + | ------------------ `XEmpty1` defined here +LL | pub struct XEmpty2; LL | pub struct XEmpty6(); | --------------------- similarly named tuple struct `XEmpty6` defined here | diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr index 066c42d8181..aac872ba0ec 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr @@ -13,8 +13,11 @@ error[E0532]: expected tuple struct or tuple variant, found struct variant `XE:: LL | XE::XEmpty3() => () | ^^^^^^^^^^^^^ | - ::: $DIR/auxiliary/empty-struct.rs:8:5 + ::: $DIR/auxiliary/empty-struct.rs:6:5 | +LL | XEmpty3 {}, + | ------- `XE::XEmpty3` defined here +LL | XEmpty4, LL | XEmpty5(), | --------- similarly named tuple variant `XEmpty5` defined here | @@ -42,8 +45,11 @@ error[E0532]: expected tuple struct or tuple variant, found struct variant `XE:: LL | XE::XEmpty3(..) => () | ^^^^^^^^^^^^^^^ | - ::: $DIR/auxiliary/empty-struct.rs:8:5 + ::: $DIR/auxiliary/empty-struct.rs:6:5 | +LL | XEmpty3 {}, + | ------- `XE::XEmpty3` defined here +LL | XEmpty4, LL | XEmpty5(), | --------- similarly named tuple variant `XEmpty5` defined here | diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr index 9388ed26657..7b21d31635c 100644 --- a/src/test/ui/empty/empty-struct-tuple-pat.stderr +++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr @@ -38,6 +38,8 @@ LL | XE::XEmpty5 => (), | LL | XEmpty4, | ------- similarly named unit variant `XEmpty4` defined here +LL | XEmpty5(), + | --------- `XE::XEmpty5` defined here error: aborting due to 4 previous errors diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index 2e25ffa168f..ded3173f45b 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -74,8 +74,10 @@ error[E0423]: expected value, found struct variant `xm7::V` LL | check(xm7::V); | ^^^^^^ | - ::: $DIR/auxiliary/namespace-mix.rs:7:9 + ::: $DIR/auxiliary/namespace-mix.rs:6:9 | +LL | V {}, + | - `xm7::V` defined here LL | TV(), | ---- similarly named tuple variant `TV` defined here | diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr index d1690d4eef7..6c519d73480 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -12,6 +12,11 @@ error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Mad | LL | let homura = issue_19452_aux::Homura::Madoka; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `issue_19452_aux::Homura::Madoka { /* fields */ }` + | + ::: $DIR/auxiliary/issue-19452-aux.rs:2:5 + | +LL | Madoka { age: u32 } + | ------ `issue_19452_aux::Homura::Madoka` defined here error: aborting due to 2 previous errors diff --git a/src/test/ui/xcrate/xcrate-unit-struct.stderr b/src/test/ui/xcrate/xcrate-unit-struct.stderr index 813d5d4fdb1..3dc8b90795c 100644 --- a/src/test/ui/xcrate/xcrate-unit-struct.stderr +++ b/src/test/ui/xcrate/xcrate-unit-struct.stderr @@ -3,6 +3,11 @@ error[E0423]: expected value, found struct `xcrate_unit_struct::StructWithFields | LL | let _ = xcrate_unit_struct::StructWithFields; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `xcrate_unit_struct::StructWithFields { foo: val }` + | + ::: $DIR/auxiliary/xcrate_unit_struct.rs:20:1 + | +LL | pub struct StructWithFields { + | --------------------------- `xcrate_unit_struct::StructWithFields` defined here error: aborting due to previous error From 54f1b4313013ef6993e070aeb6d71ac0cb269113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 9 Aug 2020 21:24:05 -0700 Subject: [PATCH 4/4] Add missing primary label --- src/librustc_resolve/late/diagnostics.rs | 6 +++++- src/test/ui/error-codes/E0423.stderr | 2 +- src/test/ui/hygiene/rustc-macro-transparency.stderr | 4 ++-- src/test/ui/resolve/resolve-hint-macro.stderr | 2 +- src/test/ui/struct-literal-variant-in-if.stderr | 2 +- src/test/ui/try-block/try-block-in-edition2015.stderr | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 38bbbb1db1b..dcab0858a75 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -532,6 +532,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { }), ) if followed_by_brace => { if let Some(sp) = closing_brace { + err.span_label(span, fallback_label); err.multipart_suggestion( "surround the struct literal with parentheses", vec![ @@ -595,12 +596,15 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { applicability, ); } - _ => {} + _ => { + err.span_label(span, fallback_label); + } } }; match (res, source) { (Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => { + err.span_label(span, fallback_label); err.span_suggestion_verbose( span.shrink_to_hi(), "use `!` to invoke the macro", diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index e43b3c3546b..a9aecb520b2 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -51,7 +51,7 @@ error[E0423]: expected value, found struct `T` --> $DIR/E0423.rs:14:8 | LL | if T {} == T {} { println!("Ok"); } - | ^ + | ^ not a value | help: surround the struct literal with parentheses | diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr index 024ce820760..94256b2eb79 100644 --- a/src/test/ui/hygiene/rustc-macro-transparency.stderr +++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr @@ -8,7 +8,7 @@ error[E0423]: expected value, found macro `semitransparent` --> $DIR/rustc-macro-transparency.rs:29:5 | LL | semitransparent; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ not a value | help: use `!` to invoke the macro | @@ -19,7 +19,7 @@ error[E0423]: expected value, found macro `opaque` --> $DIR/rustc-macro-transparency.rs:30:5 | LL | opaque; - | ^^^^^^ + | ^^^^^^ not a value | help: use `!` to invoke the macro | diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr index 361da4cc78e..7d35ce7e65e 100644 --- a/src/test/ui/resolve/resolve-hint-macro.stderr +++ b/src/test/ui/resolve/resolve-hint-macro.stderr @@ -2,7 +2,7 @@ error[E0423]: expected function, found macro `assert` --> $DIR/resolve-hint-macro.rs:2:5 | LL | assert(true); - | ^^^^^^ + | ^^^^^^ not a function | help: use `!` to invoke the macro | diff --git a/src/test/ui/struct-literal-variant-in-if.stderr b/src/test/ui/struct-literal-variant-in-if.stderr index 4cd1169cc1b..a2252d4e4d2 100644 --- a/src/test/ui/struct-literal-variant-in-if.stderr +++ b/src/test/ui/struct-literal-variant-in-if.stderr @@ -46,7 +46,7 @@ error[E0423]: expected value, found struct variant `E::V` --> $DIR/struct-literal-variant-in-if.rs:10:13 | LL | if x == E::V { field } {} - | ^^^^ + | ^^^^ not a value | help: surround the struct literal with parentheses | diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr index fe870ab737c..78cdfb2cc7f 100644 --- a/src/test/ui/try-block/try-block-in-edition2015.stderr +++ b/src/test/ui/try-block/try-block-in-edition2015.stderr @@ -11,7 +11,7 @@ error[E0574]: expected struct, variant or union type, found macro `try` --> $DIR/try-block-in-edition2015.rs:4:33 | LL | let try_result: Option<_> = try { - | ^^^ + | ^^^ not a struct, variant or union type | = note: if you want the `try` keyword, you need to be in the 2018 edition help: use `!` to invoke the macro