Skip to content

Commit 4a788a2

Browse files
committed
Auto merge of #26479 - arielb1:expr-kind, r=eddyb
Previously it also tried to find out the best way to translate the expression, which could ICE during type-checking. Fixes #23173 Fixes #24322 Fixes #25757 r? @eddyb
2 parents fd874cd + 59be753 commit 4a788a2

File tree

5 files changed

+256
-140
lines changed

5 files changed

+256
-140
lines changed

src/librustc/middle/ty.rs

+28-129
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ pub use self::Variance::*;
2020
pub use self::AutoAdjustment::*;
2121
pub use self::Representability::*;
2222
pub use self::AutoRef::*;
23-
pub use self::ExprKind::*;
2423
pub use self::DtorKind::*;
2524
pub use self::ExplicitSelfCategory::*;
2625
pub use self::FnOutput::*;
@@ -87,7 +86,7 @@ use syntax::abi;
8786
use syntax::ast::{CrateNum, DefId, ItemImpl, ItemTrait, LOCAL_CRATE};
8887
use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
8988
use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
90-
use syntax::ast_util::{self, is_local, lit_is_str, local_def};
89+
use syntax::ast_util::{self, is_local, local_def};
9190
use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
9291
use syntax::codemap::Span;
9392
use syntax::parse::token::{self, InternedString, special_idents};
@@ -5106,104 +5105,35 @@ pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
51065105
}
51075106
}
51085107

5109-
pub fn expr_is_lval(tcx: &ctxt, e: &ast::Expr) -> bool {
5110-
match expr_kind(tcx, e) {
5111-
LvalueExpr => true,
5112-
RvalueDpsExpr | RvalueDatumExpr | RvalueStmtExpr => false
5113-
}
5114-
}
5115-
5116-
/// We categorize expressions into three kinds. The distinction between
5117-
/// lvalue/rvalue is fundamental to the language. The distinction between the
5118-
/// two kinds of rvalues is an artifact of trans which reflects how we will
5119-
/// generate code for that kind of expression. See trans/expr.rs for more
5120-
/// information.
5121-
#[derive(Copy, Clone)]
5122-
pub enum ExprKind {
5123-
LvalueExpr,
5124-
RvalueDpsExpr,
5125-
RvalueDatumExpr,
5126-
RvalueStmtExpr
5127-
}
5128-
5129-
pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
5130-
if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) {
5131-
// Overloaded operations are generally calls, and hence they are
5132-
// generated via DPS, but there are a few exceptions:
5133-
return match expr.node {
5134-
// `a += b` has a unit result.
5135-
ast::ExprAssignOp(..) => RvalueStmtExpr,
5136-
5137-
// the deref method invoked for `*a` always yields an `&T`
5138-
ast::ExprUnary(ast::UnDeref, _) => LvalueExpr,
5139-
5140-
// the index method invoked for `a[i]` always yields an `&T`
5141-
ast::ExprIndex(..) => LvalueExpr,
5142-
5143-
// in the general case, result could be any type, use DPS
5144-
_ => RvalueDpsExpr
5145-
};
5146-
}
5147-
5148-
match expr.node {
5108+
pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool {
5109+
match expr.node {
51495110
ast::ExprPath(..) => {
5150-
match resolve_expr(tcx, expr) {
5151-
def::DefVariant(tid, vid, _) => {
5152-
let variant_info = enum_variant_with_id(tcx, tid, vid);
5153-
if !variant_info.args.is_empty() {
5154-
// N-ary variant.
5155-
RvalueDatumExpr
5156-
} else {
5157-
// Nullary variant.
5158-
RvalueDpsExpr
5159-
}
5111+
// We can't use resolve_expr here, as this needs to run on broken
5112+
// programs. We don't need to through - associated items are all
5113+
// rvalues.
5114+
match tcx.def_map.borrow().get(&expr.id) {
5115+
Some(&def::PathResolution {
5116+
base_def: def::DefStatic(..), ..
5117+
}) | Some(&def::PathResolution {
5118+
base_def: def::DefUpvar(..), ..
5119+
}) | Some(&def::PathResolution {
5120+
base_def: def::DefLocal(..), ..
5121+
}) => {
5122+
true
51605123
}
51615124

5162-
def::DefStruct(_) => {
5163-
match tcx.node_types.borrow().get(&expr.id) {
5164-
Some(ty) => match ty.sty {
5165-
TyBareFn(..) => RvalueDatumExpr,
5166-
_ => RvalueDpsExpr
5167-
},
5168-
// See ExprCast below for why types might be missing.
5169-
None => RvalueDatumExpr
5170-
}
5171-
}
5125+
Some(..) => false,
51725126

5173-
// Special case: A unit like struct's constructor must be called without () at the
5174-
// end (like `UnitStruct`) which means this is an ExprPath to a DefFn. But in case
5175-
// of unit structs this is should not be interpreted as function pointer but as
5176-
// call to the constructor.
5177-
def::DefFn(_, true) => RvalueDpsExpr,
5178-
5179-
// Fn pointers are just scalar values.
5180-
def::DefFn(..) | def::DefMethod(..) => RvalueDatumExpr,
5181-
5182-
// Note: there is actually a good case to be made that
5183-
// DefArg's, particularly those of immediate type, ought to
5184-
// considered rvalues.
5185-
def::DefStatic(..) |
5186-
def::DefUpvar(..) |
5187-
def::DefLocal(..) => LvalueExpr,
5188-
5189-
def::DefConst(..) |
5190-
def::DefAssociatedConst(..) => RvalueDatumExpr,
5191-
5192-
def => {
5193-
tcx.sess.span_bug(
5194-
expr.span,
5195-
&format!("uncategorized def for expr {}: {:?}",
5196-
expr.id,
5197-
def));
5198-
}
5127+
None => tcx.sess.span_bug(expr.span, &format!(
5128+
"no def for path {}", expr.id))
51995129
}
52005130
}
52015131

52025132
ast::ExprUnary(ast::UnDeref, _) |
52035133
ast::ExprField(..) |
52045134
ast::ExprTupField(..) |
52055135
ast::ExprIndex(..) => {
5206-
LvalueExpr
5136+
true
52075137
}
52085138

52095139
ast::ExprCall(..) |
@@ -5216,60 +5146,29 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
52165146
ast::ExprClosure(..) |
52175147
ast::ExprBlock(..) |
52185148
ast::ExprRepeat(..) |
5219-
ast::ExprVec(..) => {
5220-
RvalueDpsExpr
5221-
}
5222-
5223-
ast::ExprIfLet(..) => {
5224-
tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
5225-
}
5226-
ast::ExprWhileLet(..) => {
5227-
tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
5228-
}
5229-
5230-
ast::ExprForLoop(..) => {
5231-
tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
5232-
}
5233-
5234-
ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
5235-
RvalueDpsExpr
5236-
}
5237-
5149+
ast::ExprVec(..) |
52385150
ast::ExprBreak(..) |
52395151
ast::ExprAgain(..) |
52405152
ast::ExprRet(..) |
52415153
ast::ExprWhile(..) |
52425154
ast::ExprLoop(..) |
52435155
ast::ExprAssign(..) |
52445156
ast::ExprInlineAsm(..) |
5245-
ast::ExprAssignOp(..) => {
5246-
RvalueStmtExpr
5247-
}
5248-
5249-
ast::ExprLit(_) | // Note: LitStr is carved out above
5157+
ast::ExprAssignOp(..) |
5158+
ast::ExprLit(_) |
52505159
ast::ExprUnary(..) |
5251-
ast::ExprBox(None, _) |
5160+
ast::ExprBox(..) |
52525161
ast::ExprAddrOf(..) |
52535162
ast::ExprBinary(..) |
52545163
ast::ExprCast(..) => {
5255-
RvalueDatumExpr
5256-
}
5257-
5258-
ast::ExprBox(Some(ref place), _) => {
5259-
// Special case `Box<T>` for now:
5260-
let def_id = match tcx.def_map.borrow().get(&place.id) {
5261-
Some(def) => def.def_id(),
5262-
None => panic!("no def for place"),
5263-
};
5264-
if tcx.lang_items.exchange_heap() == Some(def_id) {
5265-
RvalueDatumExpr
5266-
} else {
5267-
RvalueDpsExpr
5268-
}
5164+
false
52695165
}
52705166

5271-
ast::ExprParen(ref e) => expr_kind(tcx, &**e),
5167+
ast::ExprParen(ref e) => expr_is_lval(tcx, e),
52725168

5169+
ast::ExprIfLet(..) |
5170+
ast::ExprWhileLet(..) |
5171+
ast::ExprForLoop(..) |
52735172
ast::ExprMac(..) => {
52745173
tcx.sess.span_bug(
52755174
expr.span,

0 commit comments

Comments
 (0)