Skip to content

Commit 2ec79f9

Browse files
committed
Remove E0245; improve E0404 explanation
1 parent 9f9183d commit 2ec79f9

File tree

6 files changed

+45
-17
lines changed

6 files changed

+45
-17
lines changed

src/librustc_resolve/diagnostics.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
542542
// parameter in this type parameter list
543543
```
544544
545-
Please verify that none of the type parameterss are misspelled, and rename any
545+
Please verify that none of the type parameters are misspelled, and rename any
546546
clashing parameters. Example:
547547
548548
```
@@ -551,7 +551,8 @@ fn foo<T, Y>(s: T, u: Y) {} // ok!
551551
"##,
552552

553553
E0404: r##"
554-
You tried to implement something which was not a trait on an object.
554+
You tried to use something which is not a trait in a trait position, such as
555+
a bound or `impl`.
555556
556557
Erroneous code example:
557558
@@ -562,6 +563,14 @@ struct Bar;
562563
impl Foo for Bar {} // error: `Foo` is not a trait
563564
```
564565
566+
Another erroneous code example:
567+
568+
```compile_fail,E0404
569+
struct Foo;
570+
571+
fn bar<T: Foo>(t: T) {} // error: `Foo` is not a trait
572+
```
573+
565574
Please verify that you didn't misspell the trait's name or otherwise use the
566575
wrong identifier. Example:
567576
@@ -575,6 +584,17 @@ impl Foo for Bar { // ok!
575584
// functions implementation
576585
}
577586
```
587+
588+
or
589+
590+
```
591+
trait Foo {
592+
// some functions
593+
}
594+
595+
fn bar<T: Foo>(t: T) {} // ok!
596+
```
597+
578598
"##,
579599

580600
E0405: r##"

src/librustc_resolve/lib.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -2163,6 +2163,7 @@ impl<'a> Resolver<'a> {
21632163
result
21642164
}
21652165

2166+
/// This is called to resolve a trait reference from an `impl` (i.e. `impl Trait for Foo`)
21662167
fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
21672168
where F: FnOnce(&mut Resolver, Option<DefId>) -> T
21682169
{
@@ -2172,13 +2173,14 @@ impl<'a> Resolver<'a> {
21722173
let path: Vec<_> = trait_ref.path.segments.iter()
21732174
.map(|seg| respan(seg.span, seg.identifier))
21742175
.collect();
2175-
let def = self.smart_resolve_path_fragment(trait_ref.ref_id,
2176-
None,
2177-
&path,
2178-
trait_ref.path.span,
2179-
trait_ref.path.segments.last().unwrap().span,
2180-
PathSource::Trait(AliasPossibility::No))
2181-
.base_def();
2176+
let def = self.smart_resolve_path_fragment(
2177+
trait_ref.ref_id,
2178+
None,
2179+
&path,
2180+
trait_ref.path.span,
2181+
trait_ref.path.segments.last().unwrap().span,
2182+
PathSource::Trait(AliasPossibility::No)
2183+
).base_def();
21822184
if def != Def::Err {
21832185
new_id = Some(def.def_id());
21842186
let span = trait_ref.path.span;

src/librustc_typeck/astconv.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
313313

314314
/// Instantiates the path for the given trait reference, assuming that it's
315315
/// bound to a valid trait type. Returns the def_id for the defining trait.
316-
/// Fails if the type is a type other than a trait type.
316+
/// The type _cannot_ be a type other than a trait type.
317317
///
318318
/// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
319319
/// are disallowed. Otherwise, they are pushed onto the vector given.
@@ -331,6 +331,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
331331
trait_ref.path.segments.last().unwrap())
332332
}
333333

334+
/// Get the DefId of the given trait ref. It _must_ actually be a trait.
334335
fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
335336
let path = &trait_ref.path;
336337
match path.def {
@@ -339,13 +340,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
339340
Def::Err => {
340341
self.tcx().sess.fatal("cannot continue compilation due to previous error");
341342
}
342-
_ => {
343-
span_fatal!(self.tcx().sess, path.span, E0245, "`{}` is not a trait",
344-
self.tcx().hir.node_to_pretty_string(trait_ref.ref_id));
345-
}
343+
_ => unreachable!(),
346344
}
347345
}
348346

347+
/// The given `trait_ref` must actually be trait.
349348
pub(super) fn instantiate_poly_trait_ref_inner(&self,
350349
trait_ref: &hir::TraitRef,
351350
self_ty: Ty<'tcx>,

src/librustc_typeck/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4802,7 +4802,7 @@ register_diagnostics! {
48024802
// E0240,
48034803
// E0241,
48044804
// E0242,
4805-
E0245, // not a trait
4805+
// E0245, // not a trait
48064806
// E0246, // invalid recursive type
48074807
// E0247,
48084808
// E0248, // value used as a type, now reported earlier during resolution as E0412

src/test/ui/error-codes/E0404.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ struct Bar;
1313

1414
impl Foo for Bar {} //~ ERROR E0404
1515

16-
fn main() {
17-
}
16+
fn main() {}
17+
18+
fn baz<T: Foo>(_: T) {} //~ ERROR E0404

src/test/ui/error-codes/E0404.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ error[E0404]: expected trait, found struct `Foo`
44
LL | impl Foo for Bar {} //~ ERROR E0404
55
| ^^^ not a trait
66

7+
error[E0404]: expected trait, found struct `Foo`
8+
--> $DIR/E0404.rs:18:11
9+
|
10+
LL | fn baz<T: Foo>(_: T) {} //~ ERROR E0404
11+
| ^^^ not a trait
12+
713
error: cannot continue compilation due to previous error
814

915
If you want more information on this error, try using "rustc --explain E0404"

0 commit comments

Comments
 (0)