about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0404.md26
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs9
-rw-r--r--src/test/ui/codemap_tests/two_files.stderr5
-rw-r--r--src/test/ui/resolve/issue-3907.stderr5
-rw-r--r--src/test/ui/resolve/issue-5035.stderr14
-rw-r--r--src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr5
-rw-r--r--src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.fixed13
-rw-r--r--src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.rs13
-rw-r--r--src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.stderr14
9 files changed, 81 insertions, 23 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0404.md b/compiler/rustc_error_codes/src/error_codes/E0404.md
index 1360cc99afc..d6fa51e618c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0404.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0404.md
@@ -8,14 +8,15 @@ struct Foo;
 struct Bar;
 
 impl Foo for Bar {} // error: `Foo` is not a trait
+fn baz<T: Foo>(t: T) {} // error: `Foo` is not a trait
 ```
 
 Another erroneous code example:
 
 ```compile_fail,E0404
-struct Foo;
+type Foo = Iterator<Item=String>;
 
-fn bar<T: Foo>(t: T) {} // error: `Foo` is not a trait
+fn bar<T: Foo>(t: T) {} // error: `Foo` is a type alias
 ```
 
 Please verify that the trait's name was not misspelled or that the right
@@ -30,14 +31,27 @@ struct Bar;
 impl Foo for Bar { // ok!
     // functions implementation
 }
+
+fn baz<T: Foo>(t: T) {} // ok!
 ```
 
-or:
+Alternatively, you could introduce a new trait with your desired restrictions
+as a super trait:
 
 ```
-trait Foo {
-    // some functions
-}
+# trait Foo {}
+# struct Bar;
+# impl Foo for Bar {}
+trait Qux: Foo {} // Anything that implements Qux also needs to implement Foo
+fn baz<T: Qux>(t: T) {} // also ok!
+```
+
+Finally, if you are on nightly and want to use a trait alias
+instead of a type alias, you should use `#![feature(trait_alias)]`:
+
+```
+#![feature(trait_alias)]
+trait Foo = Iterator<Item=String>;
 
 fn bar<T: Foo>(t: T) {} // ok!
 ```
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 6fae6921fc9..e33c374f562 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -930,7 +930,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                     let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \
                                `type` alias";
                     if let Some(span) = self.def_span(def_id) {
-                        err.span_help(span, msg);
+                        if let Ok(snip) = self.r.session.source_map().span_to_snippet(span) {
+                            // The span contains a type alias so we should be able to
+                            // replace `type` with `trait`.
+                            let snip = snip.replacen("type", "trait", 1);
+                            err.span_suggestion(span, msg, snip, Applicability::MaybeIncorrect);
+                        } else {
+                            err.span_help(span, msg);
+                        }
                     } else {
                         err.help(msg);
                     }
diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr
index de2ffc2e5dc..aff51ee9e2f 100644
--- a/src/test/ui/codemap_tests/two_files.stderr
+++ b/src/test/ui/codemap_tests/two_files.stderr
@@ -5,10 +5,9 @@ LL | impl Bar for Baz { }
    |      ^^^ type aliases cannot be used as traits
    |
 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;
-   | ^^^^^^^^^^^^^^^^^^^
+LL | trait Bar = dyn Foo;
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr
index 4d0b0af58a3..6fc61cae843 100644
--- a/src/test/ui/resolve/issue-3907.stderr
+++ b/src/test/ui/resolve/issue-3907.stderr
@@ -5,10 +5,9 @@ LL | impl Foo for S {
    |      ^^^ type aliases cannot be used as traits
    |
 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;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | trait Foo = dyn issue_3907::Foo;
+   |
 help: consider importing this trait instead
    |
 LL | use issue_3907::Foo;
diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr
index 41dff2fe542..a8aa50b7c3a 100644
--- a/src/test/ui/resolve/issue-5035.stderr
+++ b/src/test/ui/resolve/issue-5035.stderr
@@ -11,16 +11,16 @@ LL | trait I {}
    | ------- similarly named trait `I` defined here
 LL | type K = dyn I;
 LL | impl K for isize {}
-   |      ^
-   |      |
-   |      type aliases cannot be used as traits
-   |      help: a trait with a similar name exists: `I`
+   |      ^ type aliases cannot be used as traits
    |
 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;
-   | ^^^^^^^^^^^^^^^
+LL | trait K = dyn I;
+   |
+help: a trait with a similar name exists
+   |
+LL | impl I for isize {}
+   |      ^
 
 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 2974d08eb23..8addc0303fb 100644
--- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr
+++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr
@@ -11,10 +11,9 @@ LL | fn g<F:Typedef(isize) -> isize>(x: F) {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used as traits
    |
 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;
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | trait Typedef = isize;
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.fixed b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.fixed
new file mode 100644
index 00000000000..8a94abaeb07
--- /dev/null
+++ b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.fixed
@@ -0,0 +1,13 @@
+// Regression test of #43913.
+
+// run-rustfix
+
+#![feature(trait_alias)]
+#![allow(bare_trait_objects, dead_code)]
+
+trait Strings = Iterator<Item=String>;
+
+struct Struct<S: Strings>(S);
+//~^ ERROR: expected trait, found type alias `Strings`
+
+fn main() {}
diff --git a/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.rs b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.rs
new file mode 100644
index 00000000000..40c678c281f
--- /dev/null
+++ b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.rs
@@ -0,0 +1,13 @@
+// Regression test of #43913.
+
+// run-rustfix
+
+#![feature(trait_alias)]
+#![allow(bare_trait_objects, dead_code)]
+
+type Strings = Iterator<Item=String>;
+
+struct Struct<S: Strings>(S);
+//~^ ERROR: expected trait, found type alias `Strings`
+
+fn main() {}
diff --git a/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.stderr b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.stderr
new file mode 100644
index 00000000000..6e03eeada49
--- /dev/null
+++ b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.stderr
@@ -0,0 +1,14 @@
+error[E0404]: expected trait, found type alias `Strings`
+  --> $DIR/suggest-trait-alias-instead-of-type.rs:10:18
+   |
+LL | struct Struct<S: Strings>(S);
+   |                  ^^^^^^^ type aliases cannot be used as traits
+   |
+help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
+   |
+LL | trait Strings = Iterator<Item=String>;
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0404`.