Make the error messages that result from referencing
nonexistent traits consistent, and add a test.
This commit is contained in:
parent
0c6fc46c03
commit
656c8f9143
@ -510,6 +510,13 @@ pub struct NameBindings {
|
||||
value_def: Option<ValueNsDef>, //< Meaning in value namespace.
|
||||
}
|
||||
|
||||
/// Ways in which a trait can be referenced
|
||||
enum TraitReferenceType {
|
||||
TraitImplementation, // impl SomeTrait for T { ... }
|
||||
TraitDerivation, // trait T : SomeTrait { ... }
|
||||
TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
|
||||
}
|
||||
|
||||
impl NameBindings {
|
||||
/// Creates a new module in this set of name bindings.
|
||||
pub fn define_module(@mut self,
|
||||
@ -3554,23 +3561,7 @@ pub fn resolve_item(@mut self, item: @item, visitor: ResolveVisitor) {
|
||||
|
||||
// Resolve derived traits.
|
||||
for traits.iter().advance |trt| {
|
||||
match self.resolve_path(trt.path, TypeNS, true,
|
||||
visitor) {
|
||||
None =>
|
||||
self.session.span_err(trt.path.span,
|
||||
"attempt to derive a \
|
||||
nonexistent trait"),
|
||||
Some(def) => {
|
||||
// Write a mapping from the trait ID to the
|
||||
// definition of the trait into the definition
|
||||
// map.
|
||||
|
||||
debug!("(resolving trait) found trait def: \
|
||||
%?", def);
|
||||
|
||||
self.record_def(trt.ref_id, def);
|
||||
}
|
||||
}
|
||||
self.resolve_trait_reference(*trt, visitor, TraitDerivation);
|
||||
}
|
||||
|
||||
for (*methods).iter().advance |method| {
|
||||
@ -3821,7 +3812,7 @@ pub fn resolve_type_parameter_bound(@mut self,
|
||||
visitor: ResolveVisitor) {
|
||||
match *type_parameter_bound {
|
||||
TraitTyParamBound(tref) => {
|
||||
self.resolve_trait_reference(tref, visitor)
|
||||
self.resolve_trait_reference(tref, visitor, TraitBoundingTypeParameter)
|
||||
}
|
||||
RegionTyParamBound => {}
|
||||
}
|
||||
@ -3829,14 +3820,23 @@ pub fn resolve_type_parameter_bound(@mut self,
|
||||
|
||||
pub fn resolve_trait_reference(@mut self,
|
||||
trait_reference: &trait_ref,
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: ResolveVisitor,
|
||||
reference_type: TraitReferenceType) {
|
||||
match self.resolve_path(trait_reference.path, TypeNS, true, visitor) {
|
||||
None => {
|
||||
let idents = self.idents_to_str(trait_reference.path.idents);
|
||||
self.session.span_err(trait_reference.path.span,
|
||||
fmt!("attempt to implement an unknown trait `%s`", idents));
|
||||
let path_str = self.idents_to_str(trait_reference.path.idents);
|
||||
|
||||
let usage_str = match reference_type {
|
||||
TraitBoundingTypeParameter => "bound type parameter to",
|
||||
TraitImplementation => "implement",
|
||||
TraitDerivation => "derive"
|
||||
};
|
||||
|
||||
let msg = fmt!("attempt to %s a nonexistent trait `%s`", usage_str, path_str);
|
||||
self.session.span_err(trait_reference.path.span, msg);
|
||||
}
|
||||
Some(def) => {
|
||||
debug!("(resolving trait) found trait def: %?", def);
|
||||
self.record_def(trait_reference.ref_id, def);
|
||||
}
|
||||
}
|
||||
@ -3930,7 +3930,7 @@ pub fn resolve_implementation(@mut self,
|
||||
let original_trait_refs;
|
||||
match opt_trait_reference {
|
||||
Some(trait_reference) => {
|
||||
self.resolve_trait_reference(trait_reference, visitor);
|
||||
self.resolve_trait_reference(trait_reference, visitor, TraitImplementation);
|
||||
|
||||
// Record the current set of trait references.
|
||||
let mut new_trait_refs = ~[];
|
||||
|
20
src/test/compile-fail/resolve-unknown-trait.rs
Normal file
20
src/test/compile-fail/resolve-unknown-trait.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
trait NewTrait : SomeNonExistentTrait {}
|
||||
//~^ ERROR attempt to derive a nonexistent trait `SomeNonExistentTrait`
|
||||
|
||||
impl SomeNonExistentTrait for int {}
|
||||
//~^ ERROR attempt to implement a nonexistent trait `SomeNonExistentTrait`
|
||||
|
||||
fn f<T:SomeNonExistentTrait>() {}
|
||||
//~^ ERROR attempt to bound type parameter to a nonexistent trait `SomeNonExistentTrait`
|
||||
|
Loading…
Reference in New Issue
Block a user