about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-08-09 20:29:39 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-08-10 12:04:10 -0700
commiteef284be59bbbe50e4d5369542a80e1ccd2ba7ab (patch)
treee071f85f8fcfeb6ca763eb37ca0d1b2d9e9901a5 /src
parent18f3be7704a4ec7976fcd1272c728974243d29bd (diff)
downloadrust-eef284be59bbbe50e4d5369542a80e1ccd2ba7ab.tar.gz
rust-eef284be59bbbe50e4d5369542a80e1ccd2ba7ab.zip
Tweak ordering of suggestions
Modify logic to make it easier to follow and recover labels that would
otherwise be lost.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/late/diagnostics.rs16
-rw-r--r--src/test/ui/empty/empty-struct-braces-expr.stderr38
-rw-r--r--src/test/ui/empty/empty-struct-braces-pat-1.stderr8
-rw-r--r--src/test/ui/empty/empty-struct-braces-pat-2.stderr44
-rw-r--r--src/test/ui/empty/empty-struct-braces-pat-3.stderr22
-rw-r--r--src/test/ui/error-codes/E0423.stderr11
-rw-r--r--src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr10
-rw-r--r--src/test/ui/namespace/namespace-mix.stderr16
-rw-r--r--src/test/ui/resolve/issue-39226.stderr8
-rw-r--r--src/test/ui/resolve/privacy-enum-ctor.stderr16
-rw-r--r--src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr16
-rw-r--r--src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr8
-rw-r--r--src/test/ui/type/type-ascription-with-fn-call.stderr5
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