From 656c8f91435df99b11bfe31be73eba6d8f391870 Mon Sep 17 00:00:00 2001 From: Gareth Smith Date: Wed, 3 Jul 2013 22:16:08 +0100 Subject: [PATCH 1/2] Make the error messages that result from referencing nonexistent traits consistent, and add a test. --- src/librustc/middle/resolve.rs | 46 +++++++++---------- .../compile-fail/resolve-unknown-trait.rs | 20 ++++++++ 2 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 src/test/compile-fail/resolve-unknown-trait.rs diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 8e25f598f365f..6ddac371e0c6c 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -510,6 +510,13 @@ pub struct NameBindings { value_def: Option, //< 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() { ... } +} + impl NameBindings { /// Creates a new module in this set of name bindings. pub fn define_module(@mut self, @@ -3554,23 +3561,7 @@ impl Resolver { // 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 @@ impl Resolver { 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 @@ impl Resolver { 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 @@ impl Resolver { 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 = ~[]; diff --git a/src/test/compile-fail/resolve-unknown-trait.rs b/src/test/compile-fail/resolve-unknown-trait.rs new file mode 100644 index 0000000000000..be3b381663a7d --- /dev/null +++ b/src/test/compile-fail/resolve-unknown-trait.rs @@ -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 or the MIT license +// , 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() {} +//~^ ERROR attempt to bound type parameter to a nonexistent trait `SomeNonExistentTrait` + From 908a22b62697fcb6c943527492158729dc762f10 Mon Sep 17 00:00:00 2001 From: Gareth Smith Date: Wed, 3 Jul 2013 23:43:03 +0100 Subject: [PATCH 2/2] Address @catamorphism's error message grammar nit. --- src/librustc/middle/resolve.rs | 2 +- src/test/compile-fail/resolve-unknown-trait.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 6ddac371e0c6c..dc55dcad99d1b 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3827,7 +3827,7 @@ impl Resolver { let path_str = self.idents_to_str(trait_reference.path.idents); let usage_str = match reference_type { - TraitBoundingTypeParameter => "bound type parameter to", + TraitBoundingTypeParameter => "bound type parameter with", TraitImplementation => "implement", TraitDerivation => "derive" }; diff --git a/src/test/compile-fail/resolve-unknown-trait.rs b/src/test/compile-fail/resolve-unknown-trait.rs index be3b381663a7d..699a30ad4ebdd 100644 --- a/src/test/compile-fail/resolve-unknown-trait.rs +++ b/src/test/compile-fail/resolve-unknown-trait.rs @@ -16,5 +16,5 @@ impl SomeNonExistentTrait for int {} //~^ ERROR attempt to implement a nonexistent trait `SomeNonExistentTrait` fn f() {} -//~^ ERROR attempt to bound type parameter to a nonexistent trait `SomeNonExistentTrait` +//~^ ERROR attempt to bound type parameter with a nonexistent trait `SomeNonExistentTrait`