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