@@ -310,6 +310,34 @@ pub fn unexpected_hidden_region_diagnostic(
310
310
err
311
311
}
312
312
313
+ /// Structurally compares two types, modulo any inference variables.
314
+ ///
315
+ /// Returns `true` if two types are equal, or if one type is an inference variable compatible
316
+ /// with the other type. A TyVar inference type is compatible with any type, and an IntVar or
317
+ /// FloatVar inference type are compatible with themselves or their concrete types (Int and
318
+ /// Float types, respectively). When comparing two ADTs, these rules apply recursively.
319
+ pub fn same_type_modulo_infer ( a : Ty < ' tcx > , b : Ty < ' ctx > ) -> bool {
320
+ match ( & a. kind ( ) , & b. kind ( ) ) {
321
+ ( & ty:: Adt ( did_a, substs_a) , & ty:: Adt ( did_b, substs_b) ) => {
322
+ if did_a != did_b {
323
+ return false ;
324
+ }
325
+
326
+ substs_a. types ( ) . zip ( substs_b. types ( ) ) . all ( |( a, b) | same_type_modulo_infer ( a, b) )
327
+ }
328
+ ( & ty:: Int ( _) , & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) )
329
+ | ( & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) , & ty:: Int ( _) | & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) )
330
+ | ( & ty:: Float ( _) , & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) )
331
+ | (
332
+ & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) ,
333
+ & ty:: Float ( _) | & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) ,
334
+ )
335
+ | ( & ty:: Infer ( ty:: InferTy :: TyVar ( _) ) , _)
336
+ | ( _, & ty:: Infer ( ty:: InferTy :: TyVar ( _) ) ) => true ,
337
+ _ => a == b,
338
+ }
339
+ }
340
+
313
341
impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
314
342
pub fn report_region_errors ( & self , errors : & Vec < RegionResolutionError < ' tcx > > ) {
315
343
debug ! ( "report_region_errors(): {} errors to start" , errors. len( ) ) ;
@@ -1761,7 +1789,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1761
1789
self . get_impl_future_output_ty ( exp_found. expected ) ,
1762
1790
self . get_impl_future_output_ty ( exp_found. found ) ,
1763
1791
) {
1764
- ( Some ( exp) , Some ( found) ) if ty :: TyS :: same_type ( exp, found) => match & cause. code {
1792
+ ( Some ( exp) , Some ( found) ) if same_type_modulo_infer ( exp, found) => match & cause. code {
1765
1793
ObligationCauseCode :: IfExpression ( box IfExpressionCause { then, .. } ) => {
1766
1794
diag. multipart_suggestion (
1767
1795
"consider `await`ing on both `Future`s" ,
@@ -1793,15 +1821,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1793
1821
diag. help ( "consider `await`ing on both `Future`s" ) ;
1794
1822
}
1795
1823
} ,
1796
- ( _, Some ( ty) ) if ty :: TyS :: same_type ( exp_found. expected , ty) => {
1824
+ ( _, Some ( ty) ) if same_type_modulo_infer ( exp_found. expected , ty) => {
1797
1825
diag. span_suggestion_verbose (
1798
1826
exp_span. shrink_to_hi ( ) ,
1799
1827
"consider `await`ing on the `Future`" ,
1800
1828
".await" . to_string ( ) ,
1801
1829
Applicability :: MaybeIncorrect ,
1802
1830
) ;
1803
1831
}
1804
- ( Some ( ty) , _) if ty :: TyS :: same_type ( ty, exp_found. found ) => match cause. code {
1832
+ ( Some ( ty) , _) if same_type_modulo_infer ( ty, exp_found. found ) => match cause. code {
1805
1833
ObligationCauseCode :: Pattern { span : Some ( span) , .. }
1806
1834
| ObligationCauseCode :: IfExpression ( box IfExpressionCause { then : span, .. } ) => {
1807
1835
diag. span_suggestion_verbose (
0 commit comments