Skip to content

Commit 6c09421

Browse files
committed
---
yaml --- r: 101979 b: refs/heads/master c: 111e092 h: refs/heads/master i: 101977: 5b2b824 101975: 7298be3 v: v3
1 parent 59124f1 commit 6c09421

File tree

17 files changed

+122
-74
lines changed

17 files changed

+122
-74
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 99f838012b58f869dff5292f83a9e9628a8ec436
2+
refs/heads/master: 111e092481ec8a6e958f3f4d3e13eaccd844d99e
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 6e7f170fedd3c526a643c0b2d13863acd982be02
55
refs/heads/try: a97642026c18a624ff6ea01075dd9550f8ed07ff

trunk/src/doc/tutorial.md

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,24 +1750,6 @@ closures, but they also own them: that is, no other code can access
17501750
them. Owned closures are used in concurrent code, particularly
17511751
for spawning [tasks][tasks].
17521752
1753-
Closures can be used to spawn tasks.
1754-
A practical example of this pattern is found when using the `spawn` function,
1755-
which starts a new task.
1756-
1757-
~~~~
1758-
use std::task::spawn;
1759-
1760-
// proc is the closure which will be spawned.
1761-
spawn(proc() {
1762-
debug!("I'm a new task")
1763-
});
1764-
~~~~
1765-
1766-
> ***Note:*** If you want to see the output of `debug!` statements, you will need to turn on
1767-
> `debug!` logging. To enable `debug!` logging, set the RUST_LOG environment
1768-
> variable to the name of your crate, which, for a file named `foo.rs`, will be
1769-
> `foo` (e.g., with bash, `export RUST_LOG=foo`).
1770-
17711753
## Closure compatibility
17721754
17731755
Rust closures have a convenient subtyping property: you can pass any kind of
@@ -1789,6 +1771,45 @@ call_twice(function);
17891771
> in small ways. At the moment they can be unsound in some
17901772
> scenarios, particularly with non-copyable types.
17911773
1774+
## Do syntax
1775+
1776+
The `do` expression makes it easier to call functions that take procedures
1777+
as arguments.
1778+
1779+
Consider this function that takes a procedure:
1780+
1781+
~~~~
1782+
fn call_it(op: proc(v: int)) {
1783+
op(10)
1784+
}
1785+
~~~~
1786+
1787+
As a caller, if we use a closure to provide the final operator
1788+
argument, we can write it in a way that has a pleasant, block-like
1789+
structure.
1790+
1791+
~~~~
1792+
# fn call_it(op: proc(v: int)) { }
1793+
call_it(proc(n) {
1794+
println!("{}", n);
1795+
});
1796+
~~~~
1797+
1798+
A practical example of this pattern is found when using the `spawn` function,
1799+
which starts a new task.
1800+
1801+
~~~~
1802+
use std::task::spawn;
1803+
spawn(proc() {
1804+
debug!("I'm a new task")
1805+
});
1806+
~~~~
1807+
1808+
If you want to see the output of `debug!` statements, you will need to turn on
1809+
`debug!` logging. To enable `debug!` logging, set the RUST_LOG environment
1810+
variable to the name of your crate, which, for a file named `foo.rs`, will be
1811+
`foo` (e.g., with bash, `export RUST_LOG=foo`).
1812+
17921813
# Methods
17931814
17941815
Methods are like functions except that they always begin with a special argument,

trunk/src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4142,7 +4142,7 @@ pub fn enum_variants(cx: ctxt, id: ast::DefId) -> @~[@VariantInfo] {
41424142
.span_err(e.span,
41434143
format!("expected \
41444144
constant: {}",
4145-
(*err)));
4145+
*err));
41464146
}
41474147
},
41484148
None => {}

trunk/src/librustc/middle/typeck/check/method.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,15 +1303,15 @@ impl<'a> LookupContext<'a> {
13031303
self.tcx().sess.span_note(
13041304
span,
13051305
format!("candidate \\#{} is `{}`",
1306-
(idx+1u),
1306+
idx+1u,
13071307
ty::item_path_str(self.tcx(), did)));
13081308
}
13091309

13101310
fn report_param_candidate(&self, idx: uint, did: DefId) {
13111311
self.tcx().sess.span_note(
13121312
self.expr.span,
13131313
format!("candidate \\#{} derives from the bound `{}`",
1314-
(idx+1u),
1314+
idx+1u,
13151315
ty::item_path_str(self.tcx(), did)));
13161316
}
13171317

@@ -1320,7 +1320,7 @@ impl<'a> LookupContext<'a> {
13201320
self.expr.span,
13211321
format!("candidate \\#{} derives from the type of the receiver, \
13221322
which is the trait `{}`",
1323-
(idx+1u),
1323+
idx+1u,
13241324
ty::item_path_str(self.tcx(), did)));
13251325
}
13261326

trunk/src/librustc/middle/typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3551,7 +3551,7 @@ pub fn check_enum_variants(ccx: @CrateCtxt,
35513551
ccx.tcx.sess.span_err(e.span, "expected signed integer constant");
35523552
}
35533553
Err(ref err) => {
3554-
ccx.tcx.sess.span_err(e.span, format!("expected constant: {}", (*err)));
3554+
ccx.tcx.sess.span_err(e.span, format!("expected constant: {}", *err));
35553555
}
35563556
}
35573557
},

trunk/src/librustc/util/ppaux.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ pub fn note_and_explain_region(cx: ctxt,
4949
(ref str, Some(span)) => {
5050
cx.sess.span_note(
5151
span,
52-
format!("{}{}{}", prefix, (*str), suffix));
52+
format!("{}{}{}", prefix, *str, suffix));
5353
}
5454
(ref str, None) => {
5555
cx.sess.note(
56-
format!("{}{}{}", prefix, (*str), suffix));
56+
format!("{}{}{}", prefix, *str, suffix));
5757
}
5858
}
5959
}

trunk/src/libsyntax/ext/asm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
6464
"inline assembly must be a string literal.") {
6565
Some((s, st)) => (s, st),
6666
// let compilation continue
67-
None => return MacResult::dummy_expr(sp),
67+
None => return MacResult::dummy_expr(),
6868
};
6969
asm = s;
7070
asm_str_style = Some(style);

trunk/src/libsyntax/ext/base.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ pub trait AnyMacro {
101101
fn make_stmt(&self) -> @ast::Stmt;
102102
}
103103

104-
105104
pub enum MacResult {
106105
MRExpr(@ast::Expr),
107106
MRItem(@ast::Item),
@@ -113,15 +112,10 @@ impl MacResult {
113112
/// type signatures after emitting a non-fatal error (which stop
114113
/// compilation well before the validity (or otherwise)) of the
115114
/// expression are checked.
116-
pub fn raw_dummy_expr(sp: codemap::Span) -> @ast::Expr {
117-
@ast::Expr {
118-
id: ast::DUMMY_NODE_ID,
119-
node: ast::ExprLogLevel,
120-
span: sp
121-
}
122-
}
123-
pub fn dummy_expr(sp: codemap::Span) -> MacResult {
124-
MRExpr(MacResult::raw_dummy_expr(sp))
115+
pub fn dummy_expr() -> MacResult {
116+
MRExpr(@ast::Expr {
117+
id: ast::DUMMY_NODE_ID, node: ast::ExprLogLevel, span: codemap::DUMMY_SP
118+
})
125119
}
126120
}
127121

trunk/src/libsyntax/ext/bytes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::char;
2121
pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult {
2222
// Gather all argument expressions
2323
let exprs = match get_exprs_from_tts(cx, sp, tts) {
24-
None => return MacResult::dummy_expr(sp),
24+
None => return MacResult::dummy_expr(),
2525
Some(e) => e,
2626
};
2727
let mut bytes = ~[];

trunk/src/libsyntax/ext/concat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
2121
tts: &[ast::TokenTree]) -> base::MacResult {
2222
let es = match base::get_exprs_from_tts(cx, sp, tts) {
2323
Some(e) => e,
24-
None => return base::MacResult::dummy_expr(sp)
24+
None => return base::MacResult::dummy_expr()
2525
};
2626
let mut accumulator = ~"";
2727
for e in es.move_iter() {

trunk/src/libsyntax/ext/concat_idents.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
2525
ast::TTTok(_, token::COMMA) => (),
2626
_ => {
2727
cx.span_err(sp, "concat_idents! expecting comma.");
28-
return MacResult::dummy_expr(sp);
28+
return MacResult::dummy_expr();
2929
}
3030
}
3131
} else {
@@ -35,7 +35,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
3535
}
3636
_ => {
3737
cx.span_err(sp, "concat_idents! requires ident args.");
38-
return MacResult::dummy_expr(sp);
38+
return MacResult::dummy_expr();
3939
}
4040
}
4141
}

trunk/src/libsyntax/ext/env.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use std::os;
2626
pub fn expand_option_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
2727
-> base::MacResult {
2828
let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
29-
None => return MacResult::dummy_expr(sp),
29+
None => return MacResult::dummy_expr(),
3030
Some(v) => v
3131
};
3232

@@ -42,14 +42,14 @@ pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
4242
let exprs = match get_exprs_from_tts(cx, sp, tts) {
4343
Some([]) => {
4444
cx.span_err(sp, "env! takes 1 or 2 arguments");
45-
return MacResult::dummy_expr(sp);
45+
return MacResult::dummy_expr();
4646
}
47-
None => return MacResult::dummy_expr(sp),
47+
None => return MacResult::dummy_expr(),
4848
Some(exprs) => exprs
4949
};
5050

5151
let var = match expr_to_str(cx, exprs[0], "expected string literal") {
52-
None => return MacResult::dummy_expr(sp),
52+
None => return MacResult::dummy_expr(),
5353
Some((v, _style)) => v
5454
};
5555
let msg = match exprs.len() {
@@ -60,13 +60,13 @@ pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
6060
}
6161
2 => {
6262
match expr_to_str(cx, exprs[1], "expected string literal") {
63-
None => return MacResult::dummy_expr(sp),
63+
None => return MacResult::dummy_expr(),
6464
Some((s, _style)) => s
6565
}
6666
}
6767
_ => {
6868
cx.span_err(sp, "env! takes 1 or 2 arguments");
69-
return MacResult::dummy_expr(sp);
69+
return MacResult::dummy_expr();
7070
}
7171
};
7272

trunk/src/libsyntax/ext/expand.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
5151
format!("expected macro name without module \
5252
separators"));
5353
// let compilation continue
54-
return MacResult::raw_dummy_expr(e.span);
54+
return e;
5555
}
5656
let extname = pth.segments[0].identifier;
5757
let extnamestr = token::get_ident(extname);
@@ -64,7 +64,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
6464
extnamestr.get()));
6565

6666
// let compilation continue
67-
return MacResult::raw_dummy_expr(e.span);
67+
return e;
6868
}
6969
Some(&NormalTT(ref expandfun, exp_span)) => {
7070
fld.cx.bt_push(ExpnInfo {
@@ -98,7 +98,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
9898
extnamestr.get()
9999
)
100100
);
101-
return MacResult::raw_dummy_expr(e.span);
101+
return e;
102102
}
103103
};
104104

@@ -111,7 +111,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
111111
format!("'{}' is not a tt-style macro",
112112
extnamestr.get())
113113
);
114-
return MacResult::raw_dummy_expr(e.span);
114+
return e;
115115
}
116116
};
117117

trunk/src/libsyntax/ext/format.rs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,8 @@ impl<'a> Context<'a> {
607607
let mut lets = ~[];
608608
let mut locals = ~[];
609609
let mut names = vec::from_fn(self.name_positions.len(), |_| None);
610+
let mut pats = ~[];
611+
let mut heads = ~[];
610612

611613
// First, declare all of our methods that are statics
612614
for &method in self.method_statics.iter() {
@@ -653,8 +655,8 @@ impl<'a> Context<'a> {
653655
if self.arg_types[i].is_none() { continue } // error already generated
654656

655657
let name = self.ecx.ident_of(format!("__arg{}", i));
656-
let e = self.ecx.expr_addr_of(e.span, e);
657-
lets.push(self.ecx.stmt_let(e.span, false, name, e));
658+
pats.push(self.ecx.pat_ident(e.span, name));
659+
heads.push(self.ecx.expr_addr_of(e.span, e));
658660
locals.push(self.format_arg(e.span, Exact(i),
659661
self.ecx.expr_ident(e.span, name)));
660662
}
@@ -664,8 +666,8 @@ impl<'a> Context<'a> {
664666
}
665667

666668
let lname = self.ecx.ident_of(format!("__arg{}", *name));
667-
let e = self.ecx.expr_addr_of(e.span, e);
668-
lets.push(self.ecx.stmt_let(e.span, false, lname, e));
669+
pats.push(self.ecx.pat_ident(e.span, lname));
670+
heads.push(self.ecx.expr_addr_of(e.span, e));
669671
names[*self.name_positions.get(name)] =
670672
Some(self.format_arg(e.span,
671673
Named((*name).clone()),
@@ -706,8 +708,40 @@ impl<'a> Context<'a> {
706708
let res = self.ecx.expr_ident(self.fmtsp, resname);
707709
let result = self.ecx.expr_call(extra.span, extra, ~[
708710
self.ecx.expr_addr_of(extra.span, res)]);
709-
self.ecx.expr_block(self.ecx.block(self.fmtsp, lets,
710-
Some(result)))
711+
let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets,
712+
Some(result)));
713+
714+
// Constructs an AST equivalent to:
715+
//
716+
// match (&arg0, &arg1) {
717+
// (tmp0, tmp1) => body
718+
// }
719+
//
720+
// It was:
721+
//
722+
// let tmp0 = &arg0;
723+
// let tmp1 = &arg1;
724+
// body
725+
//
726+
// Because of #11585 the new temporary lifetime rule, the enclosing
727+
// statements for these temporaries become the let's themselves.
728+
// If one or more of them are RefCell's, RefCell borrow() will also
729+
// end there; they don't last long enough for body to use them. The
730+
// match expression solves the scope problem.
731+
//
732+
// Note, it may also very well be transformed to:
733+
//
734+
// match arg0 {
735+
// ref tmp0 => {
736+
// match arg1 => {
737+
// ref tmp1 => body } } }
738+
//
739+
// But the nested match expression is proved to perform not as well
740+
// as series of let's; the first approach does.
741+
let pat = self.ecx.pat(self.fmtsp, ast::PatTup(pats));
742+
let arm = self.ecx.arm(self.fmtsp, ~[pat], body);
743+
let head = self.ecx.expr(self.fmtsp, ast::ExprTup(heads));
744+
self.ecx.expr_match(self.fmtsp, head, ~[arm])
711745
}
712746

713747
fn format_arg(&self, sp: Span, argno: Position, arg: @ast::Expr)
@@ -811,7 +845,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
811845
expr,
812846
"format argument must be a string literal.") {
813847
Some((fmt, _)) => fmt,
814-
None => return MacResult::raw_dummy_expr(sp)
848+
None => return efmt
815849
};
816850

817851
let mut parser = parse::Parser::new(fmt.get());
@@ -829,7 +863,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
829863
match parser.errors.shift() {
830864
Some(error) => {
831865
cx.ecx.span_err(efmt.span, "invalid format string: " + error);
832-
return MacResult::raw_dummy_expr(sp);
866+
return efmt;
833867
}
834868
None => {}
835869
}

0 commit comments

Comments
 (0)