Skip to content

Commit

Permalink
Move is_place_expr to be a method on hir::Expr
Browse files Browse the repository at this point in the history
  • Loading branch information
KiChjang committed Sep 21, 2018
1 parent 79fcc58 commit 8132d4e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 60 deletions.
53 changes: 53 additions & 0 deletions src/librustc/hir/mod.rs
Expand Up @@ -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 {
Expand Down
67 changes: 8 additions & 59 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/op.rs
Expand Up @@ -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")
Expand Down

0 comments on commit 8132d4e

Please sign in to comment.