auto merge of #12267 : alexcrichton/rust/rollup, r=alexcrichton

The last commit has the closed PRs
This commit is contained in:
bors 2014-02-14 12:21:51 -08:00
commit 3f717bbe96
49 changed files with 415 additions and 289 deletions

View File

@ -60,9 +60,9 @@ DEPS_extra := std term sync serialize getopts collections
DEPS_green := std native:context_switch
DEPS_rustuv := std native:uv native:uv_support
DEPS_native := std
DEPS_syntax := std extra term serialize collections
DEPS_syntax := std term serialize collections
DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \
collections
collections extra
DEPS_rustdoc := rustc native:sundown serialize sync getopts collections
DEPS_flate := std native:miniz
DEPS_arena := std collections

View File

@ -236,7 +236,7 @@ COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS)
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS)
@$$(call E, make: compiler-rt)
$$(Q)$$(MAKE) -C "$(S)src/compiler-rt" \
ProjSrcRoot="$(S)src/compiler-rt" \

View File

@ -30,6 +30,8 @@ pub struct TestProps {
check_lines: ~[~str],
// Flag to force a crate to be built with the host architecture
force_host: bool,
// Check stdout for error-pattern output as well as stderr
check_stdout: bool,
}
// Load any test directives embedded in the file
@ -42,6 +44,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
let mut debugger_cmds = ~[];
let mut check_lines = ~[];
let mut force_host = false;
let mut check_stdout = false;
iter_header(testfile, |ln| {
match parse_error_pattern(ln) {
Some(ep) => error_patterns.push(ep),
@ -60,6 +63,10 @@ pub fn load_props(testfile: &Path) -> TestProps {
force_host = parse_force_host(ln);
}
if !check_stdout {
check_stdout = parse_check_stdout(ln);
}
match parse_aux_build(ln) {
Some(ab) => { aux_builds.push(ab); }
None => {}
@ -91,6 +98,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
debugger_cmds: debugger_cmds,
check_lines: check_lines,
force_host: force_host,
check_stdout: check_stdout,
};
}
@ -155,6 +163,10 @@ fn parse_force_host(line: &str) -> bool {
parse_name_directive(line, "force-host")
}
fn parse_check_stdout(line: &str) -> bool {
parse_name_directive(line, "check-stdout")
}
fn parse_exec_env(line: &str) -> Option<(~str, ~str)> {
parse_name_value_directive(line, ~"exec-env").map(|nv| {
// nv is either FOO or FOO=BAR

View File

@ -452,7 +452,12 @@ fn check_error_patterns(props: &TestProps,
let mut next_err_idx = 0u;
let mut next_err_pat = &props.error_patterns[next_err_idx];
let mut done = false;
for line in ProcRes.stderr.lines() {
let output_to_check = if props.check_stdout {
ProcRes.stdout + ProcRes.stderr
} else {
ProcRes.stderr.clone()
};
for line in output_to_check.lines() {
if line.contains(*next_err_pat) {
debug!("found error pattern {}", *next_err_pat);
next_err_idx += 1u;

View File

@ -57,8 +57,8 @@ they don't contain references to names that aren't actually defined.
# Getting started
> **NOTE**: The tarball and installer links are for the most recent release,
> not master.
> **WARNING**: The tarball and installer links are for the most recent
> release, not master. To use master, you **must** build from [git].
The Rust compiler currently must be built from a [tarball] or [git], unless
you are on Windows, in which case using the [installer][win-exe] is

View File

@ -1561,6 +1561,7 @@ mod tests {
let mut bitv = 0 as uint;
b.iter(|| {
bitv |= (1 << ((r.next_u32() as uint) % uint::BITS));
&bitv
})
}
@ -1570,6 +1571,7 @@ mod tests {
let mut bitv = SmallBitv::new(uint::BITS);
b.iter(|| {
bitv.set((r.next_u32() as uint) % uint::BITS, true);
&bitv
})
}
@ -1579,6 +1581,7 @@ mod tests {
let mut bitv = BigBitv::new(~[0]);
b.iter(|| {
bitv.set((r.next_u32() as uint) % uint::BITS, true);
&bitv
})
}
@ -1590,6 +1593,7 @@ mod tests {
let mut bitv = BigBitv::new(storage);
b.iter(|| {
bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
&bitv
})
}
@ -1599,6 +1603,7 @@ mod tests {
let mut bitv = Bitv::new(BENCH_BITS, false);
b.iter(|| {
bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
&bitv
})
}
@ -1608,6 +1613,7 @@ mod tests {
let mut bitv = Bitv::new(uint::BITS, false);
b.iter(|| {
bitv.set((r.next_u32() as uint) % uint::BITS, true);
&bitv
})
}
@ -1617,6 +1623,7 @@ mod tests {
let mut bitv = BitvSet::new();
b.iter(|| {
bitv.insert((r.next_u32() as uint) % uint::BITS);
&bitv
})
}
@ -1626,6 +1633,7 @@ mod tests {
let mut bitv = BitvSet::new();
b.iter(|| {
bitv.insert((r.next_u32() as uint) % BENCH_BITS);
&bitv
})
}

View File

@ -115,8 +115,9 @@ pub mod bench {
// measure
let mut i = 0;
bh.iter(|| {
map.find(&i);
let x = map.find(&i);
i = (i + 1) % n;
x
})
}
}

View File

@ -26,12 +26,11 @@ use stats;
use time::precise_time_ns;
use collections::TreeMap;
use std::clone::Clone;
use std::cmp;
use std::io;
use std::io::File;
use std::io::Writer;
use std::io::{File, PortReader, ChanWriter};
use std::io::stdio::StdWriter;
use std::str;
use std::task;
use std::to_str::ToStr;
use std::f64;
@ -358,7 +357,7 @@ struct ConsoleTestState<T> {
ignored: uint,
measured: uint,
metrics: MetricMap,
failures: ~[TestDesc],
failures: ~[(TestDesc, ~[u8])],
max_name_len: uint, // number of columns to fill when aligning names
}
@ -498,9 +497,23 @@ impl<T: Writer> ConsoleTestState<T> {
pub fn write_failures(&mut self) -> io::IoResult<()> {
if_ok!(self.write_plain("\nfailures:\n"));
let mut failures = ~[];
for f in self.failures.iter() {
let mut fail_out = ~"";
for &(ref f, ref stdout) in self.failures.iter() {
failures.push(f.name.to_str());
if stdout.len() > 0 {
fail_out.push_str(format!("---- {} stdout ----\n\t",
f.name.to_str()));
let output = str::from_utf8_lossy(*stdout);
fail_out.push_str(output.as_slice().replace("\n", "\n\t"));
fail_out.push_str("\n");
}
}
if fail_out.len() > 0 {
if_ok!(self.write_plain("\n"));
if_ok!(self.write_plain(fail_out));
}
if_ok!(self.write_plain("\nfailures:\n"));
failures.sort();
for name in failures.iter() {
if_ok!(self.write_plain(format!(" {}\n", name.to_str())));
@ -632,7 +645,7 @@ pub fn run_tests_console(opts: &TestOpts,
match (*event).clone() {
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
TeWait(ref test, padding) => st.write_test_start(test, padding),
TeResult(test, result) => {
TeResult(test, result, stdout) => {
if_ok!(st.write_log(&test, &result));
if_ok!(st.write_result(&result));
match result {
@ -655,7 +668,7 @@ pub fn run_tests_console(opts: &TestOpts,
}
TrFailed => {
st.failed += 1;
st.failures.push(test);
st.failures.push((test, stdout));
}
}
Ok(())
@ -717,17 +730,17 @@ fn should_sort_failures_before_printing_them() {
measured: 0u,
max_name_len: 10u,
metrics: MetricMap::new(),
failures: ~[test_b, test_a]
failures: ~[(test_b, ~[]), (test_a, ~[])]
};
st.write_failures().unwrap();
let s = match st.out {
Raw(ref m) => str::from_utf8(m.get_ref()).unwrap(),
Raw(ref m) => str::from_utf8_lossy(m.get_ref()),
Pretty(_) => unreachable!()
};
let apos = s.find_str("a").unwrap();
let bpos = s.find_str("b").unwrap();
let apos = s.as_slice().find_str("a").unwrap();
let bpos = s.as_slice().find_str("b").unwrap();
assert!(apos < bpos);
}
@ -737,11 +750,10 @@ fn use_color() -> bool { return get_concurrency() == 1; }
enum TestEvent {
TeFiltered(~[TestDesc]),
TeWait(TestDesc, NamePadding),
TeResult(TestDesc, TestResult),
TeResult(TestDesc, TestResult, ~[u8] /* stdout */),
}
/// The message sent to the test monitor from the individual runners.
pub type MonitorMsg = (TestDesc, TestResult);
pub type MonitorMsg = (TestDesc, TestResult, ~[u8] /* stdout */);
fn run_tests(opts: &TestOpts,
tests: ~[TestDescAndFn],
@ -783,11 +795,11 @@ fn run_tests(opts: &TestOpts,
pending += 1;
}
let (desc, result) = p.recv();
let (desc, result, stdout) = p.recv();
if concurrency != 1 {
if_ok!(callback(TeWait(desc.clone(), PadNone)));
}
if_ok!(callback(TeResult(desc, result)));
if_ok!(callback(TeResult(desc, result, stdout)));
pending -= 1;
}
@ -796,8 +808,8 @@ fn run_tests(opts: &TestOpts,
for b in filtered_benchs_and_metrics.move_iter() {
if_ok!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
run_test(!opts.run_benchmarks, b, ch.clone());
let (test, result) = p.recv();
if_ok!(callback(TeResult(test, result)));
let (test, result, stdout) = p.recv();
if_ok!(callback(TeResult(test, result, stdout)));
}
Ok(())
}
@ -884,7 +896,7 @@ pub fn run_test(force_ignore: bool,
let TestDescAndFn {desc, testfn} = test;
if force_ignore || desc.ignore {
monitor_ch.send((desc, TrIgnored));
monitor_ch.send((desc, TrIgnored, ~[]));
return;
}
@ -893,40 +905,47 @@ pub fn run_test(force_ignore: bool,
testfn: proc()) {
spawn(proc() {
let mut task = task::task();
task.name(match desc.name {
DynTestName(ref name) => name.to_owned().into_maybe_owned(),
StaticTestName(name) => name.into_maybe_owned()
});
let (p, c) = Chan::new();
let mut reader = PortReader::new(p);
let stdout = ChanWriter::new(c.clone());
let stderr = ChanWriter::new(c);
match desc.name {
DynTestName(ref name) => task.name(name.clone()),
StaticTestName(name) => task.name(name),
}
task.opts.stdout = Some(~stdout as ~Writer);
task.opts.stderr = Some(~stderr as ~Writer);
let result_future = task.future_result();
task.spawn(testfn);
let stdout = reader.read_to_end().unwrap();
let task_result = result_future.recv();
let test_result = calc_result(&desc, task_result.is_ok());
monitor_ch.send((desc.clone(), test_result));
});
monitor_ch.send((desc.clone(), test_result, stdout));
})
}
match testfn {
DynBenchFn(bencher) => {
let bs = ::test::bench::benchmark(|harness| bencher.run(harness));
monitor_ch.send((desc, TrBench(bs)));
monitor_ch.send((desc, TrBench(bs), ~[]));
return;
}
StaticBenchFn(benchfn) => {
let bs = ::test::bench::benchmark(|harness| benchfn(harness));
monitor_ch.send((desc, TrBench(bs)));
monitor_ch.send((desc, TrBench(bs), ~[]));
return;
}
DynMetricFn(f) => {
let mut mm = MetricMap::new();
f(&mut mm);
monitor_ch.send((desc, TrMetrics(mm)));
monitor_ch.send((desc, TrMetrics(mm), ~[]));
return;
}
StaticMetricFn(f) => {
let mut mm = MetricMap::new();
f(&mut mm);
monitor_ch.send((desc, TrMetrics(mm)));
monitor_ch.send((desc, TrMetrics(mm), ~[]));
return;
}
DynTestFn(f) => run_test_inner(desc, monitor_ch, f),
@ -1264,7 +1283,7 @@ mod tests {
};
let (p, ch) = Chan::new();
run_test(false, desc, ch);
let (_, res) = p.recv();
let (_, res, _) = p.recv();
assert!(res != TrOk);
}
@ -1281,7 +1300,7 @@ mod tests {
};
let (p, ch) = Chan::new();
run_test(false, desc, ch);
let (_, res) = p.recv();
let (_, res, _) = p.recv();
assert_eq!(res, TrIgnored);
}
@ -1298,7 +1317,7 @@ mod tests {
};
let (p, ch) = Chan::new();
run_test(false, desc, ch);
let (_, res) = p.recv();
let (_, res, _) = p.recv();
assert_eq!(res, TrOk);
}
@ -1315,7 +1334,7 @@ mod tests {
};
let (p, ch) = Chan::new();
run_test(false, desc, ch);
let (_, res) = p.recv();
let (_, res, _) = p.recv();
assert_eq!(res, TrFailed);
}

View File

@ -1,4 +1,4 @@
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -139,10 +139,19 @@ fn encode_inner(s: &str, full_url: bool) -> ~str {
}
/**
* Encodes a URI by replacing reserved characters with percent encoded
* Encodes a URI by replacing reserved characters with percent-encoded
* character sequences.
*
* This function is compliant with RFC 3986.
*
* # Example
*
* ```rust
* use extra::url::encode;
*
* let url = encode(&"https://example.com/Rust (programming language)");
* println!("{}", url); // https://example.com/Rust%20(programming%20language)
* ```
*/
pub fn encode(s: &str) -> ~str {
encode_inner(s, true)
@ -206,9 +215,18 @@ fn decode_inner(s: &str, full_url: bool) -> ~str {
}
/**
* Decode a string encoded with percent encoding.
* Decodes a percent-encoded string representing a URI.
*
* This will only decode escape sequences generated by encode.
* This will only decode escape sequences generated by `encode`.
*
* # Example
*
* ```rust
* use extra::url::decode;
*
* let url = decode(&"https://example.com/Rust%20(programming%20language)");
* println!("{}", url); // https://example.com/Rust (programming language)
* ```
*/
pub fn decode(s: &str) -> ~str {
decode_inner(s, true)
@ -410,7 +428,23 @@ pub fn query_to_str(query: &Query) -> ~str {
return strvec.connect("&");
}
// returns the scheme and the rest of the url, or a parsing error
/**
* Returns a tuple of the URI scheme and the rest of the URI, or a parsing error.
*
* Does not include the separating `:` character.
*
* # Example
*
* ```rust
* use extra::url::get_scheme;
*
* let scheme = match get_scheme("https://example.com/") {
* Ok((sch, _)) => sch,
* Err(_) => ~"(None)",
* };
* println!("Scheme in use: {}.", scheme); // Scheme in use: https.
* ```
*/
pub fn get_scheme(rawurl: &str) -> Result<(~str, ~str), ~str> {
for (i,c) in rawurl.chars().enumerate() {
match c {
@ -654,18 +688,16 @@ fn get_query_fragment(rawurl: &str) ->
}
/**
* Parse a `str` to a `url`
* Parses a URL, converting it from a string to `Url` representation.
*
* # Arguments
*
* `rawurl` - a string representing a full url, including scheme.
* `rawurl` - a string representing the full URL, including scheme.
*
* # Returns
*
* a `url` that contains the parsed representation of the url.
*
* A `Url` struct type representing the URL.
*/
pub fn from_str(rawurl: &str) -> Result<Url, ~str> {
// scheme
let (scheme, rest) = match get_scheme(rawurl) {
@ -705,19 +737,18 @@ impl FromStr for Url {
}
/**
* Format a `url` as a string
* Converts a URL from `Url` to string representation.
*
* # Arguments
*
* `url` - a url.
* `url` - a URL.
*
* # Returns
*
* a `str` that contains the formatted url. Note that this will usually
* be an inverse of `from_str` but might strip out unneeded separators.
* A string that contains the formatted URL. Note that this will usually
* be an inverse of `from_str` but might strip out unneeded separators;
* for example, "http://somehost.com?", when parsed and formatted, will
* result in just "http://somehost.com".
*
*/
pub fn to_str(url: &Url) -> ~str {
let user = match url.user {

View File

@ -831,10 +831,10 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
ast::ExprAssignOp(_, _, dest, _) => {
this.check_assignment(dest);
}
ast::ExprCall(f, ref args, _) => {
ast::ExprCall(f, ref args) => {
this.check_call(expr, Some(f), f.id, f.span, *args);
}
ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
ast::ExprMethodCall(callee_id, _, _, ref args) => {
this.check_call(expr, None, callee_id, expr.span, *args);
}
ast::ExprIndex(callee_id, _, rval) |

View File

@ -351,11 +351,11 @@ impl CFGBuilder {
self.straightline(expr, pred, *elems)
}
ast::ExprCall(func, ref args, _) => {
ast::ExprCall(func, ref args) => {
self.call(expr, pred, func, *args)
}
ast::ExprMethodCall(_, _, _, ref args, _) => {
ast::ExprMethodCall(_, _, _, ref args) => {
self.call(expr, pred, args[0], args.slice_from(1))
}

View File

@ -160,7 +160,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
}
}
}
ExprCall(callee, _, NoSugar) => {
ExprCall(callee, _) => {
let def_map = def_map.borrow();
match def_map.get().find(&callee.id) {
Some(&DefStruct(..)) => {} // OK.

View File

@ -577,12 +577,12 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
self.walk_opt_expr(with_expr, in_out, loop_scopes);
}
ast::ExprCall(f, ref args, _) => {
ast::ExprCall(f, ref args) => {
self.walk_expr(f, in_out, loop_scopes);
self.walk_call(f.id, expr.id, *args, in_out, loop_scopes);
}
ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
ast::ExprMethodCall(callee_id, _, _, ref args) => {
self.walk_call(callee_id, expr.id, *args, in_out, loop_scopes);
}

View File

@ -120,7 +120,7 @@ impl Visitor<()> for EffectCheckVisitor {
fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
match expr.node {
ast::ExprMethodCall(callee_id, _, _, _, _) => {
ast::ExprMethodCall(callee_id, _, _, _) => {
let base_type = ty::node_id_to_type(self.tcx, callee_id);
debug!("effect: method call case, base type is {}",
ppaux::ty_to_str(self.tcx, base_type));
@ -129,7 +129,7 @@ impl Visitor<()> for EffectCheckVisitor {
"invocation of unsafe method")
}
}
ast::ExprCall(base, _, _) => {
ast::ExprCall(base, _) => {
let base_type = ty::node_id_to_type(self.tcx, base.id);
debug!("effect: call case, base type is {}",
ppaux::ty_to_str(self.tcx, base_type));

View File

@ -1205,7 +1205,7 @@ impl Liveness {
})
}
ExprCall(f, ref args, _) => {
ExprCall(f, ref args) => {
// calling a fn with bot return type means that the fn
// will fail, and hence the successors can be ignored
let t_ret = ty::ty_fn_ret(ty::expr_ty(self.tcx, f));
@ -1215,7 +1215,7 @@ impl Liveness {
self.propagate_through_expr(f, succ)
}
ExprMethodCall(callee_id, _, _, ref args, _) => {
ExprMethodCall(callee_id, _, _, ref args) => {
// calling a method with bot return type means that the method
// will fail, and hence the successors can be ignored
let t_ret = ty::ty_fn_ret(ty::node_id_to_type(self.tcx, callee_id));

View File

@ -382,7 +382,7 @@ impl VisitContext {
}
}
ExprCall(callee, ref args, _) => { // callee(args)
ExprCall(callee, ref args) => { // callee(args)
// Figure out whether the called function is consumed.
let mode = match ty::get(ty::expr_ty(self.tcx, callee)).sty {
ty::ty_closure(ref cty) => {
@ -412,7 +412,7 @@ impl VisitContext {
self.use_fn_args(callee.id, *args);
}
ExprMethodCall(callee_id, _, _, ref args, _) => { // callee.m(args)
ExprMethodCall(callee_id, _, _, ref args) => { // callee.m(args)
self.use_fn_args(callee_id, *args);
}

View File

@ -705,7 +705,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
_ => {}
}
}
ast::ExprMethodCall(_, ident, _, ref args, _) => {
ast::ExprMethodCall(_, ident, _, ref args) => {
// see above
let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
match ty::get(t).sty {

View File

@ -5221,7 +5221,7 @@ impl Resolver {
let traits = self.search_for_traits_containing_method(ident);
self.trait_map.insert(expr.id, @RefCell::new(traits));
}
ExprMethodCall(_, ident, _, _, _) => {
ExprMethodCall(_, ident, _, _) => {
debug!("(recording candidate traits for expr) recording \
traits for {}",
expr.id);

View File

@ -647,7 +647,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
}
}
}
ast::ExprCall(callee, ref args, _) => {
ast::ExprCall(callee, ref args) => {
let tcx = cx.tcx;
let opt_def = {
let def_map = tcx.def_map.borrow();

View File

@ -2624,7 +2624,7 @@ fn populate_scope_map(cx: &CrateContext,
})
}
ast::ExprCall(fn_exp, ref args, _) => {
ast::ExprCall(fn_exp, ref args) => {
walk_expr(cx, fn_exp, scope_stack, scope_map);
for arg_exp in args.iter() {
@ -2632,7 +2632,7 @@ fn populate_scope_map(cx: &CrateContext,
}
}
ast::ExprMethodCall(node_id, _, _, ref args, _) => {
ast::ExprMethodCall(node_id, _, _, ref args) => {
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
for arg_exp in args.iter() {

View File

@ -777,11 +777,11 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
expr_to_str(expr), expr_ty.repr(tcx));
closure::trans_expr_fn(bcx, sigil, decl, body, expr.id, dest)
}
ast::ExprCall(f, ref args, _) => {
ast::ExprCall(f, ref args) => {
callee::trans_call(bcx, expr, f,
callee::ArgExprs(*args), expr.id, dest)
}
ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
ast::ExprMethodCall(callee_id, _, _, ref args) => {
callee::trans_method_call(bcx, expr, callee_id, args[0],
callee::ArgExprs(*args), dest)
}

View File

@ -353,17 +353,24 @@ fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
// converting to an rvalue.
let self_datum = unpack_datum!(
bcx, expr::trans(bcx, self_expr));
let self_datum = unpack_datum!(
bcx, self_datum.to_rvalue_datum(bcx, "trait_callee"));
// Convert to by-ref since `trans_trait_callee_from_llval` wants it
// that way.
let self_datum = unpack_datum!(
bcx, self_datum.to_ref_datum(bcx));
let llval = if ty::type_needs_drop(bcx.tcx(), self_datum.ty) {
let self_datum = unpack_datum!(
bcx, self_datum.to_rvalue_datum(bcx, "trait_callee"));
// Arrange cleanup in case something should go wrong before the
// actual call occurs.
let llval = self_datum.add_clean(bcx.fcx, arg_cleanup_scope);
// Convert to by-ref since `trans_trait_callee_from_llval` wants it
// that way.
let self_datum = unpack_datum!(
bcx, self_datum.to_ref_datum(bcx));
// Arrange cleanup in case something should go wrong before the
// actual call occurs.
self_datum.add_clean(bcx.fcx, arg_cleanup_scope)
} else {
// We don't have to do anything about cleanups for &Trait and &mut Trait.
assert!(self_datum.kind.is_by_ref());
self_datum.val
};
let callee_ty = node_id_type(bcx, callee_id);
trans_trait_callee_from_llval(bcx, callee_ty, n_method, llval)

View File

@ -1592,22 +1592,20 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
method_fn_ty: ty::t,
callee_expr: &ast::Expr,
args: &[@ast::Expr],
sugar: ast::CallSugar,
deref_args: DerefArgs) -> ty::t
{
deref_args: DerefArgs) -> ty::t {
// HACK(eddyb) ignore provided self (it has special typeck rules).
let args = args.slice_from(1);
if ty::type_is_error(method_fn_ty) {
let err_inputs = err_args(args.len());
check_argument_types(fcx, sp, err_inputs, callee_expr,
args, sugar, deref_args, false);
args, deref_args, false);
method_fn_ty
} else {
match ty::get(method_fn_ty).sty {
ty::ty_bare_fn(ref fty) => {
// HACK(eddyb) ignore self in the definition (see above).
check_argument_types(fcx, sp, fty.sig.inputs.slice_from(1),
callee_expr, args, sugar, deref_args,
callee_expr, args, deref_args,
fty.sig.variadic);
fty.sig.output
}
@ -1625,7 +1623,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fn_inputs: &[ty::t],
callee_expr: &ast::Expr,
args: &[@ast::Expr],
sugar: ast::CallSugar,
deref_args: DerefArgs,
variadic: bool) {
/*!
@ -1659,18 +1656,12 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
err_args(supplied_arg_count)
}
} else {
let suffix = match sugar {
ast::NoSugar => "",
ast::ForSugar => " (including the closure passed by \
the `for` keyword)"
};
let msg = format!(
"this function takes {} parameter{} \
but {} parameter{} supplied{}",
but {} parameter{} supplied",
expected_arg_count, if expected_arg_count == 1 {""} else {"s"},
supplied_arg_count,
if supplied_arg_count == 1 {" was"} else {"s were"},
suffix);
if supplied_arg_count == 1 {" was"} else {"s were"});
tcx.sess.span_err(sp, msg);
@ -1783,24 +1774,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// The callee checks for bot / err, we don't need to
}
fn write_call(fcx: @FnCtxt,
call_expr: &ast::Expr,
output: ty::t,
sugar: ast::CallSugar) {
let ret_ty = match sugar {
ast::ForSugar => {
match ty::get(output).sty {
ty::ty_bool => {}
_ => fcx.type_error_message(call_expr.span, |actual| {
format!("expected `for` closure to return `bool`, \
but found `{}`", actual) },
output, None)
}
ty::mk_nil()
}
_ => output
};
fcx.write_ty(call_expr.id, ret_ty);
fn write_call(fcx: @FnCtxt, call_expr: &ast::Expr, output: ty::t) {
fcx.write_ty(call_expr.id, output);
}
// A generic function for doing all of the checking for call expressions
@ -1808,8 +1783,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
callee_id: ast::NodeId,
call_expr: &ast::Expr,
f: &ast::Expr,
args: &[@ast::Expr],
sugar: ast::CallSugar) {
args: &[@ast::Expr]) {
// Index expressions need to be handled separately, to inform them
// that they appear in call position.
check_expr(fcx, f);
@ -1857,9 +1831,9 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// Call the generic checker.
check_argument_types(fcx, call_expr.span, fn_sig.inputs, f,
args, sugar, DontDerefArgs, fn_sig.variadic);
args, DontDerefArgs, fn_sig.variadic);
write_call(fcx, call_expr, fn_sig.output, sugar);
write_call(fcx, call_expr, fn_sig.output);
}
// Checks a method call.
@ -1868,8 +1842,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
expr: &ast::Expr,
method_name: ast::Ident,
args: &[@ast::Expr],
tps: &[ast::P<ast::Ty>],
sugar: ast::CallSugar) {
tps: &[ast::P<ast::Ty>]) {
let rcvr = args[0];
check_expr(fcx, rcvr);
@ -1915,10 +1888,10 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// Call the generic checker.
let fn_ty = fcx.node_ty(callee_id);
let ret_ty = check_method_argument_types(fcx, expr.span,
fn_ty, expr, args, sugar,
fn_ty, expr, args,
DontDerefArgs);
write_call(fcx, expr, ret_ty, sugar);
write_call(fcx, expr, ret_ty);
}
// A generic function for checking the then and else in an if
@ -1985,8 +1958,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
method_map.get().insert(op_ex.id, *origin);
}
check_method_argument_types(fcx, op_ex.span,
method_ty, op_ex, args,
ast::NoSugar, deref_args)
method_ty, op_ex,
args, deref_args)
}
_ => {
unbound_method();
@ -1994,8 +1967,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// so we get all the error messages
let expected_ty = ty::mk_err();
check_method_argument_types(fcx, op_ex.span,
expected_ty, op_ex, args,
ast::NoSugar, deref_args);
expected_ty, op_ex,
args, deref_args);
ty::mk_err()
}
}
@ -2948,8 +2921,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
check_block_with_expected(fcx, b, expected);
fcx.write_ty(id, fcx.node_ty(b.id));
}
ast::ExprCall(f, ref args, sugar) => {
check_call(fcx, expr.id, expr, f, *args, sugar);
ast::ExprCall(f, ref args) => {
check_call(fcx, expr.id, expr, f, *args);
let f_ty = fcx.expr_ty(f);
let (args_bot, args_err) = args.iter().fold((false, false),
|(rest_bot, rest_err), a| {
@ -2964,8 +2937,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_bot(id);
}
}
ast::ExprMethodCall(callee_id, ident, ref tps, ref args, sugar) => {
check_method_call(fcx, callee_id, expr, ident, *args, *tps, sugar);
ast::ExprMethodCall(callee_id, ident, ref tps, ref args) => {
check_method_call(fcx, callee_id, expr, ident, *args, *tps);
let arg_tys = args.map(|a| fcx.expr_ty(*a));
let (args_bot, args_err) = arg_tys.iter().fold((false, false),
|(rest_bot, rest_err), a| {

View File

@ -432,14 +432,14 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
}
match expr.node {
ast::ExprCall(callee, ref args, _) => {
ast::ExprCall(callee, ref args) => {
constrain_callee(rcx, callee.id, expr, callee);
constrain_call(rcx, callee.id, expr, None, *args, false);
visit::walk_expr(rcx, expr, ());
}
ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
ast::ExprMethodCall(callee_id, _, _, ref args) => {
constrain_call(rcx, callee_id, expr, Some(args[0]),
args.slice_from(1), false);

View File

@ -702,7 +702,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) {
ast::ExprUnary(callee_id, _, _) |
ast::ExprAssignOp(callee_id, _, _, _) |
ast::ExprIndex(callee_id, _, _) |
ast::ExprMethodCall(callee_id, _, _, _, _) => {
ast::ExprMethodCall(callee_id, _, _, _) => {
match ty::method_call_type_param_defs(cx.tcx, fcx.inh.method_map, ex.id) {
Some(type_param_defs) => {
debug!("vtable resolution on parameter bounds for method call {}",

View File

@ -307,7 +307,7 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
maybe_resolve_type_vars_for_node(wbcx, e.span, callee_id);
}
ast::ExprMethodCall(callee_id, _, _, _, _) => {
ast::ExprMethodCall(callee_id, _, _, _) => {
// We must always have written in a callee ID type for these.
resolve_type_vars_for_node(wbcx, e.span, callee_id);
}

View File

@ -15,7 +15,7 @@ use syntax::visit;
use syntax::visit::Visitor;
use std::local_data;
use extra;
use extra::time;
pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
local_data_key!(depth: uint);
@ -24,9 +24,9 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
let old = local_data::get(depth, |d| d.map(|a| *a).unwrap_or(0));
local_data::set(depth, old + 1);
let start = extra::time::precise_time_s();
let start = time::precise_time_s();
let rv = f(u);
let end = extra::time::precise_time_s();
let end = time::precise_time_s();
println!("{}time: {:3.3f} s\t{}", " ".repeat(old), end - start, what);
local_data::set(depth, old);

View File

@ -117,7 +117,10 @@ mod test {
match *slot.get() {
(ref mut task, ref mut val) => {
*val = n;
task.take_unwrap()
match task.take() {
Some(t) => t,
None => return
}
}
}
}

View File

@ -565,14 +565,14 @@ mod test {
#[bench]
fn bench_buffered_reader(bh: &mut Harness) {
bh.iter(|| {
BufferedReader::new(NullStream);
BufferedReader::new(NullStream)
});
}
#[bench]
fn bench_buffered_writer(bh: &mut Harness) {
bh.iter(|| {
BufferedWriter::new(NullStream);
BufferedWriter::new(NullStream)
});
}

View File

@ -96,6 +96,12 @@ impl ChanWriter {
}
}
impl Clone for ChanWriter {
fn clone(&self) -> ChanWriter {
ChanWriter { chan: self.chan.clone() }
}
}
impl Writer for ChanWriter {
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
if !self.chan.try_send(buf.to_owned()) {

View File

@ -292,7 +292,7 @@ mod bench {
let s = Struct { field: 10 };
let t = &s as &Trait;
bh.iter(|| {
t.method();
t.method()
});
}
@ -300,7 +300,7 @@ mod bench {
fn trait_static_method_call(bh: &mut BenchHarness) {
let s = Struct { field: 10 };
bh.iter(|| {
s.method();
s.method()
});
}
@ -310,10 +310,10 @@ mod bench {
fn match_option_some(bh: &mut BenchHarness) {
let x = Some(10);
bh.iter(|| {
let _q = match x {
match x {
Some(y) => y,
None => 11
};
}
});
}
@ -321,10 +321,10 @@ mod bench {
fn match_vec_pattern(bh: &mut BenchHarness) {
let x = [1,2,3,4,5,6];
bh.iter(|| {
let _q = match x {
match x {
[1,2,3,..] => 10,
_ => 11
};
}
});
}
}

View File

@ -112,14 +112,14 @@ mod bench {
#[bench]
fn alloc_owned_small(bh: &mut BenchHarness) {
bh.iter(|| {
~10;
~10
})
}
#[bench]
fn alloc_owned_big(bh: &mut BenchHarness) {
bh.iter(|| {
~[10, ..1000];
~[10, ..1000]
})
}
}

View File

@ -4357,7 +4357,7 @@ mod bench {
assert_eq!(100, s.len());
bh.iter(|| {
let _ = is_utf8(s);
is_utf8(s)
});
}
@ -4366,7 +4366,7 @@ mod bench {
let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
assert_eq!(100, s.len());
bh.iter(|| {
let _ = is_utf8(s);
is_utf8(s)
});
}
@ -4409,7 +4409,7 @@ mod bench {
#[bench]
fn bench_with_capacity(bh: &mut BenchHarness) {
bh.iter(|| {
let _ = with_capacity(100);
with_capacity(100)
});
}

View File

@ -4428,6 +4428,7 @@ mod bench {
let mut vec: ~[uint] = ~[0u];
bh.iter(|| {
vec.push(0);
&vec
})
}
@ -4435,7 +4436,7 @@ mod bench {
fn starts_with_same_vector(bh: &mut BenchHarness) {
let vec: ~[uint] = vec::from_fn(100, |i| i);
bh.iter(|| {
vec.starts_with(vec);
vec.starts_with(vec)
})
}
@ -4443,7 +4444,7 @@ mod bench {
fn starts_with_single_element(bh: &mut BenchHarness) {
let vec: ~[uint] = ~[0u];
bh.iter(|| {
vec.starts_with(vec);
vec.starts_with(vec)
})
}
@ -4453,7 +4454,7 @@ mod bench {
let mut match_vec: ~[uint] = vec::from_fn(99, |i| i);
match_vec.push(0);
bh.iter(|| {
vec.starts_with(match_vec);
vec.starts_with(match_vec)
})
}
@ -4461,7 +4462,7 @@ mod bench {
fn ends_with_same_vector(bh: &mut BenchHarness) {
let vec: ~[uint] = vec::from_fn(100, |i| i);
bh.iter(|| {
vec.ends_with(vec);
vec.ends_with(vec)
})
}
@ -4469,7 +4470,7 @@ mod bench {
fn ends_with_single_element(bh: &mut BenchHarness) {
let vec: ~[uint] = ~[0u];
bh.iter(|| {
vec.ends_with(vec);
vec.ends_with(vec)
})
}
@ -4479,7 +4480,7 @@ mod bench {
let mut match_vec: ~[uint] = vec::from_fn(100, |i| i);
match_vec[0] = 200;
bh.iter(|| {
vec.starts_with(match_vec);
vec.starts_with(match_vec)
})
}
@ -4487,7 +4488,7 @@ mod bench {
fn contains_last_element(bh: &mut BenchHarness) {
let vec: ~[uint] = vec::from_fn(100, |i| i);
bh.iter(|| {
vec.contains(&99u);
vec.contains(&99u)
})
}
@ -4507,13 +4508,14 @@ mod bench {
ptr::set_memory(vp, 0, 1024);
v.set_len(1024);
}
v
});
}
#[bench]
fn zero_1kb_fixed_repeat(bh: &mut BenchHarness) {
bh.iter(|| {
let _v: ~[u8] = ~[0u8, ..1024];
~[0u8, ..1024]
});
}
@ -4542,6 +4544,7 @@ mod bench {
for x in v.mut_iter() {
*x = 0;
}
v
});
}

View File

@ -519,7 +519,7 @@ pub struct Expr {
impl Expr {
pub fn get_callee_id(&self) -> Option<NodeId> {
match self.node {
ExprMethodCall(callee_id, _, _, _, _) |
ExprMethodCall(callee_id, _, _, _) |
ExprIndex(callee_id, _, _) |
ExprBinary(callee_id, _, _, _) |
ExprAssignOp(callee_id, _, _, _) |
@ -529,20 +529,14 @@ impl Expr {
}
}
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum CallSugar {
NoSugar,
ForSugar
}
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum Expr_ {
ExprVstore(@Expr, ExprVstore),
// First expr is the place; second expr is the value.
ExprBox(@Expr, @Expr),
ExprVec(~[@Expr], Mutability),
ExprCall(@Expr, ~[@Expr], CallSugar),
ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr], CallSugar),
ExprCall(@Expr, ~[@Expr]),
ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr]),
ExprTup(~[@Expr]),
ExprBinary(NodeId, BinOp, @Expr, @Expr),
ExprUnary(NodeId, UnOp, @Expr),

View File

@ -525,11 +525,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
fn expr_call(&self, span: Span, expr: @ast::Expr, args: ~[@ast::Expr]) -> @ast::Expr {
self.expr(span, ast::ExprCall(expr, args, ast::NoSugar))
self.expr(span, ast::ExprCall(expr, args))
}
fn expr_call_ident(&self, span: Span, id: ast::Ident, args: ~[@ast::Expr]) -> @ast::Expr {
self.expr(span,
ast::ExprCall(self.expr_ident(span, id), args, ast::NoSugar))
self.expr(span, ast::ExprCall(self.expr_ident(span, id), args))
}
fn expr_call_global(&self, sp: Span, fn_path: ~[ast::Ident],
args: ~[@ast::Expr]) -> @ast::Expr {
@ -541,7 +540,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
ident: ast::Ident,
mut args: ~[@ast::Expr]) -> @ast::Expr {
args.unshift(expr);
self.expr(span, ast::ExprMethodCall(ast::DUMMY_NODE_ID, ident, ~[], args, ast::NoSugar))
self.expr(span, ast::ExprMethodCall(ast::DUMMY_NODE_ID, ident, ~[], args))
}
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
self.expr(b.span, ast::ExprBlock(b))

View File

@ -203,52 +203,6 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
}
}
// This is a secondary mechanism for invoking syntax extensions on items:
// "decorator" attributes, such as #[auto_encode]. These are invoked by an
// attribute prefixing an item, and are interpreted by feeding the item
// through the named attribute _as a syntax extension_ and splicing in the
// resulting item vec into place in favour of the decorator. Note that
// these do _not_ work for macro extensions, just ItemDecorator ones.
//
// NB: there is some redundancy between this and expand_item, below, and
// they might benefit from some amount of semantic and language-UI merger.
pub fn expand_mod_items(module_: &ast::Mod, fld: &mut MacroExpander) -> ast::Mod {
// Fold the contents first:
let module_ = noop_fold_mod(module_, fld);
// For each item, look through the attributes. If any of them are
// decorated with "item decorators", then use that function to transform
// the item into a new set of items.
let mut new_items = module_.items.clone();
for item in module_.items.iter() {
for attr in item.attrs.rev_iter() {
let mname = attr.name();
match fld.extsbox.find(&intern(mname.get())) {
Some(&ItemDecorator(dec_fn)) => {
fld.cx.bt_push(ExpnInfo {
call_site: attr.span,
callee: NameAndSpan {
name: mname.get().to_str(),
format: MacroAttribute,
span: None
}
});
dec_fn(fld.cx, attr.span, attr.node.value, *item,
|item| new_items.push(item));
fld.cx.bt_pop();
},
_ => {},
}
}
}
ast::Mod {
items: new_items,
..module_
}
}
// eval $e with a new exts frame:
macro_rules! with_exts_frame (
($extsboxexpr:expr,$macros_escape:expr,$e:expr) =>
@ -263,7 +217,35 @@ macro_rules! with_exts_frame (
// When we enter a module, record it, for the sake of `module!`
pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
-> SmallVector<@ast::Item> {
match it.node {
let mut decorator_items = SmallVector::zero();
for attr in it.attrs.rev_iter() {
let mname = attr.name();
match fld.extsbox.find(&intern(mname.get())) {
Some(&ItemDecorator(dec_fn)) => {
fld.cx.bt_push(ExpnInfo {
call_site: attr.span,
callee: NameAndSpan {
name: mname.get().to_str(),
format: MacroAttribute,
span: None
}
});
// we'd ideally decorator_items.push_all(expand_item(item, fld)),
// but that double-mut-borrows fld
dec_fn(fld.cx, attr.span, attr.node.value, it,
|item| decorator_items.push(item));
fld.cx.bt_pop();
}
_ => {}
}
}
let decorator_items = decorator_items.move_iter()
.flat_map(|item| expand_item(item, fld).move_iter())
.collect();
let mut new_items = match it.node {
ast::ItemMac(..) => expand_item_mac(it, fld),
ast::ItemMod(_) | ast::ItemForeignMod(_) => {
fld.cx.mod_push(it.ident);
@ -275,7 +257,10 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
result
},
_ => noop_fold_item(it, fld)
}
};
new_items.push_all(decorator_items);
new_items
}
// does this attribute list contain "macro_escape" ?
@ -778,10 +763,6 @@ impl<'a> Folder for MacroExpander<'a> {
expand_expr(expr, self)
}
fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
expand_mod_items(module, self)
}
fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> {
expand_item(item, self)
}

View File

@ -727,19 +727,16 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
ExprRepeat(folder.fold_expr(expr), folder.fold_expr(count), mutt)
}
ExprTup(ref elts) => ExprTup(elts.map(|x| folder.fold_expr(*x))),
ExprCall(f, ref args, blk) => {
ExprCall(f, ref args) => {
ExprCall(folder.fold_expr(f),
args.map(|&x| folder.fold_expr(x)),
blk)
args.map(|&x| folder.fold_expr(x)))
}
ExprMethodCall(callee_id, i, ref tps, ref args, blk) => {
ExprMethodCall(callee_id, i, ref tps, ref args) => {
ExprMethodCall(
folder.new_id(callee_id),
folder.fold_ident(i),
tps.map(|&x| folder.fold_ty(x)),
args.map(|&x| folder.fold_expr(x)),
blk
)
args.map(|&x| folder.fold_expr(x)))
}
ExprBinary(callee_id, binop, lhs, rhs) => {
ExprBinary(folder.new_id(callee_id),

View File

@ -32,7 +32,7 @@ This API is completely unstable and subject to change.
#[deny(non_camel_case_types)];
extern mod extra;
#[cfg(test)] extern mod extra;
extern mod serialize;
extern mod term;
extern mod collections;

View File

@ -23,15 +23,13 @@ use ast;
// isn't parsed as (if true {...} else {...} | x) | 5
pub fn expr_requires_semi_to_be_stmt(e: @ast::Expr) -> bool {
match e.node {
ast::ExprIf(..)
| ast::ExprMatch(..)
| ast::ExprBlock(_)
| ast::ExprWhile(..)
| ast::ExprLoop(..)
| ast::ExprForLoop(..)
| ast::ExprCall(_, _, ast::ForSugar)
| ast::ExprMethodCall(_, _, _, _, ast::ForSugar) => false,
_ => true
ast::ExprIf(..)
| ast::ExprMatch(..)
| ast::ExprBlock(_)
| ast::ExprWhile(..)
| ast::ExprLoop(..)
| ast::ExprForLoop(..) => false,
_ => true
}
}

View File

@ -13,7 +13,6 @@
use abi;
use abi::AbiSet;
use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
use ast::{CallSugar, NoSugar};
use ast::{BareFnTy, ClosureTy};
use ast::{RegionTyParamBound, TraitTyParamBound};
use ast::{Provided, Public, Purity};
@ -1690,13 +1689,12 @@ impl Parser {
ExprBinary(ast::DUMMY_NODE_ID, binop, lhs, rhs)
}
pub fn mk_call(&mut self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ {
ExprCall(f, args, sugar)
pub fn mk_call(&mut self, f: @Expr, args: ~[@Expr]) -> ast::Expr_ {
ExprCall(f, args)
}
fn mk_method_call(&mut self, ident: Ident, tps: ~[P<Ty>], args: ~[@Expr],
sugar: CallSugar) -> ast::Expr_ {
ExprMethodCall(ast::DUMMY_NODE_ID, ident, tps, args, sugar)
fn mk_method_call(&mut self, ident: Ident, tps: ~[P<Ty>], args: ~[@Expr]) -> ast::Expr_ {
ExprMethodCall(ast::DUMMY_NODE_ID, ident, tps, args)
}
pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
@ -1997,7 +1995,7 @@ impl Parser {
hi = self.last_span.hi;
es.unshift(e);
let nd = self.mk_method_call(i, tys, es, NoSugar);
let nd = self.mk_method_call(i, tys, es);
e = self.mk_expr(lo, hi, nd);
}
_ => {
@ -2022,7 +2020,7 @@ impl Parser {
);
hi = self.last_span.hi;
let nd = self.mk_call(e, es, NoSugar);
let nd = self.mk_call(e, es);
e = self.mk_expr(lo, hi, nd);
}

View File

@ -1141,33 +1141,10 @@ pub fn print_expr_vstore(s: &mut State, t: ast::ExprVstore) -> io::IoResult<()>
}
}
pub fn print_call_pre(s: &mut State,
sugar: ast::CallSugar,
base_args: &mut ~[@ast::Expr])
-> io::IoResult<Option<@ast::Expr>> {
match sugar {
ast::ForSugar => {
if_ok!(head(s, "for"));
Ok(Some(base_args.pop().unwrap()))
}
ast::NoSugar => Ok(None)
}
}
pub fn print_call_post(s: &mut State,
sugar: ast::CallSugar,
blk: &Option<@ast::Expr>,
base_args: &mut ~[@ast::Expr]) -> io::IoResult<()> {
if sugar == ast::NoSugar || !base_args.is_empty() {
if_ok!(popen(s));
if_ok!(commasep_exprs(s, Inconsistent, *base_args));
if_ok!(pclose(s));
}
if sugar != ast::NoSugar {
if_ok!(nbsp(s));
// not sure if this can happen
if_ok!(print_expr(s, blk.unwrap()));
}
fn print_call_post(s: &mut State, args: &[@ast::Expr]) -> io::IoResult<()> {
if_ok!(popen(s));
if_ok!(commasep_exprs(s, Inconsistent, args));
if_ok!(pclose(s));
Ok(())
}
@ -1254,15 +1231,12 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
}
if_ok!(pclose(s));
}
ast::ExprCall(func, ref args, sugar) => {
let mut base_args = (*args).clone();
let blk = if_ok!(print_call_pre(s, sugar, &mut base_args));
ast::ExprCall(func, ref args) => {
if_ok!(print_expr(s, func));
if_ok!(print_call_post(s, sugar, &blk, &mut base_args));
if_ok!(print_call_post(s, *args));
}
ast::ExprMethodCall(_, ident, ref tys, ref args, sugar) => {
let mut base_args = args.slice_from(1).to_owned();
let blk = if_ok!(print_call_pre(s, sugar, &mut base_args));
ast::ExprMethodCall(_, ident, ref tys, ref args) => {
let base_args = args.slice_from(1);
if_ok!(print_expr(s, args[0]));
if_ok!(word(&mut s.s, "."));
if_ok!(print_ident(s, ident));
@ -1271,7 +1245,7 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
if_ok!(commasep(s, Inconsistent, *tys, print_type_ref));
if_ok!(word(&mut s.s, ">"));
}
if_ok!(print_call_post(s, sugar, &blk, &mut base_args));
if_ok!(print_call_post(s, base_args));
}
ast::ExprBinary(_, op, lhs, rhs) => {
if_ok!(print_expr(s, lhs));

View File

@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -64,6 +64,12 @@ impl<T> SmallVector<T> {
}
}
pub fn push_all(&mut self, other: SmallVector<T>) {
for v in other.move_iter() {
self.push(v);
}
}
pub fn get<'a>(&'a self, idx: uint) -> &'a T {
match *self {
One(ref v) if idx == 0 => v,

View File

@ -652,13 +652,13 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
visitor.visit_expr(*subexpression, env.clone())
}
}
ExprCall(callee_expression, ref arguments, _) => {
ExprCall(callee_expression, ref arguments) => {
for argument in arguments.iter() {
visitor.visit_expr(*argument, env.clone())
}
visitor.visit_expr(callee_expression, env.clone())
}
ExprMethodCall(_, _, ref types, ref arguments, _) => {
ExprMethodCall(_, _, ref types, ref arguments) => {
walk_exprs(visitor, *arguments, env.clone());
for &typ in types.iter() {
visitor.visit_ty(typ, env.clone())

View File

@ -0,0 +1,28 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Verify the compiler fails with an error on infinite function
// recursions.
struct Data(~Option<Data>);
fn generic<T>( _ : ~[(Data,T)] ) {
//~^ ERROR overly deep expansion of inlined function
let rec : ~[(Data,(bool,T))] = ~[];
generic( rec );
}
fn main () {
// Use generic<T> at least once to trigger instantiation.
let input : ~[(Data,())] = ~[];
generic(input);
}

View File

@ -10,6 +10,7 @@
// error-pattern:runned an unexported test
// compile-flags:--test
// check-stdout
extern mod extra;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// check-stdout
// error-pattern:task 'test_foo' failed at
// compile-flags: --test

View File

@ -0,0 +1,19 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub fn main() {
#[deriving(ToStr)]
struct Foo {
foo: int,
}
let f = Foo { foo: 10 };
let _ = f.to_str();
}

View File

@ -0,0 +1,62 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-fast
extern mod green;
static mut DROP: int = 0i;
static mut DROP_S: int = 0i;
static mut DROP_T: int = 0i;
#[start]
fn start(argc: int, argv: **u8) -> int {
let ret = green::start(argc, argv, main);
unsafe {
assert_eq!(2, DROP);
assert_eq!(1, DROP_S);
assert_eq!(1, DROP_T);
}
ret
}
struct S;
impl Drop for S {
fn drop(&mut self) {
unsafe {
DROP_S += 1;
DROP += 1;
}
}
}
fn f(ref _s: S) {}
struct T { i: int }
impl Drop for T {
fn drop(&mut self) {
unsafe {
DROP_T += 1;
DROP += 1;
}
}
}
fn g(ref _t: T) {}
fn main() {
let s = S;
f(s);
unsafe {
assert_eq!(1, DROP);
assert_eq!(1, DROP_S);
}
let t = T { i: 1 };
g(t);
unsafe { assert_eq!(1, DROP_T); }
}