From 8132d4e1000f012d1f25dbcedf006a9dc2f8598c Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 20 Sep 2018 14:13:41 -0700 Subject: [PATCH] Move is_place_expr to be a method on hir::Expr --- src/librustc/hir/mod.rs | 53 +++++++++++++++++++++++++ src/librustc_typeck/check/mod.rs | 67 ++++---------------------------- src/librustc_typeck/check/op.rs | 2 +- 3 files changed, 62 insertions(+), 60 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index de9808ffe70..b55b175cade 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1345,6 +1345,59 @@ impl Expr { ExprKind::Yield(..) => ExprPrecedence::Yield, } } + + pub fn is_place_expr(&self) -> bool { + match self.node { + ExprKind::Path(QPath::Resolved(_, ref path)) => { + match path.def { + Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true, + _ => false, + } + } + + ExprKind::Type(ref e, _) => { + e.is_place_expr() + } + + ExprKind::Unary(UnDeref, _) | + ExprKind::Field(..) | + ExprKind::Index(..) => { + true + } + + // Partially qualified paths in expressions can only legally + // refer to associated items which are always rvalues. + ExprKind::Path(QPath::TypeRelative(..)) | + + ExprKind::Call(..) | + ExprKind::MethodCall(..) | + ExprKind::Struct(..) | + ExprKind::Tup(..) | + ExprKind::If(..) | + ExprKind::Match(..) | + ExprKind::Closure(..) | + ExprKind::Block(..) | + ExprKind::Repeat(..) | + ExprKind::Array(..) | + ExprKind::Break(..) | + ExprKind::Continue(..) | + ExprKind::Ret(..) | + ExprKind::While(..) | + ExprKind::Loop(..) | + ExprKind::Assign(..) | + ExprKind::InlineAsm(..) | + ExprKind::AssignOp(..) | + ExprKind::Lit(_) | + ExprKind::Unary(..) | + ExprKind::Box(..) | + ExprKind::AddrOf(..) | + ExprKind::Binary(..) | + ExprKind::Yield(..) | + ExprKind::Cast(..) => { + false + } + } + } } impl fmt::Debug for Expr { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index db0c4fdb03a..6d1f5be8470 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2447,59 +2447,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - fn is_place_expr(&self, expr: &hir::Expr) -> bool { - match expr.node { - hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => { - match path.def { - Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true, - _ => false, - } - } - - hir::ExprKind::Type(ref e, _) => { - self.is_place_expr(e) - } - - hir::ExprKind::Unary(hir::UnDeref, _) | - hir::ExprKind::Field(..) | - hir::ExprKind::Index(..) => { - true - } - - // Partially qualified paths in expressions can only legally - // refer to associated items which are always rvalues. - hir::ExprKind::Path(hir::QPath::TypeRelative(..)) | - - hir::ExprKind::Call(..) | - hir::ExprKind::MethodCall(..) | - hir::ExprKind::Struct(..) | - hir::ExprKind::Tup(..) | - hir::ExprKind::If(..) | - hir::ExprKind::Match(..) | - hir::ExprKind::Closure(..) | - hir::ExprKind::Block(..) | - hir::ExprKind::Repeat(..) | - hir::ExprKind::Array(..) | - hir::ExprKind::Break(..) | - hir::ExprKind::Continue(..) | - hir::ExprKind::Ret(..) | - hir::ExprKind::While(..) | - hir::ExprKind::Loop(..) | - hir::ExprKind::Assign(..) | - hir::ExprKind::InlineAsm(..) | - hir::ExprKind::AssignOp(..) | - hir::ExprKind::Lit(_) | - hir::ExprKind::Unary(..) | - hir::ExprKind::Box(..) | - hir::ExprKind::AddrOf(..) | - hir::ExprKind::Binary(..) | - hir::ExprKind::Yield(..) | - hir::ExprKind::Cast(..) => { - false - } - } - } - /// 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 @@ -3762,10 +3709,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty } - fn check_expr_kind(&self, - expr: &'gcx hir::Expr, - expected: Expectation<'tcx>, - needs: Needs) -> Ty<'tcx> { + fn check_expr_kind( + &self, + expr: &'gcx hir::Expr, + expected: Expectation<'tcx>, + needs: Needs + ) -> Ty<'tcx> { let tcx = self.tcx; let id = expr.id; match expr.node { @@ -3862,7 +3811,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| { match ty.sty { ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { - if self.is_place_expr(&oprnd) { + if oprnd.is_place_expr() { // Places may legitimately have unsized types. // For example, dereferences of a fat pointer and // the last field of a struct can be unsized. @@ -4041,7 +3990,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.is_place_expr(&lhs) { + if !lhs.is_place_expr() { 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 5004880ce47..304238488d8 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -40,7 +40,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return_ty }; - if !self.is_place_expr(lhs_expr) { + if !lhs_expr.is_place_expr() { struct_span_err!( self.tcx.sess, lhs_expr.span, E0067, "invalid left-hand side expression")