@@ -45,12 +45,7 @@ pub(super) fn compare_impl_method<'tcx>(
45
45
debug ! ( "compare_impl_method(impl_trait_ref={:?})" , impl_trait_ref) ;
46
46
47
47
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 ) ?;
54
49
compare_method_predicate_entailment (
55
50
tcx,
56
51
impl_m,
@@ -61,6 +56,26 @@ pub(super) fn compare_impl_method<'tcx>(
61
56
} ;
62
57
}
63
58
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
+
64
79
/// This function is best explained by example. Consider a trait with it's implementation:
65
80
///
66
81
/// ```rust
@@ -177,9 +192,6 @@ fn compare_method_predicate_entailment<'tcx>(
177
192
let impl_m_predicates = tcx. predicates_of ( impl_m. def_id ) ;
178
193
let trait_m_predicates = tcx. predicates_of ( trait_m. def_id ) ;
179
194
180
- // Check region bounds.
181
- check_region_bounds_on_impl_item ( tcx, impl_m, trait_m, false ) ?;
182
-
183
195
// Create obligations for each predicate declared by the impl
184
196
// definition in the context of the trait's parameter
185
197
// environment. We can't just use `impl_env.caller_bounds`,
@@ -534,6 +546,7 @@ fn compare_asyncness<'tcx>(
534
546
tcx : TyCtxt < ' tcx > ,
535
547
impl_m : ty:: AssocItem ,
536
548
trait_m : ty:: AssocItem ,
549
+ delay : bool ,
537
550
) -> Result < ( ) , ErrorGuaranteed > {
538
551
if tcx. asyncness ( trait_m. def_id ) == hir:: IsAsync :: Async {
539
552
match tcx. fn_sig ( impl_m. def_id ) . skip_binder ( ) . skip_binder ( ) . output ( ) . kind ( ) {
@@ -544,11 +557,14 @@ fn compare_asyncness<'tcx>(
544
557
// We don't know if it's ok, but at least it's already an error.
545
558
}
546
559
_ => {
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) ) ;
552
568
}
553
569
} ;
554
570
}
@@ -602,9 +618,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
602
618
603
619
// First, check a few of the same things as `compare_impl_method`,
604
620
// 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 ) ?;
608
622
609
623
let trait_to_impl_substs = impl_trait_ref. substs ;
610
624
@@ -1097,6 +1111,7 @@ fn compare_self_type<'tcx>(
1097
1111
impl_m : ty:: AssocItem ,
1098
1112
trait_m : ty:: AssocItem ,
1099
1113
impl_trait_ref : ty:: TraitRef < ' tcx > ,
1114
+ delay : bool ,
1100
1115
) -> Result < ( ) , ErrorGuaranteed > {
1101
1116
// Try to give more informative error messages about self typing
1102
1117
// mismatches. Note that any mismatch will also be detected
@@ -1145,7 +1160,7 @@ fn compare_self_type<'tcx>(
1145
1160
} else {
1146
1161
err. note_trait_signature ( trait_m. name , trait_m. signature ( tcx) ) ;
1147
1162
}
1148
- return Err ( err. emit ( ) ) ;
1163
+ return Err ( err. emit_unless ( delay ) ) ;
1149
1164
}
1150
1165
1151
1166
( true , false ) => {
@@ -1166,7 +1181,7 @@ fn compare_self_type<'tcx>(
1166
1181
err. note_trait_signature ( trait_m. name , trait_m. signature ( tcx) ) ;
1167
1182
}
1168
1183
1169
- return Err ( err. emit ( ) ) ;
1184
+ return Err ( err. emit_unless ( delay ) ) ;
1170
1185
}
1171
1186
}
1172
1187
@@ -1352,6 +1367,7 @@ fn compare_number_of_method_arguments<'tcx>(
1352
1367
tcx : TyCtxt < ' tcx > ,
1353
1368
impl_m : ty:: AssocItem ,
1354
1369
trait_m : ty:: AssocItem ,
1370
+ delay : bool ,
1355
1371
) -> Result < ( ) , ErrorGuaranteed > {
1356
1372
let impl_m_fty = tcx. fn_sig ( impl_m. def_id ) ;
1357
1373
let trait_m_fty = tcx. fn_sig ( trait_m. def_id ) ;
@@ -1422,7 +1438,7 @@ fn compare_number_of_method_arguments<'tcx>(
1422
1438
) ,
1423
1439
) ;
1424
1440
1425
- return Err ( err. emit ( ) ) ;
1441
+ return Err ( err. emit_unless ( delay ) ) ;
1426
1442
}
1427
1443
1428
1444
Ok ( ( ) )
@@ -1432,6 +1448,7 @@ fn compare_synthetic_generics<'tcx>(
1432
1448
tcx : TyCtxt < ' tcx > ,
1433
1449
impl_m : ty:: AssocItem ,
1434
1450
trait_m : ty:: AssocItem ,
1451
+ delay : bool ,
1435
1452
) -> Result < ( ) , ErrorGuaranteed > {
1436
1453
// FIXME(chrisvittal) Clean up this function, list of FIXME items:
1437
1454
// 1. Better messages for the span labels
@@ -1551,7 +1568,7 @@ fn compare_synthetic_generics<'tcx>(
1551
1568
}
1552
1569
_ => unreachable ! ( ) ,
1553
1570
}
1554
- error_found = Some ( err. emit ( ) ) ;
1571
+ error_found = Some ( err. emit_unless ( delay ) ) ;
1555
1572
}
1556
1573
}
1557
1574
if let Some ( reported) = error_found { Err ( reported) } else { Ok ( ( ) ) }
0 commit comments