@@ -1317,6 +1317,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13171317 // If this is a trait impl, ensure the const
13181318 // exists in trait
13191319 this. check_trait_item (
1320+ item. id ,
13201321 item. ident ,
13211322 & item. kind ,
13221323 ValueNS ,
@@ -1352,6 +1353,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13521353 // If this is a trait impl, ensure the method
13531354 // exists in trait
13541355 this. check_trait_item (
1356+ item. id ,
13551357 item. ident ,
13561358 & item. kind ,
13571359 ValueNS ,
@@ -1379,6 +1381,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13791381 // If this is a trait impl, ensure the type
13801382 // exists in trait
13811383 this. check_trait_item (
1384+ item. id ,
13821385 item. ident ,
13831386 & item. kind ,
13841387 TypeNS ,
@@ -1409,6 +1412,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
14091412
14101413 fn check_trait_item < F > (
14111414 & mut self ,
1415+ id : NodeId ,
14121416 ident : Ident ,
14131417 kind : & AssocItemKind ,
14141418 ns : Namespace ,
@@ -1417,26 +1421,94 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
14171421 ) where
14181422 F : FnOnce ( Ident , & str , Option < Symbol > ) -> ResolutionError < ' _ > ,
14191423 {
1420- // If there is a TraitRef in scope for an impl, then the method must be in the
1421- // trait.
1422- if let Some ( ( module, _) ) = self . current_trait_ref {
1423- if self
1424- . r
1425- . resolve_ident_in_module (
1426- ModuleOrUniformRoot :: Module ( module) ,
1424+ // If there is a TraitRef in scope for an impl, then the method must be in the trait.
1425+ let Some ( ( module, _) ) = & self . current_trait_ref else { return ; } ;
1426+ let mut binding = self . r . resolve_ident_in_module (
1427+ ModuleOrUniformRoot :: Module ( module) ,
1428+ ident,
1429+ ns,
1430+ & self . parent_scope ,
1431+ false ,
1432+ span,
1433+ ) ;
1434+ if binding. is_err ( ) {
1435+ // We could not find the trait item in the correct namespace.
1436+ // Check the other namespace to report an error.
1437+ let ns = match ns {
1438+ ValueNS => TypeNS ,
1439+ TypeNS => ValueNS ,
1440+ _ => ns,
1441+ } ;
1442+ binding = self . r . resolve_ident_in_module (
1443+ ModuleOrUniformRoot :: Module ( module) ,
1444+ ident,
1445+ ns,
1446+ & self . parent_scope ,
1447+ false ,
1448+ span,
1449+ ) ;
1450+ }
1451+ let Ok ( binding) = binding else {
1452+ // We could not find the method: report an error.
1453+ let candidate = self . find_similarly_named_assoc_item ( ident. name , kind) ;
1454+ let path = & self . current_trait_ref . as_ref ( ) . unwrap ( ) . 1 . path ;
1455+ self . report_error ( span, err ( ident, & path_names_to_string ( path) , candidate) ) ;
1456+ return ;
1457+ } ;
1458+
1459+ let res = binding. res ( ) ;
1460+ let Res :: Def ( def_kind, _) = res else { bug ! ( ) } ;
1461+ match ( def_kind, kind) {
1462+ ( DefKind :: AssocTy , AssocItemKind :: TyAlias ( ..) )
1463+ | ( DefKind :: AssocFn , AssocItemKind :: Fn ( ..) )
1464+ | ( DefKind :: AssocConst , AssocItemKind :: Const ( ..) ) => {
1465+ self . r . record_partial_res ( id, PartialRes :: new ( res) ) ;
1466+ return ;
1467+ }
1468+ _ => { }
1469+ }
1470+
1471+ // The method kind does not correspond to what appeared in the trait, report.
1472+ let path = & self . current_trait_ref . as_ref ( ) . unwrap ( ) . 1 . path ;
1473+ let path = & path_names_to_string ( path) ;
1474+ let mut err = match kind {
1475+ AssocItemKind :: Const ( ..) => {
1476+ rustc_errors:: struct_span_err!(
1477+ self . r. session,
1478+ span,
1479+ E0323 ,
1480+ "item `{}` is an associated const, which doesn't match its trait `{}`" ,
14271481 ident,
1428- ns,
1429- & self . parent_scope ,
1430- false ,
1482+ path,
1483+ )
1484+ }
1485+ AssocItemKind :: Fn ( ..) => {
1486+ rustc_errors:: struct_span_err!(
1487+ self . r. session,
14311488 span,
1489+ E0324 ,
1490+ "item `{}` is an associated method, which doesn't match its trait `{}`" ,
1491+ ident,
1492+ path,
14321493 )
1433- . is_err ( )
1434- {
1435- let candidate = self . find_similarly_named_assoc_item ( ident. name , kind) ;
1436- let path = & self . current_trait_ref . as_ref ( ) . unwrap ( ) . 1 . path ;
1437- self . report_error ( span, err ( ident, & path_names_to_string ( path) , candidate) ) ;
14381494 }
1439- }
1495+ AssocItemKind :: TyAlias ( ..) => {
1496+ rustc_errors:: struct_span_err!(
1497+ self . r. session,
1498+ span,
1499+ E0325 ,
1500+ "item `{}` is an associated type, which doesn't match its trait `{}`" ,
1501+ ident,
1502+ path,
1503+ )
1504+ }
1505+ AssocItemKind :: MacCall ( ..) => {
1506+ span_bug ! ( span, "macros should have been expanded" )
1507+ }
1508+ } ;
1509+ err. span_label ( span, "does not match trait" ) ;
1510+ err. span_label ( binding. span , "item in trait" ) ;
1511+ err. emit ( ) ;
14401512 }
14411513
14421514 fn resolve_params ( & mut self , params : & ' ast [ Param ] ) {
0 commit comments