@@ -628,21 +628,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
628628 expected : Expectation < ' tcx > ,
629629 expr : & ' tcx hir:: Expr < ' tcx > ,
630630 ) -> 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+ }
641644 }
645+ _ => NoExpectation ,
642646 }
643- _ => NoExpectation ,
644- }
645- } ) ;
647+ } ,
648+ ) ;
646649 let ty =
647650 self . check_expr_with_expectation_and_needs ( oprnd, hint, Needs :: maybe_mut_place ( mutbl) ) ;
648651
@@ -1294,7 +1297,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12941297 let cond_diverges = self . diverges . get ( ) ;
12951298 self . diverges . set ( Diverges :: Maybe ) ;
12961299
1297- let expected = orig_expected. adjust_for_branches ( self ) ;
1300+ let expected = orig_expected. adjust_for_branches ( self , sp ) ;
12981301 let then_ty = self . check_expr_with_expectation ( then_expr, expected) ;
12991302 let then_diverges = self . diverges . get ( ) ;
13001303 self . diverges . set ( Diverges :: Maybe ) ;
@@ -1305,7 +1308,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13051308 // `expected` if it represents a *hard* constraint
13061309 // (`only_has_type`); otherwise, we just go with a
13071310 // 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) ) ;
13091314 let mut coerce: DynamicCoerceMany < ' _ > = CoerceMany :: new ( coerce_to_ty) ;
13101315
13111316 coerce. coerce ( self , & self . misc ( sp) , then_expr, then_ty) ;
@@ -1315,7 +1320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13151320 let else_diverges = self . diverges . get ( ) ;
13161321
13171322 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 ) ;
13191324 let if_cause = self . if_cause (
13201325 sp,
13211326 cond_expr. span ,
@@ -1355,8 +1360,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13551360 rhs : & ' tcx hir:: Expr < ' tcx > ,
13561361 span : Span ,
13571362 ) -> 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 ) {
13601365 let guar = self . expr_assign_expected_bool_error ( expr, lhs, rhs, span) ;
13611366 return Ty :: new_error ( self . tcx , guar) ;
13621367 }
@@ -1522,7 +1527,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15221527 let coerce = match source {
15231528 // you can only use break with a value from a normal `loop { }`
15241529 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 ) ) ;
15261533 Some ( CoerceMany :: new ( coerce_to) )
15271534 }
15281535
@@ -1639,7 +1646,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16391646 ) -> Ty < ' tcx > {
16401647 let element_ty = if !args. is_empty ( ) {
16411648 let coerce_to = expected
1642- . to_option ( self )
1649+ . structurally_resolve ( self , expr . span )
16431650 . and_then ( |uty| match * uty. kind ( ) {
16441651 ty:: Array ( ty, _) | ty:: Slice ( ty) => Some ( ty) ,
16451652 _ => None ,
@@ -1824,13 +1831,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18241831 expected : Expectation < ' tcx > ,
18251832 expr : & ' tcx hir:: Expr < ' tcx > ,
18261833 ) -> 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+ {
18301838 ty:: Tuple ( flds) => Some ( & flds[ ..] ) ,
18311839 _ => None ,
1832- }
1833- } ) ;
1840+ } ) ;
18341841
18351842 let elt_ts_iter = elts. iter ( ) . enumerate ( ) . map ( |( i, e) | match flds {
18361843 Some ( fs) if i < fs. len ( ) => {
@@ -1904,17 +1911,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19041911 let tcx = self . tcx ;
19051912
19061913 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+ } ) ;
19181926 if let Some ( adt_ty_hint) = adt_ty_hint {
19191927 // re-link the variables that the fudging above can create.
19201928 self . demand_eqtype ( span, adt_ty_hint, adt_ty) ;
@@ -2682,7 +2690,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26822690 base_ty,
26832691 field,
26842692 did,
2685- expected. only_has_type ( self ) ,
2693+ expected. structurally_resolve_hard_expectation ( self , expr . span ) ,
26862694 ) ;
26872695 return Ty :: new_error ( self . tcx ( ) , guar) ;
26882696 }
@@ -2693,7 +2701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26932701 field,
26942702 base_ty,
26952703 expr. hir_id ,
2696- expected. only_has_type ( self ) ,
2704+ expected. structurally_resolve_hard_expectation ( self , expr . span ) ,
26972705 ) {
26982706 self . ban_take_value_of_method ( expr, base_ty, field)
26992707 } else if !base_ty. is_primitive_ty ( ) {
0 commit comments