@@ -628,21 +628,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
628
628
expected : Expectation < ' tcx > ,
629
629
expr : & ' tcx hir:: Expr < ' tcx > ,
630
630
) -> Ty < ' tcx > {
631
- let hint = expected. only_has_type ( self ) . map_or ( NoExpectation , |ty| {
632
- match ty. kind ( ) {
633
- ty:: Ref ( _, ty, _) | ty:: RawPtr ( ty, _) => {
634
- if oprnd. is_syntactic_place_expr ( ) {
635
- // Places may legitimately have unsized types.
636
- // For example, dereferences of a wide pointer and
637
- // the last field of a struct can be unsized.
638
- ExpectHasType ( * ty)
639
- } else {
640
- Expectation :: rvalue_hint ( self , * ty)
631
+ let hint = expected. structurally_resolve_hard_expectation ( self , expr. span ) . map_or (
632
+ NoExpectation ,
633
+ |ty| {
634
+ match ty. kind ( ) {
635
+ ty:: Ref ( _, ty, _) | ty:: RawPtr ( ty, _) => {
636
+ if oprnd. is_syntactic_place_expr ( ) {
637
+ // Places may legitimately have unsized types.
638
+ // For example, dereferences of a wide pointer and
639
+ // the last field of a struct can be unsized.
640
+ ExpectHasType ( * ty)
641
+ } else {
642
+ Expectation :: rvalue_hint ( self , * ty)
643
+ }
641
644
}
645
+ _ => NoExpectation ,
642
646
}
643
- _ => NoExpectation ,
644
- }
645
- } ) ;
647
+ } ,
648
+ ) ;
646
649
let ty =
647
650
self . check_expr_with_expectation_and_needs ( oprnd, hint, Needs :: maybe_mut_place ( mutbl) ) ;
648
651
@@ -1294,7 +1297,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1294
1297
let cond_diverges = self . diverges . get ( ) ;
1295
1298
self . diverges . set ( Diverges :: Maybe ) ;
1296
1299
1297
- let expected = orig_expected. adjust_for_branches ( self ) ;
1300
+ let expected = orig_expected. adjust_for_branches ( self , sp ) ;
1298
1301
let then_ty = self . check_expr_with_expectation ( then_expr, expected) ;
1299
1302
let then_diverges = self . diverges . get ( ) ;
1300
1303
self . diverges . set ( Diverges :: Maybe ) ;
@@ -1305,7 +1308,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1305
1308
// `expected` if it represents a *hard* constraint
1306
1309
// (`only_has_type`); otherwise, we just go with a
1307
1310
// fresh type variable.
1308
- let coerce_to_ty = expected. coercion_target_type ( self , sp) ;
1311
+ let coerce_to_ty = expected
1312
+ . structurally_resolve_hard_expectation ( self , sp)
1313
+ . unwrap_or_else ( || self . next_ty_var ( sp) ) ;
1309
1314
let mut coerce: DynamicCoerceMany < ' _ > = CoerceMany :: new ( coerce_to_ty) ;
1310
1315
1311
1316
coerce. coerce ( self , & self . misc ( sp) , then_expr, then_ty) ;
@@ -1315,7 +1320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1315
1320
let else_diverges = self . diverges . get ( ) ;
1316
1321
1317
1322
let tail_defines_return_position_impl_trait =
1318
- self . return_position_impl_trait_from_match_expectation ( orig_expected) ;
1323
+ self . return_position_impl_trait_from_match_expectation ( orig_expected, sp ) ;
1319
1324
let if_cause = self . if_cause (
1320
1325
sp,
1321
1326
cond_expr. span ,
@@ -1355,8 +1360,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1355
1360
rhs : & ' tcx hir:: Expr < ' tcx > ,
1356
1361
span : Span ,
1357
1362
) -> Ty < ' tcx > {
1358
- let expected_ty = expected. coercion_target_type ( self , expr. span ) ;
1359
- if expected_ty == self . tcx . types . bool {
1363
+ let expected_ty = expected. structurally_resolve_hard_expectation ( self , expr. span ) ;
1364
+ if expected_ty == Some ( self . tcx . types . bool ) {
1360
1365
let guar = self . expr_assign_expected_bool_error ( expr, lhs, rhs, span) ;
1361
1366
return Ty :: new_error ( self . tcx , guar) ;
1362
1367
}
@@ -1522,7 +1527,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1522
1527
let coerce = match source {
1523
1528
// you can only use break with a value from a normal `loop { }`
1524
1529
hir:: LoopSource :: Loop => {
1525
- let coerce_to = expected. coercion_target_type ( self , body. span ) ;
1530
+ let coerce_to = expected
1531
+ . structurally_resolve_hard_expectation ( self , body. span )
1532
+ . unwrap_or_else ( || self . next_ty_var ( body. span ) ) ;
1526
1533
Some ( CoerceMany :: new ( coerce_to) )
1527
1534
}
1528
1535
@@ -1639,7 +1646,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1639
1646
) -> Ty < ' tcx > {
1640
1647
let element_ty = if !args. is_empty ( ) {
1641
1648
let coerce_to = expected
1642
- . to_option ( self )
1649
+ . structurally_resolve ( self , expr . span )
1643
1650
. and_then ( |uty| match * uty. kind ( ) {
1644
1651
ty:: Array ( ty, _) | ty:: Slice ( ty) => Some ( ty) ,
1645
1652
_ => None ,
@@ -1824,13 +1831,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1824
1831
expected : Expectation < ' tcx > ,
1825
1832
expr : & ' tcx hir:: Expr < ' tcx > ,
1826
1833
) -> Ty < ' tcx > {
1827
- let flds = expected. only_has_type ( self ) . and_then ( |ty| {
1828
- let ty = self . try_structurally_resolve_type ( expr. span , ty) ;
1829
- match ty. kind ( ) {
1834
+ let flds =
1835
+ expected. structurally_resolve_hard_expectation ( self , expr. span ) . and_then ( |ty| match ty
1836
+ . kind ( )
1837
+ {
1830
1838
ty:: Tuple ( flds) => Some ( & flds[ ..] ) ,
1831
1839
_ => None ,
1832
- }
1833
- } ) ;
1840
+ } ) ;
1834
1841
1835
1842
let elt_ts_iter = elts. iter ( ) . enumerate ( ) . map ( |( i, e) | match flds {
1836
1843
Some ( fs) if i < fs. len ( ) => {
@@ -1904,17 +1911,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1904
1911
let tcx = self . tcx ;
1905
1912
1906
1913
let adt_ty = self . try_structurally_resolve_type ( span, adt_ty) ;
1907
- let adt_ty_hint = expected. only_has_type ( self ) . and_then ( |expected| {
1908
- self . fudge_inference_if_ok ( || {
1909
- let ocx = ObligationCtxt :: new ( self ) ;
1910
- ocx. sup ( & self . misc ( span) , self . param_env , expected, adt_ty) ?;
1911
- if !ocx. select_where_possible ( ) . is_empty ( ) {
1912
- return Err ( TypeError :: Mismatch ) ;
1913
- }
1914
- Ok ( self . resolve_vars_if_possible ( adt_ty) )
1915
- } )
1916
- . ok ( )
1917
- } ) ;
1914
+ let adt_ty_hint =
1915
+ expected. structurally_resolve_hard_expectation ( self , expr. span ) . and_then ( |expected| {
1916
+ self . fudge_inference_if_ok ( || {
1917
+ let ocx = ObligationCtxt :: new ( self ) ;
1918
+ ocx. sup ( & self . misc ( span) , self . param_env , expected, adt_ty) ?;
1919
+ if !ocx. select_where_possible ( ) . is_empty ( ) {
1920
+ return Err ( TypeError :: Mismatch ) ;
1921
+ }
1922
+ Ok ( self . resolve_vars_if_possible ( adt_ty) )
1923
+ } )
1924
+ . ok ( )
1925
+ } ) ;
1918
1926
if let Some ( adt_ty_hint) = adt_ty_hint {
1919
1927
// re-link the variables that the fudging above can create.
1920
1928
self . demand_eqtype ( span, adt_ty_hint, adt_ty) ;
@@ -2682,7 +2690,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2682
2690
base_ty,
2683
2691
field,
2684
2692
did,
2685
- expected. only_has_type ( self ) ,
2693
+ expected. structurally_resolve_hard_expectation ( self , expr . span ) ,
2686
2694
) ;
2687
2695
return Ty :: new_error ( self . tcx ( ) , guar) ;
2688
2696
}
@@ -2693,7 +2701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2693
2701
field,
2694
2702
base_ty,
2695
2703
expr. hir_id ,
2696
- expected. only_has_type ( self ) ,
2704
+ expected. structurally_resolve_hard_expectation ( self , expr . span ) ,
2697
2705
) {
2698
2706
self . ban_take_value_of_method ( expr, base_ty, field)
2699
2707
} else if !base_ty. is_primitive_ty ( ) {
0 commit comments