Skip to content

Commit 4d6086f

Browse files
committed
---
yaml --- r: 277415 b: refs/heads/try c: f242fe3 h: refs/heads/master i: 277413: d2703b4 277411: 066383d 277407: bafd7a0
1 parent 181e466 commit 4d6086f

File tree

25 files changed

+887
-776
lines changed

25 files changed

+887
-776
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: 6dbb0e86aec11050480beb76eade6fb805010ba7
33
refs/heads/snap-stage3: 235d77457d80b549dad3ac36d94f235208a1eafb
4-
refs/heads/try: cf3970aac536ea446a967a246cc3527a11d89655
4+
refs/heads/try: f242fe3c04621dca3aaa3ab288a3812b45633ffd
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc_driver/driver.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,13 +528,19 @@ pub fn phase_2_configure_and_expand(sess: &Session,
528528
middle::recursion_limit::update_recursion_limit(sess, &krate);
529529
});
530530

531-
// these need to be set "early" so that expansion sees `quote` if enabled.
532-
sess.track_errors(|| {
533-
*sess.features.borrow_mut() =
534-
syntax::feature_gate::get_features(&sess.parse_sess.span_diagnostic,
535-
&krate);
531+
time(time_passes, "gated macro checking", || {
532+
sess.track_errors(|| {
533+
let features =
534+
syntax::feature_gate::check_crate_macros(sess.codemap(),
535+
&sess.parse_sess.span_diagnostic,
536+
&krate);
537+
538+
// these need to be set "early" so that expansion sees `quote` if enabled.
539+
*sess.features.borrow_mut() = features;
540+
})
536541
})?;
537542

543+
538544
krate = time(time_passes, "crate injection", || {
539545
syntax::std_inject::maybe_inject_crates_ref(krate, sess.opts.alt_std_name.clone())
540546
});

branches/try/src/librustc_mir/build/block.rs

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
// except according to those terms.
1010

1111
use build::{BlockAnd, BlockAndExtension, Builder};
12+
use build::scope::LoopScope;
1213
use hair::*;
14+
use rustc::middle::region::CodeExtent;
1315
use rustc::mir::repr::*;
1416
use rustc::hir;
17+
use syntax::codemap::Span;
1518

1619
impl<'a,'tcx> Builder<'a,'tcx> {
1720
pub fn ast_block(&mut self,
@@ -44,11 +47,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
4447
StmtKind::Expr { scope, expr } => {
4548
unpack!(block = this.in_scope(scope, block, |this, _| {
4649
let expr = this.hir.mirror(expr);
47-
let expr_span = expr.span;
48-
let temp = this.temp(expr.ty.clone());
49-
unpack!(block = this.into(&temp, block, expr));
50-
unpack!(block = this.build_drop(block, expr_span, temp));
51-
block.unit()
50+
this.stmt_expr(block, expr)
5251
}));
5352
}
5453
StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => {
@@ -83,4 +82,118 @@ impl<'a,'tcx> Builder<'a,'tcx> {
8382
block.unit()
8483
})
8584
}
85+
86+
pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<()> {
87+
let this = self;
88+
let expr_span = expr.span;
89+
let scope_id = this.innermost_scope_id();
90+
// Handle a number of expressions that don't need a destination at all. This
91+
// avoids needing a mountain of temporary `()` variables.
92+
match expr.kind {
93+
ExprKind::Scope { extent, value } => {
94+
let value = this.hir.mirror(value);
95+
this.in_scope(extent, block, |this, _| this.stmt_expr(block, value))
96+
}
97+
ExprKind::Assign { lhs, rhs } => {
98+
let lhs = this.hir.mirror(lhs);
99+
let scope_id = this.innermost_scope_id();
100+
let lhs_span = lhs.span;
101+
let lhs_ty = lhs.ty;
102+
103+
let lhs_needs_drop = this.hir.needs_drop(lhs_ty);
104+
105+
// Note: we evaluate assignments right-to-left. This
106+
// is better for borrowck interaction with overloaded
107+
// operators like x[j] = x[i].
108+
109+
// Generate better code for things that don't need to be
110+
// dropped. We need the temporary as_operand generates
111+
// so we can clean up the data if evaluating the LHS unwinds,
112+
// but if the LHS (and therefore the RHS) doesn't need
113+
// unwinding, we just translate directly to an rvalue instead.
114+
let rhs = if lhs_needs_drop {
115+
let op = unpack!(block = this.as_operand(block, rhs));
116+
Rvalue::Use(op)
117+
} else {
118+
unpack!(block = this.as_rvalue(block, rhs))
119+
};
120+
121+
let lhs = unpack!(block = this.as_lvalue(block, lhs));
122+
unpack!(block = this.build_drop(block, lhs_span, lhs.clone(), lhs_ty));
123+
this.cfg.push_assign(block, scope_id, expr_span, &lhs, rhs);
124+
block.unit()
125+
}
126+
ExprKind::AssignOp { op, lhs, rhs } => {
127+
// FIXME(#28160) there is an interesting semantics
128+
// question raised here -- should we "freeze" the
129+
// value of the lhs here? I'm inclined to think not,
130+
// since it seems closer to the semantics of the
131+
// overloaded version, which takes `&mut self`. This
132+
// only affects weird things like `x += {x += 1; x}`
133+
// -- is that equal to `x + (x + 1)` or `2*(x+1)`?
134+
135+
// As above, RTL.
136+
let rhs = unpack!(block = this.as_operand(block, rhs));
137+
let lhs = unpack!(block = this.as_lvalue(block, lhs));
138+
139+
// we don't have to drop prior contents or anything
140+
// because AssignOp is only legal for Copy types
141+
// (overloaded ops should be desugared into a call).
142+
this.cfg.push_assign(block, scope_id, expr_span, &lhs,
143+
Rvalue::BinaryOp(op,
144+
Operand::Consume(lhs.clone()),
145+
rhs));
146+
147+
block.unit()
148+
}
149+
ExprKind::Continue { label } => {
150+
this.break_or_continue(expr_span, label, block,
151+
|loop_scope| loop_scope.continue_block)
152+
}
153+
ExprKind::Break { label } => {
154+
this.break_or_continue(expr_span, label, block, |loop_scope| {
155+
loop_scope.might_break = true;
156+
loop_scope.break_block
157+
})
158+
}
159+
ExprKind::Return { value } => {
160+
block = match value {
161+
Some(value) => unpack!(this.into(&Lvalue::ReturnPointer, block, value)),
162+
None => {
163+
this.cfg.push_assign_unit(block, scope_id,
164+
expr_span, &Lvalue::ReturnPointer);
165+
block
166+
}
167+
};
168+
let extent = this.extent_of_return_scope();
169+
let return_block = this.return_block();
170+
this.exit_scope(expr_span, extent, block, return_block);
171+
this.cfg.start_new_block().unit()
172+
}
173+
_ => {
174+
let expr_span = expr.span;
175+
let expr_ty = expr.ty;
176+
let temp = this.temp(expr.ty.clone());
177+
unpack!(block = this.into(&temp, block, expr));
178+
unpack!(block = this.build_drop(block, expr_span, temp, expr_ty));
179+
block.unit()
180+
}
181+
}
182+
}
183+
184+
fn break_or_continue<F>(&mut self,
185+
span: Span,
186+
label: Option<CodeExtent>,
187+
block: BasicBlock,
188+
exit_selector: F)
189+
-> BlockAnd<()>
190+
where F: FnOnce(&mut LoopScope) -> BasicBlock
191+
{
192+
let (exit_block, extent) = {
193+
let loop_scope = self.find_loop_scope(span, label);
194+
(exit_selector(loop_scope), loop_scope.extent)
195+
};
196+
self.exit_scope(span, extent, block, exit_block);
197+
self.cfg.start_new_block().unit()
198+
}
86199
}

branches/try/src/librustc_mir/build/expr/into.rs

Lines changed: 9 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@
1212
1313
use build::{BlockAnd, BlockAndExtension, Builder};
1414
use build::expr::category::{Category, RvalueFunc};
15-
use build::scope::LoopScope;
1615
use hair::*;
17-
use rustc::middle::region::CodeExtent;
1816
use rustc::ty;
1917
use rustc::mir::repr::*;
20-
use syntax::codemap::Span;
2118

2219
impl<'a,'tcx> Builder<'a,'tcx> {
2320
/// Compile `expr`, storing the result into `destination`, which
@@ -207,65 +204,6 @@ impl<'a,'tcx> Builder<'a,'tcx> {
207204
}
208205
exit_block.unit()
209206
}
210-
ExprKind::Assign { lhs, rhs } => {
211-
// Note: we evaluate assignments right-to-left. This
212-
// is better for borrowck interaction with overloaded
213-
// operators like x[j] = x[i].
214-
let lhs = this.hir.mirror(lhs);
215-
let lhs_span = lhs.span;
216-
let rhs = unpack!(block = this.as_operand(block, rhs));
217-
let lhs = unpack!(block = this.as_lvalue(block, lhs));
218-
unpack!(block = this.build_drop(block, lhs_span, lhs.clone()));
219-
this.cfg.push_assign(block, scope_id, expr_span, &lhs, Rvalue::Use(rhs));
220-
block.unit()
221-
}
222-
ExprKind::AssignOp { op, lhs, rhs } => {
223-
// FIXME(#28160) there is an interesting semantics
224-
// question raised here -- should we "freeze" the
225-
// value of the lhs here? I'm inclined to think not,
226-
// since it seems closer to the semantics of the
227-
// overloaded version, which takes `&mut self`. This
228-
// only affects weird things like `x += {x += 1; x}`
229-
// -- is that equal to `x + (x + 1)` or `2*(x+1)`?
230-
231-
// As above, RTL.
232-
let rhs = unpack!(block = this.as_operand(block, rhs));
233-
let lhs = unpack!(block = this.as_lvalue(block, lhs));
234-
235-
// we don't have to drop prior contents or anything
236-
// because AssignOp is only legal for Copy types
237-
// (overloaded ops should be desugared into a call).
238-
this.cfg.push_assign(block, scope_id, expr_span, &lhs,
239-
Rvalue::BinaryOp(op,
240-
Operand::Consume(lhs.clone()),
241-
rhs));
242-
243-
block.unit()
244-
}
245-
ExprKind::Continue { label } => {
246-
this.break_or_continue(expr_span, label, block,
247-
|loop_scope| loop_scope.continue_block)
248-
}
249-
ExprKind::Break { label } => {
250-
this.break_or_continue(expr_span, label, block, |loop_scope| {
251-
loop_scope.might_break = true;
252-
loop_scope.break_block
253-
})
254-
}
255-
ExprKind::Return { value } => {
256-
block = match value {
257-
Some(value) => unpack!(this.into(&Lvalue::ReturnPointer, block, value)),
258-
None => {
259-
this.cfg.push_assign_unit(block, scope_id,
260-
expr_span, &Lvalue::ReturnPointer);
261-
block
262-
}
263-
};
264-
let extent = this.extent_of_return_scope();
265-
let return_block = this.return_block();
266-
this.exit_scope(expr_span, extent, block, return_block);
267-
this.cfg.start_new_block().unit()
268-
}
269207
ExprKind::Call { ty, fun, args } => {
270208
let diverges = match ty.sty {
271209
ty::TyFnDef(_, _, ref f) | ty::TyFnPtr(ref f) => {
@@ -294,6 +232,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
294232
success.unit()
295233
}
296234

235+
// These cases don't actually need a destination
236+
ExprKind::Assign { .. } |
237+
ExprKind::AssignOp { .. } |
238+
ExprKind::Continue { .. } |
239+
ExprKind::Break { .. } |
240+
ExprKind::Return {.. } => {
241+
this.stmt_expr(block, expr)
242+
}
243+
297244
// these are the cases that are more naturally handled by some other mode
298245
ExprKind::Unary { .. } |
299246
ExprKind::Binary { .. } |
@@ -327,20 +274,4 @@ impl<'a,'tcx> Builder<'a,'tcx> {
327274
}
328275
}
329276
}
330-
331-
fn break_or_continue<F>(&mut self,
332-
span: Span,
333-
label: Option<CodeExtent>,
334-
block: BasicBlock,
335-
exit_selector: F)
336-
-> BlockAnd<()>
337-
where F: FnOnce(&mut LoopScope) -> BasicBlock
338-
{
339-
let (exit_block, extent) = {
340-
let loop_scope = self.find_loop_scope(span, label);
341-
(exit_selector(loop_scope), loop_scope.extent)
342-
};
343-
self.exit_scope(span, extent, block, exit_block);
344-
self.cfg.start_new_block().unit()
345-
}
346277
}

branches/try/src/librustc_mir/build/expr/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,5 @@ mod as_lvalue;
7575
mod as_rvalue;
7676
mod as_operand;
7777
mod as_temp;
78-
mod category;
78+
pub mod category;
7979
mod into;

branches/try/src/librustc_mir/build/scope.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,11 @@ impl<'a,'tcx> Builder<'a,'tcx> {
497497
pub fn build_drop(&mut self,
498498
block: BasicBlock,
499499
span: Span,
500-
value: Lvalue<'tcx>)
501-
-> BlockAnd<()> {
500+
value: Lvalue<'tcx>,
501+
ty: Ty<'tcx>) -> BlockAnd<()> {
502+
if !self.hir.needs_drop(ty) {
503+
return block.unit();
504+
}
502505
let scope_id = self.innermost_scope_id();
503506
let next_target = self.cfg.start_new_block();
504507
let diverge_target = self.diverge_cleanup();

branches/try/src/librustc_plugin/load.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,27 @@ pub fn load_plugins(sess: &Session,
5151
addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
5252
let mut loader = PluginLoader::new(sess, cstore, crate_name);
5353

54-
// do not report any error now. since crate attributes are
55-
// not touched by expansion, every use of plugin without
56-
// the feature enabled will result in an error later...
57-
if sess.features.borrow().plugin {
58-
for attr in &krate.attrs {
59-
if !attr.check_name("plugin") {
54+
for attr in &krate.attrs {
55+
if !attr.check_name("plugin") {
56+
continue;
57+
}
58+
59+
let plugins = match attr.meta_item_list() {
60+
Some(xs) => xs,
61+
None => {
62+
call_malformed_plugin_attribute(sess, attr.span);
6063
continue;
6164
}
65+
};
6266

63-
let plugins = match attr.meta_item_list() {
64-
Some(xs) => xs,
65-
None => {
66-
call_malformed_plugin_attribute(sess, attr.span);
67-
continue;
68-
}
69-
};
70-
71-
for plugin in plugins {
72-
if plugin.value_str().is_some() {
73-
call_malformed_plugin_attribute(sess, attr.span);
74-
continue;
75-
}
76-
77-
let args = plugin.meta_item_list().map(ToOwned::to_owned).unwrap_or_default();
78-
loader.load_plugin(plugin.span, &plugin.name(), args);
67+
for plugin in plugins {
68+
if plugin.value_str().is_some() {
69+
call_malformed_plugin_attribute(sess, attr.span);
70+
continue;
7971
}
72+
73+
let args = plugin.meta_item_list().map(ToOwned::to_owned).unwrap_or_default();
74+
loader.load_plugin(plugin.span, &plugin.name(), args);
8075
}
8176
}
8277

0 commit comments

Comments
 (0)