1
Fork 0

Tweak ordering of suggestions

Modify logic to make it easier to follow and recover labels that would
otherwise be lost.
This commit is contained in:
Esteban Küber 2020-08-09 20:29:39 -07:00
parent 18f3be7704
commit eef284be59
13 changed files with 131 additions and 87 deletions

View file

@ -339,8 +339,6 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
// Try Levenshtein algorithm. // Try Levenshtein algorithm.
let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected, span); 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. // Try context-dependent help if relaxed lookup didn't work.
if let Some(res) = res { if let Some(res) = res {
if self.smart_resolve_context_dependent_help( if self.smart_resolve_context_dependent_help(
@ -351,14 +349,18 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
&path_str, &path_str,
&fallback_label, &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); return (err, candidates);
} }
} }
// Fallback label. if !self.type_ascription_suggestion(&mut err, base_span)
if !levenshtein_worked { && !self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span)
{
// Fallback label.
err.span_label(base_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 { match self.diagnostic_metadata.current_let_binding {
Some((pat_sp, Some(ty_sp), None)) if ty_sp.contains(base_span) && could_be_expr => { Some((pat_sp, Some(ty_sp), None)) if ty_sp.contains(base_span) && could_be_expr => {
err.span_suggestion_short( err.span_suggestion_short(
@ -869,7 +871,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
start.to(sm.next_point(start)) 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 sm = self.r.session.source_map();
let base_snippet = sm.span_to_snippet(base_span); let base_snippet = sm.span_to_snippet(base_span);
if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() { 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", "expecting a type here because of type ascription",
); );
} }
return show_label;
} }
} }
} }
false
} }
fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> { fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {

View file

@ -12,14 +12,14 @@ LL | let e1 = Empty1;
LL | pub struct XEmpty2; LL | pub struct XEmpty2;
| ------------------- similarly named unit struct `XEmpty2` defined here | ------------------- 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 help: use struct literal syntax instead
| |
LL | let e1 = Empty1 {}; 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` error[E0423]: expected function, tuple struct or tuple variant, found struct `Empty1`
--> $DIR/empty-struct-braces-expr.rs:16:14 --> $DIR/empty-struct-braces-expr.rs:16:14
@ -29,15 +29,20 @@ LL | struct Empty1 {}
... ...
LL | let e1 = 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 help: use struct literal syntax instead
| |
LL | let e1 = Empty1 {}; 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` error[E0423]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14 --> $DIR/empty-struct-braces-expr.rs:18:14
@ -68,29 +73,34 @@ LL | let xe1 = XEmpty1;
LL | pub struct XEmpty2; LL | pub struct XEmpty2;
| ------------------- similarly named unit struct `XEmpty2` defined here | ------------------- 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 help: use struct literal syntax instead
| |
LL | let xe1 = XEmpty1 {}; 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` error[E0423]: expected function, tuple struct or tuple variant, found struct `XEmpty1`
--> $DIR/empty-struct-braces-expr.rs:23:15 --> $DIR/empty-struct-braces-expr.rs:23:15
| |
LL | let xe1 = XEmpty1(); 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 help: use struct literal syntax instead
| |
LL | let xe1 = XEmpty1 {}; 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 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 --> $DIR/empty-struct-braces-expr.rs:25:19

View file

@ -18,14 +18,14 @@ LL | XE::XEmpty3 => ()
LL | XEmpty4, LL | XEmpty4,
| ------- similarly named unit variant `XEmpty4` defined here | ------- 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 help: use struct pattern syntax instead
| |
LL | XE::XEmpty3 { /* fields */ } => () LL | XE::XEmpty3 { /* fields */ } => ()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: a unit variant with a similar name exists
|
LL | XE::XEmpty4 => ()
| ^^^^^^^
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -6,30 +6,40 @@ LL | struct Empty1 {}
... ...
LL | 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 help: use struct pattern syntax instead
| |
LL | Empty1 {} => () LL | Empty1 {} => ()
| ^^^^^^^^^ | ^^^^^^^^^
help: a tuple struct with a similar name exists
|
LL | XEmpty6() => ()
| ^^^^^^^
error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1`
--> $DIR/empty-struct-braces-pat-2.rs:18:9 --> $DIR/empty-struct-braces-pat-2.rs:18:9
| |
LL | XEmpty1() => () 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 help: use struct pattern syntax instead
| |
LL | XEmpty1 {} => () LL | XEmpty1 {} => ()
| ^^^^^^^^^^ | ^^^^^^^^^^
help: a tuple struct with a similar name exists
|
LL | XEmpty6() => ()
| ^^^^^^^
error[E0532]: expected tuple struct or tuple variant, found struct `Empty1` error[E0532]: expected tuple struct or tuple variant, found struct `Empty1`
--> $DIR/empty-struct-braces-pat-2.rs:21:9 --> $DIR/empty-struct-braces-pat-2.rs:21:9
@ -39,30 +49,40 @@ LL | struct Empty1 {}
... ...
LL | 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 help: use struct pattern syntax instead
| |
LL | Empty1 {} => () LL | Empty1 {} => ()
| ^^^^^^^^^ | ^^^^^^^^^
help: a tuple struct with a similar name exists
|
LL | XEmpty6(..) => ()
| ^^^^^^^
error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1`
--> $DIR/empty-struct-braces-pat-2.rs:24:9 --> $DIR/empty-struct-braces-pat-2.rs:24:9
| |
LL | XEmpty1(..) => () 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 help: use struct pattern syntax instead
| |
LL | XEmpty1 {} => () LL | XEmpty1 {} => ()
| ^^^^^^^^^^ | ^^^^^^^^^^
help: a tuple struct with a similar name exists
|
LL | XEmpty6(..) => ()
| ^^^^^^^
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -12,15 +12,20 @@ error[E0532]: expected tuple struct or tuple variant, found struct variant `XE::
| |
LL | XE::XEmpty3() => () 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 help: use struct pattern syntax instead
| |
LL | XE::XEmpty3 { /* fields */ } => () 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` error[E0532]: expected tuple struct or tuple variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:25:9 --> $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(..) => () 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 help: use struct pattern syntax instead
| |
LL | XE::XEmpty3 { /* fields */ } => () LL | XE::XEmpty3 { /* fields */ } => ()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: a tuple variant with a similar name exists
|
LL | XE::XEmpty5(..) => ()
| ^^^^^^^
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -34,15 +34,18 @@ LL | struct Foo { a: bool };
LL | LL |
LL | let f = Foo(); 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 help: use struct literal syntax instead
| |
LL | let f = Foo { a: val }; 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` error[E0423]: expected value, found struct `T`
--> $DIR/E0423.rs:14:8 --> $DIR/E0423.rs:14:8

View file

@ -5,16 +5,16 @@ LL | struct X {}
| ----------- `X` defined here | ----------- `X` defined here
LL | LL |
LL | const Y: X = X("ö"); 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 help: use struct literal syntax instead
| |
LL | const Y: X = X {}; LL | const Y: X = X {};
| ^^^^ | ^^^^
help: a constant with a similar name exists
|
LL | const Y: X = Y("ö");
| ^
error: aborting due to previous error error: aborting due to previous error

View file

@ -53,14 +53,14 @@ LL | TV(),
LL | check(m7::V); LL | check(m7::V);
| ^^^^^ | ^^^^^
| |
help: a tuple variant with a similar name exists
|
LL | check(m7::TV);
| ^^
help: use struct literal syntax instead help: use struct literal syntax instead
| |
LL | check(m7::V {}); 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 help: consider importing one of these items instead
| |
LL | use m8::V; LL | use m8::V;
@ -79,14 +79,14 @@ LL | check(xm7::V);
LL | TV(), LL | TV(),
| ---- similarly named tuple variant `TV` defined here | ---- 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 help: use struct literal syntax instead
| |
LL | check(xm7::V { /* fields */ }); 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 help: consider importing one of these items instead
| |
LL | use m8::V; LL | use m8::V;

View file

@ -7,14 +7,14 @@ LL | struct Handle {}
LL | handle: Handle LL | handle: Handle
| ^^^^^^ | ^^^^^^
| |
help: a local variable with a similar name exists
|
LL | handle: handle
| ^^^^^^
help: use struct literal syntax instead help: use struct literal syntax instead
| |
LL | handle: Handle {} LL | handle: Handle {}
| ^^^^^^^^^ | ^^^^^^^^^
help: a local variable with a similar name exists
|
LL | handle: handle
| ^^^^^^
error: aborting due to previous error error: aborting due to previous error

View file

@ -22,10 +22,6 @@ LL | fn f() {
LL | Z; LL | Z;
| ^ | ^
| |
help: a function with a similar name exists
|
LL | f;
| ^
help: try using one of the enum's variants help: try using one of the enum's variants
| |
LL | m::Z::Fn; LL | m::Z::Fn;
@ -34,6 +30,10 @@ LL | m::Z::Struct;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
LL | m::Z::Unit; LL | m::Z::Unit;
| ^^^^^^^^^^ | ^^^^^^^^^^
help: a function with a similar name exists
|
LL | f;
| ^
error[E0423]: expected value, found struct variant `Z::Struct` error[E0423]: expected value, found struct variant `Z::Struct`
--> $DIR/privacy-enum-ctor.rs:29:20 --> $DIR/privacy-enum-ctor.rs:29:20
@ -55,10 +55,6 @@ LL | fn f() {
LL | let _: E = m::E; 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 help: try using one of the enum's variants
| |
LL | let _: E = E::Fn; LL | let _: E = E::Fn;
@ -67,6 +63,10 @@ LL | let _: E = E::Struct;
| ^^^^^^^^^ | ^^^^^^^^^
LL | let _: E = E::Unit; 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 help: consider importing one of these items instead
| |
LL | use std::f32::consts::E; LL | use std::f32::consts::E;

View file

@ -31,14 +31,14 @@ LL | pub const I: i32 = 1;
LL | a::b.J 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 help: use the path separator to refer to an item
| |
LL | a::b::J LL | a::b::J
| |
help: a constant with a similar name exists
|
LL | a::I.J
| ^
error[E0423]: expected value, found module `a` error[E0423]: expected value, found module `a`
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:37:5 --> $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() 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 help: use the path separator to refer to an item
| |
LL | a::b::f() LL | a::b::f()
| ^^^^^^^ | ^^^^^^^
help: a constant with a similar name exists
|
LL | a::I.f()
| ^
error[E0423]: expected value, found module `a::b` error[E0423]: expected value, found module `a::b`
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5 --> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5

View file

@ -9,14 +9,14 @@ LL | B { a: usize },
LL | let _: E = E::B; 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 help: use struct literal syntax instead
| |
LL | let _: E = E::B { a: val }; 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 error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:29:20 --> $DIR/fn-or-tuple-struct-without-args.rs:29:20

View file

@ -4,10 +4,7 @@ error[E0573]: expected type, found function `f`
LL | f() : LL | f() :
| - help: maybe you meant to write `;` here | - help: maybe you meant to write `;` here
LL | f(); LL | f();
| ^^^ | ^^^ expecting a type here because of type ascription
| |
| not a type
| expecting a type here because of type ascription
error: aborting due to previous error error: aborting due to previous error