@@ -624,21 +624,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
624624 expected : Expectation < ' tcx > ,
625625 expr : & ' tcx hir:: Expr < ' tcx > ,
626626 ) -> 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+ }
637640 }
641+ _ => NoExpectation ,
638642 }
639- _ => NoExpectation ,
640- }
641- } ) ;
643+ } ,
644+ ) ;
642645 let ty =
643646 self . check_expr_with_expectation_and_needs ( oprnd, hint, Needs :: maybe_mut_place ( mutbl) ) ;
644647
@@ -1301,7 +1304,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13011304 // `expected` if it represents a *hard* constraint
13021305 // (`only_has_type`); otherwise, we just go with a
13031306 // 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) ) ;
13051310 let mut coerce: DynamicCoerceMany < ' _ > = CoerceMany :: new ( coerce_to_ty) ;
13061311
13071312 coerce. coerce ( self , & self . misc ( sp) , then_expr, then_ty) ;
@@ -1311,7 +1316,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13111316 let else_diverges = self . diverges . get ( ) ;
13121317
13131318 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 ) ;
13151320 let if_cause = self . if_cause (
13161321 sp,
13171322 cond_expr. span ,
@@ -1351,8 +1356,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13511356 rhs : & ' tcx hir:: Expr < ' tcx > ,
13521357 span : Span ,
13531358 ) -> 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 ) {
13561361 let guar = self . expr_assign_expected_bool_error ( expr, lhs, rhs, span) ;
13571362 return Ty :: new_error ( self . tcx , guar) ;
13581363 }
@@ -1518,7 +1523,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15181523 let coerce = match source {
15191524 // you can only use break with a value from a normal `loop { }`
15201525 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 ) ) ;
15221529 Some ( CoerceMany :: new ( coerce_to) )
15231530 }
15241531
@@ -1635,7 +1642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16351642 ) -> Ty < ' tcx > {
16361643 let element_ty = if !args. is_empty ( ) {
16371644 let coerce_to = expected
1638- . to_option ( self )
1645+ . structurally_resolve ( self , expr . span )
16391646 . and_then ( |uty| match * uty. kind ( ) {
16401647 ty:: Array ( ty, _) | ty:: Slice ( ty) => Some ( ty) ,
16411648 _ => None ,
@@ -1820,13 +1827,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18201827 expected : Expectation < ' tcx > ,
18211828 expr : & ' tcx hir:: Expr < ' tcx > ,
18221829 ) -> 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+ {
18261834 ty:: Tuple ( flds) => Some ( & flds[ ..] ) ,
18271835 _ => None ,
1828- }
1829- } ) ;
1836+ } ) ;
18301837
18311838 let elt_ts_iter = elts. iter ( ) . enumerate ( ) . map ( |( i, e) | match flds {
18321839 Some ( fs) if i < fs. len ( ) => {
@@ -1900,17 +1907,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19001907 let tcx = self . tcx ;
19011908
19021909 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+ } ) ;
19141922 if let Some ( adt_ty_hint) = adt_ty_hint {
19151923 // re-link the variables that the fudging above can create.
19161924 self . demand_eqtype ( span, adt_ty_hint, adt_ty) ;
@@ -2678,7 +2686,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26782686 base_ty,
26792687 field,
26802688 did,
2681- expected. only_has_type ( self ) ,
2689+ expected. structurally_resolve_hard_expectation ( self , expr . span ) ,
26822690 ) ;
26832691 return Ty :: new_error ( self . tcx ( ) , guar) ;
26842692 }
@@ -2689,7 +2697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26892697 field,
26902698 base_ty,
26912699 expr. hir_id ,
2692- expected. only_has_type ( self ) ,
2700+ expected. structurally_resolve_hard_expectation ( self , expr . span ) ,
26932701 ) {
26942702 self . ban_take_value_of_method ( expr, base_ty, field)
26952703 } else if !base_ty. is_primitive_ty ( ) {
0 commit comments