Skip to content

Commit 603e400

Browse files
committed
---
yaml --- r: 226074 b: refs/heads/stable c: feba393 h: refs/heads/master v: v3
1 parent 516ad5c commit 603e400

File tree

17 files changed

+171
-386
lines changed

17 files changed

+171
-386
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ refs/heads/tmp: e5d90d98402475b6e154ce216f9efcb80da1a747
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: 1fe32ca12c51afcd761d9962f51a74ff0d07a591
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 2287b4b628cb6f4d66578e1298cd9f34e9ef77db
32+
refs/heads/stable: feba393b8ed60efe79f9f5207fde904d085949f5
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b

branches/stable/src/doc/footer.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ or the <a href="http://opensource.org/licenses/MIT">MIT license</a>, at your opt
55
</p><p>
66
This file may not be copied, modified, or distributed except according to those terms.
77
</p></footer>
8+
<script type="text/javascript" src="jquery.js"></script>
89
<script type="text/javascript" src="playpen.js"></script>

branches/stable/src/librustc/middle/ty.rs

Lines changed: 129 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub use self::Variance::*;
2020
pub use self::AutoAdjustment::*;
2121
pub use self::Representability::*;
2222
pub use self::AutoRef::*;
23+
pub use self::ExprKind::*;
2324
pub use self::DtorKind::*;
2425
pub use self::ExplicitSelfCategory::*;
2526
pub use self::FnOutput::*;
@@ -86,7 +87,7 @@ use syntax::abi;
8687
use syntax::ast::{CrateNum, DefId, ItemImpl, ItemTrait, LOCAL_CRATE};
8788
use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
8889
use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
89-
use syntax::ast_util::{self, is_local, local_def};
90+
use syntax::ast_util::{self, is_local, lit_is_str, local_def};
9091
use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
9192
use syntax::codemap::Span;
9293
use syntax::parse::token::{self, InternedString, special_idents};
@@ -5105,35 +5106,104 @@ pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
51055106
}
51065107
}
51075108

5108-
pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool {
5109-
match expr.node {
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 {
51105149
ast::ExprPath(..) => {
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
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+
}
51235160
}
51245161

5125-
Some(..) => false,
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+
}
51265172

5127-
None => tcx.sess.span_bug(expr.span, &format!(
5128-
"no def for path {}", expr.id))
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+
}
51295199
}
51305200
}
51315201

51325202
ast::ExprUnary(ast::UnDeref, _) |
51335203
ast::ExprField(..) |
51345204
ast::ExprTupField(..) |
51355205
ast::ExprIndex(..) => {
5136-
true
5206+
LvalueExpr
51375207
}
51385208

51395209
ast::ExprCall(..) |
@@ -5146,29 +5216,60 @@ pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool {
51465216
ast::ExprClosure(..) |
51475217
ast::ExprBlock(..) |
51485218
ast::ExprRepeat(..) |
5149-
ast::ExprVec(..) |
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+
51505238
ast::ExprBreak(..) |
51515239
ast::ExprAgain(..) |
51525240
ast::ExprRet(..) |
51535241
ast::ExprWhile(..) |
51545242
ast::ExprLoop(..) |
51555243
ast::ExprAssign(..) |
51565244
ast::ExprInlineAsm(..) |
5157-
ast::ExprAssignOp(..) |
5158-
ast::ExprLit(_) |
5245+
ast::ExprAssignOp(..) => {
5246+
RvalueStmtExpr
5247+
}
5248+
5249+
ast::ExprLit(_) | // Note: LitStr is carved out above
51595250
ast::ExprUnary(..) |
5160-
ast::ExprBox(..) |
5251+
ast::ExprBox(None, _) |
51615252
ast::ExprAddrOf(..) |
51625253
ast::ExprBinary(..) |
51635254
ast::ExprCast(..) => {
5164-
false
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+
}
51655269
}
51665270

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

5169-
ast::ExprIfLet(..) |
5170-
ast::ExprWhileLet(..) |
5171-
ast::ExprForLoop(..) |
51725273
ast::ExprMac(..) => {
51735274
tcx.sess.span_bug(
51745275
expr.span,

0 commit comments

Comments
 (0)