From 800166cf9697226910104c2812afe2bc1e2e5399 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Sun, 28 Jan 2018 23:29:40 +0200
Subject: [PATCH 1/7] rustc: remove `LvaluePreference` argument from
 `Ty::builtin_deref`.

---
 src/librustc/middle/mem_categorization.rs     |  4 ++--
 src/librustc/mir/tcx.rs                       |  2 +-
 src/librustc/ty/mod.rs                        | 16 -------------
 src/librustc/ty/sty.rs                        | 10 ++------
 .../borrow_check/nll/type_check/mod.rs        |  2 +-
 src/librustc_trans/abi.rs                     |  2 +-
 src/librustc_trans/mir/constant.rs            |  4 ++--
 src/librustc_trans/mir/operand.rs             |  3 +--
 src/librustc_typeck/check/_match.rs           |  6 ++---
 src/librustc_typeck/check/autoderef.rs        |  9 ++++----
 src/librustc_typeck/check/callee.rs           |  4 ++--
 src/librustc_typeck/check/coercion.rs         |  5 ++--
 src/librustc_typeck/check/method/confirm.rs   |  6 ++---
 src/librustc_typeck/check/mod.rs              | 23 +++++++++++++++----
 src/librustc_typeck/check/op.rs               |  4 ++--
 15 files changed, 45 insertions(+), 55 deletions(-)

diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index a8955723e3a..b5d2bb1cffc 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -517,7 +517,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                     // a bind-by-ref means that the base_ty will be the type of the ident itself,
                     // but what we want here is the type of the underlying value being borrowed.
                     // So peel off one-level, turning the &T into T.
-                    match base_ty.builtin_deref(false, ty::NoPreference) {
+                    match base_ty.builtin_deref(false) {
                         Some(t) => t.ty,
                         None => {
                             debug!("By-ref binding of non-derefable type {:?}", base_ty);
@@ -1019,7 +1019,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         debug!("cat_deref: base_cmt={:?}", base_cmt);
 
         let base_cmt_ty = base_cmt.ty;
-        let deref_ty = match base_cmt_ty.builtin_deref(true, ty::NoPreference) {
+        let deref_ty = match base_cmt_ty.builtin_deref(true) {
             Some(mt) => mt.ty,
             None => {
                 debug!("Explicit deref of non-derefable type: {:?}",
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 23f360d5c39..53607764b39 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -52,7 +52,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
         match *elem {
             ProjectionElem::Deref => {
                 let ty = self.to_ty(tcx)
-                             .builtin_deref(true, ty::LvaluePreference::NoPreference)
+                             .builtin_deref(true)
                              .unwrap_or_else(|| {
                                  bug!("deref projection of non-dereferencable ty {:?}", self)
                              })
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 63df1179af2..600c823aaf8 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -12,7 +12,6 @@ pub use self::Variance::*;
 pub use self::AssociatedItemContainer::*;
 pub use self::BorrowKind::*;
 pub use self::IntVarValue::*;
-pub use self::LvaluePreference::*;
 pub use self::fold::TypeFoldable;
 
 use hir::{map as hir_map, FreevarMap, TraitMap};
@@ -2099,21 +2098,6 @@ impl<'tcx> TyS<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum LvaluePreference {
-    PreferMutLvalue,
-    NoPreference
-}
-
-impl LvaluePreference {
-    pub fn from_mutbl(m: hir::Mutability) -> Self {
-        match m {
-            hir::MutMutable => PreferMutLvalue,
-            hir::MutImmutable => NoPreference,
-        }
-    }
-}
-
 impl BorrowKind {
     pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
         match m {
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index db7e4fe45ef..0c1ebd1a2ba 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1514,18 +1514,12 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
     ///
     /// The parameter `explicit` indicates if this is an *explicit* dereference.
     /// Some types---notably unsafe ptrs---can only be dereferenced explicitly.
-    pub fn builtin_deref(&self, explicit: bool, pref: ty::LvaluePreference)
-        -> Option<TypeAndMut<'tcx>>
-    {
+    pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
         match self.sty {
             TyAdt(def, _) if def.is_box() => {
                 Some(TypeAndMut {
                     ty: self.boxed_ty(),
-                    mutbl: if pref == ty::PreferMutLvalue {
-                        hir::MutMutable
-                    } else {
-                        hir::MutImmutable
-                    },
+                    mutbl: hir::MutImmutable,
                 })
             },
             TyRef(_, mt) => Some(mt),
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 9dcd4435580..6d9354360d3 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -397,7 +397,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
         let base_ty = base.to_ty(tcx);
         match *pi {
             ProjectionElem::Deref => {
-                let deref_ty = base_ty.builtin_deref(true, ty::LvaluePreference::NoPreference);
+                let deref_ty = base_ty.builtin_deref(true);
                 PlaceTy::Ty {
                     ty: deref_ty.map(|t| t.ty).unwrap_or_else(|| {
                         span_mirbug_and_err!(self, place, "deref of non-pointer {:?}", base_ty)
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index 9cabd9356e9..4c17929fe98 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -674,7 +674,7 @@ impl<'a, 'tcx> FnType<'tcx> {
                 _ => bug!("FnType::new_vtable: non-pair self {:?}", self_arg)
             }
 
-            let pointee = self_arg.layout.ty.builtin_deref(true, ty::NoPreference)
+            let pointee = self_arg.layout.ty.builtin_deref(true)
                 .unwrap_or_else(|| {
                     bug!("FnType::new_vtable: non-pointer self {:?}", self_arg)
                 }).ty;
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 71ce0aa3da9..b4cdf38a513 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -740,7 +740,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                         operand.llval
                     }
                     mir::CastKind::Unsize => {
-                        let pointee_ty = operand.ty.builtin_deref(true, ty::NoPreference)
+                        let pointee_ty = operand.ty.builtin_deref(true)
                             .expect("consts: unsizing got non-pointer type").ty;
                         let (base, old_info) = if !self.cx.type_is_sized(pointee_ty) {
                             // Normally, the source is a thin pointer and we are
@@ -755,7 +755,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                             (operand.llval, None)
                         };
 
-                        let unsized_ty = cast_ty.builtin_deref(true, ty::NoPreference)
+                        let unsized_ty = cast_ty.builtin_deref(true)
                             .expect("consts: unsizing got non-pointer target type").ty;
                         let ptr_ty = self.cx.layout_of(unsized_ty).llvm_type(self.cx).ptr_to();
                         let base = consts::ptrcast(base, ptr_ty);
diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs
index 25db9f9b4c8..e1b906646aa 100644
--- a/src/librustc_trans/mir/operand.rs
+++ b/src/librustc_trans/mir/operand.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use llvm::ValueRef;
-use rustc::ty;
 use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
 use rustc::mir;
 use rustc_data_structures::indexed_vec::Idx;
@@ -100,7 +99,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
     }
 
     pub fn deref(self, cx: &CodegenCx<'a, 'tcx>) -> PlaceRef<'tcx> {
-        let projected_ty = self.layout.ty.builtin_deref(true, ty::NoPreference)
+        let projected_ty = self.layout.ty.builtin_deref(true)
             .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty;
         let (llptr, llextra) = match self.val {
             OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()),
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index d5e4aa69c5b..a6530aa3e15 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -14,8 +14,8 @@ use rustc::hir::pat_util::EnumerateAndAdjustIterator;
 use rustc::infer;
 use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::traits::ObligationCauseCode;
-use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference};
-use check::{FnCtxt, Expectation, Diverges};
+use rustc::ty::{self, Ty, TypeFoldable};
+use check::{FnCtxt, Expectation, Diverges, LvaluePreference};
 use check::coercion::CoerceMany;
 use util::nodemap::FxHashMap;
 
@@ -500,7 +500,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
     pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
         if let PatKind::Binding(..) = inner.node {
-            if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true, ty::NoPreference) {
+            if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
                 if let ty::TyDynamic(..) = mt.ty.sty {
                     // This is "x = SomeTrait" being reduced from
                     // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 169959d12b5..fec9f4c658e 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -10,7 +10,7 @@
 
 use astconv::AstConv;
 
-use super::{FnCtxt, LvalueOp};
+use super::{FnCtxt, LvalueOp, LvaluePreference};
 use super::method::MethodCallee;
 
 use rustc::infer::InferOk;
@@ -18,7 +18,6 @@ use rustc::session::DiagnosticMessageId;
 use rustc::traits;
 use rustc::ty::{self, Ty, TraitRef};
 use rustc::ty::{ToPredicate, TypeFoldable};
-use rustc::ty::{LvaluePreference, NoPreference};
 use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
 
 use syntax_pos::Span;
@@ -85,7 +84,7 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> {
 
         // Otherwise, deref if type is derefable:
         let (kind, new_ty) =
-            if let Some(mt) = self.cur_ty.builtin_deref(self.include_raw_pointers, NoPreference) {
+            if let Some(mt) = self.cur_ty.builtin_deref(self.include_raw_pointers) {
                 (AutoderefKind::Builtin, mt.ty)
             } else {
                 let ty = self.overloaded_deref_ty(self.cur_ty)?;
@@ -238,8 +237,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     pub fn try_overloaded_deref(&self,
                                 span: Span,
                                 base_ty: Ty<'tcx>,
-                                pref: LvaluePreference)
+                                needs: Needs)
                                 -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
-        self.try_overloaded_lvalue_op(span, base_ty, &[], pref, LvalueOp::Deref)
+        self.try_overloaded_lvalue_op(span, base_ty, &[], needs, LvalueOp::Deref)
     }
 }
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 5c5e5f2735b..84e1de5c362 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::{Expectation, FnCtxt, TupleArgumentsFlag};
+use super::{Expectation, FnCtxt, LvaluePreference, TupleArgumentsFlag};
 use super::autoderef::Autoderef;
 use super::method::MethodCallee;
 
 use hir::def::Def;
 use hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::{infer, traits};
-use rustc::ty::{self, TyCtxt, TypeFoldable, LvaluePreference, Ty};
+use rustc::ty::{self, TyCtxt, TypeFoldable, Ty};
 use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
 use syntax::abi;
 use syntax::symbol::Symbol;
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index edda557c98c..25c175c5388 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -60,7 +60,7 @@
 //! sort of a minor point so I've opted to leave it for later---after all
 //! we may want to adjust precisely when coercions occur.
 
-use check::{Diverges, FnCtxt};
+use check::{Diverges, FnCtxt, LvaluePreference};
 
 use rustc::hir;
 use rustc::hir::def_id::DefId;
@@ -69,8 +69,7 @@ use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::lint;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
 use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
-use rustc::ty::{self, LvaluePreference, TypeAndMut,
-                Ty, ClosureSubsts};
+use rustc::ty::{self, TypeAndMut, Ty, ClosureSubsts};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::error::TypeError;
 use rustc::ty::relate::RelateResult;
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 3a9c4e1901d..3f4281d2a60 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -11,11 +11,11 @@
 use super::{probe, MethodCallee};
 
 use astconv::AstConv;
-use check::{FnCtxt, LvalueOp, callee};
+use check::{FnCtxt, LvalueOp, callee, LvaluePreference, PreferMutLvalue};
 use hir::def_id::DefId;
 use rustc::ty::subst::Substs;
 use rustc::traits;
-use rustc::ty::{self, LvaluePreference, NoPreference, PreferMutLvalue, Ty};
+use rustc::ty::{self, Ty};
 use rustc::ty::subst::Subst;
 use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, OverloadedDeref};
 use rustc::ty::fold::TypeFoldable;
@@ -500,7 +500,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
         let base_ty = self.resolve_type_vars_if_possible(&base_ty);
 
         // Need to deref because overloaded lvalue ops take self by-reference.
-        let base_ty = base_ty.builtin_deref(false, NoPreference)
+        let base_ty = base_ty.builtin_deref(false)
             .expect("lvalue op takes something that is not a ref")
             .ty;
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 9b24c09036b..4514910f1b5 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -77,6 +77,7 @@ type parameter).
 */
 
 pub use self::Expectation::*;
+use self::LvaluePreference::*;
 use self::autoderef::Autoderef;
 use self::callee::DeferredCallResolution;
 use self::coercion::{CoerceMany, DynamicCoerceMany};
@@ -95,7 +96,6 @@ use rustc::infer::type_variable::{TypeVariableOrigin};
 use rustc::middle::region;
 use rustc::ty::subst::{Kind, Subst, Substs};
 use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
-use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
 use rustc::ty::{self, Ty, TyCtxt, Visibility, ToPredicate};
 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc::ty::fold::TypeFoldable;
@@ -368,6 +368,21 @@ impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
     }
 }
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum LvaluePreference {
+    PreferMutLvalue,
+    NoPreference
+}
+
+impl LvaluePreference {
+    fn from_mutbl(m: hir::Mutability) -> Self {
+        match m {
+            hir::MutMutable => PreferMutLvalue,
+            hir::MutImmutable => NoPreference,
+        }
+    }
+}
+
 #[derive(Copy, Clone)]
 pub struct UnsafetyState {
     pub def: ast::NodeId,
@@ -2219,7 +2234,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let ret_ty = method.sig.output();
 
         // method returns &T, but the type as visible to user is T, so deref
-        ret_ty.builtin_deref(true, NoPreference).unwrap()
+        ret_ty.builtin_deref(true).unwrap()
     }
 
     fn lookup_indexing(&self,
@@ -3572,7 +3587,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
                 match unop {
                     hir::UnDeref => {
-                        if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
+                        if let Some(mt) = oprnd_t.builtin_deref(true) {
                             oprnd_t = mt.ty;
                         } else if let Some(ok) = self.try_overloaded_deref(
                                 expr.span, oprnd_t, lvalue_pref) {
@@ -5023,7 +5038,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let lifetime_count = generics.lifetimes().count();
 
     for leaf_ty in ty.walk() {
-        if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
+        if let ty::TyParam(ty::ParamTy {idx, ..}) = leaf_ty.sty {
             debug!("Found use of ty param num {}", idx);
             tps_used[idx as usize - lifetime_count] = true;
         } else if let ty::TyError = leaf_ty.sty {
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index e099d1c0c25..0d02212e725 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -10,9 +10,9 @@
 
 //! Code related to processing overloaded binary and unary operators.
 
-use super::FnCtxt;
+use super::{FnCtxt, NoPreference, PreferMutLvalue};
 use super::method::MethodCallee;
-use rustc::ty::{self, Ty, TypeFoldable, NoPreference, PreferMutLvalue, TypeVariants};
+use rustc::ty::{self, Ty, TypeFoldable, TypeVariants};
 use rustc::ty::TypeVariants::{TyStr, TyRef};
 use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
 use rustc::infer::type_variable::TypeVariableOrigin;

From 2c4a75bf097104e3e08ee307deb34bed0b5531d4 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Mon, 29 Jan 2018 00:51:34 +0200
Subject: [PATCH 2/7] rustc_typeck: rename `LvaluePreference::PreferMutLvalue`
 to `Needs::MutPlace`.

---
 src/librustc_typeck/check/_match.rs         |   4 +-
 src/librustc_typeck/check/autoderef.rs      |  10 +-
 src/librustc_typeck/check/callee.rs         |   8 +-
 src/librustc_typeck/check/coercion.rs       |   6 +-
 src/librustc_typeck/check/method/confirm.rs |  10 +-
 src/librustc_typeck/check/mod.rs            | 112 ++++++++++----------
 src/librustc_typeck/check/op.rs             |  12 +--
 7 files changed, 80 insertions(+), 82 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index a6530aa3e15..1a285cd869a 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -15,7 +15,7 @@ use rustc::infer;
 use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::traits::ObligationCauseCode;
 use rustc::ty::{self, Ty, TypeFoldable};
-use check::{FnCtxt, Expectation, Diverges, LvaluePreference};
+use check::{FnCtxt, Expectation, Diverges, Needs};
 use check::coercion::CoerceMany;
 use util::nodemap::FxHashMap;
 
@@ -584,7 +584,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                         });
         let discrim_ty;
         if let Some(m) = contains_ref_bindings {
-            discrim_ty = self.check_expr_with_lvalue_pref(discrim, LvaluePreference::from_mutbl(m));
+            discrim_ty = self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m));
         } else {
             // ...but otherwise we want to use any supertype of the
             // discriminant. This is sort of a workaround, see note (*) in
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index fec9f4c658e..5353d4cc672 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -10,7 +10,7 @@
 
 use astconv::AstConv;
 
-use super::{FnCtxt, LvalueOp, LvaluePreference};
+use super::{FnCtxt, LvalueOp, Needs};
 use super::method::MethodCallee;
 
 use rustc::infer::InferOk;
@@ -162,19 +162,19 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
     }
 
     /// Returns the adjustment steps.
-    pub fn adjust_steps(&self, pref: LvaluePreference)
+    pub fn adjust_steps(&self, needs: Needs)
                         -> Vec<Adjustment<'tcx>> {
-        self.fcx.register_infer_ok_obligations(self.adjust_steps_as_infer_ok(pref))
+        self.fcx.register_infer_ok_obligations(self.adjust_steps_as_infer_ok(needs))
     }
 
-    pub fn adjust_steps_as_infer_ok(&self, pref: LvaluePreference)
+    pub fn adjust_steps_as_infer_ok(&self, needs: Needs)
                                     -> InferOk<'tcx, Vec<Adjustment<'tcx>>> {
         let mut obligations = vec![];
         let targets = self.steps.iter().skip(1).map(|&(ty, _)| ty)
             .chain(iter::once(self.cur_ty));
         let steps: Vec<_> = self.steps.iter().map(|&(source, kind)| {
             if let AutoderefKind::Overloaded = kind {
-                self.fcx.try_overloaded_deref(self.span, source, pref)
+                self.fcx.try_overloaded_deref(self.span, source, needs)
                     .and_then(|InferOk { value: method, obligations: o }| {
                         obligations.extend(o);
                         if let ty::TyRef(region, mt) = method.sig.output().sty {
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 84e1de5c362..76df9be4838 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::{Expectation, FnCtxt, LvaluePreference, TupleArgumentsFlag};
+use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag};
 use super::autoderef::Autoderef;
 use super::method::MethodCallee;
 
@@ -96,7 +96,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // If the callee is a bare function or a closure, then we're all set.
         match adjusted_ty.sty {
             ty::TyFnDef(..) | ty::TyFnPtr(_) => {
-                let adjustments = autoderef.adjust_steps(LvaluePreference::NoPreference);
+                let adjustments = autoderef.adjust_steps(Needs::None);
                 self.apply_adjustments(callee_expr, adjustments);
                 return Some(CallStep::Builtin(adjusted_ty));
             }
@@ -113,7 +113,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                                                    infer::FnCall,
                                                                    &closure_ty)
                         .0;
-                    let adjustments = autoderef.adjust_steps(LvaluePreference::NoPreference);
+                    let adjustments = autoderef.adjust_steps(Needs::None);
                     self.record_deferred_call_resolution(def_id, DeferredCallResolution {
                         call_expr,
                         callee_expr,
@@ -143,7 +143,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         }
 
         self.try_overloaded_call_traits(call_expr, adjusted_ty).map(|(autoref, method)| {
-            let mut adjustments = autoderef.adjust_steps(LvaluePreference::NoPreference);
+            let mut adjustments = autoderef.adjust_steps(Needs::None);
             adjustments.extend(autoref);
             self.apply_adjustments(callee_expr, adjustments);
             CallStep::Overloaded(method)
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 25c175c5388..d0280bf0b30 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -60,7 +60,7 @@
 //! sort of a minor point so I've opted to leave it for later---after all
 //! we may want to adjust precisely when coercions occur.
 
-use check::{Diverges, FnCtxt, LvaluePreference};
+use check::{Diverges, FnCtxt, Needs};
 
 use rustc::hir;
 use rustc::hir::def_id::DefId;
@@ -409,9 +409,9 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
             return success(vec![], ty, obligations);
         }
 
-        let pref = LvaluePreference::from_mutbl(mt_b.mutbl);
+        let needs = Needs::maybe_mut_place(mt_b.mutbl);
         let InferOk { value: mut adjustments, obligations: o }
-            = autoderef.adjust_steps_as_infer_ok(pref);
+            = autoderef.adjust_steps_as_infer_ok(needs);
         obligations.extend(o);
         obligations.extend(autoderef.into_obligations());
 
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 3f4281d2a60..691ce18c738 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -11,7 +11,7 @@
 use super::{probe, MethodCallee};
 
 use astconv::AstConv;
-use check::{FnCtxt, LvalueOp, callee, LvaluePreference, PreferMutLvalue};
+use check::{FnCtxt, LvalueOp, callee, Needs};
 use hir::def_id::DefId;
 use rustc::ty::subst::Substs;
 use rustc::traits;
@@ -155,7 +155,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
         let (_, n) = autoderef.nth(pick.autoderefs).unwrap();
         assert_eq!(n, pick.autoderefs);
 
-        let mut adjustments = autoderef.adjust_steps(LvaluePreference::NoPreference);
+        let mut adjustments = autoderef.adjust_steps(Needs::None);
 
         let mut target = autoderef.unambiguous_final_ty();
 
@@ -449,10 +449,10 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
                                            .adjustments_mut()
                                            .remove(expr.hir_id);
             if let Some(mut adjustments) = previous_adjustments {
-                let pref = LvaluePreference::PreferMutLvalue;
+                let needs = Needs::MutPlace;
                 for adjustment in &mut adjustments {
                     if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind {
-                        if let Some(ok) = self.try_overloaded_deref(expr.span, source, pref) {
+                        if let Some(ok) = self.try_overloaded_deref(expr.span, source, needs) {
                             let method = self.register_infer_ok_obligations(ok);
                             if let ty::TyRef(region, mt) = method.sig.output().sty {
                                 *deref = OverloadedDeref {
@@ -505,7 +505,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             .ty;
 
         let method = self.try_overloaded_lvalue_op(
-            expr.span, base_ty, arg_tys, PreferMutLvalue, op);
+            expr.span, base_ty, arg_tys, Needs::MutPlace, op);
         let method = match method {
             Some(ok) => self.register_infer_ok_obligations(ok),
             None => return self.tcx.sess.delay_span_bug(expr.span, "re-trying op failed")
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 4514910f1b5..4ccc88f9b15 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -77,7 +77,6 @@ type parameter).
 */
 
 pub use self::Expectation::*;
-use self::LvaluePreference::*;
 use self::autoderef::Autoderef;
 use self::callee::DeferredCallResolution;
 use self::coercion::{CoerceMany, DynamicCoerceMany};
@@ -369,16 +368,16 @@ impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum LvaluePreference {
-    PreferMutLvalue,
-    NoPreference
+pub enum Needs {
+    MutPlace,
+    None
 }
 
-impl LvaluePreference {
-    fn from_mutbl(m: hir::Mutability) -> Self {
+impl Needs {
+    fn maybe_mut_place(m: hir::Mutability) -> Self {
         match m {
-            hir::MutMutable => PreferMutLvalue,
-            hir::MutImmutable => NoPreference,
+            hir::MutMutable => Needs::MutPlace,
+            hir::MutImmutable => Needs::None,
         }
     }
 }
@@ -2242,7 +2241,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                        base_expr: &'gcx hir::Expr,
                        base_ty: Ty<'tcx>,
                        idx_ty: Ty<'tcx>,
-                       lvalue_pref: LvaluePreference)
+                       needs: Needs)
                        -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
     {
         // FIXME(#18741) -- this is almost but not quite the same as the
@@ -2252,7 +2251,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let mut autoderef = self.autoderef(base_expr.span, base_ty);
         let mut result = None;
         while result.is_none() && autoderef.next().is_some() {
-            result = self.try_index_step(expr, base_expr, &autoderef, lvalue_pref, idx_ty);
+            result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
         }
         autoderef.finalize();
         result
@@ -2267,7 +2266,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                       expr: &hir::Expr,
                       base_expr: &hir::Expr,
                       autoderef: &Autoderef<'a, 'gcx, 'tcx>,
-                      lvalue_pref: LvaluePreference,
+                      needs: Needs,
                       index_ty: Ty<'tcx>)
                       -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
     {
@@ -2295,13 +2294,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             // If some lookup succeeded, install method in table
             let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
             let method = self.try_overloaded_lvalue_op(
-                expr.span, self_ty, &[input_ty], lvalue_pref, LvalueOp::Index);
+                expr.span, self_ty, &[input_ty], needs, LvalueOp::Index);
 
             let result = method.map(|ok| {
                 debug!("try_index_step: success, using overloaded indexing");
                 let method = self.register_infer_ok_obligations(ok);
 
-                let mut adjustments = autoderef.adjust_steps(lvalue_pref);
+                let mut adjustments = autoderef.adjust_steps(needs);
                 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
                     adjustments.push(Adjustment {
                         kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
@@ -2348,20 +2347,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                 span: Span,
                                 base_ty: Ty<'tcx>,
                                 arg_tys: &[Ty<'tcx>],
-                                lvalue_pref: LvaluePreference,
+                                needs: Needs,
                                 op: LvalueOp)
                                 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
     {
         debug!("try_overloaded_lvalue_op({:?},{:?},{:?},{:?})",
                span,
                base_ty,
-               lvalue_pref,
+               needs,
                op);
 
-        // Try Mut first, if preferred.
+        // Try Mut first, if needed.
         let (mut_tr, mut_op) = self.resolve_lvalue_op(op, true);
-        let method = match (lvalue_pref, mut_tr) {
-            (PreferMutLvalue, Some(trait_did)) => {
+        let method = match (needs, mut_tr) {
+            (Needs::MutPlace, Some(trait_did)) => {
                 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
             }
             _ => None,
@@ -2753,18 +2752,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn check_expr_coercable_to_type(&self,
                                     expr: &'gcx hir::Expr,
                                     expected: Ty<'tcx>) -> Ty<'tcx> {
-        self.check_expr_coercable_to_type_with_lvalue_pref(expr, expected, NoPreference)
+        self.check_expr_coercable_to_type_with_needs(expr, expected, Needs::None)
     }
 
-    fn check_expr_coercable_to_type_with_lvalue_pref(&self,
-                                                     expr: &'gcx hir::Expr,
-                                                     expected: Ty<'tcx>,
-                                                     lvalue_pref: LvaluePreference)
-                                                     -> Ty<'tcx> {
-        let ty = self.check_expr_with_expectation_and_lvalue_pref(
+    fn check_expr_coercable_to_type_with_needs(&self,
+                                               expr: &'gcx hir::Expr,
+                                               expected: Ty<'tcx>,
+                                               needs: Needs)
+                                               -> Ty<'tcx> {
+        let ty = self.check_expr_with_expectation_and_needs(
             expr,
             ExpectHasType(expected),
-            lvalue_pref);
+            needs);
         self.demand_coerce(expr, ty, expected)
     }
 
@@ -2776,16 +2775,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn check_expr_with_expectation(&self,
                                    expr: &'gcx hir::Expr,
                                    expected: Expectation<'tcx>) -> Ty<'tcx> {
-        self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
+        self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
     }
 
     fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
         self.check_expr_with_expectation(expr, NoExpectation)
     }
 
-    fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
-                                   lvalue_pref: LvaluePreference) -> Ty<'tcx> {
-        self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
+    fn check_expr_with_needs(&self, expr: &'gcx hir::Expr, needs: Needs) -> Ty<'tcx> {
+        self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
     }
 
     // determine the `self` type, using fresh variables for all variables
@@ -2868,9 +2866,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                          span: Span,
                          args: &'gcx [hir::Expr],
                          expected: Expectation<'tcx>,
-                         lvalue_pref: LvaluePreference) -> Ty<'tcx> {
+                         needs: Needs) -> Ty<'tcx> {
         let rcvr = &args[0];
-        let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
+        let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
         // no need to check for bot/err -- callee does that
         let rcvr_t = self.structurally_resolved_type(expr.span, rcvr_t);
 
@@ -2980,10 +2978,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     // Check field access expressions
     fn check_field(&self,
                    expr: &'gcx hir::Expr,
-                   lvalue_pref: LvaluePreference,
+                   needs: Needs,
                    base: &'gcx hir::Expr,
                    field: &Spanned<ast::Name>) -> Ty<'tcx> {
-        let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
+        let expr_t = self.check_expr_with_needs(base, needs);
         let expr_t = self.structurally_resolved_type(expr.span,
                                                      expr_t);
         let mut private_candidate = None;
@@ -2998,7 +2996,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
                         let field_ty = self.field_ty(expr.span, field, substs);
                         if field.vis.is_accessible_from(def_scope, self.tcx) {
-                            let adjustments = autoderef.adjust_steps(lvalue_pref);
+                            let adjustments = autoderef.adjust_steps(needs);
                             self.apply_adjustments(base, adjustments);
                             autoderef.finalize();
 
@@ -3117,10 +3115,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     // Check tuple index expressions
     fn check_tup_field(&self,
                        expr: &'gcx hir::Expr,
-                       lvalue_pref: LvaluePreference,
+                       needs: Needs,
                        base: &'gcx hir::Expr,
                        idx: codemap::Spanned<usize>) -> Ty<'tcx> {
-        let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
+        let expr_t = self.check_expr_with_needs(base, needs);
         let expr_t = self.structurally_resolved_type(expr.span,
                                                      expr_t);
         let mut private_candidate = None;
@@ -3161,7 +3159,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             };
 
             if let Some(field_ty) = field {
-                let adjustments = autoderef.adjust_steps(lvalue_pref);
+                let adjustments = autoderef.adjust_steps(needs);
                 self.apply_adjustments(base, adjustments);
                 autoderef.finalize();
                 return field_ty;
@@ -3491,10 +3489,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     /// Note that inspecting a type's structure *directly* may expose the fact
     /// that there are actually multiple representations for `TyError`, so avoid
     /// that when err needs to be handled differently.
-    fn check_expr_with_expectation_and_lvalue_pref(&self,
+    fn check_expr_with_expectation_and_needs(&self,
                                                    expr: &'gcx hir::Expr,
                                                    expected: Expectation<'tcx>,
-                                                   lvalue_pref: LvaluePreference) -> Ty<'tcx> {
+                                                   needs: Needs) -> Ty<'tcx> {
         debug!(">> typechecking: expr={:?} expected={:?}",
                expr, expected);
 
@@ -3507,7 +3505,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         self.diverges.set(Diverges::Maybe);
         self.has_errors.set(false);
 
-        let ty = self.check_expr_kind(expr, expected, lvalue_pref);
+        let ty = self.check_expr_kind(expr, expected, needs);
 
         // Warn for non-block expressions with diverging children.
         match expr.node {
@@ -3541,7 +3539,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn check_expr_kind(&self,
                        expr: &'gcx hir::Expr,
                        expected: Expectation<'tcx>,
-                       lvalue_pref: LvaluePreference) -> Ty<'tcx> {
+                       needs: Needs) -> Ty<'tcx> {
         let tcx = self.tcx;
         let id = expr.id;
         match expr.node {
@@ -3575,13 +3573,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     NoExpectation
                 }
             };
-            let lvalue_pref = match unop {
-                hir::UnDeref => lvalue_pref,
-                _ => NoPreference
+            let needs = match unop {
+                hir::UnDeref => needs,
+                _ => Needs::None
             };
-            let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
+            let mut oprnd_t = self.check_expr_with_expectation_and_needs(&oprnd,
                                                                                expected_inner,
-                                                                               lvalue_pref);
+                                                                               needs);
 
             if !oprnd_t.references_error() {
                 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
@@ -3590,7 +3588,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         if let Some(mt) = oprnd_t.builtin_deref(true) {
                             oprnd_t = mt.ty;
                         } else if let Some(ok) = self.try_overloaded_deref(
-                                expr.span, oprnd_t, lvalue_pref) {
+                                expr.span, oprnd_t, needs) {
                             let method = self.register_infer_ok_obligations(ok);
                             if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
                                 self.apply_adjustments(oprnd, vec![Adjustment {
@@ -3641,8 +3639,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     _ => NoExpectation
                 }
             });
-            let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
-            let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
+            let needs = Needs::maybe_mut_place(mutbl);
+            let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
 
             let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
             if tm.ty.references_error() {
@@ -3786,7 +3784,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             tcx.types.never
           }
           hir::ExprAssign(ref lhs, ref rhs) => {
-            let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
+            let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
 
             let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
 
@@ -3887,7 +3885,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
               self.check_call(expr, &callee, args, expected)
           }
           hir::ExprMethodCall(ref segment, span, ref args) => {
-              self.check_method_call(expr, segment, span, args, expected, lvalue_pref)
+              self.check_method_call(expr, segment, span, args, expected, needs)
           }
           hir::ExprCast(ref e, ref t) => {
             // Find the type of `e`. Supply hints based on the type we are casting to,
@@ -4030,13 +4028,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             self.check_expr_struct(expr, expected, qpath, fields, base_expr)
           }
           hir::ExprField(ref base, ref field) => {
-            self.check_field(expr, lvalue_pref, &base, field)
+            self.check_field(expr, needs, &base, field)
           }
           hir::ExprTupField(ref base, idx) => {
-            self.check_tup_field(expr, lvalue_pref, &base, idx)
+            self.check_tup_field(expr, needs, &base, idx)
           }
           hir::ExprIndex(ref base, ref idx) => {
-              let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
+              let base_t = self.check_expr_with_needs(&base, needs);
               let idx_t = self.check_expr(&idx);
 
               if base_t.references_error() {
@@ -4045,7 +4043,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                   idx_t
               } else {
                   let base_t = self.structurally_resolved_type(expr.span, base_t);
-                  match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
+                  match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
                       Some((index_ty, element_ty)) => {
                           self.demand_coerce(idx, idx_t, index_ty);
                           element_ty
@@ -4195,7 +4193,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             // referent for the reference that results is *equal to* the
             // type of the lvalue it is referencing, and not some
             // supertype thereof.
-            let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
+            let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
             self.demand_eqtype(init.span, local_ty, init_ty);
             init_ty
         } else {
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 0d02212e725..3631b9799d5 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -10,7 +10,7 @@
 
 //! Code related to processing overloaded binary and unary operators.
 
-use super::{FnCtxt, NoPreference, PreferMutLvalue};
+use super::{FnCtxt, Needs};
 use super::method::MethodCallee;
 use rustc::ty::{self, Ty, TypeFoldable, TypeVariants};
 use rustc::ty::TypeVariants::{TyStr, TyRef};
@@ -166,18 +166,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                op,
                is_assign);
 
-        let lhs_pref = match is_assign {
-            IsAssign::Yes => PreferMutLvalue,
-            IsAssign::No => NoPreference
+        let lhs_needs = match is_assign {
+            IsAssign::Yes => Needs::MutPlace,
+            IsAssign::No => Needs::None
         };
         // Find a suitable supertype of the LHS expression's type, by coercing to
         // a type variable, to pass as the `Self` to the trait, avoiding invariant
         // trait matching creating lifetime constraints that are too strict.
         // E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
         // in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
-        let lhs_ty = self.check_expr_coercable_to_type_with_lvalue_pref(lhs_expr,
+        let lhs_ty = self.check_expr_coercable_to_type_with_needs(lhs_expr,
             self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span)),
-            lhs_pref);
+            lhs_needs);
         let lhs_ty = self.resolve_type_vars_with_obligations(lhs_ty);
 
         // NB: As we have not yet type-checked the RHS, we don't have the

From 3f4a489f8fc73138cde77bcf10497d5f209d3b3a Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Mon, 29 Jan 2018 00:55:39 +0200
Subject: [PATCH 3/7] rustc_typeck: rename `LvalueOp` to `PlaceOp`.

---
 src/librustc_typeck/check/autoderef.rs      |  4 +--
 src/librustc_typeck/check/method/confirm.rs | 32 ++++++++++-----------
 src/librustc_typeck/check/mod.rs            | 26 ++++++++---------
 3 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 5353d4cc672..1d7c533178f 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -10,7 +10,7 @@
 
 use astconv::AstConv;
 
-use super::{FnCtxt, LvalueOp, Needs};
+use super::{FnCtxt, PlaceOp, Needs};
 use super::method::MethodCallee;
 
 use rustc::infer::InferOk;
@@ -239,6 +239,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                 base_ty: Ty<'tcx>,
                                 needs: Needs)
                                 -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
-        self.try_overloaded_lvalue_op(span, base_ty, &[], needs, LvalueOp::Deref)
+        self.try_overloaded_place_op(span, base_ty, &[], needs, PlaceOp::Deref)
     }
 }
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 691ce18c738..71c1326b412 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -11,7 +11,7 @@
 use super::{probe, MethodCallee};
 
 use astconv::AstConv;
-use check::{FnCtxt, LvalueOp, callee, Needs};
+use check::{FnCtxt, PlaceOp, callee, Needs};
 use hir::def_id::DefId;
 use rustc::ty::subst::Substs;
 use rustc::traits;
@@ -438,7 +438,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             debug!("convert_lvalue_derefs_to_mutable: i={} expr={:?}", i, expr);
 
             // Fix up the autoderefs. Autorefs can only occur immediately preceding
-            // overloaded lvalue ops, and will be fixed by them in order to get
+            // overloaded place ops, and will be fixed by them in order to get
             // the correct region.
             let mut source = self.node_ty(expr.hir_id);
             // Do not mutate adjustments in place, but rather take them,
@@ -470,28 +470,28 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             match expr.node {
                 hir::ExprIndex(ref base_expr, ref index_expr) => {
                     let index_expr_ty = self.node_ty(index_expr.hir_id);
-                    self.convert_lvalue_op_to_mutable(
-                        LvalueOp::Index, expr, base_expr, &[index_expr_ty]);
+                    self.convert_place_op_to_mutable(
+                        PlaceOp::Index, expr, base_expr, &[index_expr_ty]);
                 }
                 hir::ExprUnary(hir::UnDeref, ref base_expr) => {
-                    self.convert_lvalue_op_to_mutable(
-                        LvalueOp::Deref, expr, base_expr, &[]);
+                    self.convert_place_op_to_mutable(
+                        PlaceOp::Deref, expr, base_expr, &[]);
                 }
                 _ => {}
             }
         }
     }
 
-    fn convert_lvalue_op_to_mutable(&self,
-                                    op: LvalueOp,
+    fn convert_place_op_to_mutable(&self,
+                                    op: PlaceOp,
                                     expr: &hir::Expr,
                                     base_expr: &hir::Expr,
                                     arg_tys: &[Ty<'tcx>])
     {
-        debug!("convert_lvalue_op_to_mutable({:?}, {:?}, {:?}, {:?})",
+        debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})",
                op, expr, base_expr, arg_tys);
         if !self.tables.borrow().is_method_call(expr) {
-            debug!("convert_lvalue_op_to_mutable - builtin, nothing to do");
+            debug!("convert_place_op_to_mutable - builtin, nothing to do");
             return
         }
 
@@ -499,24 +499,24 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             .map_or_else(|| self.node_ty(expr.hir_id), |adj| adj.target);
         let base_ty = self.resolve_type_vars_if_possible(&base_ty);
 
-        // Need to deref because overloaded lvalue ops take self by-reference.
+        // Need to deref because overloaded place ops take self by-reference.
         let base_ty = base_ty.builtin_deref(false)
-            .expect("lvalue op takes something that is not a ref")
+            .expect("place op takes something that is not a ref")
             .ty;
 
-        let method = self.try_overloaded_lvalue_op(
+        let method = self.try_overloaded_place_op(
             expr.span, base_ty, arg_tys, Needs::MutPlace, op);
         let method = match method {
             Some(ok) => self.register_infer_ok_obligations(ok),
             None => return self.tcx.sess.delay_span_bug(expr.span, "re-trying op failed")
         };
-        debug!("convert_lvalue_op_to_mutable: method={:?}", method);
+        debug!("convert_place_op_to_mutable: method={:?}", method);
         self.write_method_call(expr.hir_id, method);
 
         let (region, mutbl) = if let ty::TyRef(r, mt) = method.sig.inputs()[0].sty {
             (r, mt.mutbl)
         } else {
-            span_bug!(expr.span, "input to lvalue op is not a ref?");
+            span_bug!(expr.span, "input to place op is not a ref?");
         };
 
         // Convert the autoref in the base expr to mutable with the correct
@@ -529,7 +529,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             let mut source = base_expr_ty;
             for adjustment in &mut adjustments[..] {
                 if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind {
-                    debug!("convert_lvalue_op_to_mutable: converting autoref {:?}", adjustment);
+                    debug!("convert_place_op_to_mutable: converting autoref {:?}", adjustment);
                     adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(region, mutbl));
                     adjustment.target = self.tcx.mk_ref(region, ty::TypeAndMut {
                         ty: source,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 4ccc88f9b15..8a54240c1e7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -424,7 +424,7 @@ impl UnsafetyState {
 }
 
 #[derive(Debug, Copy, Clone)]
-pub enum LvalueOp {
+pub enum PlaceOp {
     Deref,
     Index
 }
@@ -2293,8 +2293,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             // type from the method signature.
             // If some lookup succeeded, install method in table
             let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
-            let method = self.try_overloaded_lvalue_op(
-                expr.span, self_ty, &[input_ty], needs, LvalueOp::Index);
+            let method = self.try_overloaded_place_op(
+                expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
 
             let result = method.map(|ok| {
                 debug!("try_index_step: success, using overloaded indexing");
@@ -2329,36 +2329,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         None
     }
 
-    fn resolve_lvalue_op(&self, op: LvalueOp, is_mut: bool) -> (Option<DefId>, Symbol) {
+    fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Symbol) {
         let (tr, name) = match (op, is_mut) {
-            (LvalueOp::Deref, false) =>
+            (PlaceOp::Deref, false) =>
                 (self.tcx.lang_items().deref_trait(), "deref"),
-            (LvalueOp::Deref, true) =>
+            (PlaceOp::Deref, true) =>
                 (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
-            (LvalueOp::Index, false) =>
+            (PlaceOp::Index, false) =>
                 (self.tcx.lang_items().index_trait(), "index"),
-            (LvalueOp::Index, true) =>
+            (PlaceOp::Index, true) =>
                 (self.tcx.lang_items().index_mut_trait(), "index_mut"),
         };
         (tr, Symbol::intern(name))
     }
 
-    fn try_overloaded_lvalue_op(&self,
+    fn try_overloaded_place_op(&self,
                                 span: Span,
                                 base_ty: Ty<'tcx>,
                                 arg_tys: &[Ty<'tcx>],
                                 needs: Needs,
-                                op: LvalueOp)
+                                op: PlaceOp)
                                 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
     {
-        debug!("try_overloaded_lvalue_op({:?},{:?},{:?},{:?})",
+        debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
                span,
                base_ty,
                needs,
                op);
 
         // Try Mut first, if needed.
-        let (mut_tr, mut_op) = self.resolve_lvalue_op(op, true);
+        let (mut_tr, mut_op) = self.resolve_place_op(op, true);
         let method = match (needs, mut_tr) {
             (Needs::MutPlace, Some(trait_did)) => {
                 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
@@ -2367,7 +2367,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         };
 
         // Otherwise, fall back to the immutable version.
-        let (imm_tr, imm_op) = self.resolve_lvalue_op(op, false);
+        let (imm_tr, imm_op) = self.resolve_place_op(op, false);
         let method = match (method, imm_tr) {
             (None, Some(trait_did)) => {
                 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))

From 06a0e4f7ae6d2e23adff1fe84e2a988f6b77fa53 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Mon, 29 Jan 2018 01:16:02 +0200
Subject: [PATCH 4/7] rustc: move `expr_is_lval` to rustc_typeck and rename to
 `is_place_expr`.

---
 src/librustc/ty/mod.rs           | 54 -----------------------------
 src/librustc_typeck/check/mod.rs | 58 ++++++++++++++++++++++++++++++--
 src/librustc_typeck/check/op.rs  |  5 ++-
 3 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 600c823aaf8..f52f2ea0f9f 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2177,60 +2177,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
-         match expr.node {
-            hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
-                match path.def {
-                    Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
-                    _ => false,
-                }
-            }
-
-            hir::ExprType(ref e, _) => {
-                self.expr_is_lval(e)
-            }
-
-            hir::ExprUnary(hir::UnDeref, _) |
-            hir::ExprField(..) |
-            hir::ExprTupField(..) |
-            hir::ExprIndex(..) => {
-                true
-            }
-
-            // Partially qualified paths in expressions can only legally
-            // refer to associated items which are always rvalues.
-            hir::ExprPath(hir::QPath::TypeRelative(..)) |
-
-            hir::ExprCall(..) |
-            hir::ExprMethodCall(..) |
-            hir::ExprStruct(..) |
-            hir::ExprTup(..) |
-            hir::ExprIf(..) |
-            hir::ExprMatch(..) |
-            hir::ExprClosure(..) |
-            hir::ExprBlock(..) |
-            hir::ExprRepeat(..) |
-            hir::ExprArray(..) |
-            hir::ExprBreak(..) |
-            hir::ExprAgain(..) |
-            hir::ExprRet(..) |
-            hir::ExprWhile(..) |
-            hir::ExprLoop(..) |
-            hir::ExprAssign(..) |
-            hir::ExprInlineAsm(..) |
-            hir::ExprAssignOp(..) |
-            hir::ExprLit(_) |
-            hir::ExprUnary(..) |
-            hir::ExprBox(..) |
-            hir::ExprAddrOf(..) |
-            hir::ExprBinary(..) |
-            hir::ExprYield(..) |
-            hir::ExprCast(..) => {
-                false
-            }
-        }
-    }
-
     pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
         self.associated_items(id)
             .filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value())
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 8a54240c1e7..1313b86f7dc 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2221,6 +2221,60 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
+    fn is_place_expr(&self, expr: &hir::Expr) -> bool {
+         match expr.node {
+            hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
+                match path.def {
+                    Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
+                    _ => false,
+                }
+            }
+
+            hir::ExprType(ref e, _) => {
+                self.is_place_expr(e)
+            }
+
+            hir::ExprUnary(hir::UnDeref, _) |
+            hir::ExprField(..) |
+            hir::ExprTupField(..) |
+            hir::ExprIndex(..) => {
+                true
+            }
+
+            // Partially qualified paths in expressions can only legally
+            // refer to associated items which are always rvalues.
+            hir::ExprPath(hir::QPath::TypeRelative(..)) |
+
+            hir::ExprCall(..) |
+            hir::ExprMethodCall(..) |
+            hir::ExprStruct(..) |
+            hir::ExprTup(..) |
+            hir::ExprIf(..) |
+            hir::ExprMatch(..) |
+            hir::ExprClosure(..) |
+            hir::ExprBlock(..) |
+            hir::ExprRepeat(..) |
+            hir::ExprArray(..) |
+            hir::ExprBreak(..) |
+            hir::ExprAgain(..) |
+            hir::ExprRet(..) |
+            hir::ExprWhile(..) |
+            hir::ExprLoop(..) |
+            hir::ExprAssign(..) |
+            hir::ExprInlineAsm(..) |
+            hir::ExprAssignOp(..) |
+            hir::ExprLit(_) |
+            hir::ExprUnary(..) |
+            hir::ExprBox(..) |
+            hir::ExprAddrOf(..) |
+            hir::ExprBinary(..) |
+            hir::ExprYield(..) |
+            hir::ExprCast(..) => {
+                false
+            }
+        }
+    }
+
     /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
     /// returns a type of `&T`, but the actual type we assign to the
     /// *expression* is `T`. So this function just peels off the return
@@ -3627,7 +3681,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
                 match ty.sty {
                     ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
-                        if self.tcx.expr_is_lval(&oprnd) {
+                        if self.is_place_expr(&oprnd) {
                             // Lvalues may legitimately have unsized types.
                             // For example, dereferences of a fat pointer and
                             // the last field of a struct can be unsized.
@@ -3796,7 +3850,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 _ => {
                     // Only check this if not in an `if` condition, as the
                     // mistyped comparison help is more appropriate.
-                    if !self.tcx.expr_is_lval(&lhs) {
+                    if !self.is_place_expr(&lhs) {
                         struct_span_err!(self.tcx.sess, expr.span, E0070,
                                          "invalid left-hand side expression")
                             .span_label(expr.span, "left-hand of expression not valid")
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 3631b9799d5..0698e3ecb6e 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -40,10 +40,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             return_ty
         };
 
-        let tcx = self.tcx;
-        if !tcx.expr_is_lval(lhs_expr) {
+        if !self.is_place_expr(lhs_expr) {
             struct_span_err!(
-                tcx.sess, lhs_expr.span,
+                self.tcx.sess, lhs_expr.span,
                 E0067, "invalid left-hand side expression")
             .span_label(
                 lhs_expr.span,

From 46a9bdda78ead362b9bcef4146a7dadb698237ee Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Mon, 29 Jan 2018 01:49:29 +0200
Subject: [PATCH 5/7] rustc: replace "lvalue" terminology with "place" in the
 code.

---
 src/librustc/middle/liveness.rs               |  68 ++++++------
 src/librustc/middle/mem_categorization.rs     |  24 ++--
 src/librustc/middle/region.rs                 |   4 +-
 src/librustc/mir/mod.rs                       |  14 +--
 src/librustc/ty/adjustment.rs                 |   2 +-
 .../borrowck/gather_loans/lifetime.rs         |   2 +-
 src/librustc_borrowck/borrowck/mod.rs         |   2 +-
 src/librustc_borrowck/borrowck/move_data.rs   |   2 +-
 src/librustc_mir/borrow_check/flows.rs        |  16 +--
 src/librustc_mir/borrow_check/mod.rs          |  10 +-
 src/librustc_mir/borrow_check/nll/mod.rs      |   4 +-
 .../borrow_check/nll/type_check/liveness.rs   |   6 +-
 .../borrow_check/nll/type_check/mod.rs        |   4 +-
 src/librustc_mir/dataflow/impls/borrows.rs    |   8 +-
 src/librustc_mir/dataflow/impls/mod.rs        | 104 +++++++++---------
 src/librustc_mir/dataflow/mod.rs              |   6 +-
 src/librustc_mir/dataflow/move_paths/mod.rs   |   6 +-
 src/librustc_mir/interpret/place.rs           |   8 +-
 src/librustc_mir/transform/elaborate_drops.rs |  12 +-
 src/librustc_mir/transform/rustc_peek.rs      |   8 +-
 src/librustc_mir/util/elaborate_drops.rs      |   4 +-
 src/librustc_trans/abi.rs                     |   2 +-
 src/librustc_trans/mir/constant.rs            |   2 +-
 src/librustc_typeck/check/method/confirm.rs   |   8 +-
 src/librustc_typeck/check/mod.rs              |  14 +--
 src/librustc_typeck/diagnostics.rs            |  14 +--
 src/libsyntax_ext/deriving/generic/mod.rs     |   4 +-
 27 files changed, 179 insertions(+), 179 deletions(-)

diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index d4fa03b5085..297586f140e 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1034,10 +1034,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
           }
 
           hir::ExprAssign(ref l, ref r) => {
-            // see comment on lvalues in
-            // propagate_through_lvalue_components()
-            let succ = self.write_lvalue(&l, succ, ACC_WRITE);
-            let succ = self.propagate_through_lvalue_components(&l, succ);
+            // see comment on places in
+            // propagate_through_place_components()
+            let succ = self.write_place(&l, succ, ACC_WRITE);
+            let succ = self.propagate_through_place_components(&l, succ);
             self.propagate_through_expr(&r, succ)
           }
 
@@ -1047,11 +1047,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 let succ = self.propagate_through_expr(&l, succ);
                 self.propagate_through_expr(&r, succ)
             } else {
-                // see comment on lvalues in
-                // propagate_through_lvalue_components()
-                let succ = self.write_lvalue(&l, succ, ACC_WRITE|ACC_READ);
+                // see comment on places in
+                // propagate_through_place_components()
+                let succ = self.write_place(&l, succ, ACC_WRITE|ACC_READ);
                 let succ = self.propagate_through_expr(&r, succ);
-                self.propagate_through_lvalue_components(&l, succ)
+                self.propagate_through_place_components(&l, succ)
             }
           }
 
@@ -1121,14 +1121,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
           hir::ExprInlineAsm(ref ia, ref outputs, ref inputs) => {
             let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
-                // see comment on lvalues
-                // in propagate_through_lvalue_components()
+                // see comment on places
+                // in propagate_through_place_components()
                 if o.is_indirect {
                     self.propagate_through_expr(output, succ)
                 } else {
                     let acc = if o.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
-                    let succ = self.write_lvalue(output, succ, acc);
-                    self.propagate_through_lvalue_components(output, succ)
+                    let succ = self.write_place(output, succ, acc);
+                    self.propagate_through_place_components(output, succ)
                 }
             });
 
@@ -1146,11 +1146,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn propagate_through_lvalue_components(&mut self,
+    fn propagate_through_place_components(&mut self,
                                            expr: &Expr,
                                            succ: LiveNode)
                                            -> LiveNode {
-        // # Lvalues
+        // # Places
         //
         // In general, the full flow graph structure for an
         // assignment/move/etc can be handled in one of two ways,
@@ -1160,7 +1160,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         //
         // The two kinds of graphs are:
         //
-        //    Tracked lvalue          Untracked lvalue
+        //    Tracked place          Untracked place
         // ----------------------++-----------------------
         //                       ||
         //         |             ||           |
@@ -1168,7 +1168,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         //     (rvalue)          ||       (rvalue)
         //         |             ||           |
         //         v             ||           v
-        // (write of lvalue)     ||   (lvalue components)
+        // (write of place)     ||   (place components)
         //         |             ||           |
         //         v             ||           v
         //      (succ)           ||        (succ)
@@ -1177,25 +1177,25 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         //
         // I will cover the two cases in turn:
         //
-        // # Tracked lvalues
+        // # Tracked places
         //
-        // A tracked lvalue is a local variable/argument `x`.  In
+        // A tracked place is a local variable/argument `x`.  In
         // these cases, the link_node where the write occurs is linked
-        // to node id of `x`.  The `write_lvalue()` routine generates
+        // to node id of `x`.  The `write_place()` routine generates
         // the contents of this node.  There are no subcomponents to
         // consider.
         //
-        // # Non-tracked lvalues
+        // # Non-tracked places
         //
-        // These are lvalues like `x[5]` or `x.f`.  In that case, we
+        // These are places like `x[5]` or `x.f`.  In that case, we
         // basically ignore the value which is written to but generate
         // reads for the components---`x` in these two examples.  The
         // components reads are generated by
-        // `propagate_through_lvalue_components()` (this fn).
+        // `propagate_through_place_components()` (this fn).
         //
-        // # Illegal lvalues
+        // # Illegal places
         //
-        // It is still possible to observe assignments to non-lvalues;
+        // It is still possible to observe assignments to non-places;
         // these errors are detected in the later pass borrowck.  We
         // just ignore such cases and treat them as reads.
 
@@ -1207,17 +1207,17 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    // see comment on propagate_through_lvalue()
-    fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
+    // see comment on propagate_through_place()
+    fn write_place(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
                     -> LiveNode {
         match expr.node {
           hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
               self.access_path(expr.id, path, succ, acc)
           }
 
-          // We do not track other lvalues, so just propagate through
+          // We do not track other places, so just propagate through
           // to their subcomponents.  Also, it may happen that
-          // non-lvalues occur here, because those are detected in the
+          // non-places occur here, because those are detected in the
           // later pass borrowck.
           _ => succ
         }
@@ -1363,14 +1363,14 @@ fn check_arm<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, arm: &'tcx hir::Arm) {
 fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
     match expr.node {
       hir::ExprAssign(ref l, _) => {
-        this.check_lvalue(&l);
+        this.check_place(&l);
 
         intravisit::walk_expr(this, expr);
       }
 
       hir::ExprAssignOp(_, ref l, _) => {
         if !this.tables.is_method_call(expr) {
-            this.check_lvalue(&l);
+            this.check_place(&l);
         }
 
         intravisit::walk_expr(this, expr);
@@ -1381,10 +1381,10 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
           this.visit_expr(input);
         }
 
-        // Output operands must be lvalues
+        // Output operands must be places
         for (o, output) in ia.outputs.iter().zip(outputs) {
           if !o.is_indirect {
-            this.check_lvalue(output);
+            this.check_place(output);
           }
           this.visit_expr(output);
         }
@@ -1409,7 +1409,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
 }
 
 impl<'a, 'tcx> Liveness<'a, 'tcx> {
-    fn check_lvalue(&mut self, expr: &'tcx Expr) {
+    fn check_place(&mut self, expr: &'tcx Expr) {
         match expr.node {
             hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
                 if let Def::Local(nid) = path.def {
@@ -1423,7 +1423,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 }
             }
             _ => {
-                // For other kinds of lvalues, no checks are required,
+                // For other kinds of places, no checks are required,
                 // and any embedded expressions are actually rvalues
                 intravisit::walk_expr(self, expr);
             }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index b5d2bb1cffc..45b595adfe7 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -26,8 +26,8 @@
 //!       | E.comp    // access to an interior component
 //!
 //! Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
-//! address where the result is to be found.  If Expr is an lvalue, then this
-//! is the address of the lvalue.  If Expr is an rvalue, this is the address of
+//! address where the result is to be found.  If Expr is a place, then this
+//! is the address of the place.  If Expr is an rvalue, this is the address of
 //! some temporary spot in memory where the result is stored.
 //!
 //! Now, cat_expr() classifies the expression Expr and the address A=ToAddr(Expr)
@@ -182,7 +182,7 @@ pub struct cmt_<'tcx> {
     pub id: ast::NodeId,           // id of expr/pat producing this value
     pub span: Span,                // span of same expr/pat
     pub cat: Categorization<'tcx>, // categorization of expr
-    pub mutbl: MutabilityCategory, // mutability of expr as lvalue
+    pub mutbl: MutabilityCategory, // mutability of expr as place
     pub ty: Ty<'tcx>,              // type of the expr (*see WARNING above*)
     pub note: Note,                // Note about the provenance of this cmt
 }
@@ -603,7 +603,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         match expr.node {
           hir::ExprUnary(hir::UnDeref, ref e_base) => {
             if self.tables.is_method_call(expr) {
-                self.cat_overloaded_lvalue(expr, e_base, false)
+                self.cat_overloaded_place(expr, e_base, false)
             } else {
                 let base_cmt = self.cat_expr(&e_base)?;
                 self.cat_deref(expr, base_cmt, false)
@@ -631,7 +631,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                 // The call to index() returns a `&T` value, which
                 // is an rvalue. That is what we will be
                 // dereferencing.
-                self.cat_overloaded_lvalue(expr, base, true)
+                self.cat_overloaded_place(expr, base, true)
             } else {
                 let base_cmt = self.cat_expr(&base)?;
                 self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
@@ -983,27 +983,27 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         ret
     }
 
-    fn cat_overloaded_lvalue(&self,
+    fn cat_overloaded_place(&self,
                              expr: &hir::Expr,
                              base: &hir::Expr,
                              implicit: bool)
                              -> McResult<cmt<'tcx>> {
-        debug!("cat_overloaded_lvalue: implicit={}", implicit);
+        debug!("cat_overloaded_place: implicit={}", implicit);
 
         // Reconstruct the output assuming it's a reference with the
         // same region and mutability as the receiver. This holds for
         // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
-        let lvalue_ty = self.expr_ty(expr)?;
+        let place_ty = self.expr_ty(expr)?;
         let base_ty = self.expr_ty_adjusted(base)?;
 
         let (region, mutbl) = match base_ty.sty {
             ty::TyRef(region, mt) => (region, mt.mutbl),
             _ => {
-                span_bug!(expr.span, "cat_overloaded_lvalue: base is not a reference")
+                span_bug!(expr.span, "cat_overloaded_place: base is not a reference")
             }
         };
         let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
-            ty: lvalue_ty,
+            ty: place_ty,
             mutbl,
         });
 
@@ -1386,7 +1386,7 @@ impl<'tcx> cmt_<'tcx> {
         }
     }
 
-    /// Returns `FreelyAliasable(_)` if this lvalue represents a freely aliasable pointer type.
+    /// Returns `FreelyAliasable(_)` if this place represents a freely aliasable pointer type.
     pub fn freely_aliasable(&self) -> Aliasability {
         // Maybe non-obvious: copied upvars can only be considered
         // non-aliasable in once closures, since any other kind can be
@@ -1453,7 +1453,7 @@ impl<'tcx> cmt_<'tcx> {
                 "static item".to_string()
             }
             Categorization::Rvalue(..) => {
-                "non-lvalue".to_string()
+                "non-place".to_string()
             }
             Categorization::Local(vid) => {
                 if tcx.hir.is_argument(vid) {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 66b3adb83c1..dad2d7a7c90 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -1112,7 +1112,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
     //    I mean that creating a binding into a ref-counted or managed value
     //    would still count.)
     //
-    // 3. `ET`, which matches both rvalues like `foo()` as well as lvalues
+    // 3. `ET`, which matches both rvalues like `foo()` as well as places
     //    based on rvalues like `foo().x[2].y`.
     //
     // A subexpression `<rvalue>` that appears in a let initializer
@@ -1283,7 +1283,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
     ///        | (ET)
     ///        | <rvalue>
     ///
-    /// Note: ET is intended to match "rvalues or lvalues based on rvalues".
+    /// Note: ET is intended to match "rvalues or places based on rvalues".
     fn record_rvalue_scope<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
                                      expr: &hir::Expr,
                                      blk_scope: Option<Scope>) {
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 3aa94b34699..3b644aa13f3 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -733,13 +733,13 @@ pub enum TerminatorKind<'tcx> {
     },
 
     /// Drop the Place and assign the new value over it. This ensures
-    /// that the assignment to LV occurs *even if* the destructor for
+    /// that the assignment to `P` occurs *even if* the destructor for
     /// place unwinds. Its semantics are best explained by by the
     /// elaboration:
     ///
     /// ```
     /// BB0 {
-    ///   DropAndReplace(LV <- RV, goto BB1, unwind BB2)
+    ///   DropAndReplace(P <- V, goto BB1, unwind BB2)
     /// }
     /// ```
     ///
@@ -747,15 +747,15 @@ pub enum TerminatorKind<'tcx> {
     ///
     /// ```
     /// BB0 {
-    ///   Drop(LV, goto BB1, unwind BB2)
+    ///   Drop(P, goto BB1, unwind BB2)
     /// }
     /// BB1 {
-    ///   // LV is now unitialized
-    ///   LV <- RV
+    ///   // P is now unitialized
+    ///   P <- V
     /// }
     /// BB2 {
-    ///   // LV is now unitialized -- its dtor panicked
-    ///   LV <- RV
+    ///   // P is now unitialized -- its dtor panicked
+    ///   P <- V
     /// }
     /// ```
     DropAndReplace {
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index 6df6bb9df23..96d69b4fba2 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -77,7 +77,7 @@ pub enum Adjust<'tcx> {
     /// Go from a mut raw pointer to a const raw pointer.
     MutToConstPointer,
 
-    /// Dereference once, producing an lvalue.
+    /// Dereference once, producing a place.
     Deref(Option<OverloadedDeref<'tcx>>),
 
     /// Take the address and produce either a `&` or `*` pointer.
diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
index 66aaafb77f7..97fa94b5e5c 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
@@ -104,7 +104,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
 
     fn scope(&self, cmt: &mc::cmt<'tcx>) -> ty::Region<'tcx> {
         //! Returns the maximal region scope for the which the
-        //! lvalue `cmt` is guaranteed to be valid without any
+        //! place `cmt` is guaranteed to be valid without any
         //! rooting etc, and presuming `cmt` is not mutated.
 
         match cmt.cat {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index b35e8c6b419..bfe894f9eb9 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -170,7 +170,7 @@ fn build_borrowck_dataflow_data<'a, 'c, 'tcx, F>(this: &mut BorrowckCtxt<'a, 'tc
     if !force_analysis && move_data.is_empty() && all_loans.is_empty() {
         // large arrays of data inserted as constants can take a lot of
         // time and memory to borrow-check - see issue #36799. However,
-        // they don't have lvalues, so no borrow-check is actually needed.
+        // they don't have places, so no borrow-check is actually needed.
         // Recognize that case and skip borrow-checking.
         debug!("skipping loan propagation for {:?} because of no loans", body_id);
         return None;
diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs
index 98de394ae39..a90dcd1072f 100644
--- a/src/librustc_borrowck/borrowck/move_data.rs
+++ b/src/librustc_borrowck/borrowck/move_data.rs
@@ -153,7 +153,7 @@ pub struct Assignment {
     /// span of node where assignment occurs
     pub span: Span,
 
-    /// id for l-value expression on lhs of assignment
+    /// id for place expression on lhs of assignment
     pub assignee_id: hir::ItemLocalId,
 }
 
diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs
index 61d6c14d627..ba966c9d4e3 100644
--- a/src/librustc_mir/borrow_check/flows.rs
+++ b/src/librustc_mir/borrow_check/flows.rs
@@ -15,8 +15,8 @@
 
 use rustc::mir::{BasicBlock, Location};
 
-use dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
-use dataflow::{EverInitializedLvals, MovingOutStatements};
+use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
+use dataflow::{EverInitializedPlaces, MovingOutStatements};
 use dataflow::{ActiveBorrows, FlowAtLocation, FlowsAtLocation};
 use dataflow::move_paths::HasMoveData;
 use std::fmt;
@@ -24,19 +24,19 @@ use std::fmt;
 // (forced to be `pub` due to its use as an associated type below.)
 pub(crate) struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {
     pub borrows: FlowAtLocation<ActiveBorrows<'b, 'gcx, 'tcx>>,
-    pub inits: FlowAtLocation<MaybeInitializedLvals<'b, 'gcx, 'tcx>>,
-    pub uninits: FlowAtLocation<MaybeUninitializedLvals<'b, 'gcx, 'tcx>>,
+    pub inits: FlowAtLocation<MaybeInitializedPlaces<'b, 'gcx, 'tcx>>,
+    pub uninits: FlowAtLocation<MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>,
     pub move_outs: FlowAtLocation<MovingOutStatements<'b, 'gcx, 'tcx>>,
-    pub ever_inits: FlowAtLocation<EverInitializedLvals<'b, 'gcx, 'tcx>>,
+    pub ever_inits: FlowAtLocation<EverInitializedPlaces<'b, 'gcx, 'tcx>>,
 }
 
 impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> {
     pub fn new(
         borrows: FlowAtLocation<ActiveBorrows<'b, 'gcx, 'tcx>>,
-        inits: FlowAtLocation<MaybeInitializedLvals<'b, 'gcx, 'tcx>>,
-        uninits: FlowAtLocation<MaybeUninitializedLvals<'b, 'gcx, 'tcx>>,
+        inits: FlowAtLocation<MaybeInitializedPlaces<'b, 'gcx, 'tcx>>,
+        uninits: FlowAtLocation<MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>,
         move_outs: FlowAtLocation<MovingOutStatements<'b, 'gcx, 'tcx>>,
-        ever_inits: FlowAtLocation<EverInitializedLvals<'b, 'gcx, 'tcx>>,
+        ever_inits: FlowAtLocation<EverInitializedPlaces<'b, 'gcx, 'tcx>>,
     ) -> Self {
         Flows {
             borrows,
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index f6923651663..c16d70a14db 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -35,8 +35,8 @@ use dataflow::{do_dataflow, DebugFormatted};
 use dataflow::FlowAtLocation;
 use dataflow::MoveDataParamEnv;
 use dataflow::{DataflowAnalysis, DataflowResultsConsumer};
-use dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
-use dataflow::{EverInitializedLvals, MovingOutStatements};
+use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
+use dataflow::{EverInitializedPlaces, MovingOutStatements};
 use dataflow::{BorrowData, Borrows, ReserveOrActivateIndex};
 use dataflow::{ActiveBorrows, Reservations};
 use dataflow::indexes::BorrowIndex;
@@ -160,7 +160,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         id,
         &attributes,
         &dead_unwinds,
-        MaybeInitializedLvals::new(tcx, mir, &mdpe),
+        MaybeInitializedPlaces::new(tcx, mir, &mdpe),
         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
     ));
     let flow_uninits = FlowAtLocation::new(do_dataflow(
@@ -169,7 +169,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         id,
         &attributes,
         &dead_unwinds,
-        MaybeUninitializedLvals::new(tcx, mir, &mdpe),
+        MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
     ));
     let flow_move_outs = FlowAtLocation::new(do_dataflow(
@@ -187,7 +187,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         id,
         &attributes,
         &dead_unwinds,
-        EverInitializedLvals::new(tcx, mir, &mdpe),
+        EverInitializedPlaces::new(tcx, mir, &mdpe),
         |bd, i| DebugFormatted::new(&bd.move_data().inits[i]),
     ));
 
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index f96e107efa3..66ca74b0139 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -19,7 +19,7 @@ use std::io;
 use transform::MirSource;
 use util::liveness::{LivenessResults, LocalSet};
 use dataflow::FlowAtLocation;
-use dataflow::MaybeInitializedLvals;
+use dataflow::MaybeInitializedPlaces;
 use dataflow::move_paths::MoveData;
 
 use util as mir_util;
@@ -71,7 +71,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
     universal_regions: UniversalRegions<'tcx>,
     mir: &Mir<'tcx>,
     param_env: ty::ParamEnv<'gcx>,
-    flow_inits: &mut FlowAtLocation<MaybeInitializedLvals<'cx, 'gcx, 'tcx>>,
+    flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'cx, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
 ) -> (
     RegionInferenceContext<'tcx>,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
index 8a0578ae4d4..6c2037810d3 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
@@ -10,7 +10,7 @@
 
 use dataflow::{FlowAtLocation, FlowsAtLocation};
 use borrow_check::nll::region_infer::Cause;
-use dataflow::MaybeInitializedLvals;
+use dataflow::MaybeInitializedPlaces;
 use dataflow::move_paths::{HasMoveData, MoveData};
 use rustc::mir::{BasicBlock, Location, Mir};
 use rustc::mir::Local;
@@ -34,7 +34,7 @@ pub(super) fn generate<'gcx, 'tcx>(
     cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
     mir: &Mir<'tcx>,
     liveness: &LivenessResults,
-    flow_inits: &mut FlowAtLocation<MaybeInitializedLvals<'_, 'gcx, 'tcx>>,
+    flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
 ) {
     let tcx = cx.tcx();
@@ -63,7 +63,7 @@ where
     tcx: TyCtxt<'typeck, 'gcx, 'tcx>,
     mir: &'gen Mir<'tcx>,
     liveness: &'gen LivenessResults,
-    flow_inits: &'gen mut FlowAtLocation<MaybeInitializedLvals<'flow, 'gcx, 'tcx>>,
+    flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
     move_data: &'gen MoveData<'tcx>,
 }
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 6d9354360d3..015eb8a3b66 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -15,7 +15,7 @@ use borrow_check::nll::region_infer::Cause;
 use borrow_check::nll::region_infer::ClosureRegionRequirementsExt;
 use borrow_check::nll::universal_regions::UniversalRegions;
 use dataflow::FlowAtLocation;
-use dataflow::MaybeInitializedLvals;
+use dataflow::MaybeInitializedPlaces;
 use dataflow::move_paths::MoveData;
 use rustc::hir::def_id::DefId;
 use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
@@ -100,7 +100,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
     mir_def_id: DefId,
     universal_regions: &UniversalRegions<'tcx>,
     liveness: &LivenessResults,
-    flow_inits: &mut FlowAtLocation<MaybeInitializedLvals<'_, 'gcx, 'tcx>>,
+    flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
 ) -> MirTypeckRegionConstraints<'tcx> {
     let body_id = infcx.tcx.hir.as_local_node_id(mir_def_id).unwrap();
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index d7cd8830adb..632bb5b3428 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -575,10 +575,10 @@ impl<'a, 'b, 'tcx> FindPlaceUses<'a, 'b, 'tcx> {
     /// has a reservation at the time).
     fn is_potential_use(context: PlaceContext) -> bool {
         match context {
-            // storage effects on an place do not activate it
+            // storage effects on a place do not activate it
             PlaceContext::StorageLive | PlaceContext::StorageDead => false,
 
-            // validation effects do not activate an place
+            // validation effects do not activate a place
             //
             // FIXME: Should they? Is it just another read? Or can we
             // guarantee it won't dereference the stored address? How
@@ -589,11 +589,11 @@ impl<'a, 'b, 'tcx> FindPlaceUses<'a, 'b, 'tcx> {
             // AsmOutput existed, but it's not necessarily a pure overwrite.
             // so it's possible this should activate the place.
             PlaceContext::AsmOutput |
-            // pure overwrites of an place do not activate it. (note
+            // pure overwrites of a place do not activate it. (note
             // PlaceContext::Call is solely about dest place)
             PlaceContext::Store | PlaceContext::Call => false,
 
-            // reads of an place *do* activate it
+            // reads of a place *do* activate it
             PlaceContext::Move |
             PlaceContext::Copy |
             PlaceContext::Drop |
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs
index 106a88e703c..e7c15625cbe 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/src/librustc_mir/dataflow/impls/mod.rs
@@ -36,7 +36,7 @@ pub use self::storage_liveness::*;
 #[allow(dead_code)]
 pub(super) mod borrows;
 
-/// `MaybeInitializedLvals` tracks all l-values that might be
+/// `MaybeInitializedPlaces` tracks all places that might be
 /// initialized upon reaching a particular point in the control flow
 /// for a function.
 ///
@@ -63,35 +63,35 @@ pub(super) mod borrows;
 /// }
 /// ```
 ///
-/// To determine whether an l-value *must* be initialized at a
+/// To determine whether a place *must* be initialized at a
 /// particular control-flow point, one can take the set-difference
-/// between this data and the data from `MaybeUninitializedLvals` at the
+/// between this data and the data from `MaybeUninitializedPlaces` at the
 /// corresponding control-flow point.
 ///
 /// Similarly, at a given `drop` statement, the set-intersection
-/// between this data and `MaybeUninitializedLvals` yields the set of
-/// l-values that would require a dynamic drop-flag at that statement.
-pub struct MaybeInitializedLvals<'a, 'gcx: 'tcx, 'tcx: 'a> {
+/// between this data and `MaybeUninitializedPlaces` yields the set of
+/// places that would require a dynamic drop-flag at that statement.
+pub struct MaybeInitializedPlaces<'a, 'gcx: 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     mir: &'a Mir<'tcx>,
     mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
 }
 
-impl<'a, 'gcx: 'tcx, 'tcx> MaybeInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx: 'tcx, 'tcx> MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
     pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                mir: &'a Mir<'tcx>,
                mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
                -> Self
     {
-        MaybeInitializedLvals { tcx: tcx, mir: mir, mdpe: mdpe }
+        MaybeInitializedPlaces { tcx: tcx, mir: mir, mdpe: mdpe }
     }
 }
 
-impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
     fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
 }
 
-/// `MaybeUninitializedLvals` tracks all l-values that might be
+/// `MaybeUninitializedPlaces` tracks all places that might be
 /// uninitialized upon reaching a particular point in the control flow
 /// for a function.
 ///
@@ -118,42 +118,42 @@ impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeInitializedLvals<'a, 'gcx, 'tcx>
 /// }
 /// ```
 ///
-/// To determine whether an l-value *must* be uninitialized at a
+/// To determine whether a place *must* be uninitialized at a
 /// particular control-flow point, one can take the set-difference
-/// between this data and the data from `MaybeInitializedLvals` at the
+/// between this data and the data from `MaybeInitializedPlaces` at the
 /// corresponding control-flow point.
 ///
 /// Similarly, at a given `drop` statement, the set-intersection
-/// between this data and `MaybeInitializedLvals` yields the set of
-/// l-values that would require a dynamic drop-flag at that statement.
-pub struct MaybeUninitializedLvals<'a, 'gcx: 'tcx, 'tcx: 'a> {
+/// between this data and `MaybeInitializedPlaces` yields the set of
+/// places that would require a dynamic drop-flag at that statement.
+pub struct MaybeUninitializedPlaces<'a, 'gcx: 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     mir: &'a Mir<'tcx>,
     mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx> MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
     pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                mir: &'a Mir<'tcx>,
                mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
                -> Self
     {
-        MaybeUninitializedLvals { tcx: tcx, mir: mir, mdpe: mdpe }
+        MaybeUninitializedPlaces { tcx: tcx, mir: mir, mdpe: mdpe }
     }
 }
 
-impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
     fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
 }
 
-/// `DefinitelyInitializedLvals` tracks all l-values that are definitely
+/// `DefinitelyInitializedPlaces` tracks all places that are definitely
 /// initialized upon reaching a particular point in the control flow
 /// for a function.
 ///
 /// FIXME: Note that once flow-analysis is complete, this should be
-/// the set-complement of MaybeUninitializedLvals; thus we can get rid
+/// the set-complement of MaybeUninitializedPlaces; thus we can get rid
 /// of one or the other of these two. I'm inclined to get rid of
-/// MaybeUninitializedLvals, simply because the sets will tend to be
+/// MaybeUninitializedPlaces, simply because the sets will tend to be
 /// smaller in this analysis and thus easier for humans to process
 /// when debugging.
 ///
@@ -180,43 +180,43 @@ impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeUninitializedLvals<'a, 'gcx, 'tc
 /// }
 /// ```
 ///
-/// To determine whether an l-value *may* be uninitialized at a
+/// To determine whether a place *may* be uninitialized at a
 /// particular control-flow point, one can take the set-complement
 /// of this data.
 ///
 /// Similarly, at a given `drop` statement, the set-difference between
-/// this data and `MaybeInitializedLvals` yields the set of l-values
+/// this data and `MaybeInitializedPlaces` yields the set of places
 /// that would require a dynamic drop-flag at that statement.
-pub struct DefinitelyInitializedLvals<'a, 'gcx: 'tcx, 'tcx: 'a> {
+pub struct DefinitelyInitializedPlaces<'a, 'gcx: 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     mir: &'a Mir<'tcx>,
     mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx: 'a> DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx: 'a> DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
     pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                mir: &'a Mir<'tcx>,
                mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
                -> Self
     {
-        DefinitelyInitializedLvals { tcx: tcx, mir: mir, mdpe: mdpe }
+        DefinitelyInitializedPlaces { tcx: tcx, mir: mir, mdpe: mdpe }
     }
 }
 
-impl<'a, 'gcx, 'tcx: 'a> HasMoveData<'tcx> for DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx: 'a> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
     fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
 }
 
 /// `MovingOutStatements` tracks the statements that perform moves out
-/// of particular l-values. More precisely, it tracks whether the
+/// of particular places. More precisely, it tracks whether the
 /// *effect* of such moves (namely, the uninitialization of the
-/// l-value in question) can reach some point in the control-flow of
+/// place in question) can reach some point in the control-flow of
 /// the function, or if that effect is "killed" by some intervening
-/// operation reinitializing that l-value.
+/// operation reinitializing that place.
 ///
 /// The resulting dataflow is a more enriched version of
-/// `MaybeUninitializedLvals`. Both structures on their own only tell
-/// you if an l-value *might* be uninitialized at a given point in the
+/// `MaybeUninitializedPlaces`. Both structures on their own only tell
+/// you if a place *might* be uninitialized at a given point in the
 /// control flow. But `MovingOutStatements` also includes the added
 /// data of *which* particular statement causing the deinitialization
 /// that the borrow checker's error message may need to report.
@@ -241,7 +241,7 @@ impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MovingOutStatements<'a, 'gcx, 'tcx> {
     fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
 }
 
-/// `EverInitializedLvals` tracks all l-values that might have ever been
+/// `EverInitializedPlaces` tracks all places that might have ever been
 /// initialized upon reaching a particular point in the control flow
 /// for a function, without an intervening `Storage Dead`.
 ///
@@ -270,28 +270,28 @@ impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MovingOutStatements<'a, 'gcx, 'tcx> {
 ///     c = S;                                 // {a, b, c, d }
 /// }
 /// ```
-pub struct EverInitializedLvals<'a, 'gcx: 'tcx, 'tcx: 'a> {
+pub struct EverInitializedPlaces<'a, 'gcx: 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     mir: &'a Mir<'tcx>,
     mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
 }
 
-impl<'a, 'gcx: 'tcx, 'tcx: 'a> EverInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx: 'tcx, 'tcx: 'a> EverInitializedPlaces<'a, 'gcx, 'tcx> {
     pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                mir: &'a Mir<'tcx>,
                mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
                -> Self
     {
-        EverInitializedLvals { tcx: tcx, mir: mir, mdpe: mdpe }
+        EverInitializedPlaces { tcx: tcx, mir: mir, mdpe: mdpe }
     }
 }
 
-impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for EverInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tcx> {
     fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
 }
 
 
-impl<'a, 'gcx, 'tcx> MaybeInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
     fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
                    state: DropFlagState)
     {
@@ -302,7 +302,7 @@ impl<'a, 'gcx, 'tcx> MaybeInitializedLvals<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
     fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
                    state: DropFlagState)
     {
@@ -313,7 +313,7 @@ impl<'a, 'gcx, 'tcx> MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
     fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
                    state: DropFlagState)
     {
@@ -324,7 +324,7 @@ impl<'a, 'gcx, 'tcx> DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
     type Idx = MovePathIndex;
     fn name() -> &'static str { "maybe_init" }
     fn bits_per_block(&self) -> usize {
@@ -375,7 +375,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
     type Idx = MovePathIndex;
     fn name() -> &'static str { "maybe_uninit" }
     fn bits_per_block(&self) -> usize {
@@ -430,7 +430,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
     type Idx = MovePathIndex;
     fn name() -> &'static str { "definite_init" }
     fn bits_per_block(&self) -> usize {
@@ -561,7 +561,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedPlaces<'a, 'gcx, 'tcx> {
     type Idx = InitIndex;
     fn name() -> &'static str { "ever_init" }
     fn bits_per_block(&self) -> usize {
@@ -657,21 +657,21 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
     #[inline]
     fn join(&self, pred1: usize, pred2: usize) -> usize {
         pred1 | pred2 // "maybe" means we union effects of both preds
     }
 }
 
-impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
     #[inline]
     fn join(&self, pred1: usize, pred2: usize) -> usize {
         pred1 | pred2 // "maybe" means we union effects of both preds
     }
 }
 
-impl<'a, 'gcx, 'tcx> BitwiseOperator for DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> BitwiseOperator for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
     #[inline]
     fn join(&self, pred1: usize, pred2: usize) -> usize {
         pred1 & pred2 // "definitely" means we intersect effects of both preds
@@ -685,7 +685,7 @@ impl<'a, 'gcx, 'tcx> BitwiseOperator for MovingOutStatements<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> BitwiseOperator for EverInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> BitwiseOperator for EverInitializedPlaces<'a, 'gcx, 'tcx> {
     #[inline]
     fn join(&self, pred1: usize, pred2: usize) -> usize {
         pred1 | pred2 // inits from both preds are in scope
@@ -702,21 +702,21 @@ impl<'a, 'gcx, 'tcx> BitwiseOperator for EverInitializedLvals<'a, 'gcx, 'tcx> {
 // propagating, or you start at all-ones and then use Intersect as
 // your merge when propagating.
 
-impl<'a, 'gcx, 'tcx> InitialFlow for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> InitialFlow for MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
     #[inline]
     fn bottom_value() -> bool {
         false // bottom = uninitialized
     }
 }
 
-impl<'a, 'gcx, 'tcx> InitialFlow for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> InitialFlow for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
     #[inline]
     fn bottom_value() -> bool {
         false // bottom = initialized (start_block_effect counters this at outset)
     }
 }
 
-impl<'a, 'gcx, 'tcx> InitialFlow for DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> InitialFlow for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
     #[inline]
     fn bottom_value() -> bool {
         true // bottom = initialized (start_block_effect counters this at outset)
@@ -730,7 +730,7 @@ impl<'a, 'gcx, 'tcx> InitialFlow for MovingOutStatements<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> InitialFlow for EverInitializedLvals<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> InitialFlow for EverInitializedPlaces<'a, 'gcx, 'tcx> {
     #[inline]
     fn bottom_value() -> bool {
         false // bottom = no initialized variables by default
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index b18fb7c7b9c..bd63198ecd0 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -26,9 +26,9 @@ use std::path::PathBuf;
 use std::usize;
 
 pub use self::impls::{MaybeStorageLive};
-pub use self::impls::{MaybeInitializedLvals, MaybeUninitializedLvals};
-pub use self::impls::{DefinitelyInitializedLvals, MovingOutStatements};
-pub use self::impls::EverInitializedLvals;
+pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
+pub use self::impls::{DefinitelyInitializedPlaces, MovingOutStatements};
+pub use self::impls::EverInitializedPlaces;
 pub use self::impls::borrows::{Borrows, BorrowData};
 pub(crate) use self::impls::borrows::{ActiveBorrows, Reservations, ReserveOrActivateIndex};
 pub use self::at_location::{FlowAtLocation, FlowsAtLocation};
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index bcf4662211e..7b6ebc6fba8 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -86,7 +86,7 @@ impl MoveOutIndex {
 /// It follows a tree structure.
 ///
 /// Given `struct X { m: M, n: N }` and `x: X`, moves like `drop x.m;`
-/// move *out* of the l-value `x.m`.
+/// move *out* of the place `x.m`.
 ///
 /// The MovePaths representing `x.m` and `x.n` are siblings (that is,
 /// one of them will link to the other via the `next_sibling` field,
@@ -222,7 +222,7 @@ impl fmt::Debug for Init {
     }
 }
 
-/// Tables mapping from an l-value to its MovePathIndex.
+/// Tables mapping from a place to its MovePathIndex.
 #[derive(Debug)]
 pub struct MovePathLookup<'tcx> {
     locals: IndexVec<Local, MovePathIndex>,
@@ -247,7 +247,7 @@ pub enum LookupResult {
 impl<'tcx> MovePathLookup<'tcx> {
     // Unlike the builder `fn move_path_for` below, this lookup
     // alternative will *not* create a MovePath on the fly for an
-    // unknown l-value, but will rather return the nearest available
+    // unknown place, but will rather return the nearest available
     // parent.
     pub fn find(&self, place: &Place<'tcx>) -> LookupResult {
         match *place {
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index c2c6b23c083..701b7a07ac9 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -9,9 +9,9 @@ use interpret::memory::HasMemory;
 
 #[derive(Copy, Clone, Debug)]
 pub enum Place {
-    /// An place referring to a value allocated in the `Memory` system.
+    /// A place referring to a value allocated in the `Memory` system.
     Ptr {
-        /// An place may have an invalid (integral or undef) pointer,
+        /// A place may have an invalid (integral or undef) pointer,
         /// since it might be turned back into a reference
         /// before ever being dereferenced.
         ptr: Pointer,
@@ -19,7 +19,7 @@ pub enum Place {
         extra: PlaceExtra,
     },
 
-    /// An place referring to a value on the stack. Represented by a stack frame index paired with
+    /// A place referring to a value on the stack. Represented by a stack frame index paired with
     /// a Mir local index.
     Local { frame: usize, local: mir::Local },
 }
@@ -33,7 +33,7 @@ pub enum PlaceExtra {
 }
 
 impl<'tcx> Place {
-    /// Produces an Place that will error if attempted to be read from
+    /// Produces a Place that will error if attempted to be read from
     pub fn undef() -> Self {
         Self::from_primval_ptr(PrimVal::Undef.into(), Align::from_bytes(1, 1).unwrap())
     }
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 106bc39d0fc..9eca343cb5e 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex, LookupResult};
-use dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
+use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 use dataflow::{DataflowResults};
 use dataflow::{on_all_children_bits, on_all_drop_children_bits};
 use dataflow::{drop_flag_effects_for_location, on_lookup_result_bits};
@@ -60,11 +60,11 @@ impl MirPass for ElaborateDrops {
             let dead_unwinds = find_dead_unwinds(tcx, mir, id, &env);
             let flow_inits =
                 do_dataflow(tcx, mir, id, &[], &dead_unwinds,
-                            MaybeInitializedLvals::new(tcx, mir, &env),
+                            MaybeInitializedPlaces::new(tcx, mir, &env),
                             |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
             let flow_uninits =
                 do_dataflow(tcx, mir, id, &[], &dead_unwinds,
-                            MaybeUninitializedLvals::new(tcx, mir, &env),
+                            MaybeUninitializedPlaces::new(tcx, mir, &env),
                             |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
 
             ElaborateDropsCtxt {
@@ -97,7 +97,7 @@ fn find_dead_unwinds<'a, 'tcx>(
     let mut dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
     let flow_inits =
         do_dataflow(tcx, mir, id, &[], &dead_unwinds,
-                    MaybeInitializedLvals::new(tcx, mir, &env),
+                    MaybeInitializedPlaces::new(tcx, mir, &env),
                     |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
     for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
         let location = match bb_data.terminator().kind {
@@ -300,8 +300,8 @@ struct ElaborateDropsCtxt<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     mir: &'a Mir<'tcx>,
     env: &'a MoveDataParamEnv<'tcx, 'tcx>,
-    flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx, 'tcx>>,
-    flow_uninits:  DataflowResults<MaybeUninitializedLvals<'a, 'tcx, 'tcx>>,
+    flow_inits: DataflowResults<MaybeInitializedPlaces<'a, 'tcx, 'tcx>>,
+    flow_uninits:  DataflowResults<MaybeUninitializedPlaces<'a, 'tcx, 'tcx>>,
     drop_flags: FxHashMap<MovePathIndex, Local>,
     patch: MirPatch<'tcx>,
 }
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index b6153ea1fdb..76283edac72 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -22,7 +22,7 @@ use dataflow::{do_dataflow, DebugFormatted};
 use dataflow::MoveDataParamEnv;
 use dataflow::BitDenotation;
 use dataflow::DataflowResults;
-use dataflow::{DefinitelyInitializedLvals, MaybeInitializedLvals, MaybeUninitializedLvals};
+use dataflow::{DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces};
 use dataflow::move_paths::{MovePathIndex, LookupResult};
 use dataflow::move_paths::{HasMoveData, MoveData};
 use dataflow;
@@ -50,15 +50,15 @@ impl MirPass for SanityCheck {
         let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
         let flow_inits =
             do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
-                        MaybeInitializedLvals::new(tcx, mir, &mdpe),
+                        MaybeInitializedPlaces::new(tcx, mir, &mdpe),
                         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
         let flow_uninits =
             do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
-                        MaybeUninitializedLvals::new(tcx, mir, &mdpe),
+                        MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
                         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
         let flow_def_inits =
             do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
-                        DefinitelyInitializedLvals::new(tcx, mir, &mdpe),
+                        DefinitelyInitializedPlaces::new(tcx, mir, &mdpe),
                         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
 
         if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() {
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 3331bc9e59e..65771068014 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -560,7 +560,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
     ///        ptr = cur
     ///        cur = cur.offset(1)
     ///    } else {
-    ///        ptr = &mut LV[cur]
+    ///        ptr = &mut P[cur]
     ///        cur = cur + 1
     ///    }
     ///    drop(ptr)
@@ -731,7 +731,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
         if ptr_based {
             let tmp_ty = tcx.mk_mut_ptr(self.place_ty(self.place));
             let tmp = Place::Local(self.new_temp(tmp_ty));
-            // tmp = &LV;
+            // tmp = &P;
             // cur = tmp as *mut T;
             // end = Offset(cur, len);
             drop_block_stmts.push(self.assign(&tmp, Rvalue::Ref(
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index 4c17929fe98..12698964d2e 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -545,7 +545,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
         self.mode == PassMode::Ignore
     }
 
-    /// Get the LLVM type for an place of the original Rust type of
+    /// Get the LLVM type for a place of the original Rust type of
     /// this argument/return, i.e. the result of `type_of::type_of`.
     pub fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
         self.layout.llvm_type(cx)
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index b4cdf38a513..416e3639bc1 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -209,7 +209,7 @@ enum Base {
     Static(ValueRef)
 }
 
-/// An place as seen from a constant.
+/// A place as seen from a constant.
 #[derive(Copy, Clone)]
 struct ConstPlace<'tcx> {
     base: Base,
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 71c1326b412..7f5b353f79e 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -136,7 +136,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
         };
 
         if let Some(hir::MutMutable) = pick.autoref {
-            self.convert_lvalue_derefs_to_mutable();
+            self.convert_place_derefs_to_mutable();
         }
 
         ConfirmResult { callee, illegal_sized_bound }
@@ -416,7 +416,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
     /// When we select a method with a mutable autoref, we have to go convert any
     /// auto-derefs, indices, etc from `Deref` and `Index` into `DerefMut` and `IndexMut`
     /// respectively.
-    fn convert_lvalue_derefs_to_mutable(&self) {
+    fn convert_place_derefs_to_mutable(&self) {
         // Gather up expressions we want to munge.
         let mut exprs = Vec::new();
         exprs.push(self.self_expr);
@@ -431,11 +431,11 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             }
         }
 
-        debug!("convert_lvalue_derefs_to_mutable: exprs={:?}", exprs);
+        debug!("convert_place_derefs_to_mutable: exprs={:?}", exprs);
 
         // Fix up autoderefs and derefs.
         for (i, &expr) in exprs.iter().rev().enumerate() {
-            debug!("convert_lvalue_derefs_to_mutable: i={} expr={:?}", i, expr);
+            debug!("convert_place_derefs_to_mutable: i={} expr={:?}", i, expr);
 
             // Fix up the autoderefs. Autorefs can only occur immediately preceding
             // overloaded place ops, and will be fixed by them in order to get
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1313b86f7dc..483dd345286 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -557,7 +557,7 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     ///   foo();}` or `{return; 22}`, where we would warn on the
     ///   `foo()` or `22`.
     ///
-    /// - To permit assignment into a local variable or other lvalue
+    /// - To permit assignment into a local variable or other place
     ///   (including the "return slot") of type `!`.  This is allowed
     ///   if **either** the type of value being assigned is `!`, which
     ///   means the current code is dead, **or** the expression's
@@ -2275,11 +2275,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
+    /// For the overloaded place expressions (`*x`, `x[3]`), the trait
     /// returns a type of `&T`, but the actual type we assign to the
     /// *expression* is `T`. So this function just peels off the return
     /// type by one layer to yield `T`.
-    fn make_overloaded_lvalue_return_type(&self,
+    fn make_overloaded_place_return_type(&self,
                                           method: MethodCallee<'tcx>)
                                           -> ty::TypeAndMut<'tcx>
     {
@@ -2373,7 +2373,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 self.apply_adjustments(base_expr, adjustments);
 
                 self.write_method_call(expr.hir_id, method);
-                (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
+                (input_ty, self.make_overloaded_place_return_type(method).ty)
             });
             if result.is_some() {
                 return result;
@@ -3650,7 +3650,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                     target: method.sig.inputs()[0]
                                 }]);
                             }
-                            oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
+                            oprnd_t = self.make_overloaded_place_return_type(method).ty;
                             self.write_method_call(expr.hir_id, method);
                         } else {
                             type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
@@ -3682,7 +3682,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 match ty.sty {
                     ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
                         if self.is_place_expr(&oprnd) {
-                            // Lvalues may legitimately have unsized types.
+                            // Places may legitimately have unsized types.
                             // For example, dereferences of a fat pointer and
                             // the last field of a struct can be unsized.
                             ExpectHasType(mt.ty)
@@ -4245,7 +4245,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             // ref mut, for soundness (issue #23116). In particular, in
             // the latter case, we need to be clear that the type of the
             // referent for the reference that results is *equal to* the
-            // type of the lvalue it is referencing, and not some
+            // type of the place it is referencing, and not some
             // supertype thereof.
             let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
             self.demand_eqtype(init.span, local_ty, init_ty);
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 18d573bd581..ac7f54250d3 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -732,8 +732,8 @@ and [RFC 809] for more details.
 "##,
 
 E0067: r##"
-The left-hand side of a compound assignment expression must be an lvalue
-expression. An lvalue expression represents a memory location and includes
+The left-hand side of a compound assignment expression must be a place
+expression. A place expression represents a memory location and includes
 item paths (ie, namespaced variables), dereferences, indexing expressions,
 and field references.
 
@@ -742,7 +742,7 @@ Let's start with some erroneous code examples:
 ```compile_fail,E0067
 use std::collections::LinkedList;
 
-// Bad: assignment to non-lvalue expression
+// Bad: assignment to non-place expression
 LinkedList::new() += 1;
 
 // ...
@@ -783,14 +783,14 @@ function's return type and the value being returned.
 "##,
 
 E0070: r##"
-The left-hand side of an assignment operator must be an lvalue expression. An
-lvalue expression represents a memory location and can be a variable (with
+The left-hand side of an assignment operator must be a place expression. An
+place expression represents a memory location and can be a variable (with
 optional namespacing), a dereference, an indexing expression or a field
 reference.
 
 More details can be found in the [Expressions] section of the Reference.
 
-[Expressions]: https://doc.rust-lang.org/reference/expressions.html#lvalues-rvalues-and-temporaries
+[Expressions]: https://doc.rust-lang.org/reference/expressions.html#places-rvalues-and-temporaries
 
 Now, we can go further. Here are some erroneous code examples:
 
@@ -806,7 +806,7 @@ fn some_other_func() {}
 
 fn some_function() {
     SOME_CONST = 14; // error : a constant value cannot be changed!
-    1 = 3; // error : 1 isn't a valid lvalue!
+    1 = 3; // error : 1 isn't a valid place!
     some_other_func() = 4; // error : we can't assign value to a function!
     SomeStruct.x = 12; // error : SomeStruct a structure name but it is used
                        // like a variable!
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 3660d2fe46a..0dfe9cb970e 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -1439,7 +1439,7 @@ impl<'a> MethodDef<'a> {
                                                          &catch_all_substructure);
 
             // Final wrinkle: the self_args are expressions that deref
-            // down to desired l-values, but we cannot actually deref
+            // down to desired places, but we cannot actually deref
             // them when they are fed as r-values into a tuple
             // expression; here add a layer of borrowing, turning
             // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
@@ -1516,7 +1516,7 @@ impl<'a> MethodDef<'a> {
         } else {
 
             // Final wrinkle: the self_args are expressions that deref
-            // down to desired l-values, but we cannot actually deref
+            // down to desired places, but we cannot actually deref
             // them when they are fed as r-values into a tuple
             // expression; here add a layer of borrowing, turning
             // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.

From 6f8d263e876106a3c05a05b93fb78a4de07b37f5 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Mon, 29 Jan 2018 01:59:34 +0200
Subject: [PATCH 6/7] tests: replace "lvalue" terminology with "place".

---
 src/test/compile-fail/regions-adjusted-lvalue-op.rs         | 2 +-
 src/test/incremental/hashes/unary_and_binary_exprs.rs       | 6 +++---
 src/test/run-pass/issue-18514.rs                            | 2 +-
 src/test/run-pass/issue-18845.rs                            | 2 +-
 .../run-pass/method-mut-self-modifies-mut-slice-lvalue.rs   | 4 ++--
 src/test/run-pass/mir_drop_order.rs                         | 2 +-
 src/test/run-pass/type-ascription.rs                        | 2 +-
 src/test/ui/issue-26093.rs                                  | 4 ++--
 src/test/ui/issue-26093.stderr                              | 4 ++--
 9 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/test/compile-fail/regions-adjusted-lvalue-op.rs b/src/test/compile-fail/regions-adjusted-lvalue-op.rs
index 167c8630707..bb02d6d8bba 100644
--- a/src/test/compile-fail/regions-adjusted-lvalue-op.rs
+++ b/src/test/compile-fail/regions-adjusted-lvalue-op.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// check that we link regions in mutable lvalue ops correctly - issue #41774
+// check that we link regions in mutable place ops correctly - issue #41774
 
 struct Data(i32);
 
diff --git a/src/test/incremental/hashes/unary_and_binary_exprs.rs b/src/test/incremental/hashes/unary_and_binary_exprs.rs
index 85f6ef60c5d..466690e7ca1 100644
--- a/src/test/incremental/hashes/unary_and_binary_exprs.rs
+++ b/src/test/incremental/hashes/unary_and_binary_exprs.rs
@@ -404,9 +404,9 @@ pub fn value_cast(a: u32) -> i32 {
 
 
 
-// Change l-value in assignment ------------------------------------------------
+// Change place in assignment --------------------------------------------------
 #[cfg(cfail1)]
-pub fn lvalue() -> i32 {
+pub fn place() -> i32 {
     let mut x = 10;
     let mut y = 11;
     x = 9;
@@ -416,7 +416,7 @@ pub fn lvalue() -> i32 {
 #[cfg(not(cfail1))]
 #[rustc_clean(except="HirBody,MirOptimized,MirValidated", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
-pub fn lvalue() -> i32 {
+pub fn place() -> i32 {
     let mut x = 10;
     let mut y = 11;
     y = 9;
diff --git a/src/test/run-pass/issue-18514.rs b/src/test/run-pass/issue-18514.rs
index 88bf95f036b..2a1e55d867f 100644
--- a/src/test/run-pass/issue-18514.rs
+++ b/src/test/run-pass/issue-18514.rs
@@ -10,7 +10,7 @@
 
 // Test that we don't ICE when translating a generic impl method from
 // an extern crate that contains a match expression on a local
-// variable lvalue where one of the match case bodies contains an
+// variable place where one of the match case bodies contains an
 // expression that autoderefs through an overloaded generic deref
 // impl.
 
diff --git a/src/test/run-pass/issue-18845.rs b/src/test/run-pass/issue-18845.rs
index 3d8e0556a56..241408ddef1 100644
--- a/src/test/run-pass/issue-18845.rs
+++ b/src/test/run-pass/issue-18845.rs
@@ -11,7 +11,7 @@
 // This used to generate invalid IR in that even if we took the
 // `false` branch we'd still try to free the Box from the other
 // arm. This was due to treating `*Box::new(9)` as an rvalue datum
-// instead of as an lvalue.
+// instead of as a place.
 
 fn test(foo: bool) -> u8 {
     match foo {
diff --git a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
index c729f736115..4de8f6a7194 100644
--- a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
+++ b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test that an `&mut self` method, when invoked on an lvalue whose
-// type is `&mut [u8]`, passes in a pointer to the lvalue and not a
+// Test that an `&mut self` method, when invoked on a place whose
+// type is `&mut [u8]`, passes in a pointer to the place and not a
 // temporary. Issue #19147.
 
 use std::slice;
diff --git a/src/test/run-pass/mir_drop_order.rs b/src/test/run-pass/mir_drop_order.rs
index 41cb458c0b8..7ab133bbab4 100644
--- a/src/test/run-pass/mir_drop_order.rs
+++ b/src/test/run-pass/mir_drop_order.rs
@@ -41,7 +41,7 @@ fn main() {
         // all borrows are extended - nothing has been dropped yet
         assert_eq!(get(), vec![]);
     }
-    // in a let-statement, extended lvalues are dropped
+    // in a let-statement, extended places are dropped
     // *after* the let result (tho they have the same scope
     // as far as scope-based borrowck goes).
     assert_eq!(get(), vec![0, 2, 3, 1]);
diff --git a/src/test/run-pass/type-ascription.rs b/src/test/run-pass/type-ascription.rs
index bca384c6471..18fb8e2e408 100644
--- a/src/test/run-pass/type-ascription.rs
+++ b/src/test/run-pass/type-ascription.rs
@@ -40,6 +40,6 @@ fn main() {
     assert_eq!(b, 1: u16);
 
     let mut v = Vec::new();
-    v: Vec<u8> = vec![1, 2, 3]; // Lvalue type ascription
+    v: Vec<u8> = vec![1, 2, 3]; // Place expression type ascription
     assert_eq!(v, [1u8, 2, 3]);
 }
diff --git a/src/test/ui/issue-26093.rs b/src/test/ui/issue-26093.rs
index 3489a2ca9be..22751c4a37c 100644
--- a/src/test/ui/issue-26093.rs
+++ b/src/test/ui/issue-26093.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-macro_rules! not_an_lvalue {
+macro_rules! not_a_place {
     ($thing:expr) => {
         $thing = 42;
         //~^ ERROR invalid left-hand side expression
@@ -16,5 +16,5 @@ macro_rules! not_an_lvalue {
 }
 
 fn main() {
-    not_an_lvalue!(99);
+    not_a_place!(99);
 }
diff --git a/src/test/ui/issue-26093.stderr b/src/test/ui/issue-26093.stderr
index c2b81b2ce43..b850852623f 100644
--- a/src/test/ui/issue-26093.stderr
+++ b/src/test/ui/issue-26093.stderr
@@ -4,8 +4,8 @@ error[E0070]: invalid left-hand side expression
 13 |         $thing = 42;
    |         ^^^^^^^^^^^ left-hand of expression not valid
 ...
-19 |     not_an_lvalue!(99);
-   |     ------------------- in this macro invocation
+19 |     not_a_place!(99);
+   |     ----------------- in this macro invocation
 
 error: aborting due to previous error
 

From bba81c975d9136d2bf10413826c743d25e54d97b Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Mon, 29 Jan 2018 02:25:35 +0200
Subject: [PATCH 7/7] rustc_borrowck: replace "lvalue" terminology with "place"
 in docs.

---
 src/librustc_borrowck/borrowck/README.md | 156 +++++++++++------------
 src/librustc_borrowck/borrowck/mod.rs    |   4 +-
 src/librustc_mir/borrow_check/mod.rs     |   2 +-
 3 files changed, 81 insertions(+), 81 deletions(-)

diff --git a/src/librustc_borrowck/borrowck/README.md b/src/librustc_borrowck/borrowck/README.md
index b877c5a9cbc..da2b1ef0b1c 100644
--- a/src/librustc_borrowck/borrowck/README.md
+++ b/src/librustc_borrowck/borrowck/README.md
@@ -43,14 +43,14 @@ it is safe with respect to the in-scope loans.
 # Formal model
 
 Throughout the docs we'll consider a simple subset of Rust in which
-you can only borrow from lvalues, defined like so:
+you can only borrow from places, defined like so:
 
 ```text
-LV = x | LV.f | *LV
+P = x | P.f | *P
 ```
 
-Here `x` represents some variable, `LV.f` is a field reference,
-and `*LV` is a pointer dereference. There is no auto-deref or other
+Here `x` represents some variable, `P.f` is a field reference,
+and `*P` is a pointer dereference. There is no auto-deref or other
 niceties. This means that if you have a type like:
 
 ```rust
@@ -58,7 +58,7 @@ struct S { f: i32 }
 ```
 
 and a variable `a: Box<S>`, then the rust expression `a.f` would correspond
-to an `LV` of `(*a).f`.
+to an `P` of `(*a).f`.
 
 Here is the formal grammar for the types we'll consider:
 
@@ -99,7 +99,7 @@ this sort of thing.
 #### Loans and restrictions
 
 The way the borrow checker works is that it analyzes each borrow
-expression (in our simple model, that's stuff like `&LV`, though in
+expression (in our simple model, that's stuff like `&P`, though in
 real life there are a few other cases to consider). For each borrow
 expression, it computes a `Loan`, which is a data structure that
 records (1) the value being borrowed, (2) the mutability and scope of
@@ -108,29 +108,29 @@ struct defined in `middle::borrowck`. Formally, we define `LOAN` as
 follows:
 
 ```text
-LOAN = (LV, LT, MQ, RESTRICTION*)
-RESTRICTION = (LV, ACTION*)
+LOAN = (P, LT, MQ, RESTRICTION*)
+RESTRICTION = (P, ACTION*)
 ACTION = MUTATE | CLAIM | FREEZE
 ```
 
-Here the `LOAN` tuple defines the lvalue `LV` being borrowed; the
+Here the `LOAN` tuple defines the place `P` being borrowed; the
 lifetime `LT` of that borrow; the mutability `MQ` of the borrow; and a
 list of restrictions. The restrictions indicate actions which, if
 taken, could invalidate the loan and lead to type safety violations.
 
-Each `RESTRICTION` is a pair of a restrictive lvalue `LV` (which will
+Each `RESTRICTION` is a pair of a restrictive place `P` (which will
 either be the path that was borrowed or some prefix of the path that
 was borrowed) and a set of restricted actions.  There are three kinds
-of actions that may be restricted for the path `LV`:
+of actions that may be restricted for the path `P`:
 
-- `MUTATE` means that `LV` cannot be assigned to;
-- `CLAIM` means that the `LV` cannot be borrowed mutably;
-- `FREEZE` means that the `LV` cannot be borrowed immutably;
+- `MUTATE` means that `P` cannot be assigned to;
+- `CLAIM` means that the `P` cannot be borrowed mutably;
+- `FREEZE` means that the `P` cannot be borrowed immutably;
 
-Finally, it is never possible to move from an lvalue that appears in a
-restriction. This implies that the "empty restriction" `(LV, [])`,
+Finally, it is never possible to move from a place that appears in a
+restriction. This implies that the "empty restriction" `(P, [])`,
 which contains an empty set of actions, still has a purpose---it
-prevents moves from `LV`. I chose not to make `MOVE` a fourth kind of
+prevents moves from `P`. I chose not to make `MOVE` a fourth kind of
 action because that would imply that sometimes moves are permitted
 from restricted values, which is not the case.
 
@@ -239,22 +239,22 @@ live. (This is done via restrictions, read on.)
 
 We start with the `gather_loans` pass, which walks the AST looking for
 borrows.  For each borrow, there are three bits of information: the
-lvalue `LV` being borrowed and the mutability `MQ` and lifetime `LT`
+place `P` being borrowed and the mutability `MQ` and lifetime `LT`
 of the resulting pointer. Given those, `gather_loans` applies four
 validity tests:
 
-1. `MUTABILITY(LV, MQ)`: The mutability of the reference is
-compatible with the mutability of `LV` (i.e., not borrowing immutable
+1. `MUTABILITY(P, MQ)`: The mutability of the reference is
+compatible with the mutability of `P` (i.e., not borrowing immutable
 data as mutable).
 
-2. `ALIASABLE(LV, MQ)`: The aliasability of the reference is
-compatible with the aliasability of `LV`. The goal is to prevent
+2. `ALIASABLE(P, MQ)`: The aliasability of the reference is
+compatible with the aliasability of `P`. The goal is to prevent
 `&mut` borrows of aliasability data.
 
-3. `LIFETIME(LV, LT, MQ)`: The lifetime of the borrow does not exceed
+3. `LIFETIME(P, LT, MQ)`: The lifetime of the borrow does not exceed
 the lifetime of the value being borrowed.
 
-4. `RESTRICTIONS(LV, LT, ACTIONS) = RS`: This pass checks and computes the
+4. `RESTRICTIONS(P, LT, ACTIONS) = RS`: This pass checks and computes the
 restrictions to maintain memory safety. These are the restrictions
 that will go into the final loan. We'll discuss in more detail below.
 
@@ -263,7 +263,7 @@ that will go into the final loan. We'll discuss in more detail below.
 Checking mutability is fairly straightforward. We just want to prevent
 immutable data from being borrowed as mutable. Note that it is ok to borrow
 mutable data as immutable, since that is simply a freeze. The judgement
-`MUTABILITY(LV, MQ)` means the mutability of `LV` is compatible with a borrow
+`MUTABILITY(P, MQ)` means the mutability of `P` is compatible with a borrow
 of mutability `MQ`. The Rust code corresponding to this predicate is the
 function `check_mutability` in `middle::borrowck::gather_loans`.
 
@@ -288,15 +288,15 @@ MUTABILITY(X, imm)                  // M-Var-Imm
 
 Fields and boxes inherit their mutability from
 their base expressions, so both of their rules basically
-delegate the check to the base expression `LV`:
+delegate the check to the base expression `P`:
 
 ```text
-MUTABILITY(LV.f, MQ)                // M-Field
-  MUTABILITY(LV, MQ)
+MUTABILITY(P.f, MQ)                // M-Field
+  MUTABILITY(P, MQ)
 
-MUTABILITY(*LV, MQ)                 // M-Deref-Unique
-  TYPE(LV) = Box<Ty>
-  MUTABILITY(LV, MQ)
+MUTABILITY(*P, MQ)                 // M-Deref-Unique
+  TYPE(P) = Box<Ty>
+  MUTABILITY(P, MQ)
 ```
 
 ### Checking mutability of immutable pointer types
@@ -305,8 +305,8 @@ Immutable pointer types like `&T` can only
 be borrowed if MQ is immutable:
 
 ```text
-MUTABILITY(*LV, imm)               // M-Deref-Borrowed-Imm
-  TYPE(LV) = &Ty
+MUTABILITY(*P, imm)               // M-Deref-Borrowed-Imm
+  TYPE(P) = &Ty
 ```
 
 ### Checking mutability of mutable pointer types
@@ -314,15 +314,15 @@ MUTABILITY(*LV, imm)               // M-Deref-Borrowed-Imm
 `&mut T` can be frozen, so it is acceptable to borrow it as either imm or mut:
 
 ```text
-MUTABILITY(*LV, MQ)                 // M-Deref-Borrowed-Mut
-  TYPE(LV) = &mut Ty
+MUTABILITY(*P, MQ)                 // M-Deref-Borrowed-Mut
+  TYPE(P) = &mut Ty
 ```
 
 ## Checking aliasability
 
 The goal of the aliasability check is to ensure that we never permit `&mut`
-borrows of aliasable data. The judgement `ALIASABLE(LV, MQ)` means the
-aliasability of `LV` is compatible with a borrow of mutability `MQ`. The Rust
+borrows of aliasable data. The judgement `ALIASABLE(P, MQ)` means the
+aliasability of `P` is compatible with a borrow of mutability `MQ`. The Rust
 code corresponding to this predicate is the function `check_aliasability()` in
 `middle::borrowck::gather_loans`.
 
@@ -340,11 +340,11 @@ the stack frame.
 Owned content is aliasable if it is found in an aliasable location:
 
 ```text
-ALIASABLE(LV.f, MQ)                // M-Field
-  ALIASABLE(LV, MQ)
+ALIASABLE(P.f, MQ)                // M-Field
+  ALIASABLE(P, MQ)
 
-ALIASABLE(*LV, MQ)                 // M-Deref-Unique
-  ALIASABLE(LV, MQ)
+ALIASABLE(*P, MQ)                 // M-Deref-Unique
+  ALIASABLE(P, MQ)
 ```
 
 ### Checking aliasability of immutable pointer types
@@ -353,8 +353,8 @@ Immutable pointer types like `&T` are aliasable, and hence can only be
 borrowed immutably:
 
 ```text
-ALIASABLE(*LV, imm)                // M-Deref-Borrowed-Imm
-  TYPE(LV) = &Ty
+ALIASABLE(*P, imm)                // M-Deref-Borrowed-Imm
+  TYPE(P) = &Ty
 ```
 
 ### Checking aliasability of mutable pointer types
@@ -362,16 +362,16 @@ ALIASABLE(*LV, imm)                // M-Deref-Borrowed-Imm
 `&mut T` can be frozen, so it is acceptable to borrow it as either imm or mut:
 
 ```text
-ALIASABLE(*LV, MQ)                 // M-Deref-Borrowed-Mut
-  TYPE(LV) = &mut Ty
+ALIASABLE(*P, MQ)                 // M-Deref-Borrowed-Mut
+  TYPE(P) = &mut Ty
 ```
 
 ## Checking lifetime
 
 These rules aim to ensure that no data is borrowed for a scope that exceeds
 its lifetime. These two computations wind up being intimately related.
-Formally, we define a predicate `LIFETIME(LV, LT, MQ)`, which states that
-"the lvalue `LV` can be safely borrowed for the lifetime `LT` with mutability
+Formally, we define a predicate `LIFETIME(P, LT, MQ)`, which states that
+"the place `P` can be safely borrowed for the lifetime `LT` with mutability
 `MQ`". The Rust code corresponding to this predicate is the module
 `middle::borrowck::gather_loans::lifetime`.
 
@@ -391,12 +391,12 @@ The lifetime of a field or box is the same as the lifetime
 of its owner:
 
 ```text
-LIFETIME(LV.f, LT, MQ)              // L-Field
-  LIFETIME(LV, LT, MQ)
+LIFETIME(P.f, LT, MQ)              // L-Field
+  LIFETIME(P, LT, MQ)
 
-LIFETIME(*LV, LT, MQ)               // L-Deref-Send
-  TYPE(LV) = Box<Ty>
-  LIFETIME(LV, LT, MQ)
+LIFETIME(*P, LT, MQ)               // L-Deref-Send
+  TYPE(P) = Box<Ty>
+  LIFETIME(P, LT, MQ)
 ```
 
 ### Checking lifetime for derefs of references
@@ -408,8 +408,8 @@ of the borrow is shorter than the lifetime `LT'` of the pointer
 itself:
 
 ```text
-LIFETIME(*LV, LT, MQ)               // L-Deref-Borrowed
-  TYPE(LV) = &LT' Ty OR &LT' mut Ty
+LIFETIME(*P, LT, MQ)               // L-Deref-Borrowed
+  TYPE(P) = &LT' Ty OR &LT' mut Ty
   LT <= LT'
 ```
 
@@ -417,17 +417,17 @@ LIFETIME(*LV, LT, MQ)               // L-Deref-Borrowed
 
 The final rules govern the computation of *restrictions*, meaning that
 we compute the set of actions that will be illegal for the life of the
-loan. The predicate is written `RESTRICTIONS(LV, LT, ACTIONS) =
+loan. The predicate is written `RESTRICTIONS(P, LT, ACTIONS) =
 RESTRICTION*`, which can be read "in order to prevent `ACTIONS` from
-occurring on `LV`, the restrictions `RESTRICTION*` must be respected
+occurring on `P`, the restrictions `RESTRICTION*` must be respected
 for the lifetime of the loan".
 
 Note that there is an initial set of restrictions: these restrictions
 are computed based on the kind of borrow:
 
 ```text
-&mut LV =>   RESTRICTIONS(LV, LT, MUTATE|CLAIM|FREEZE)
-&LV =>       RESTRICTIONS(LV, LT, MUTATE|CLAIM)
+&mut P =>   RESTRICTIONS(P, LT, MUTATE|CLAIM|FREEZE)
+&P =>       RESTRICTIONS(P, LT, MUTATE|CLAIM)
 ```
 
 The reasoning here is that a mutable borrow must be the only writer,
@@ -451,8 +451,8 @@ Restricting a field is the same as restricting the owner of that
 field:
 
 ```text
-RESTRICTIONS(LV.f, LT, ACTIONS) = RS, (LV.f, ACTIONS)  // R-Field
-  RESTRICTIONS(LV, LT, ACTIONS) = RS
+RESTRICTIONS(P.f, LT, ACTIONS) = RS, (P.f, ACTIONS)  // R-Field
+  RESTRICTIONS(P, LT, ACTIONS) = RS
 ```
 
 The reasoning here is as follows. If the field must not be mutated,
@@ -467,16 +467,16 @@ origin of inherited mutability.
 Because the mutability of owned referents is inherited, restricting an
 owned referent is similar to restricting a field, in that it implies
 restrictions on the pointer. However, boxes have an important
-twist: if the owner `LV` is mutated, that causes the owned referent
-`*LV` to be freed! So whenever an owned referent `*LV` is borrowed, we
-must prevent the box `LV` from being mutated, which means
+twist: if the owner `P` is mutated, that causes the owned referent
+`*P` to be freed! So whenever an owned referent `*P` is borrowed, we
+must prevent the box `P` from being mutated, which means
 that we always add `MUTATE` and `CLAIM` to the restriction set imposed
-on `LV`:
+on `P`:
 
 ```text
-RESTRICTIONS(*LV, LT, ACTIONS) = RS, (*LV, ACTIONS)    // R-Deref-Send-Pointer
-  TYPE(LV) = Box<Ty>
-  RESTRICTIONS(LV, LT, ACTIONS|MUTATE|CLAIM) = RS
+RESTRICTIONS(*P, LT, ACTIONS) = RS, (*P, ACTIONS)    // R-Deref-Send-Pointer
+  TYPE(P) = Box<Ty>
+  RESTRICTIONS(P, LT, ACTIONS|MUTATE|CLAIM) = RS
 ```
 
 ### Restrictions for loans of immutable borrowed referents
@@ -484,15 +484,15 @@ RESTRICTIONS(*LV, LT, ACTIONS) = RS, (*LV, ACTIONS)    // R-Deref-Send-Pointer
 Immutable borrowed referents are freely aliasable, meaning that
 the compiler does not prevent you from copying the pointer.  This
 implies that issuing restrictions is useless. We might prevent the
-user from acting on `*LV` itself, but there could be another path
-`*LV1` that refers to the exact same memory, and we would not be
+user from acting on `*P` itself, but there could be another path
+`*P1` that refers to the exact same memory, and we would not be
 restricting that path. Therefore, the rule for `&Ty` pointers
 always returns an empty set of restrictions, and it only permits
 restricting `MUTATE` and `CLAIM` actions:
 
 ```text
-RESTRICTIONS(*LV, LT, ACTIONS) = []                    // R-Deref-Imm-Borrowed
-  TYPE(LV) = &LT' Ty
+RESTRICTIONS(*P, LT, ACTIONS) = []                    // R-Deref-Imm-Borrowed
+  TYPE(P) = &LT' Ty
   LT <= LT'                                            // (1)
   ACTIONS subset of [MUTATE, CLAIM]
 ```
@@ -546,7 +546,7 @@ This function is legal. The reason for this is that the inner pointer
 (`*point : &'b Point`) is enough to guarantee the memory is immutable
 and valid for the lifetime `'b`.  This is reflected in
 `RESTRICTIONS()` by the fact that we do not recurse (i.e., we impose
-no restrictions on `LV`, which in this particular case is the pointer
+no restrictions on `P`, which in this particular case is the pointer
 `point : &'a &'b Point`).
 
 #### Why both `LIFETIME()` and `RESTRICTIONS()`?
@@ -612,10 +612,10 @@ while the new claimant is live.
 The rule for mutable borrowed pointers is as follows:
 
 ```text
-RESTRICTIONS(*LV, LT, ACTIONS) = RS, (*LV, ACTIONS)    // R-Deref-Mut-Borrowed
-  TYPE(LV) = &LT' mut Ty
+RESTRICTIONS(*P, LT, ACTIONS) = RS, (*P, ACTIONS)    // R-Deref-Mut-Borrowed
+  TYPE(P) = &LT' mut Ty
   LT <= LT'                                            // (1)
-  RESTRICTIONS(LV, LT, ACTIONS) = RS                   // (2)
+  RESTRICTIONS(P, LT, ACTIONS) = RS                   // (2)
 ```
 
 Let's examine the two numbered clauses:
@@ -670,7 +670,7 @@ fn foo(t0: &mut i32) {
 
 Remember that `&mut` pointers are linear, and hence `let t1 = t0` is a
 move of `t0` -- or would be, if it were legal. Instead, we get an
-error, because clause (2) imposes restrictions on `LV` (`t0`, here),
+error, because clause (2) imposes restrictions on `P` (`t0`, here),
 and any restrictions on a path make it impossible to move from that
 path.
 
@@ -906,7 +906,7 @@ results of a dataflow computation.
 
 The `MovePath` tree tracks every path that is moved or assigned to.
 These paths have the same form as the `LoanPath` data structure, which
-in turn is the "real world version of the lvalues `LV` that we
+in turn is the "real world version of the places `P` that we
 introduced earlier. The difference between a `MovePath` and a `LoanPath`
 is that move paths are:
 
@@ -1132,7 +1132,7 @@ is implied by the relevant moves.
 While writing up these docs, I encountered some rules I believe to be
 stricter than necessary:
 
-- I think restricting the `&mut` LV against moves and `ALIAS` is sufficient,
+- I think restricting the `&mut` P against moves and `ALIAS` is sufficient,
   `MUTATE` and `CLAIM` are overkill. `MUTATE` was necessary when swap was
   a built-in operator, but as it is not, it is implied by `CLAIM`,
   and `CLAIM` is implied by `ALIAS`. The only net effect of this is an
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index bfe894f9eb9..84ca2a9318a 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -384,9 +384,9 @@ impl ToInteriorKind for mc::InteriorKind {
 }
 
 // This can be:
-// - a pointer dereference (`*LV` in README.md)
+// - a pointer dereference (`*P` in README.md)
 // - a field reference, with an optional definition of the containing
-//   enum variant (`LV.f` in README.md)
+//   enum variant (`P.f` in README.md)
 // `DefId` is present when the field is part of struct that is in
 // a variant of an enum. For instance in:
 // `enum E { X { foo: u32 }, Y { foo: u32 }}`
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index c16d70a14db..9a6d83b8eb7 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -607,7 +607,7 @@ enum ArtificialField {
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 enum ShallowOrDeep {
     /// From the RFC: "A *shallow* access means that the immediate
-    /// fields reached at LV are accessed, but references or pointers
+    /// fields reached at P are accessed, but references or pointers
     /// found within are not dereferenced. Right now, the only access
     /// that is shallow is an assignment like `x = ...;`, which would
     /// be a *shallow write* of `x`."