auto merge of #12267 : alexcrichton/rust/rollup, r=alexcrichton
The last commit has the closed PRs
This commit is contained in:
commit
3f717bbe96
@ -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
|
||||
|
2
mk/rt.mk
2
mk/rt.mk
@ -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" \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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) |
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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| {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {}",
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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())
|
||||
|
28
src/test/compile-fail/issue-8727.rs
Normal file
28
src/test/compile-fail/issue-8727.rs
Normal 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);
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
|
||||
// error-pattern:runned an unexported test
|
||||
// compile-flags:--test
|
||||
// check-stdout
|
||||
|
||||
extern mod extra;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
19
src/test/run-pass/deriving-in-fn.rs
Normal file
19
src/test/run-pass/deriving-in-fn.rs
Normal 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();
|
||||
}
|
62
src/test/run-pass/issue-8860.rs
Normal file
62
src/test/run-pass/issue-8860.rs
Normal 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); }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user