Skip to content

Commit f5c998f

Browse files
author
Nick Hamann
committed
---
yaml --- r: 227732 b: refs/heads/try c: 57a66f8 h: refs/heads/master v: v3
1 parent 46d3597 commit f5c998f

File tree

14 files changed

+215
-300
lines changed

14 files changed

+215
-300
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 31d9aee68499cba8d1a5332b841eca5c67991001
4+
refs/heads/try: 57a66f8ef39575448c21b179977e822c44d1d987
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/liblibc/lib.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5493,17 +5493,17 @@ pub mod funcs {
54935493
pub fn dup2(src: c_int, dst: c_int) -> c_int;
54945494
#[link_name = "_execv"]
54955495
pub fn execv(prog: *const c_char,
5496-
argv: *const *const c_char) -> intptr_t;
5496+
argv: *mut *const c_char) -> intptr_t;
54975497
#[link_name = "_execve"]
5498-
pub fn execve(prog: *const c_char, argv: *const *const c_char,
5499-
envp: *const *const c_char)
5498+
pub fn execve(prog: *const c_char, argv: *mut *const c_char,
5499+
envp: *mut *const c_char)
55005500
-> c_int;
55015501
#[link_name = "_execvp"]
55025502
pub fn execvp(c: *const c_char,
5503-
argv: *const *const c_char) -> c_int;
5503+
argv: *mut *const c_char) -> c_int;
55045504
#[link_name = "_execvpe"]
5505-
pub fn execvpe(c: *const c_char, argv: *const *const c_char,
5506-
envp: *const *const c_char) -> c_int;
5505+
pub fn execvpe(c: *const c_char, argv: *mut *const c_char,
5506+
envp: *mut *const c_char) -> c_int;
55075507
#[link_name = "_getcwd"]
55085508
pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
55095509
#[link_name = "_getpid"]
@@ -5687,12 +5687,12 @@ pub mod funcs {
56875687
pub fn dup(fd: c_int) -> c_int;
56885688
pub fn dup2(src: c_int, dst: c_int) -> c_int;
56895689
pub fn execv(prog: *const c_char,
5690-
argv: *const *const c_char) -> c_int;
5691-
pub fn execve(prog: *const c_char, argv: *const *const c_char,
5692-
envp: *const *const c_char)
5690+
argv: *mut *const c_char) -> c_int;
5691+
pub fn execve(prog: *const c_char, argv: *mut *const c_char,
5692+
envp: *mut *const c_char)
56935693
-> c_int;
56945694
pub fn execvp(c: *const c_char,
5695-
argv: *const *const c_char) -> c_int;
5695+
argv: *mut *const c_char) -> c_int;
56965696
pub fn fork() -> pid_t;
56975697
pub fn fpathconf(filedes: c_int, name: c_int) -> c_long;
56985698
pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
@@ -5702,9 +5702,7 @@ pub mod funcs {
57025702
pub fn getgroups(ngroups_max: c_int, groups: *mut gid_t)
57035703
-> c_int;
57045704
pub fn getlogin() -> *mut c_char;
5705-
// GNU getopt(3) modifies its arguments despite the
5706-
// char * const [] prototype; see the manpage.
5707-
pub fn getopt(argc: c_int, argv: *mut *mut c_char,
5705+
pub fn getopt(argc: c_int, argv: *mut *const c_char,
57085706
optstr: *const c_char) -> c_int;
57095707
pub fn getpgrp() -> pid_t;
57105708
pub fn getpid() -> pid_t;
@@ -5754,19 +5752,19 @@ pub mod funcs {
57545752
pub fn dup(fd: c_int) -> c_int;
57555753
pub fn dup2(src: c_int, dst: c_int) -> c_int;
57565754
pub fn execv(prog: *const c_char,
5757-
argv: *const *const c_char) -> c_int;
5758-
pub fn execve(prog: *const c_char, argv: *const *const c_char,
5759-
envp: *const *const c_char)
5755+
argv: *mut *const c_char) -> c_int;
5756+
pub fn execve(prog: *const c_char, argv: *mut *const c_char,
5757+
envp: *mut *const c_char)
57605758
-> c_int;
57615759
pub fn execvp(c: *const c_char,
5762-
argv: *const *const c_char) -> c_int;
5760+
argv: *mut *const c_char) -> c_int;
57635761
pub fn fork() -> pid_t;
57645762
pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
57655763
pub fn getegid() -> gid_t;
57665764
pub fn geteuid() -> uid_t;
57675765
pub fn getgid() -> gid_t;
57685766
pub fn getlogin() -> *mut c_char;
5769-
pub fn getopt(argc: c_int, argv: *const *const c_char,
5767+
pub fn getopt(argc: c_int, argv: *mut *const c_char,
57705768
optstr: *const c_char) -> c_int;
57715769
pub fn getuid() -> uid_t;
57725770
pub fn getsid(pid: pid_t) -> pid_t;

branches/try/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)