Skip to content

Commit d243e00

Browse files
committed
auto merge of #7572 : Dretch/rust/missing-trait-message-followup, r=pcwalton
This a followup to #7510. @catamorphism requested a test - so I have created one, but in doing so I noticed some inconsistency in the error messages resulting from referencing nonexistent traits, so I changed the messages to be more consistent.
2 parents a9f178c + 908a22b commit d243e00

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

src/librustc/middle/resolve.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,13 @@ pub struct NameBindings {
510510
value_def: Option<ValueNsDef>, //< Meaning in value namespace.
511511
}
512512

513+
/// Ways in which a trait can be referenced
514+
enum TraitReferenceType {
515+
TraitImplementation, // impl SomeTrait for T { ... }
516+
TraitDerivation, // trait T : SomeTrait { ... }
517+
TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
518+
}
519+
513520
impl NameBindings {
514521
/// Creates a new module in this set of name bindings.
515522
pub fn define_module(@mut self,
@@ -3554,23 +3561,7 @@ impl Resolver {
35543561

35553562
// Resolve derived traits.
35563563
for traits.iter().advance |trt| {
3557-
match self.resolve_path(trt.path, TypeNS, true,
3558-
visitor) {
3559-
None =>
3560-
self.session.span_err(trt.path.span,
3561-
"attempt to derive a \
3562-
nonexistent trait"),
3563-
Some(def) => {
3564-
// Write a mapping from the trait ID to the
3565-
// definition of the trait into the definition
3566-
// map.
3567-
3568-
debug!("(resolving trait) found trait def: \
3569-
%?", def);
3570-
3571-
self.record_def(trt.ref_id, def);
3572-
}
3573-
}
3564+
self.resolve_trait_reference(*trt, visitor, TraitDerivation);
35743565
}
35753566

35763567
for (*methods).iter().advance |method| {
@@ -3821,22 +3812,31 @@ impl Resolver {
38213812
visitor: ResolveVisitor) {
38223813
match *type_parameter_bound {
38233814
TraitTyParamBound(tref) => {
3824-
self.resolve_trait_reference(tref, visitor)
3815+
self.resolve_trait_reference(tref, visitor, TraitBoundingTypeParameter)
38253816
}
38263817
RegionTyParamBound => {}
38273818
}
38283819
}
38293820

38303821
pub fn resolve_trait_reference(@mut self,
38313822
trait_reference: &trait_ref,
3832-
visitor: ResolveVisitor) {
3823+
visitor: ResolveVisitor,
3824+
reference_type: TraitReferenceType) {
38333825
match self.resolve_path(trait_reference.path, TypeNS, true, visitor) {
38343826
None => {
3835-
let idents = self.idents_to_str(trait_reference.path.idents);
3836-
self.session.span_err(trait_reference.path.span,
3837-
fmt!("attempt to implement an unknown trait `%s`", idents));
3827+
let path_str = self.idents_to_str(trait_reference.path.idents);
3828+
3829+
let usage_str = match reference_type {
3830+
TraitBoundingTypeParameter => "bound type parameter with",
3831+
TraitImplementation => "implement",
3832+
TraitDerivation => "derive"
3833+
};
3834+
3835+
let msg = fmt!("attempt to %s a nonexistent trait `%s`", usage_str, path_str);
3836+
self.session.span_err(trait_reference.path.span, msg);
38383837
}
38393838
Some(def) => {
3839+
debug!("(resolving trait) found trait def: %?", def);
38403840
self.record_def(trait_reference.ref_id, def);
38413841
}
38423842
}
@@ -3930,7 +3930,7 @@ impl Resolver {
39303930
let original_trait_refs;
39313931
match opt_trait_reference {
39323932
Some(trait_reference) => {
3933-
self.resolve_trait_reference(trait_reference, visitor);
3933+
self.resolve_trait_reference(trait_reference, visitor, TraitImplementation);
39343934

39353935
// Record the current set of trait references.
39363936
let mut new_trait_refs = ~[];
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
12+
trait NewTrait : SomeNonExistentTrait {}
13+
//~^ ERROR attempt to derive a nonexistent trait `SomeNonExistentTrait`
14+
15+
impl SomeNonExistentTrait for int {}
16+
//~^ ERROR attempt to implement a nonexistent trait `SomeNonExistentTrait`
17+
18+
fn f<T:SomeNonExistentTrait>() {}
19+
//~^ ERROR attempt to bound type parameter with a nonexistent trait `SomeNonExistentTrait`
20+

0 commit comments

Comments
 (0)