@@ -45,12 +45,7 @@ pub(super) fn compare_impl_method<'tcx>(
4545 debug ! ( "compare_impl_method(impl_trait_ref={:?})" , impl_trait_ref) ;
4646
4747 let _: Result < _ , ErrorGuaranteed > = try {
48- compare_self_type ( tcx, impl_m, trait_m, impl_trait_ref) ?;
49- compare_number_of_generics ( tcx, impl_m, trait_m, false ) ?;
50- compare_generic_param_kinds ( tcx, impl_m, trait_m, false ) ?;
51- compare_number_of_method_arguments ( tcx, impl_m, trait_m) ?;
52- compare_synthetic_generics ( tcx, impl_m, trait_m) ?;
53- compare_asyncness ( tcx, impl_m, trait_m) ?;
48+ check_method_is_structurally_compatible ( tcx, impl_m, trait_m, impl_trait_ref, false ) ?;
5449 compare_method_predicate_entailment (
5550 tcx,
5651 impl_m,
@@ -61,6 +56,26 @@ pub(super) fn compare_impl_method<'tcx>(
6156 } ;
6257}
6358
59+ /// Checks a bunch of different properties of the impl/trait methods for
60+ /// compatibility, such as asyncness, number of argument, self receiver kind,
61+ /// and number of early- and late-bound generics.
62+ fn check_method_is_structurally_compatible < ' tcx > (
63+ tcx : TyCtxt < ' tcx > ,
64+ impl_m : ty:: AssocItem ,
65+ trait_m : ty:: AssocItem ,
66+ impl_trait_ref : ty:: TraitRef < ' tcx > ,
67+ delay : bool ,
68+ ) -> Result < ( ) , ErrorGuaranteed > {
69+ compare_self_type ( tcx, impl_m, trait_m, impl_trait_ref, delay) ?;
70+ compare_number_of_generics ( tcx, impl_m, trait_m, delay) ?;
71+ compare_generic_param_kinds ( tcx, impl_m, trait_m, delay) ?;
72+ compare_number_of_method_arguments ( tcx, impl_m, trait_m, delay) ?;
73+ compare_synthetic_generics ( tcx, impl_m, trait_m, delay) ?;
74+ compare_asyncness ( tcx, impl_m, trait_m, delay) ?;
75+ check_region_bounds_on_impl_item ( tcx, impl_m, trait_m, delay) ?;
76+ Ok ( ( ) )
77+ }
78+
6479/// This function is best explained by example. Consider a trait with it's implementation:
6580///
6681/// ```rust
@@ -177,9 +192,6 @@ fn compare_method_predicate_entailment<'tcx>(
177192 let impl_m_predicates = tcx. predicates_of ( impl_m. def_id ) ;
178193 let trait_m_predicates = tcx. predicates_of ( trait_m. def_id ) ;
179194
180- // Check region bounds.
181- check_region_bounds_on_impl_item ( tcx, impl_m, trait_m, false ) ?;
182-
183195 // Create obligations for each predicate declared by the impl
184196 // definition in the context of the trait's parameter
185197 // environment. We can't just use `impl_env.caller_bounds`,
@@ -534,6 +546,7 @@ fn compare_asyncness<'tcx>(
534546 tcx : TyCtxt < ' tcx > ,
535547 impl_m : ty:: AssocItem ,
536548 trait_m : ty:: AssocItem ,
549+ delay : bool ,
537550) -> Result < ( ) , ErrorGuaranteed > {
538551 if tcx. asyncness ( trait_m. def_id ) == hir:: IsAsync :: Async {
539552 match tcx. fn_sig ( impl_m. def_id ) . skip_binder ( ) . skip_binder ( ) . output ( ) . kind ( ) {
@@ -544,11 +557,14 @@ fn compare_asyncness<'tcx>(
544557 // We don't know if it's ok, but at least it's already an error.
545558 }
546559 _ => {
547- return Err ( tcx. sess . emit_err ( crate :: errors:: AsyncTraitImplShouldBeAsync {
548- span : tcx. def_span ( impl_m. def_id ) ,
549- method_name : trait_m. name ,
550- trait_item_span : tcx. hir ( ) . span_if_local ( trait_m. def_id ) ,
551- } ) ) ;
560+ return Err ( tcx
561+ . sess
562+ . create_err ( crate :: errors:: AsyncTraitImplShouldBeAsync {
563+ span : tcx. def_span ( impl_m. def_id ) ,
564+ method_name : trait_m. name ,
565+ trait_item_span : tcx. hir ( ) . span_if_local ( trait_m. def_id ) ,
566+ } )
567+ . emit_unless ( delay) ) ;
552568 }
553569 } ;
554570 }
@@ -602,9 +618,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
602618
603619 // First, check a few of the same things as `compare_impl_method`,
604620 // just so we don't ICE during substitution later.
605- compare_number_of_generics ( tcx, impl_m, trait_m, true ) ?;
606- compare_generic_param_kinds ( tcx, impl_m, trait_m, true ) ?;
607- check_region_bounds_on_impl_item ( tcx, impl_m, trait_m, true ) ?;
621+ check_method_is_structurally_compatible ( tcx, impl_m, trait_m, impl_trait_ref, true ) ?;
608622
609623 let trait_to_impl_substs = impl_trait_ref. substs ;
610624
@@ -1097,6 +1111,7 @@ fn compare_self_type<'tcx>(
10971111 impl_m : ty:: AssocItem ,
10981112 trait_m : ty:: AssocItem ,
10991113 impl_trait_ref : ty:: TraitRef < ' tcx > ,
1114+ delay : bool ,
11001115) -> Result < ( ) , ErrorGuaranteed > {
11011116 // Try to give more informative error messages about self typing
11021117 // mismatches. Note that any mismatch will also be detected
@@ -1145,7 +1160,7 @@ fn compare_self_type<'tcx>(
11451160 } else {
11461161 err. note_trait_signature ( trait_m. name , trait_m. signature ( tcx) ) ;
11471162 }
1148- return Err ( err. emit ( ) ) ;
1163+ return Err ( err. emit_unless ( delay ) ) ;
11491164 }
11501165
11511166 ( true , false ) => {
@@ -1166,7 +1181,7 @@ fn compare_self_type<'tcx>(
11661181 err. note_trait_signature ( trait_m. name , trait_m. signature ( tcx) ) ;
11671182 }
11681183
1169- return Err ( err. emit ( ) ) ;
1184+ return Err ( err. emit_unless ( delay ) ) ;
11701185 }
11711186 }
11721187
@@ -1352,6 +1367,7 @@ fn compare_number_of_method_arguments<'tcx>(
13521367 tcx : TyCtxt < ' tcx > ,
13531368 impl_m : ty:: AssocItem ,
13541369 trait_m : ty:: AssocItem ,
1370+ delay : bool ,
13551371) -> Result < ( ) , ErrorGuaranteed > {
13561372 let impl_m_fty = tcx. fn_sig ( impl_m. def_id ) ;
13571373 let trait_m_fty = tcx. fn_sig ( trait_m. def_id ) ;
@@ -1422,7 +1438,7 @@ fn compare_number_of_method_arguments<'tcx>(
14221438 ) ,
14231439 ) ;
14241440
1425- return Err ( err. emit ( ) ) ;
1441+ return Err ( err. emit_unless ( delay ) ) ;
14261442 }
14271443
14281444 Ok ( ( ) )
@@ -1432,6 +1448,7 @@ fn compare_synthetic_generics<'tcx>(
14321448 tcx : TyCtxt < ' tcx > ,
14331449 impl_m : ty:: AssocItem ,
14341450 trait_m : ty:: AssocItem ,
1451+ delay : bool ,
14351452) -> Result < ( ) , ErrorGuaranteed > {
14361453 // FIXME(chrisvittal) Clean up this function, list of FIXME items:
14371454 // 1. Better messages for the span labels
@@ -1551,7 +1568,7 @@ fn compare_synthetic_generics<'tcx>(
15511568 }
15521569 _ => unreachable ! ( ) ,
15531570 }
1554- error_found = Some ( err. emit ( ) ) ;
1571+ error_found = Some ( err. emit_unless ( delay ) ) ;
15551572 }
15561573 }
15571574 if let Some ( reported) = error_found { Err ( reported) } else { Ok ( ( ) ) }
0 commit comments