@@ -316,37 +316,6 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
316
316
err
317
317
}
318
318
319
- /// Structurally compares two types, modulo any inference variables.
320
- ///
321
- /// Returns `true` if two types are equal, or if one type is an inference variable compatible
322
- /// with the other type. A TyVar inference type is compatible with any type, and an IntVar or
323
- /// FloatVar inference type are compatible with themselves or their concrete types (Int and
324
- /// Float types, respectively). When comparing two ADTs, these rules apply recursively.
325
- pub fn same_type_modulo_infer < ' tcx > ( a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool {
326
- match ( & a. kind ( ) , & b. kind ( ) ) {
327
- ( & ty:: Adt ( did_a, substs_a) , & ty:: Adt ( did_b, substs_b) ) => {
328
- if did_a != did_b {
329
- return false ;
330
- }
331
-
332
- substs_a. types ( ) . zip ( substs_b. types ( ) ) . all ( |( a, b) | same_type_modulo_infer ( a, b) )
333
- }
334
- ( & ty:: Int ( _) , & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) )
335
- | ( & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) , & ty:: Int ( _) | & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) )
336
- | ( & ty:: Float ( _) , & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) )
337
- | (
338
- & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) ,
339
- & ty:: Float ( _) | & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) ,
340
- )
341
- | ( & ty:: Infer ( ty:: InferTy :: TyVar ( _) ) , _)
342
- | ( _, & ty:: Infer ( ty:: InferTy :: TyVar ( _) ) ) => true ,
343
- ( & ty:: Ref ( _, ty_a, mut_a) , & ty:: Ref ( _, ty_b, mut_b) ) => {
344
- mut_a == mut_b && same_type_modulo_infer ( * ty_a, * ty_b)
345
- }
346
- _ => a == b,
347
- }
348
- }
349
-
350
319
impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
351
320
pub fn report_region_errors (
352
321
& self ,
@@ -1723,15 +1692,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1723
1692
} ;
1724
1693
debug ! ( "exp_found {:?} terr {:?} cause.code {:?}" , exp_found, terr, cause. code( ) ) ;
1725
1694
if let Some ( exp_found) = exp_found {
1726
- let should_suggest_fixes = if let ObligationCauseCode :: Pattern { root_ty, .. } =
1727
- cause. code ( )
1728
- {
1729
- // Skip if the root_ty of the pattern is not the same as the expected_ty.
1730
- // If these types aren't equal then we've probably peeled off a layer of arrays.
1731
- same_type_modulo_infer ( self . resolve_vars_if_possible ( * root_ty) , exp_found. expected )
1732
- } else {
1733
- true
1734
- } ;
1695
+ let should_suggest_fixes =
1696
+ if let ObligationCauseCode :: Pattern { root_ty, .. } = cause. code ( ) {
1697
+ // Skip if the root_ty of the pattern is not the same as the expected_ty.
1698
+ // If these types aren't equal then we've probably peeled off a layer of arrays.
1699
+ self . same_type_modulo_infer ( * root_ty, exp_found. expected )
1700
+ } else {
1701
+ true
1702
+ } ;
1735
1703
1736
1704
if should_suggest_fixes {
1737
1705
self . suggest_tuple_pattern ( cause, & exp_found, diag) ;
@@ -1786,7 +1754,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1786
1754
. filter_map ( |variant| {
1787
1755
let sole_field = & variant. fields [ 0 ] ;
1788
1756
let sole_field_ty = sole_field. ty ( self . tcx , substs) ;
1789
- if same_type_modulo_infer ( sole_field_ty, exp_found. found ) {
1757
+ if self . same_type_modulo_infer ( sole_field_ty, exp_found. found ) {
1790
1758
let variant_path =
1791
1759
with_no_trimmed_paths ! ( self . tcx. def_path_str( variant. def_id) ) ;
1792
1760
// FIXME #56861: DRYer prelude filtering
@@ -1902,47 +1870,50 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1902
1870
self . get_impl_future_output_ty ( exp_found. expected ) . map ( Binder :: skip_binder) ,
1903
1871
self . get_impl_future_output_ty ( exp_found. found ) . map ( Binder :: skip_binder) ,
1904
1872
) {
1905
- ( Some ( exp) , Some ( found) ) if same_type_modulo_infer ( exp, found) => match cause. code ( ) {
1906
- ObligationCauseCode :: IfExpression ( box IfExpressionCause { then, .. } ) => {
1907
- diag. multipart_suggestion (
1908
- "consider `await`ing on both `Future`s" ,
1909
- vec ! [
1910
- ( then. shrink_to_hi( ) , ".await" . to_string( ) ) ,
1911
- ( exp_span. shrink_to_hi( ) , ".await" . to_string( ) ) ,
1912
- ] ,
1913
- Applicability :: MaybeIncorrect ,
1914
- ) ;
1915
- }
1916
- ObligationCauseCode :: MatchExpressionArm ( box MatchExpressionArmCause {
1917
- prior_arms,
1918
- ..
1919
- } ) => {
1920
- if let [ .., arm_span] = & prior_arms[ ..] {
1873
+ ( Some ( exp) , Some ( found) ) if self . same_type_modulo_infer ( exp, found) => {
1874
+ match cause. code ( ) {
1875
+ ObligationCauseCode :: IfExpression ( box IfExpressionCause { then, .. } ) => {
1921
1876
diag. multipart_suggestion (
1922
1877
"consider `await`ing on both `Future`s" ,
1923
1878
vec ! [
1924
- ( arm_span . shrink_to_hi( ) , ".await" . to_string( ) ) ,
1879
+ ( then . shrink_to_hi( ) , ".await" . to_string( ) ) ,
1925
1880
( exp_span. shrink_to_hi( ) , ".await" . to_string( ) ) ,
1926
1881
] ,
1927
1882
Applicability :: MaybeIncorrect ,
1928
1883
) ;
1929
- } else {
1884
+ }
1885
+ ObligationCauseCode :: MatchExpressionArm ( box MatchExpressionArmCause {
1886
+ prior_arms,
1887
+ ..
1888
+ } ) => {
1889
+ if let [ .., arm_span] = & prior_arms[ ..] {
1890
+ diag. multipart_suggestion (
1891
+ "consider `await`ing on both `Future`s" ,
1892
+ vec ! [
1893
+ ( arm_span. shrink_to_hi( ) , ".await" . to_string( ) ) ,
1894
+ ( exp_span. shrink_to_hi( ) , ".await" . to_string( ) ) ,
1895
+ ] ,
1896
+ Applicability :: MaybeIncorrect ,
1897
+ ) ;
1898
+ } else {
1899
+ diag. help ( "consider `await`ing on both `Future`s" ) ;
1900
+ }
1901
+ }
1902
+ _ => {
1930
1903
diag. help ( "consider `await`ing on both `Future`s" ) ;
1931
1904
}
1932
1905
}
1933
- _ => {
1934
- diag. help ( "consider `await`ing on both `Future`s" ) ;
1935
- }
1936
- } ,
1937
- ( _, Some ( ty) ) if same_type_modulo_infer ( exp_found. expected , ty) => {
1906
+ }
1907
+ ( _, Some ( ty) ) if self . same_type_modulo_infer ( exp_found. expected , ty) => {
1938
1908
diag. span_suggestion_verbose (
1939
1909
exp_span. shrink_to_hi ( ) ,
1940
1910
"consider `await`ing on the `Future`" ,
1941
1911
".await" ,
1942
1912
Applicability :: MaybeIncorrect ,
1943
1913
) ;
1944
1914
}
1945
- ( Some ( ty) , _) if same_type_modulo_infer ( ty, exp_found. found ) => match cause. code ( ) {
1915
+ ( Some ( ty) , _) if self . same_type_modulo_infer ( ty, exp_found. found ) => match cause. code ( )
1916
+ {
1946
1917
ObligationCauseCode :: Pattern { span : Some ( span) , .. }
1947
1918
| ObligationCauseCode :: IfExpression ( box IfExpressionCause { then : span, .. } ) => {
1948
1919
diag. span_suggestion_verbose (
@@ -1992,7 +1963,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1992
1963
. iter ( )
1993
1964
. filter ( |field| field. vis . is_accessible_from ( field. did , self . tcx ) )
1994
1965
. map ( |field| ( field. name , field. ty ( self . tcx , expected_substs) ) )
1995
- . find ( |( _, ty) | same_type_modulo_infer ( * ty, exp_found. found ) )
1966
+ . find ( |( _, ty) | self . same_type_modulo_infer ( * ty, exp_found. found ) )
1996
1967
{
1997
1968
if let ObligationCauseCode :: Pattern { span : Some ( span) , .. } = * cause. code ( ) {
1998
1969
if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
@@ -2057,7 +2028,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2057
2028
| ( _, ty:: Infer ( _) )
2058
2029
| ( ty:: Param ( _) , _)
2059
2030
| ( ty:: Infer ( _) , _) => { }
2060
- _ if same_type_modulo_infer ( exp_ty, found_ty) => { }
2031
+ _ if self . same_type_modulo_infer ( exp_ty, found_ty) => { }
2061
2032
_ => show_suggestion = false ,
2062
2033
} ;
2063
2034
}
@@ -2179,7 +2150,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2179
2150
) {
2180
2151
let [ expected_tup_elem] = expected_fields[ ..] else { return } ;
2181
2152
2182
- if !same_type_modulo_infer ( expected_tup_elem, found) {
2153
+ if !self . same_type_modulo_infer ( expected_tup_elem, found) {
2183
2154
return ;
2184
2155
}
2185
2156
@@ -2647,6 +2618,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2647
2618
span. is_desugaring ( DesugaringKind :: QuestionMark )
2648
2619
&& self . tcx . is_diagnostic_item ( sym:: From , trait_def_id)
2649
2620
}
2621
+
2622
+ /// Structurally compares two types, modulo any inference variables.
2623
+ ///
2624
+ /// Returns `true` if two types are equal, or if one type is an inference variable compatible
2625
+ /// with the other type. A TyVar inference type is compatible with any type, and an IntVar or
2626
+ /// FloatVar inference type are compatible with themselves or their concrete types (Int and
2627
+ /// Float types, respectively). When comparing two ADTs, these rules apply recursively.
2628
+ pub fn same_type_modulo_infer ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool {
2629
+ let ( a, b) = self . resolve_vars_if_possible ( ( a, b) ) ;
2630
+ match ( & a. kind ( ) , & b. kind ( ) ) {
2631
+ ( & ty:: Adt ( did_a, substs_a) , & ty:: Adt ( did_b, substs_b) ) => {
2632
+ if did_a != did_b {
2633
+ return false ;
2634
+ }
2635
+
2636
+ substs_a
2637
+ . types ( )
2638
+ . zip ( substs_b. types ( ) )
2639
+ . all ( |( a, b) | self . same_type_modulo_infer ( a, b) )
2640
+ }
2641
+ ( & ty:: Int ( _) | & ty:: Uint ( _) , & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) )
2642
+ | (
2643
+ & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) ,
2644
+ & ty:: Int ( _) | & ty:: Uint ( _) | & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) ,
2645
+ )
2646
+ | ( & ty:: Float ( _) , & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) )
2647
+ | (
2648
+ & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) ,
2649
+ & ty:: Float ( _) | & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) ,
2650
+ )
2651
+ | ( & ty:: Infer ( ty:: InferTy :: TyVar ( _) ) , _)
2652
+ | ( _, & ty:: Infer ( ty:: InferTy :: TyVar ( _) ) ) => true ,
2653
+ ( & ty:: Ref ( _, ty_a, mut_a) , & ty:: Ref ( _, ty_b, mut_b) ) => {
2654
+ mut_a == mut_b && self . same_type_modulo_infer ( * ty_a, * ty_b)
2655
+ }
2656
+ // FIXME(compiler-errors): This needs to be generalized more
2657
+ _ => a == b,
2658
+ }
2659
+ }
2650
2660
}
2651
2661
2652
2662
impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
0 commit comments