Remove E0245; improve E0404 explanation

This commit is contained in:
Mark Mansi 2018-02-22 17:50:06 -06:00
parent 9f9183d34d
commit 2ec79f936a
6 changed files with 45 additions and 17 deletions

View File

@ -542,7 +542,7 @@ fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
// parameter in this type parameter list // 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: clashing parameters. Example:
``` ```
@ -551,7 +551,8 @@ fn foo<T, Y>(s: T, u: Y) {} // ok!
"##, "##,
E0404: r##" 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: Erroneous code example:
@ -562,6 +563,14 @@ struct Bar;
impl Foo for Bar {} // error: `Foo` is not a trait impl Foo for Bar {} // error: `Foo` is not a trait
``` ```
Another erroneous code example:
```compile_fail,E0404
struct Foo;
fn bar<T: Foo>(t: T) {} // error: `Foo` is not a trait
```
Please verify that you didn't misspell the trait's name or otherwise use the Please verify that you didn't misspell the trait's name or otherwise use the
wrong identifier. Example: wrong identifier. Example:
@ -575,6 +584,17 @@ impl Foo for Bar { // ok!
// functions implementation // functions implementation
} }
``` ```
or
```
trait Foo {
// some functions
}
fn bar<T: Foo>(t: T) {} // ok!
```
"##, "##,
E0405: r##" E0405: r##"

View File

@ -2163,6 +2163,7 @@ impl<'a> Resolver<'a> {
result result
} }
/// This is called to resolve a trait reference from an `impl` (i.e. `impl Trait for Foo`)
fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
where F: FnOnce(&mut Resolver, Option<DefId>) -> T where F: FnOnce(&mut Resolver, Option<DefId>) -> T
{ {
@ -2172,13 +2173,14 @@ impl<'a> Resolver<'a> {
let path: Vec<_> = trait_ref.path.segments.iter() let path: Vec<_> = trait_ref.path.segments.iter()
.map(|seg| respan(seg.span, seg.identifier)) .map(|seg| respan(seg.span, seg.identifier))
.collect(); .collect();
let def = self.smart_resolve_path_fragment(trait_ref.ref_id, let def = self.smart_resolve_path_fragment(
None, trait_ref.ref_id,
&path, None,
trait_ref.path.span, &path,
trait_ref.path.segments.last().unwrap().span, trait_ref.path.span,
PathSource::Trait(AliasPossibility::No)) trait_ref.path.segments.last().unwrap().span,
.base_def(); PathSource::Trait(AliasPossibility::No)
).base_def();
if def != Def::Err { if def != Def::Err {
new_id = Some(def.def_id()); new_id = Some(def.def_id());
let span = trait_ref.path.span; let span = trait_ref.path.span;

View File

@ -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 /// 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. /// 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<T=X>` /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
/// are disallowed. Otherwise, they are pushed onto the vector given. /// 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()) 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 { fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
let path = &trait_ref.path; let path = &trait_ref.path;
match path.def { match path.def {
@ -339,13 +340,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
Def::Err => { Def::Err => {
self.tcx().sess.fatal("cannot continue compilation due to previous error"); self.tcx().sess.fatal("cannot continue compilation due to previous error");
} }
_ => { _ => unreachable!(),
span_fatal!(self.tcx().sess, path.span, E0245, "`{}` is not a trait",
self.tcx().hir.node_to_pretty_string(trait_ref.ref_id));
}
} }
} }
/// The given `trait_ref` must actually be trait.
pub(super) fn instantiate_poly_trait_ref_inner(&self, pub(super) fn instantiate_poly_trait_ref_inner(&self,
trait_ref: &hir::TraitRef, trait_ref: &hir::TraitRef,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,

View File

@ -4802,7 +4802,7 @@ register_diagnostics! {
// E0240, // E0240,
// E0241, // E0241,
// E0242, // E0242,
E0245, // not a trait // E0245, // not a trait
// E0246, // invalid recursive type // E0246, // invalid recursive type
// E0247, // E0247,
// E0248, // value used as a type, now reported earlier during resolution as E0412 // E0248, // value used as a type, now reported earlier during resolution as E0412

View File

@ -13,5 +13,6 @@ struct Bar;
impl Foo for Bar {} //~ ERROR E0404 impl Foo for Bar {} //~ ERROR E0404
fn main() { fn main() {}
}
fn baz<T: Foo>(_: T) {} //~ ERROR E0404

View File

@ -4,6 +4,12 @@ error[E0404]: expected trait, found struct `Foo`
LL | impl Foo for Bar {} //~ ERROR E0404 LL | impl Foo for Bar {} //~ ERROR E0404
| ^^^ not a trait | ^^^ not a trait
error[E0404]: expected trait, found struct `Foo`
--> $DIR/E0404.rs:18:11
|
LL | fn baz<T: Foo>(_: T) {} //~ ERROR E0404
| ^^^ not a trait
error: cannot continue compilation due to previous error error: cannot continue compilation due to previous error
If you want more information on this error, try using "rustc --explain E0404" If you want more information on this error, try using "rustc --explain E0404"