@@ -29,9 +29,7 @@ use rustc_hir::{ExprKind, QPath};
2929use rustc_infer:: infer;
3030use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
3131use rustc_middle:: ty;
32- use rustc_middle:: ty:: adjustment:: {
33- Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability ,
34- } ;
32+ use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase } ;
3533use rustc_middle:: ty:: Ty ;
3634use rustc_middle:: ty:: TypeFoldable ;
3735use rustc_middle:: ty:: { AdtKind , Visibility } ;
@@ -113,12 +111,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
113111 self . check_expr_with_expectation ( expr, ExpectHasType ( expected) )
114112 }
115113
116- pub ( super ) fn check_expr_with_expectation (
114+ fn check_expr_with_expectation_and_needs (
117115 & self ,
118116 expr : & ' tcx hir:: Expr < ' tcx > ,
119117 expected : Expectation < ' tcx > ,
118+ needs : Needs ,
120119 ) -> Ty < ' tcx > {
121- self . check_expr_with_expectation_and_needs ( expr, expected, Needs :: None )
120+ let ty = self . check_expr_with_expectation ( expr, expected) ;
121+
122+ // If the expression is used in a place whether mutable place is required
123+ // e.g. LHS of assignment, perform the conversion.
124+ if let Needs :: MutPlace = needs {
125+ self . convert_place_derefs_to_mutable ( expr) ;
126+ }
127+
128+ ty
122129 }
123130
124131 pub ( super ) fn check_expr ( & self , expr : & ' tcx hir:: Expr < ' tcx > ) -> Ty < ' tcx > {
@@ -143,11 +150,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
143150 /// Note that inspecting a type's structure *directly* may expose the fact
144151 /// that there are actually multiple representations for `Error`, so avoid
145152 /// that when err needs to be handled differently.
146- fn check_expr_with_expectation_and_needs (
153+ pub ( super ) fn check_expr_with_expectation (
147154 & self ,
148155 expr : & ' tcx hir:: Expr < ' tcx > ,
149156 expected : Expectation < ' tcx > ,
150- needs : Needs ,
151157 ) -> Ty < ' tcx > {
152158 debug ! ( ">> type-checking: expr={:?} expected={:?}" , expr, expected) ;
153159
@@ -171,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
171177 let old_diverges = self . diverges . replace ( Diverges :: Maybe ) ;
172178 let old_has_errors = self . has_errors . replace ( false ) ;
173179
174- let ty = self . check_expr_kind ( expr, expected, needs ) ;
180+ let ty = self . check_expr_kind ( expr, expected) ;
175181
176182 // Warn for non-block expressions with diverging children.
177183 match expr. kind {
@@ -213,9 +219,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
213219 & self ,
214220 expr : & ' tcx hir:: Expr < ' tcx > ,
215221 expected : Expectation < ' tcx > ,
216- needs : Needs ,
217222 ) -> Ty < ' tcx > {
218- debug ! ( "check_expr_kind(expr={:?}, expected={:?}, needs={:?} )" , expr, expected, needs , ) ;
223+ debug ! ( "check_expr_kind(expr={:?}, expected={:?})" , expr, expected) ;
219224
220225 let tcx = self . tcx ;
221226 match expr. kind {
@@ -226,9 +231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
226231 self . check_expr_assign ( expr, expected, lhs, rhs, span)
227232 }
228233 ExprKind :: AssignOp ( op, ref lhs, ref rhs) => self . check_binop_assign ( expr, op, lhs, rhs) ,
229- ExprKind :: Unary ( unop, ref oprnd) => {
230- self . check_expr_unary ( unop, oprnd, expected, needs, expr)
231- }
234+ ExprKind :: Unary ( unop, ref oprnd) => self . check_expr_unary ( unop, oprnd, expected, expr) ,
232235 ExprKind :: AddrOf ( kind, mutbl, ref oprnd) => {
233236 self . check_expr_addr_of ( kind, mutbl, oprnd, expected, expr)
234237 }
@@ -264,7 +267,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
264267 ExprKind :: Block ( ref body, _) => self . check_block_with_expected ( & body, expected) ,
265268 ExprKind :: Call ( ref callee, ref args) => self . check_call ( expr, & callee, args, expected) ,
266269 ExprKind :: MethodCall ( ref segment, span, ref args, _) => {
267- self . check_method_call ( expr, segment, span, args, expected, needs )
270+ self . check_method_call ( expr, segment, span, args, expected)
268271 }
269272 ExprKind :: Cast ( ref e, ref t) => self . check_expr_cast ( e, t, expr) ,
270273 ExprKind :: Type ( ref e, ref t) => {
@@ -281,8 +284,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
281284 ExprKind :: Struct ( ref qpath, fields, ref base_expr) => {
282285 self . check_expr_struct ( expr, expected, qpath, fields, base_expr)
283286 }
284- ExprKind :: Field ( ref base, field) => self . check_field ( expr, needs , & base, field) ,
285- ExprKind :: Index ( ref base, ref idx) => self . check_expr_index ( base, idx, needs , expr) ,
287+ ExprKind :: Field ( ref base, field) => self . check_field ( expr, & base, field) ,
288+ ExprKind :: Index ( ref base, ref idx) => self . check_expr_index ( base, idx, expr) ,
286289 ExprKind :: Yield ( ref value, ref src) => self . check_expr_yield ( value, expr, src) ,
287290 hir:: ExprKind :: Err => tcx. types . err ,
288291 }
@@ -302,48 +305,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
302305 unop : hir:: UnOp ,
303306 oprnd : & ' tcx hir:: Expr < ' tcx > ,
304307 expected : Expectation < ' tcx > ,
305- needs : Needs ,
306308 expr : & ' tcx hir:: Expr < ' tcx > ,
307309 ) -> Ty < ' tcx > {
308310 let tcx = self . tcx ;
309311 let expected_inner = match unop {
310312 hir:: UnOp :: UnNot | hir:: UnOp :: UnNeg => expected,
311313 hir:: UnOp :: UnDeref => NoExpectation ,
312314 } ;
313- let needs = match unop {
314- hir:: UnOp :: UnDeref => needs,
315- _ => Needs :: None ,
316- } ;
317- let mut oprnd_t = self . check_expr_with_expectation_and_needs ( & oprnd, expected_inner, needs) ;
315+ let mut oprnd_t = self . check_expr_with_expectation ( & oprnd, expected_inner) ;
318316
319317 if !oprnd_t. references_error ( ) {
320318 oprnd_t = self . structurally_resolved_type ( expr. span , oprnd_t) ;
321319 match unop {
322320 hir:: UnOp :: UnDeref => {
323- if let Some ( mt) = oprnd_t. builtin_deref ( true ) {
324- oprnd_t = mt. ty ;
325- } else if let Some ( ok) = self . try_overloaded_deref ( expr. span , oprnd_t, needs) {
326- let method = self . register_infer_ok_obligations ( ok) ;
327- if let ty:: Ref ( region, _, mutbl) = method. sig . inputs ( ) [ 0 ] . kind {
328- let mutbl = match mutbl {
329- hir:: Mutability :: Not => AutoBorrowMutability :: Not ,
330- hir:: Mutability :: Mut => AutoBorrowMutability :: Mut {
331- // (It shouldn't actually matter for unary ops whether
332- // we enable two-phase borrows or not, since a unary
333- // op has no additional operands.)
334- allow_two_phase_borrow : AllowTwoPhase :: No ,
335- } ,
336- } ;
337- self . apply_adjustments (
338- oprnd,
339- vec ! [ Adjustment {
340- kind: Adjust :: Borrow ( AutoBorrow :: Ref ( region, mutbl) ) ,
341- target: method. sig. inputs( ) [ 0 ] ,
342- } ] ,
343- ) ;
344- }
345- oprnd_t = self . make_overloaded_place_return_type ( method) . ty ;
346- self . write_method_call ( expr. hir_id , method) ;
321+ if let Some ( ty) = self . lookup_derefing ( expr, oprnd, oprnd_t) {
322+ oprnd_t = ty;
347323 } else {
348324 let mut err = type_error_struct ! (
349325 tcx. sess,
@@ -405,8 +381,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
405381 _ => NoExpectation ,
406382 }
407383 } ) ;
408- let needs = Needs :: maybe_mut_place ( mutbl ) ;
409- let ty = self . check_expr_with_expectation_and_needs ( & oprnd, hint, needs ) ;
384+ let ty =
385+ self . check_expr_with_expectation_and_needs ( & oprnd, hint, Needs :: maybe_mut_place ( mutbl ) ) ;
410386
411387 let tm = ty:: TypeAndMut { ty, mutbl } ;
412388 match kind {
@@ -861,10 +837,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
861837 span : Span ,
862838 args : & ' tcx [ hir:: Expr < ' tcx > ] ,
863839 expected : Expectation < ' tcx > ,
864- needs : Needs ,
865840 ) -> Ty < ' tcx > {
866841 let rcvr = & args[ 0 ] ;
867- let rcvr_t = self . check_expr_with_needs ( & rcvr, needs ) ;
842+ let rcvr_t = self . check_expr ( & rcvr) ;
868843 // no need to check for bot/err -- callee does that
869844 let rcvr_t = self . structurally_resolved_type ( args[ 0 ] . span , rcvr_t) ;
870845
@@ -1443,11 +1418,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14431418 fn check_field (
14441419 & self ,
14451420 expr : & ' tcx hir:: Expr < ' tcx > ,
1446- needs : Needs ,
14471421 base : & ' tcx hir:: Expr < ' tcx > ,
14481422 field : Ident ,
14491423 ) -> Ty < ' tcx > {
1450- let expr_t = self . check_expr_with_needs ( base, needs ) ;
1424+ let expr_t = self . check_expr ( base) ;
14511425 let expr_t = self . structurally_resolved_type ( base. span , expr_t) ;
14521426 let mut private_candidate = None ;
14531427 let mut autoderef = self . autoderef ( expr. span , expr_t) ;
@@ -1467,7 +1441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14671441 // of error recovery.
14681442 self . write_field_index ( expr. hir_id , index) ;
14691443 if field. vis . is_accessible_from ( def_scope, self . tcx ) {
1470- let adjustments = autoderef. adjust_steps ( self , needs ) ;
1444+ let adjustments = autoderef. adjust_steps ( self ) ;
14711445 self . apply_adjustments ( base, adjustments) ;
14721446 autoderef. finalize ( self ) ;
14731447
@@ -1482,7 +1456,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14821456 if let Ok ( index) = fstr. parse :: < usize > ( ) {
14831457 if fstr == index. to_string ( ) {
14841458 if let Some ( field_ty) = tys. get ( index) {
1485- let adjustments = autoderef. adjust_steps ( self , needs ) ;
1459+ let adjustments = autoderef. adjust_steps ( self ) ;
14861460 self . apply_adjustments ( base, adjustments) ;
14871461 autoderef. finalize ( self ) ;
14881462
@@ -1721,10 +1695,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17211695 & self ,
17221696 base : & ' tcx hir:: Expr < ' tcx > ,
17231697 idx : & ' tcx hir:: Expr < ' tcx > ,
1724- needs : Needs ,
17251698 expr : & ' tcx hir:: Expr < ' tcx > ,
17261699 ) -> Ty < ' tcx > {
1727- let base_t = self . check_expr_with_needs ( & base, needs ) ;
1700+ let base_t = self . check_expr ( & base) ;
17281701 let idx_t = self . check_expr ( & idx) ;
17291702
17301703 if base_t. references_error ( ) {
@@ -1733,7 +1706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17331706 idx_t
17341707 } else {
17351708 let base_t = self . structurally_resolved_type ( base. span , base_t) ;
1736- match self . lookup_indexing ( expr, base, base_t, idx_t, needs ) {
1709+ match self . lookup_indexing ( expr, base, base_t, idx_t) {
17371710 Some ( ( index_ty, element_ty) ) => {
17381711 // two-phase not needed because index_ty is never mutable
17391712 self . demand_coerce ( idx, idx_t, index_ty, None , AllowTwoPhase :: No ) ;
0 commit comments