@@ -3894,8 +3894,31 @@ impl<'a> Resolver<'a> {
38943894 self . resolve_error ( trait_reference. path . span , msg. as_slice ( ) ) ;
38953895 }
38963896 Some ( def) => {
3897- debug ! ( "(resolving trait) found trait def: {:?}" , def) ;
3898- self . record_def ( trait_reference. ref_id , def) ;
3897+ match def {
3898+ ( DefTrait ( _) , _) => {
3899+ debug ! ( "(resolving trait) found trait def: {:?}" , def) ;
3900+ self . record_def ( trait_reference. ref_id , def) ;
3901+ }
3902+ ( def, _) => {
3903+ self . resolve_error ( trait_reference. path . span ,
3904+ format ! ( "`{}` is not a trait" ,
3905+ self . path_idents_to_str(
3906+ & trait_reference. path) ) ) ;
3907+
3908+ // If it's a typedef, give a note
3909+ match def {
3910+ DefTy ( _) => {
3911+ self . session . span_note (
3912+ trait_reference. path . span ,
3913+ format ! ( "`type` aliases cannot \
3914+ be used for traits")
3915+ . as_slice ( ) ) ;
3916+ }
3917+ _ => { }
3918+ }
3919+ }
3920+ }
3921+
38993922 }
39003923 }
39013924 }
@@ -4021,6 +4044,9 @@ impl<'a> Resolver<'a> {
40214044
40224045 this. with_current_self_type ( self_type, |this| {
40234046 for method in methods. iter ( ) {
4047+ // If this is a trait impl, ensure the method exists in trait
4048+ this. check_trait_method ( & * * method) ;
4049+
40244050 // We also need a new scope for the method-specific type parameters.
40254051 this. resolve_method ( MethodRibKind ( id, Provided ( method. id ) ) ,
40264052 & * * method) ;
@@ -4030,6 +4056,21 @@ impl<'a> Resolver<'a> {
40304056 } ) ;
40314057 }
40324058
4059+ fn check_trait_method ( & self , method : & Method ) {
4060+ // If there is a TraitRef in scope for an impl, then the method must be in the trait.
4061+ for & ( did, ref trait_ref) in self . current_trait_ref . iter ( ) {
4062+ let method_name = method. ident . name ;
4063+
4064+ if self . method_map . borrow ( ) . find ( & ( method_name, did) ) . is_none ( ) {
4065+ let path_str = self . path_idents_to_str ( & trait_ref. path ) ;
4066+ self . resolve_error ( method. span ,
4067+ format ! ( "method `{}` is not a member of trait `{}`" ,
4068+ token:: get_name( method_name) ,
4069+ path_str) . as_slice ( ) ) ;
4070+ }
4071+ }
4072+ }
4073+
40334074 fn resolve_module ( & mut self , module : & Mod , _span : Span ,
40344075 _name : Ident , id : NodeId ) {
40354076 // Write the implementations in scope into the module metadata.
0 commit comments