Skip to content

Commit

Permalink
rustc: move expr_is_lval to rustc_typeck and rename to `is_place_ex…
Browse files Browse the repository at this point in the history
…pr`.
  • Loading branch information
eddyb committed Jan 28, 2018
1 parent 3f4a489 commit 06a0e4f
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 59 deletions.
54 changes: 0 additions & 54 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
58 changes: 56 additions & 2 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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")
Expand Down
5 changes: 2 additions & 3 deletions src/librustc_typeck/check/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 06a0e4f

Please sign in to comment.