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 @@ pub fn expr_span(self, id: NodeId) -> Span { } } - 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 { 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 @@ fn select_obligations_where_possible(&self) { } } + 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 @@ fn check_expr_kind(&self, 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 @@ fn check_expr_kind(&self, _ => { // 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 @@ pub fn check_binop_assign(&self, 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,