From 2ec79f936a564c2538c28bf7bdf2ef26a6ab6006 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 22 Feb 2018 17:50:06 -0600 Subject: [PATCH] Remove E0245; improve E0404 explanation --- src/librustc_resolve/diagnostics.rs | 24 ++++++++++++++++++++++-- src/librustc_resolve/lib.rs | 16 +++++++++------- src/librustc_typeck/astconv.rs | 9 ++++----- src/librustc_typeck/diagnostics.rs | 2 +- src/test/ui/error-codes/E0404.rs | 5 +++-- src/test/ui/error-codes/E0404.stderr | 6 ++++++ 6 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index c1e6b4f5a17d9..a0fc5533f8e54 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -542,7 +542,7 @@ fn foo(s: T, u: T) {} // error: the name `T` is already used for a type // parameter in this type parameter list ``` -Please verify that none of the type parameterss are misspelled, and rename any +Please verify that none of the type parameters are misspelled, and rename any clashing parameters. Example: ``` @@ -551,7 +551,8 @@ fn foo(s: T, u: Y) {} // ok! "##, E0404: r##" -You tried to implement something which was not a trait on an object. +You tried to use something which is not a trait in a trait position, such as +a bound or `impl`. Erroneous code example: @@ -562,6 +563,14 @@ struct Bar; impl Foo for Bar {} // error: `Foo` is not a trait ``` +Another erroneous code example: + +```compile_fail,E0404 +struct Foo; + +fn bar(t: T) {} // error: `Foo` is not a trait +``` + Please verify that you didn't misspell the trait's name or otherwise use the wrong identifier. Example: @@ -575,6 +584,17 @@ impl Foo for Bar { // ok! // functions implementation } ``` + +or + +``` +trait Foo { + // some functions +} + +fn bar(t: T) {} // ok! +``` + "##, E0405: r##" diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e4e9ee58330cc..42bcc62f291c8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2163,6 +2163,7 @@ impl<'a> Resolver<'a> { result } + /// This is called to resolve a trait reference from an `impl` (i.e. `impl Trait for Foo`) fn with_optional_trait_ref(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T where F: FnOnce(&mut Resolver, Option) -> T { @@ -2172,13 +2173,14 @@ impl<'a> Resolver<'a> { let path: Vec<_> = trait_ref.path.segments.iter() .map(|seg| respan(seg.span, seg.identifier)) .collect(); - let def = self.smart_resolve_path_fragment(trait_ref.ref_id, - None, - &path, - trait_ref.path.span, - trait_ref.path.segments.last().unwrap().span, - PathSource::Trait(AliasPossibility::No)) - .base_def(); + let def = self.smart_resolve_path_fragment( + trait_ref.ref_id, + None, + &path, + trait_ref.path.span, + trait_ref.path.segments.last().unwrap().span, + PathSource::Trait(AliasPossibility::No) + ).base_def(); if def != Def::Err { new_id = Some(def.def_id()); let span = trait_ref.path.span; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 650e530519887..782638af13f73 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -313,7 +313,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { /// Instantiates the path for the given trait reference, assuming that it's /// bound to a valid trait type. Returns the def_id for the defining trait. - /// Fails if the type is a type other than a trait type. + /// The type _cannot_ be a type other than a trait type. /// /// If the `projections` argument is `None`, then assoc type bindings like `Foo` /// are disallowed. Otherwise, they are pushed onto the vector given. @@ -331,6 +331,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { trait_ref.path.segments.last().unwrap()) } + /// Get the DefId of the given trait ref. It _must_ actually be a trait. fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId { let path = &trait_ref.path; match path.def { @@ -339,13 +340,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Def::Err => { self.tcx().sess.fatal("cannot continue compilation due to previous error"); } - _ => { - span_fatal!(self.tcx().sess, path.span, E0245, "`{}` is not a trait", - self.tcx().hir.node_to_pretty_string(trait_ref.ref_id)); - } + _ => unreachable!(), } } + /// The given `trait_ref` must actually be trait. pub(super) fn instantiate_poly_trait_ref_inner(&self, trait_ref: &hir::TraitRef, self_ty: Ty<'tcx>, diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 1c0e084832ebc..6c195a991c24e 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4802,7 +4802,7 @@ register_diagnostics! { // E0240, // E0241, // E0242, - E0245, // not a trait +// E0245, // not a trait // E0246, // invalid recursive type // E0247, // E0248, // value used as a type, now reported earlier during resolution as E0412 diff --git a/src/test/ui/error-codes/E0404.rs b/src/test/ui/error-codes/E0404.rs index 1c088a71d7d4b..1c6ff5ae8413d 100644 --- a/src/test/ui/error-codes/E0404.rs +++ b/src/test/ui/error-codes/E0404.rs @@ -13,5 +13,6 @@ struct Bar; impl Foo for Bar {} //~ ERROR E0404 -fn main() { -} +fn main() {} + +fn baz(_: T) {} //~ ERROR E0404 diff --git a/src/test/ui/error-codes/E0404.stderr b/src/test/ui/error-codes/E0404.stderr index d49c0f3ea5e19..ac1d2a00cf448 100644 --- a/src/test/ui/error-codes/E0404.stderr +++ b/src/test/ui/error-codes/E0404.stderr @@ -4,6 +4,12 @@ error[E0404]: expected trait, found struct `Foo` LL | impl Foo for Bar {} //~ ERROR E0404 | ^^^ not a trait +error[E0404]: expected trait, found struct `Foo` + --> $DIR/E0404.rs:18:11 + | +LL | fn baz(_: T) {} //~ ERROR E0404 + | ^^^ not a trait + error: cannot continue compilation due to previous error If you want more information on this error, try using "rustc --explain E0404"