mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-04 01:42:54 +03:00
Merge remote-tracking branch 'brson/companion' into incoming
Conflicts: src/compiletest/compiletest.rs src/libcargo/cargo.rs src/libcore/core.rs src/librustc/rustc.rs src/librustdoc/rustdoc.rc
This commit is contained in:
@@ -1,14 +1,5 @@
|
||||
enum mode { mode_compile_fail, mode_run_fail, mode_run_pass, mode_pretty, }
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl mode : cmp::Eq {
|
||||
pure fn eq(other: &mode) -> bool {
|
||||
(*other) as int == self as int
|
||||
}
|
||||
pure fn ne(other: &mode) -> bool { !self.eq(other) }
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
impl mode : cmp::Eq {
|
||||
pure fn eq(&self, other: &mode) -> bool {
|
||||
(*other) as int == (*self) as int
|
||||
|
||||
@@ -26,6 +26,198 @@ mod common;
|
||||
#[legacy_exports]
|
||||
mod errors;
|
||||
|
||||
use std::getopts;
|
||||
use std::test;
|
||||
|
||||
use core::result;
|
||||
use result::{Ok, Err};
|
||||
|
||||
use common::config;
|
||||
use common::mode_run_pass;
|
||||
use common::mode_run_fail;
|
||||
use common::mode_compile_fail;
|
||||
use common::mode_pretty;
|
||||
use common::mode;
|
||||
use util::logv;
|
||||
|
||||
fn main() {
|
||||
let args = os::args();
|
||||
let config = parse_config(args);
|
||||
log_config(config);
|
||||
run_tests(config);
|
||||
}
|
||||
|
||||
fn parse_config(args: ~[~str]) -> config {
|
||||
let opts =
|
||||
~[getopts::reqopt(~"compile-lib-path"),
|
||||
getopts::reqopt(~"run-lib-path"),
|
||||
getopts::reqopt(~"rustc-path"), getopts::reqopt(~"src-base"),
|
||||
getopts::reqopt(~"build-base"), getopts::reqopt(~"aux-base"),
|
||||
getopts::reqopt(~"stage-id"),
|
||||
getopts::reqopt(~"mode"), getopts::optflag(~"ignored"),
|
||||
getopts::optopt(~"runtool"), getopts::optopt(~"rustcflags"),
|
||||
getopts::optflag(~"verbose"),
|
||||
getopts::optopt(~"logfile"),
|
||||
getopts::optflag(~"jit")];
|
||||
|
||||
assert (vec::is_not_empty(args));
|
||||
let args_ = vec::tail(args);
|
||||
let matches =
|
||||
&match getopts::getopts(args_, opts) {
|
||||
Ok(m) => m,
|
||||
Err(f) => fail getopts::fail_str(f)
|
||||
};
|
||||
|
||||
fn opt_path(m: &getopts::Matches, nm: ~str) -> Path {
|
||||
Path(getopts::opt_str(m, nm))
|
||||
}
|
||||
|
||||
return {compile_lib_path: getopts::opt_str(matches, ~"compile-lib-path"),
|
||||
run_lib_path: getopts::opt_str(matches, ~"run-lib-path"),
|
||||
rustc_path: opt_path(matches, ~"rustc-path"),
|
||||
src_base: opt_path(matches, ~"src-base"),
|
||||
build_base: opt_path(matches, ~"build-base"),
|
||||
aux_base: opt_path(matches, ~"aux-base"),
|
||||
stage_id: getopts::opt_str(matches, ~"stage-id"),
|
||||
mode: str_mode(getopts::opt_str(matches, ~"mode")),
|
||||
run_ignored: getopts::opt_present(matches, ~"ignored"),
|
||||
filter:
|
||||
if vec::len(matches.free) > 0u {
|
||||
option::Some(matches.free[0])
|
||||
} else { option::None },
|
||||
logfile: option::map(&getopts::opt_maybe_str(matches,
|
||||
~"logfile"),
|
||||
|s| Path(*s)),
|
||||
runtool: getopts::opt_maybe_str(matches, ~"runtool"),
|
||||
rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"),
|
||||
jit: getopts::opt_present(matches, ~"jit"),
|
||||
verbose: getopts::opt_present(matches, ~"verbose")};
|
||||
}
|
||||
|
||||
fn log_config(config: config) {
|
||||
let c = config;
|
||||
logv(c, fmt!("configuration:"));
|
||||
logv(c, fmt!("compile_lib_path: %s", config.compile_lib_path));
|
||||
logv(c, fmt!("run_lib_path: %s", config.run_lib_path));
|
||||
logv(c, fmt!("rustc_path: %s", config.rustc_path.to_str()));
|
||||
logv(c, fmt!("src_base: %s", config.src_base.to_str()));
|
||||
logv(c, fmt!("build_base: %s", config.build_base.to_str()));
|
||||
logv(c, fmt!("stage_id: %s", config.stage_id));
|
||||
logv(c, fmt!("mode: %s", mode_str(config.mode)));
|
||||
logv(c, fmt!("run_ignored: %b", config.run_ignored));
|
||||
logv(c, fmt!("filter: %s", opt_str(config.filter)));
|
||||
logv(c, fmt!("runtool: %s", opt_str(config.runtool)));
|
||||
logv(c, fmt!("rustcflags: %s", opt_str(config.rustcflags)));
|
||||
logv(c, fmt!("jit: %b", config.jit));
|
||||
logv(c, fmt!("verbose: %b", config.verbose));
|
||||
logv(c, fmt!("\n"));
|
||||
}
|
||||
|
||||
fn opt_str(maybestr: Option<~str>) -> ~str {
|
||||
match maybestr { option::Some(s) => s, option::None => ~"(none)" }
|
||||
}
|
||||
|
||||
fn str_opt(maybestr: ~str) -> Option<~str> {
|
||||
if maybestr != ~"(none)" { option::Some(maybestr) } else { option::None }
|
||||
}
|
||||
|
||||
fn str_mode(s: ~str) -> mode {
|
||||
match s {
|
||||
~"compile-fail" => mode_compile_fail,
|
||||
~"run-fail" => mode_run_fail,
|
||||
~"run-pass" => mode_run_pass,
|
||||
~"pretty" => mode_pretty,
|
||||
_ => fail ~"invalid mode"
|
||||
}
|
||||
}
|
||||
|
||||
fn mode_str(mode: mode) -> ~str {
|
||||
match mode {
|
||||
mode_compile_fail => ~"compile-fail",
|
||||
mode_run_fail => ~"run-fail",
|
||||
mode_run_pass => ~"run-pass",
|
||||
mode_pretty => ~"pretty"
|
||||
}
|
||||
}
|
||||
|
||||
fn run_tests(config: config) {
|
||||
let opts = test_opts(config);
|
||||
let tests = make_tests(config);
|
||||
let res = test::run_tests_console(&opts, tests);
|
||||
if !res { fail ~"Some tests failed"; }
|
||||
}
|
||||
|
||||
fn test_opts(config: config) -> test::TestOpts {
|
||||
{filter:
|
||||
match config.filter {
|
||||
option::Some(s) => option::Some(s),
|
||||
option::None => option::None
|
||||
},
|
||||
run_ignored: config.run_ignored,
|
||||
logfile:
|
||||
match config.logfile {
|
||||
option::Some(s) => option::Some(s.to_str()),
|
||||
option::None => option::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_tests(config: config) -> ~[test::TestDesc] {
|
||||
debug!("making tests from %s",
|
||||
config.src_base.to_str());
|
||||
let mut tests = ~[];
|
||||
for os::list_dir_path(&config.src_base).each |file| {
|
||||
let file = copy *file;
|
||||
debug!("inspecting file %s", file.to_str());
|
||||
if is_test(config, file) {
|
||||
tests.push(make_test(config, file))
|
||||
}
|
||||
}
|
||||
move tests
|
||||
}
|
||||
|
||||
fn is_test(config: config, testfile: &Path) -> bool {
|
||||
// Pretty-printer does not work with .rc files yet
|
||||
let valid_extensions =
|
||||
match config.mode {
|
||||
mode_pretty => ~[~".rs"],
|
||||
_ => ~[~".rc", ~".rs"]
|
||||
};
|
||||
let invalid_prefixes = ~[~".", ~"#", ~"~"];
|
||||
let name = testfile.filename().get();
|
||||
|
||||
let mut valid = false;
|
||||
|
||||
for valid_extensions.each |ext| {
|
||||
if str::ends_with(name, *ext) { valid = true; }
|
||||
}
|
||||
|
||||
for invalid_prefixes.each |pre| {
|
||||
if str::starts_with(name, *pre) { valid = false; }
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
fn make_test(config: config, testfile: &Path) ->
|
||||
test::TestDesc {
|
||||
{
|
||||
name: make_test_name(config, testfile),
|
||||
testfn: make_test_closure(config, testfile),
|
||||
ignore: header::is_test_ignored(config, testfile),
|
||||
should_fail: false
|
||||
}
|
||||
}
|
||||
|
||||
fn make_test_name(config: config, testfile: &Path) -> ~str {
|
||||
fmt!("[%s] %s", mode_str(config.mode), testfile.to_str())
|
||||
}
|
||||
|
||||
fn make_test_closure(config: config, testfile: &Path) -> test::TestFn {
|
||||
let testfile = testfile.to_str();
|
||||
fn~() { runtest::run(config, testfile) }
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
use std::getopts;
|
||||
use std::test;
|
||||
|
||||
use core::result;
|
||||
use result::{Ok, Err};
|
||||
|
||||
use common::config;
|
||||
use common::mode_run_pass;
|
||||
use common::mode_run_fail;
|
||||
use common::mode_compile_fail;
|
||||
use common::mode_pretty;
|
||||
use common::mode;
|
||||
use util::logv;
|
||||
|
||||
fn main() {
|
||||
let args = os::args();
|
||||
let config = parse_config(args);
|
||||
log_config(config);
|
||||
run_tests(config);
|
||||
}
|
||||
|
||||
fn parse_config(args: ~[~str]) -> config {
|
||||
let opts =
|
||||
~[getopts::reqopt(~"compile-lib-path"),
|
||||
getopts::reqopt(~"run-lib-path"),
|
||||
getopts::reqopt(~"rustc-path"), getopts::reqopt(~"src-base"),
|
||||
getopts::reqopt(~"build-base"), getopts::reqopt(~"aux-base"),
|
||||
getopts::reqopt(~"stage-id"),
|
||||
getopts::reqopt(~"mode"), getopts::optflag(~"ignored"),
|
||||
getopts::optopt(~"runtool"), getopts::optopt(~"rustcflags"),
|
||||
getopts::optflag(~"verbose"),
|
||||
getopts::optopt(~"logfile"),
|
||||
getopts::optflag(~"jit")];
|
||||
|
||||
assert (vec::is_not_empty(args));
|
||||
let args_ = vec::tail(args);
|
||||
let matches =
|
||||
&match getopts::getopts(args_, opts) {
|
||||
Ok(m) => m,
|
||||
Err(f) => fail getopts::fail_str(f)
|
||||
};
|
||||
|
||||
fn opt_path(m: &getopts::Matches, nm: ~str) -> Path {
|
||||
Path(getopts::opt_str(m, nm))
|
||||
}
|
||||
|
||||
return {compile_lib_path: getopts::opt_str(matches, ~"compile-lib-path"),
|
||||
run_lib_path: getopts::opt_str(matches, ~"run-lib-path"),
|
||||
rustc_path: opt_path(matches, ~"rustc-path"),
|
||||
src_base: opt_path(matches, ~"src-base"),
|
||||
build_base: opt_path(matches, ~"build-base"),
|
||||
aux_base: opt_path(matches, ~"aux-base"),
|
||||
stage_id: getopts::opt_str(matches, ~"stage-id"),
|
||||
mode: str_mode(getopts::opt_str(matches, ~"mode")),
|
||||
run_ignored: getopts::opt_present(matches, ~"ignored"),
|
||||
filter:
|
||||
if vec::len(matches.free) > 0u {
|
||||
option::Some(matches.free[0])
|
||||
} else { option::None },
|
||||
logfile: option::map(&getopts::opt_maybe_str(matches,
|
||||
~"logfile"),
|
||||
|s| Path(*s)),
|
||||
runtool: getopts::opt_maybe_str(matches, ~"runtool"),
|
||||
rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"),
|
||||
jit: getopts::opt_present(matches, ~"jit"),
|
||||
verbose: getopts::opt_present(matches, ~"verbose")};
|
||||
}
|
||||
|
||||
fn log_config(config: config) {
|
||||
let c = config;
|
||||
logv(c, fmt!("configuration:"));
|
||||
logv(c, fmt!("compile_lib_path: %s", config.compile_lib_path));
|
||||
logv(c, fmt!("run_lib_path: %s", config.run_lib_path));
|
||||
logv(c, fmt!("rustc_path: %s", config.rustc_path.to_str()));
|
||||
logv(c, fmt!("src_base: %s", config.src_base.to_str()));
|
||||
logv(c, fmt!("build_base: %s", config.build_base.to_str()));
|
||||
logv(c, fmt!("stage_id: %s", config.stage_id));
|
||||
logv(c, fmt!("mode: %s", mode_str(config.mode)));
|
||||
logv(c, fmt!("run_ignored: %b", config.run_ignored));
|
||||
logv(c, fmt!("filter: %s", opt_str(config.filter)));
|
||||
logv(c, fmt!("runtool: %s", opt_str(config.runtool)));
|
||||
logv(c, fmt!("rustcflags: %s", opt_str(config.rustcflags)));
|
||||
logv(c, fmt!("jit: %b", config.jit));
|
||||
logv(c, fmt!("verbose: %b", config.verbose));
|
||||
logv(c, fmt!("\n"));
|
||||
}
|
||||
|
||||
fn opt_str(maybestr: Option<~str>) -> ~str {
|
||||
match maybestr { option::Some(s) => s, option::None => ~"(none)" }
|
||||
}
|
||||
|
||||
fn str_opt(maybestr: ~str) -> Option<~str> {
|
||||
if maybestr != ~"(none)" { option::Some(maybestr) } else { option::None }
|
||||
}
|
||||
|
||||
fn str_mode(s: ~str) -> mode {
|
||||
match s {
|
||||
~"compile-fail" => mode_compile_fail,
|
||||
~"run-fail" => mode_run_fail,
|
||||
~"run-pass" => mode_run_pass,
|
||||
~"pretty" => mode_pretty,
|
||||
_ => fail ~"invalid mode"
|
||||
}
|
||||
}
|
||||
|
||||
fn mode_str(mode: mode) -> ~str {
|
||||
match mode {
|
||||
mode_compile_fail => ~"compile-fail",
|
||||
mode_run_fail => ~"run-fail",
|
||||
mode_run_pass => ~"run-pass",
|
||||
mode_pretty => ~"pretty"
|
||||
}
|
||||
}
|
||||
|
||||
fn run_tests(config: config) {
|
||||
let opts = test_opts(config);
|
||||
let tests = make_tests(config);
|
||||
let res = test::run_tests_console(&opts, tests);
|
||||
if !res { fail ~"Some tests failed"; }
|
||||
}
|
||||
|
||||
fn test_opts(config: config) -> test::TestOpts {
|
||||
{filter:
|
||||
match config.filter {
|
||||
option::Some(s) => option::Some(s),
|
||||
option::None => option::None
|
||||
},
|
||||
run_ignored: config.run_ignored,
|
||||
logfile:
|
||||
match config.logfile {
|
||||
option::Some(s) => option::Some(s.to_str()),
|
||||
option::None => option::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_tests(config: config) -> ~[test::TestDesc] {
|
||||
debug!("making tests from %s",
|
||||
config.src_base.to_str());
|
||||
let mut tests = ~[];
|
||||
for os::list_dir_path(&config.src_base).each |file| {
|
||||
let file = copy *file;
|
||||
debug!("inspecting file %s", file.to_str());
|
||||
if is_test(config, file) {
|
||||
tests.push(make_test(config, file))
|
||||
}
|
||||
}
|
||||
move tests
|
||||
}
|
||||
|
||||
fn is_test(config: config, testfile: &Path) -> bool {
|
||||
// Pretty-printer does not work with .rc files yet
|
||||
let valid_extensions =
|
||||
match config.mode {
|
||||
mode_pretty => ~[~".rs"],
|
||||
_ => ~[~".rc", ~".rs"]
|
||||
};
|
||||
let invalid_prefixes = ~[~".", ~"#", ~"~"];
|
||||
let name = testfile.filename().get();
|
||||
|
||||
let mut valid = false;
|
||||
|
||||
for valid_extensions.each |ext| {
|
||||
if str::ends_with(name, *ext) { valid = true; }
|
||||
}
|
||||
|
||||
for invalid_prefixes.each |pre| {
|
||||
if str::starts_with(name, *pre) { valid = false; }
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
fn make_test(config: config, testfile: &Path) ->
|
||||
test::TestDesc {
|
||||
{
|
||||
name: make_test_name(config, testfile),
|
||||
testfn: make_test_closure(config, testfile),
|
||||
ignore: header::is_test_ignored(config, testfile),
|
||||
should_fail: false
|
||||
}
|
||||
}
|
||||
|
||||
fn make_test_name(config: config, testfile: &Path) -> ~str {
|
||||
fmt!("[%s] %s", mode_str(config.mode), testfile.to_str())
|
||||
}
|
||||
|
||||
fn make_test_closure(config: config, testfile: &Path) -> test::TestFn {
|
||||
let testfile = testfile.to_str();
|
||||
fn~() { runtest::run(config, testfile) }
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// End:
|
||||
@@ -36,3 +36,1941 @@ use core::*;
|
||||
|
||||
#[legacy_exports]
|
||||
mod pgp;
|
||||
|
||||
use syntax::{ast, codemap, parse, visit, attr};
|
||||
use syntax::diagnostic::span_handler;
|
||||
use codemap::span;
|
||||
use rustc::metadata::filesearch::{get_cargo_root, get_cargo_root_nearest,
|
||||
get_cargo_sysroot, libdir};
|
||||
use syntax::diagnostic;
|
||||
|
||||
use result::{Ok, Err};
|
||||
use io::WriterUtil;
|
||||
use send_map::linear::LinearMap;
|
||||
use std::{map, json, tempfile, term, sort, getopts};
|
||||
use map::HashMap;
|
||||
use to_str::to_str;
|
||||
use getopts::{optflag, optopt, opt_present};
|
||||
use dvec::DVec;
|
||||
|
||||
struct Package {
|
||||
name: ~str,
|
||||
uuid: ~str,
|
||||
url: ~str,
|
||||
method: ~str,
|
||||
description: ~str,
|
||||
reference: Option<~str>,
|
||||
tags: ~[~str],
|
||||
versions: ~[(~str, ~str)]
|
||||
}
|
||||
|
||||
impl Package : cmp::Ord {
|
||||
pure fn lt(&self, other: &Package) -> bool {
|
||||
if (*self).name.lt(&(*other).name) { return true; }
|
||||
if (*other).name.lt(&(*self).name) { return false; }
|
||||
if (*self).uuid.lt(&(*other).uuid) { return true; }
|
||||
if (*other).uuid.lt(&(*self).uuid) { return false; }
|
||||
if (*self).url.lt(&(*other).url) { return true; }
|
||||
if (*other).url.lt(&(*self).url) { return false; }
|
||||
if (*self).method.lt(&(*other).method) { return true; }
|
||||
if (*other).method.lt(&(*self).method) { return false; }
|
||||
if (*self).description.lt(&(*other).description) { return true; }
|
||||
if (*other).description.lt(&(*self).description) { return false; }
|
||||
if (*self).tags.lt(&(*other).tags) { return true; }
|
||||
if (*other).tags.lt(&(*self).tags) { return false; }
|
||||
if (*self).versions.lt(&(*other).versions) { return true; }
|
||||
return false;
|
||||
}
|
||||
pure fn le(&self, other: &Package) -> bool { !(*other).lt(&(*self)) }
|
||||
pure fn ge(&self, other: &Package) -> bool { !(*self).lt(other) }
|
||||
pure fn gt(&self, other: &Package) -> bool { (*other).lt(&(*self)) }
|
||||
}
|
||||
|
||||
struct Source {
|
||||
name: ~str,
|
||||
mut url: ~str,
|
||||
mut method: ~str,
|
||||
mut key: Option<~str>,
|
||||
mut keyfp: Option<~str>,
|
||||
packages: DVec<Package>
|
||||
}
|
||||
|
||||
struct Cargo {
|
||||
pgp: bool,
|
||||
root: Path,
|
||||
installdir: Path,
|
||||
bindir: Path,
|
||||
libdir: Path,
|
||||
workdir: Path,
|
||||
sourcedir: Path,
|
||||
sources: map::HashMap<~str, @Source>,
|
||||
mut current_install: ~str,
|
||||
dep_cache: map::HashMap<~str, bool>,
|
||||
opts: Options
|
||||
}
|
||||
|
||||
struct Crate {
|
||||
name: ~str,
|
||||
vers: ~str,
|
||||
uuid: ~str,
|
||||
desc: Option<~str>,
|
||||
sigs: Option<~str>,
|
||||
crate_type: Option<~str>,
|
||||
deps: ~[~str]
|
||||
}
|
||||
|
||||
struct Options {
|
||||
test: bool,
|
||||
mode: Mode,
|
||||
free: ~[~str],
|
||||
help: bool,
|
||||
}
|
||||
|
||||
enum Mode { SystemMode, UserMode, LocalMode }
|
||||
|
||||
impl Mode : cmp::Eq {
|
||||
pure fn eq(&self, other: &Mode) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
pure fn ne(&self, other: &Mode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
fn opts() -> ~[getopts::Opt] {
|
||||
~[optflag(~"g"), optflag(~"G"), optflag(~"test"),
|
||||
optflag(~"h"), optflag(~"help")]
|
||||
}
|
||||
|
||||
fn info(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_green);
|
||||
out.write_str(~"info: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
} else { out.write_line(~"info: " + msg); }
|
||||
}
|
||||
|
||||
fn warn(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_yellow);
|
||||
out.write_str(~"warning: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
}else { out.write_line(~"warning: " + msg); }
|
||||
}
|
||||
|
||||
fn error(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_red);
|
||||
out.write_str(~"error: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
}
|
||||
else { out.write_line(~"error: " + msg); }
|
||||
}
|
||||
|
||||
fn is_uuid(id: ~str) -> bool {
|
||||
let parts = str::split_str(id, ~"-");
|
||||
if vec::len(parts) == 5u {
|
||||
let mut correct = 0u;
|
||||
for vec::eachi(parts) |i, part| {
|
||||
fn is_hex_digit(+ch: char) -> bool {
|
||||
('0' <= ch && ch <= '9') ||
|
||||
('a' <= ch && ch <= 'f') ||
|
||||
('A' <= ch && ch <= 'F')
|
||||
}
|
||||
|
||||
if !part.all(is_hex_digit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
match i {
|
||||
0u => {
|
||||
if part.len() == 8u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
1u | 2u | 3u => {
|
||||
if part.len() == 4u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
4u => {
|
||||
if part.len() == 12u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
if correct >= 5u {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_uuid() {
|
||||
assert is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaafAF09");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"");
|
||||
assert !is_uuid(~"aaaaaaaa-aaa -aaaa-aaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"aaaaaaaa-aaa!-aaaa-aaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa-a");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaป");
|
||||
}
|
||||
|
||||
// FIXME (#2661): implement url/URL parsing so we don't have to resort
|
||||
// to weak checks
|
||||
|
||||
fn has_archive_extension(p: ~str) -> bool {
|
||||
str::ends_with(p, ~".tar") ||
|
||||
str::ends_with(p, ~".tar.gz") ||
|
||||
str::ends_with(p, ~".tar.bz2") ||
|
||||
str::ends_with(p, ~".tar.Z") ||
|
||||
str::ends_with(p, ~".tar.lz") ||
|
||||
str::ends_with(p, ~".tar.xz") ||
|
||||
str::ends_with(p, ~".tgz") ||
|
||||
str::ends_with(p, ~".tbz") ||
|
||||
str::ends_with(p, ~".tbz2") ||
|
||||
str::ends_with(p, ~".tb2") ||
|
||||
str::ends_with(p, ~".taz") ||
|
||||
str::ends_with(p, ~".tlz") ||
|
||||
str::ends_with(p, ~".txz")
|
||||
}
|
||||
|
||||
fn is_archive_path(u: ~str) -> bool {
|
||||
has_archive_extension(u) && os::path_exists(&Path(u))
|
||||
}
|
||||
|
||||
fn is_archive_url(u: ~str) -> bool {
|
||||
// FIXME (#2661): this requires the protocol bit - if we had proper
|
||||
// url parsing, we wouldn't need it
|
||||
|
||||
match str::find_str(u, ~"://") {
|
||||
option::Some(_) => has_archive_extension(u),
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_git_url(url: ~str) -> bool {
|
||||
if str::ends_with(url, ~"/") { str::ends_with(url, ~".git/") }
|
||||
else {
|
||||
str::starts_with(url, ~"git://") || str::ends_with(url, ~".git")
|
||||
}
|
||||
}
|
||||
|
||||
fn assume_source_method(url: ~str) -> ~str {
|
||||
if is_git_url(url) {
|
||||
return ~"git";
|
||||
}
|
||||
if str::starts_with(url, ~"file://") || os::path_exists(&Path(url)) {
|
||||
return ~"file";
|
||||
}
|
||||
|
||||
~"curl"
|
||||
}
|
||||
|
||||
fn load_link(mis: ~[@ast::meta_item]) -> (Option<~str>,
|
||||
Option<~str>,
|
||||
Option<~str>) {
|
||||
let mut name = None;
|
||||
let mut vers = None;
|
||||
let mut uuid = None;
|
||||
for mis.each |a| {
|
||||
match a.node {
|
||||
ast::meta_name_value(v, {node: ast::lit_str(s), span: _}) => {
|
||||
match v {
|
||||
~"name" => name = Some(*s),
|
||||
~"vers" => vers = Some(*s),
|
||||
~"uuid" => uuid = Some(*s),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
_ => fail ~"load_link: meta items must be name-values"
|
||||
}
|
||||
}
|
||||
(name, vers, uuid)
|
||||
}
|
||||
|
||||
fn load_crate(filename: &Path) -> Option<Crate> {
|
||||
let sess = parse::new_parse_sess(None);
|
||||
let c = parse::parse_crate_from_file(filename, ~[], sess);
|
||||
|
||||
let mut name = None;
|
||||
let mut vers = None;
|
||||
let mut uuid = None;
|
||||
let mut desc = None;
|
||||
let mut sigs = None;
|
||||
let mut crate_type = None;
|
||||
|
||||
for c.node.attrs.each |a| {
|
||||
match a.node.value.node {
|
||||
ast::meta_name_value(v, {node: ast::lit_str(_), span: _}) => {
|
||||
match v {
|
||||
~"desc" => desc = Some(v),
|
||||
~"sigs" => sigs = Some(v),
|
||||
~"crate_type" => crate_type = Some(v),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
ast::meta_list(v, mis) => {
|
||||
if v == ~"link" {
|
||||
let (n, v, u) = load_link(mis);
|
||||
name = n;
|
||||
vers = v;
|
||||
uuid = u;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
fail ~"crate attributes may not contain " +
|
||||
~"meta_words";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type env = @{
|
||||
mut deps: ~[~str]
|
||||
};
|
||||
|
||||
fn goto_view_item(ps: syntax::parse::parse_sess, e: env,
|
||||
i: @ast::view_item) {
|
||||
match i.node {
|
||||
ast::view_item_use(ident, metas, _) => {
|
||||
let name_items =
|
||||
attr::find_meta_items_by_name(metas, ~"name");
|
||||
let m = if name_items.is_empty() {
|
||||
metas + ~[attr::mk_name_value_item_str(
|
||||
~"name", *ps.interner.get(ident))]
|
||||
} else {
|
||||
metas
|
||||
};
|
||||
let mut attr_name = ident;
|
||||
let mut attr_vers = ~"";
|
||||
let mut attr_from = ~"";
|
||||
|
||||
for m.each |item| {
|
||||
match attr::get_meta_item_value_str(*item) {
|
||||
Some(value) => {
|
||||
let name = attr::get_meta_item_name(*item);
|
||||
|
||||
match name {
|
||||
~"vers" => attr_vers = value,
|
||||
~"from" => attr_from = value,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
let query = if !str::is_empty(attr_from) {
|
||||
attr_from
|
||||
} else {
|
||||
if !str::is_empty(attr_vers) {
|
||||
ps.interner.get(attr_name) + ~"@" + attr_vers
|
||||
} else { *ps.interner.get(attr_name) }
|
||||
};
|
||||
|
||||
match *ps.interner.get(attr_name) {
|
||||
~"std" | ~"core" => (),
|
||||
_ => e.deps.push(query)
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
fn goto_item(_e: env, _i: @ast::item) {
|
||||
}
|
||||
|
||||
let e = @{
|
||||
mut deps: ~[]
|
||||
};
|
||||
let v = visit::mk_simple_visitor(@{
|
||||
visit_view_item: |a| goto_view_item(sess, e, a),
|
||||
visit_item: |a| goto_item(e, a),
|
||||
.. *visit::default_simple_visitor()
|
||||
});
|
||||
|
||||
visit::visit_crate(*c, (), v);
|
||||
|
||||
let deps = copy e.deps;
|
||||
|
||||
match (name, vers, uuid) {
|
||||
(Some(name0), Some(vers0), Some(uuid0)) => {
|
||||
Some(Crate {
|
||||
name: name0,
|
||||
vers: vers0,
|
||||
uuid: uuid0,
|
||||
desc: desc,
|
||||
sigs: sigs,
|
||||
crate_type: crate_type,
|
||||
deps: deps })
|
||||
}
|
||||
_ => return None
|
||||
}
|
||||
}
|
||||
|
||||
fn print(s: ~str) {
|
||||
io::stdout().write_line(s);
|
||||
}
|
||||
|
||||
fn rest(s: ~str, start: uint) -> ~str {
|
||||
if (start >= str::len(s)) {
|
||||
~""
|
||||
} else {
|
||||
str::slice(s, start, str::len(s))
|
||||
}
|
||||
}
|
||||
|
||||
fn need_dir(s: &Path) {
|
||||
if os::path_is_dir(s) { return; }
|
||||
if !os::make_dir(s, 493_i32 /* oct: 755 */) {
|
||||
fail fmt!("can't make_dir %s", s.to_str());
|
||||
}
|
||||
}
|
||||
|
||||
fn valid_pkg_name(s: &str) -> bool {
|
||||
fn is_valid_digit(+c: char) -> bool {
|
||||
('0' <= c && c <= '9') ||
|
||||
('a' <= c && c <= 'z') ||
|
||||
('A' <= c && c <= 'Z') ||
|
||||
c == '-' ||
|
||||
c == '_'
|
||||
}
|
||||
|
||||
s.all(is_valid_digit)
|
||||
}
|
||||
|
||||
fn parse_source(name: ~str, j: &json::Json) -> @Source {
|
||||
if !valid_pkg_name(name) {
|
||||
fail fmt!("'%s' is an invalid source name", name);
|
||||
}
|
||||
|
||||
match *j {
|
||||
json::Object(j) => {
|
||||
let mut url = match j.find(&~"url") {
|
||||
Some(json::String(u)) => u,
|
||||
_ => fail ~"needed 'url' field in source"
|
||||
};
|
||||
let method = match j.find(&~"method") {
|
||||
Some(json::String(u)) => u,
|
||||
_ => assume_source_method(url)
|
||||
};
|
||||
let key = match j.find(&~"key") {
|
||||
Some(json::String(u)) => Some(u),
|
||||
_ => None
|
||||
};
|
||||
let keyfp = match j.find(&~"keyfp") {
|
||||
Some(json::String(u)) => Some(u),
|
||||
_ => None
|
||||
};
|
||||
if method == ~"file" {
|
||||
url = os::make_absolute(&Path(url)).to_str();
|
||||
}
|
||||
return @Source {
|
||||
name: name,
|
||||
mut url: url,
|
||||
mut method: method,
|
||||
mut key: key,
|
||||
mut keyfp: keyfp,
|
||||
packages: DVec() };
|
||||
}
|
||||
_ => fail ~"needed dict value in source"
|
||||
};
|
||||
}
|
||||
|
||||
fn try_parse_sources(filename: &Path, sources: map::HashMap<~str, @Source>) {
|
||||
if !os::path_exists(filename) { return; }
|
||||
let c = io::read_whole_file_str(filename);
|
||||
match json::from_str(c.get()) {
|
||||
Ok(json::Object(j)) => {
|
||||
for j.each |k, v| {
|
||||
sources.insert(copy *k, parse_source(*k, v));
|
||||
debug!("source: %s", *k);
|
||||
}
|
||||
}
|
||||
Ok(_) => fail ~"malformed sources.json",
|
||||
Err(e) => fail fmt!("%s:%s", filename.to_str(), e.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
fn load_one_source_package(src: @Source, p: &json::Object) {
|
||||
let name = match p.find(&~"name") {
|
||||
Some(json::String(n)) => {
|
||||
if !valid_pkg_name(n) {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~", '" + n + ~"'"+
|
||||
~" is an invalid name (alphanumeric, underscores and" +
|
||||
~" dashes only)");
|
||||
return;
|
||||
}
|
||||
n
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing name)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let uuid = match p.find(&~"uuid") {
|
||||
Some(json::String(n)) => {
|
||||
if !is_uuid(n) {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~", '" + n + ~"'"+
|
||||
~" is an invalid uuid");
|
||||
return;
|
||||
}
|
||||
n
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing uuid)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let url = match p.find(&~"url") {
|
||||
Some(json::String(n)) => n,
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing url)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let method = match p.find(&~"method") {
|
||||
Some(json::String(n)) => n,
|
||||
_ => {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~" (missing method)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let reference = match p.find(&~"ref") {
|
||||
Some(json::String(n)) => Some(n),
|
||||
_ => None
|
||||
};
|
||||
|
||||
let mut tags = ~[];
|
||||
match p.find(&~"tags") {
|
||||
Some(json::List(js)) => {
|
||||
for js.each |j| {
|
||||
match *j {
|
||||
json::String(ref j) => tags.grow(1u, j),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
let description = match p.find(&~"description") {
|
||||
Some(json::String(n)) => n,
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name
|
||||
+ ~" (missing description)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let newpkg = Package {
|
||||
name: name,
|
||||
uuid: uuid,
|
||||
url: url,
|
||||
method: method,
|
||||
description: description,
|
||||
reference: reference,
|
||||
tags: tags,
|
||||
versions: ~[]
|
||||
};
|
||||
|
||||
match src.packages.position(|pkg| pkg.uuid == uuid) {
|
||||
Some(idx) => {
|
||||
src.packages.set_elt(idx, newpkg);
|
||||
log(debug, ~" updated package: " + src.name + ~"/" + name);
|
||||
}
|
||||
None => {
|
||||
src.packages.push(newpkg);
|
||||
}
|
||||
}
|
||||
|
||||
log(debug, ~" loaded package: " + src.name + ~"/" + name);
|
||||
}
|
||||
|
||||
fn load_source_info(c: &Cargo, src: @Source) {
|
||||
let dir = c.sourcedir.push(src.name);
|
||||
let srcfile = dir.push("source.json");
|
||||
if !os::path_exists(&srcfile) { return; }
|
||||
let srcstr = io::read_whole_file_str(&srcfile);
|
||||
match json::from_str(srcstr.get()) {
|
||||
Ok(ref json @ json::Object(_)) => {
|
||||
let o = parse_source(src.name, json);
|
||||
|
||||
src.key = o.key;
|
||||
src.keyfp = o.keyfp;
|
||||
}
|
||||
Ok(_) => {
|
||||
warn(~"malformed source.json: " + src.name +
|
||||
~"(source info is not a dict)");
|
||||
}
|
||||
Err(e) => {
|
||||
warn(fmt!("%s:%s", src.name, e.to_str()));
|
||||
}
|
||||
};
|
||||
}
|
||||
fn load_source_packages(c: &Cargo, src: @Source) {
|
||||
log(debug, ~"loading source: " + src.name);
|
||||
let dir = c.sourcedir.push(src.name);
|
||||
let pkgfile = dir.push("packages.json");
|
||||
if !os::path_exists(&pkgfile) { return; }
|
||||
let pkgstr = io::read_whole_file_str(&pkgfile);
|
||||
match json::from_str(pkgstr.get()) {
|
||||
Ok(json::List(js)) => {
|
||||
for js.each |j| {
|
||||
match *j {
|
||||
json::Object(p) => {
|
||||
load_one_source_package(src, p);
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name +
|
||||
~" (non-dict pkg)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(_) => {
|
||||
warn(~"malformed packages.json: " + src.name +
|
||||
~"(packages is not a list)");
|
||||
}
|
||||
Err(e) => {
|
||||
warn(fmt!("%s:%s", src.name, e.to_str()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn build_cargo_options(argv: ~[~str]) -> Options {
|
||||
let matches = &match getopts::getopts(argv, opts()) {
|
||||
result::Ok(m) => m,
|
||||
result::Err(f) => {
|
||||
fail fmt!("%s", getopts::fail_str(f));
|
||||
}
|
||||
};
|
||||
|
||||
let test = opt_present(matches, ~"test");
|
||||
let G = opt_present(matches, ~"G");
|
||||
let g = opt_present(matches, ~"g");
|
||||
let help = opt_present(matches, ~"h") || opt_present(matches, ~"help");
|
||||
let len = vec::len(matches.free);
|
||||
|
||||
let is_install = len > 1u && matches.free[1] == ~"install";
|
||||
let is_uninstall = len > 1u && matches.free[1] == ~"uninstall";
|
||||
|
||||
if G && g { fail ~"-G and -g both provided"; }
|
||||
|
||||
if !is_install && !is_uninstall && (g || G) {
|
||||
fail ~"-g and -G are only valid for `install` and `uninstall|rm`";
|
||||
}
|
||||
|
||||
let mode =
|
||||
if (!is_install && !is_uninstall) || g { UserMode }
|
||||
else if G { SystemMode }
|
||||
else { LocalMode };
|
||||
|
||||
Options {test: test, mode: mode, free: matches.free, help: help}
|
||||
}
|
||||
|
||||
fn configure(opts: Options) -> Cargo {
|
||||
let home = match get_cargo_root() {
|
||||
Ok(home) => home,
|
||||
Err(_err) => get_cargo_sysroot().get()
|
||||
};
|
||||
|
||||
let get_cargo_dir = match opts.mode {
|
||||
SystemMode => get_cargo_sysroot,
|
||||
UserMode => get_cargo_root,
|
||||
LocalMode => get_cargo_root_nearest
|
||||
};
|
||||
|
||||
let p = get_cargo_dir().get();
|
||||
|
||||
let sources = HashMap();
|
||||
try_parse_sources(&home.push("sources.json"), sources);
|
||||
try_parse_sources(&home.push("local-sources.json"), sources);
|
||||
|
||||
let dep_cache = HashMap();
|
||||
|
||||
let mut c = Cargo {
|
||||
pgp: pgp::supported(),
|
||||
root: home,
|
||||
installdir: p,
|
||||
bindir: p.push("bin"),
|
||||
libdir: p.push("lib"),
|
||||
workdir: p.push("work"),
|
||||
sourcedir: home.push("sources"),
|
||||
sources: sources,
|
||||
mut current_install: ~"",
|
||||
dep_cache: dep_cache,
|
||||
opts: opts
|
||||
};
|
||||
|
||||
need_dir(&c.root);
|
||||
need_dir(&c.installdir);
|
||||
need_dir(&c.sourcedir);
|
||||
need_dir(&c.workdir);
|
||||
need_dir(&c.libdir);
|
||||
need_dir(&c.bindir);
|
||||
|
||||
for sources.each_key |k| {
|
||||
let mut s = sources.get(k);
|
||||
load_source_packages(&c, s);
|
||||
sources.insert(k, s);
|
||||
}
|
||||
|
||||
if c.pgp {
|
||||
pgp::init(&c.root);
|
||||
} else {
|
||||
warn(~"command `gpg` was not found");
|
||||
warn(~"you have to install gpg from source " +
|
||||
~" or package manager to get it to work correctly");
|
||||
}
|
||||
|
||||
move c
|
||||
}
|
||||
|
||||
fn for_each_package(c: &Cargo, b: fn(s: @Source, p: &Package)) {
|
||||
for c.sources.each_value |v| {
|
||||
for v.packages.each |p| {
|
||||
b(v, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Runs all programs in directory <buildpath>
|
||||
fn run_programs(buildpath: &Path) {
|
||||
let newv = os::list_dir_path(buildpath);
|
||||
for newv.each |ct| {
|
||||
run::run_program(ct.to_str(), ~[]);
|
||||
}
|
||||
}
|
||||
|
||||
// Runs rustc in <path + subdir> with the given flags
|
||||
// and returns <patho + subdir>
|
||||
fn run_in_buildpath(what: &str, path: &Path, subdir: &Path, cf: &Path,
|
||||
extra_flags: ~[~str]) -> Option<Path> {
|
||||
let buildpath = path.push_rel(subdir);
|
||||
need_dir(&buildpath);
|
||||
debug!("%s: %s -> %s", what, cf.to_str(), buildpath.to_str());
|
||||
let p = run::program_output(rustc_sysroot(),
|
||||
~[~"--out-dir",
|
||||
buildpath.to_str(),
|
||||
cf.to_str()] + extra_flags);
|
||||
if p.status != 0 {
|
||||
error(fmt!("rustc failed: %d\n%s\n%s", p.status, p.err, p.out));
|
||||
return None;
|
||||
}
|
||||
Some(buildpath)
|
||||
}
|
||||
|
||||
fn test_one_crate(_c: &Cargo, path: &Path, cf: &Path) {
|
||||
let buildpath = match run_in_buildpath(~"testing", path,
|
||||
&Path("test"),
|
||||
cf,
|
||||
~[ ~"--test"]) {
|
||||
None => return,
|
||||
Some(bp) => bp
|
||||
};
|
||||
run_programs(&buildpath);
|
||||
}
|
||||
|
||||
fn install_one_crate(c: &Cargo, path: &Path, cf: &Path) {
|
||||
let buildpath = match run_in_buildpath(~"installing", path,
|
||||
&Path("build"),
|
||||
cf, ~[]) {
|
||||
None => return,
|
||||
Some(bp) => bp
|
||||
};
|
||||
let newv = os::list_dir_path(&buildpath);
|
||||
let exec_suffix = os::exe_suffix();
|
||||
for newv.each |ct| {
|
||||
if (exec_suffix != ~"" && str::ends_with(ct.to_str(),
|
||||
exec_suffix)) ||
|
||||
(exec_suffix == ~"" &&
|
||||
!str::starts_with(ct.filename().get(),
|
||||
~"lib")) {
|
||||
debug!(" bin: %s", ct.to_str());
|
||||
install_to_dir(*ct, &c.bindir);
|
||||
if c.opts.mode == SystemMode {
|
||||
// FIXME (#2662): Put this file in PATH / symlink it so it can
|
||||
// be used as a generic executable
|
||||
// `cargo install -G rustray` and `rustray file.obj`
|
||||
}
|
||||
} else {
|
||||
debug!(" lib: %s", ct.to_str());
|
||||
install_to_dir(*ct, &c.libdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn rustc_sysroot() -> ~str {
|
||||
match os::self_exe_path() {
|
||||
Some(path) => {
|
||||
let rustc = path.push_many([~"..", ~"bin", ~"rustc"]);
|
||||
debug!(" rustc: %s", rustc.to_str());
|
||||
rustc.to_str()
|
||||
}
|
||||
None => ~"rustc"
|
||||
}
|
||||
}
|
||||
|
||||
fn install_source(c: &Cargo, path: &Path) {
|
||||
debug!("source: %s", path.to_str());
|
||||
os::change_dir(path);
|
||||
|
||||
let mut cratefiles = ~[];
|
||||
for os::walk_dir(&Path(".")) |p| {
|
||||
if p.filetype() == Some(~".rc") {
|
||||
cratefiles.push(*p);
|
||||
}
|
||||
}
|
||||
|
||||
if vec::is_empty(cratefiles) {
|
||||
fail ~"this doesn't look like a rust package (no .rc files)";
|
||||
}
|
||||
|
||||
for cratefiles.each |cf| {
|
||||
match load_crate(cf) {
|
||||
None => loop,
|
||||
Some(crate) => {
|
||||
for crate.deps.each |query| {
|
||||
// FIXME (#1356): handle cyclic dependencies
|
||||
// (n.b. #1356 says "Cyclic dependency is an error
|
||||
// condition")
|
||||
|
||||
let wd = get_temp_workdir(c);
|
||||
install_query(c, &wd, *query);
|
||||
}
|
||||
|
||||
os::change_dir(path);
|
||||
|
||||
if c.opts.test {
|
||||
test_one_crate(c, path, cf);
|
||||
}
|
||||
install_one_crate(c, path, cf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn install_git(c: &Cargo, wd: &Path, url: ~str, reference: Option<~str>) {
|
||||
run::program_output(~"git", ~[~"clone", url, wd.to_str()]);
|
||||
if reference.is_some() {
|
||||
let r = reference.get();
|
||||
os::change_dir(wd);
|
||||
run::run_program(~"git", ~[~"checkout", r]);
|
||||
}
|
||||
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
fn install_curl(c: &Cargo, wd: &Path, url: ~str) {
|
||||
let tarpath = wd.push("pkg.tar");
|
||||
let p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o",
|
||||
tarpath.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
fail fmt!("fetch of %s failed: %s", url, p.err);
|
||||
}
|
||||
run::run_program(~"tar", ~[~"-x", ~"--strip-components=1",
|
||||
~"-C", wd.to_str(),
|
||||
~"-f", tarpath.to_str()]);
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
fn install_file(c: &Cargo, wd: &Path, path: &Path) {
|
||||
run::program_output(~"tar", ~[~"-x", ~"--strip-components=1",
|
||||
~"-C", wd.to_str(),
|
||||
~"-f", path.to_str()]);
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
fn install_package(c: &Cargo, src: ~str, wd: &Path, pkg: Package) {
|
||||
let url = copy pkg.url;
|
||||
let method = match pkg.method {
|
||||
~"git" => ~"git",
|
||||
~"file" => ~"file",
|
||||
_ => ~"curl"
|
||||
};
|
||||
|
||||
info(fmt!("installing %s/%s via %s...", src, pkg.name, method));
|
||||
|
||||
match method {
|
||||
~"git" => install_git(c, wd, url, copy pkg.reference),
|
||||
~"file" => install_file(c, wd, &Path(url)),
|
||||
~"curl" => install_curl(c, wd, url),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
fn cargo_suggestion(c: &Cargo, fallback: fn())
|
||||
{
|
||||
if c.sources.size() == 0u {
|
||||
error(~"no sources defined - you may wish to run " +
|
||||
~"`cargo init`");
|
||||
return;
|
||||
}
|
||||
fallback();
|
||||
}
|
||||
|
||||
fn install_uuid(c: &Cargo, wd: &Path, uuid: ~str) {
|
||||
let mut ps = ~[];
|
||||
for_each_package(c, |s, p| {
|
||||
if p.uuid == uuid {
|
||||
vec::push(&mut ps, (s.name, copy *p));
|
||||
}
|
||||
});
|
||||
if vec::len(ps) == 1u {
|
||||
let (sname, p) = copy ps[0];
|
||||
install_package(c, sname, wd, p);
|
||||
return;
|
||||
} else if vec::len(ps) == 0u {
|
||||
cargo_suggestion(c, || {
|
||||
error(~"can't find package: " + uuid);
|
||||
});
|
||||
return;
|
||||
}
|
||||
error(~"found multiple packages:");
|
||||
for ps.each |elt| {
|
||||
let (sname,p) = copy *elt;
|
||||
info(~" " + sname + ~"/" + p.uuid + ~" (" + p.name + ~")");
|
||||
}
|
||||
}
|
||||
|
||||
fn install_named(c: &Cargo, wd: &Path, name: ~str) {
|
||||
let mut ps = ~[];
|
||||
for_each_package(c, |s, p| {
|
||||
if p.name == name {
|
||||
vec::push(&mut ps, (s.name, copy *p));
|
||||
}
|
||||
});
|
||||
if vec::len(ps) == 1u {
|
||||
let (sname, p) = copy ps[0];
|
||||
install_package(c, sname, wd, p);
|
||||
return;
|
||||
} else if vec::len(ps) == 0u {
|
||||
cargo_suggestion(c, || {
|
||||
error(~"can't find package: " + name);
|
||||
});
|
||||
return;
|
||||
}
|
||||
error(~"found multiple packages:");
|
||||
for ps.each |elt| {
|
||||
let (sname,p) = copy *elt;
|
||||
info(~" " + sname + ~"/" + p.uuid + ~" (" + p.name + ~")");
|
||||
}
|
||||
}
|
||||
|
||||
fn install_uuid_specific(c: &Cargo, wd: &Path, src: ~str, uuid: ~str) {
|
||||
match c.sources.find(src) {
|
||||
Some(s) => {
|
||||
for s.packages.each |p| {
|
||||
if p.uuid == uuid {
|
||||
install_package(c, src, wd, *p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
error(~"can't find package: " + src + ~"/" + uuid);
|
||||
}
|
||||
|
||||
fn install_named_specific(c: &Cargo, wd: &Path, src: ~str, name: ~str) {
|
||||
match c.sources.find(src) {
|
||||
Some(s) => {
|
||||
for s.packages.each |p| {
|
||||
if p.name == name {
|
||||
install_package(c, src, wd, *p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
error(~"can't find package: " + src + ~"/" + name);
|
||||
}
|
||||
|
||||
fn cmd_uninstall(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let lib = &c.libdir;
|
||||
let bin = &c.bindir;
|
||||
let target = c.opts.free[2u];
|
||||
|
||||
// FIXME (#2662): needs stronger pattern matching
|
||||
// FIXME (#2662): needs to uninstall from a specified location in a
|
||||
// cache instead of looking for it (binaries can be uninstalled by
|
||||
// name only)
|
||||
|
||||
fn try_uninstall(p: &Path) -> bool {
|
||||
if os::remove_file(p) {
|
||||
info(~"uninstalled: '" + p.to_str() + ~"'");
|
||||
true
|
||||
} else {
|
||||
error(~"could not uninstall: '" +
|
||||
p.to_str() + ~"'");
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
if is_uuid(target) {
|
||||
for os::list_dir(lib).each |file| {
|
||||
match str::find_str(*file, ~"-" + target + ~"-") {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
error(~"can't find package with uuid: " + target);
|
||||
} else {
|
||||
for os::list_dir(lib).each |file| {
|
||||
match str::find_str(*file, ~"lib" + target + ~"-") {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
for os::list_dir(bin).each |file| {
|
||||
match str::find_str(*file, target) {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
error(~"can't find package with name: " + target);
|
||||
}
|
||||
}
|
||||
|
||||
fn install_query(c: &Cargo, wd: &Path, target: ~str) {
|
||||
match c.dep_cache.find(target) {
|
||||
Some(inst) => {
|
||||
if inst {
|
||||
return;
|
||||
}
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
|
||||
c.dep_cache.insert(target, true);
|
||||
|
||||
if is_archive_path(target) {
|
||||
install_file(c, wd, &Path(target));
|
||||
return;
|
||||
} else if is_git_url(target) {
|
||||
let reference = if c.opts.free.len() >= 4u {
|
||||
Some(c.opts.free[3u])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
install_git(c, wd, target, reference);
|
||||
} else if !valid_pkg_name(target) && has_archive_extension(target) {
|
||||
install_curl(c, wd, target);
|
||||
return;
|
||||
} else {
|
||||
let mut ps = copy target;
|
||||
|
||||
match str::find_char(ps, '/') {
|
||||
option::Some(idx) => {
|
||||
let source = str::slice(ps, 0u, idx);
|
||||
ps = str::slice(ps, idx + 1u, str::len(ps));
|
||||
if is_uuid(ps) {
|
||||
install_uuid_specific(c, wd, source, ps);
|
||||
} else {
|
||||
install_named_specific(c, wd, source, ps);
|
||||
}
|
||||
}
|
||||
option::None => {
|
||||
if is_uuid(ps) {
|
||||
install_uuid(c, wd, ps);
|
||||
} else {
|
||||
install_named(c, wd, ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME (#2662): This whole dep_cache and current_install thing is
|
||||
// a bit of a hack. It should be cleaned up in the future.
|
||||
|
||||
if target == c.current_install {
|
||||
for c.dep_cache.each |k, _v| {
|
||||
c.dep_cache.remove(k);
|
||||
}
|
||||
|
||||
c.current_install = ~"";
|
||||
}
|
||||
}
|
||||
|
||||
fn get_temp_workdir(c: &Cargo) -> Path {
|
||||
match tempfile::mkdtemp(&c.workdir, "cargo") {
|
||||
Some(wd) => wd,
|
||||
None => fail fmt!("needed temp dir: %s",
|
||||
c.workdir.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_install(c: &Cargo) unsafe {
|
||||
let wd = get_temp_workdir(c);
|
||||
|
||||
if vec::len(c.opts.free) == 2u {
|
||||
let cwd = os::getcwd();
|
||||
let status = run::run_program(~"cp", ~[~"-R", cwd.to_str(),
|
||||
wd.to_str()]);
|
||||
|
||||
if status != 0 {
|
||||
fail fmt!("could not copy directory: %s", cwd.to_str());
|
||||
}
|
||||
|
||||
install_source(c, &wd);
|
||||
return;
|
||||
}
|
||||
|
||||
sync(c);
|
||||
|
||||
let query = c.opts.free[2];
|
||||
c.current_install = query.to_str();
|
||||
|
||||
install_query(c, &wd, query);
|
||||
}
|
||||
|
||||
fn sync(c: &Cargo) {
|
||||
for c.sources.each_key |k| {
|
||||
let mut s = c.sources.get(k);
|
||||
sync_one(c, s);
|
||||
c.sources.insert(k, s);
|
||||
}
|
||||
}
|
||||
|
||||
fn sync_one_file(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json.new");
|
||||
let destsrcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json.new");
|
||||
let destpkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let url = Path(src.url);
|
||||
let mut has_src_file = false;
|
||||
|
||||
if !os::copy_file(&url.push("packages.json"), &pkgfile) {
|
||||
error(fmt!("fetch for source %s (url %s) failed",
|
||||
name, url.to_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if os::copy_file(&url.push("source.json"), &srcfile) {
|
||||
has_src_file = false;
|
||||
}
|
||||
|
||||
os::copy_file(&url.push("source.json.sig"), &srcsigfile);
|
||||
os::copy_file(&url.push("packages.json.sig"), &sigfile);
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
|
||||
if has_src_file {
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(fmt!("signature verification failed for source %s \
|
||||
with key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
copy_warn(&pkgfile, &destpkgfile);
|
||||
|
||||
if has_src_file {
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&srcsigfile);
|
||||
os::remove_file(&pkgfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn sync_one_git(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let url = src.url;
|
||||
|
||||
fn rollback(name: ~str, dir: &Path, insecure: bool) {
|
||||
fn msg(name: ~str, insecure: bool) {
|
||||
error(fmt!("could not rollback source: %s", name));
|
||||
|
||||
if insecure {
|
||||
warn(~"a past security check failed on source " +
|
||||
name + ~" and rolling back the source failed -"
|
||||
+ ~" this source may be compromised");
|
||||
}
|
||||
}
|
||||
|
||||
if !os::change_dir(dir) {
|
||||
msg(name, insecure);
|
||||
}
|
||||
else {
|
||||
let p = run::program_output(~"git", ~[~"reset", ~"--hard",
|
||||
~"HEAD@{1}"]);
|
||||
|
||||
if p.status != 0 {
|
||||
msg(name, insecure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !os::path_exists(&dir.push(".git")) {
|
||||
let p = run::program_output(~"git", ~[~"clone", url, dir.to_str()]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if !os::change_dir(dir) {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let p = run::program_output(~"git", ~[~"pull"]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let has_src_file = os::path_exists(&srcfile);
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if has_src_file {
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(fmt!("signature verification failed for source %s \
|
||||
with key %s", name, f));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json.new");
|
||||
let destsrcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json.new");
|
||||
let destpkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let mut url = src.url;
|
||||
let smart = !str::ends_with(src.url, ~"packages.json");
|
||||
let mut has_src_file = false;
|
||||
|
||||
if smart {
|
||||
url += ~"/packages.json";
|
||||
}
|
||||
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", pkgfile.to_str(), url]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
if smart {
|
||||
url = src.url + ~"/source.json";
|
||||
let p =
|
||||
run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", srcfile.to_str(), url]);
|
||||
|
||||
if p.status == 0 {
|
||||
has_src_file = true;
|
||||
}
|
||||
}
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
if smart {
|
||||
url = src.url + ~"/packages.json.sig";
|
||||
}
|
||||
else {
|
||||
url = src.url + ~".sig";
|
||||
}
|
||||
|
||||
let mut p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s", ~"-o",
|
||||
sigfile.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (sig %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
|
||||
if smart && has_src_file {
|
||||
url = src.url + ~"/source.json.sig";
|
||||
|
||||
p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s", ~"-o",
|
||||
srcsigfile.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (sig %s) failed",
|
||||
name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(~"signature verification failed for " +
|
||||
~"source " + name + ~" with key " + f);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
copy_warn(&pkgfile, &destpkgfile);
|
||||
|
||||
if smart && has_src_file {
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&srcsigfile);
|
||||
os::remove_file(&pkgfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn sync_one(c: &Cargo, src: @Source) {
|
||||
let name = src.name;
|
||||
let dir = c.sourcedir.push(name);
|
||||
|
||||
info(fmt!("syncing source: %s...", name));
|
||||
|
||||
need_dir(&dir);
|
||||
|
||||
let result = match src.method {
|
||||
~"git" => sync_one_git(c, &dir, src),
|
||||
~"file" => sync_one_file(c, &dir, src),
|
||||
_ => sync_one_curl(c, &dir, src)
|
||||
};
|
||||
|
||||
if result {
|
||||
load_source_info(c, src);
|
||||
load_source_packages(c, src);
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_init(c: &Cargo) {
|
||||
let srcurl = ~"http://www.rust-lang.org/cargo/sources.json";
|
||||
let sigurl = ~"http://www.rust-lang.org/cargo/sources.json.sig";
|
||||
|
||||
let srcfile = c.root.push("sources.json.new");
|
||||
let sigfile = c.root.push("sources.json.sig");
|
||||
let destsrcfile = c.root.push("sources.json");
|
||||
|
||||
let p =
|
||||
run::program_output(~"curl", ~[~"-f", ~"-s",
|
||||
~"-o", srcfile.to_str(), srcurl]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch of sources.json failed: %s", p.out));
|
||||
return;
|
||||
}
|
||||
|
||||
let p =
|
||||
run::program_output(~"curl", ~[~"-f", ~"-s",
|
||||
~"-o", sigfile.to_str(), sigurl]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch of sources.json.sig failed: %s", p.out));
|
||||
return;
|
||||
}
|
||||
|
||||
let r = pgp::verify(&c.root, &srcfile, &sigfile);
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for '%s'",
|
||||
srcfile.to_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("initialized .cargo in %s", c.root.to_str()));
|
||||
}
|
||||
|
||||
fn print_pkg(s: @Source, p: &Package) {
|
||||
let mut m = s.name + ~"/" + p.name + ~" (" + p.uuid + ~")";
|
||||
if vec::len(p.tags) > 0u {
|
||||
m = m + ~" [" + str::connect(p.tags, ~", ") + ~"]";
|
||||
}
|
||||
info(m);
|
||||
if p.description != ~"" {
|
||||
print(~" >> " + p.description + ~"\n")
|
||||
}
|
||||
}
|
||||
|
||||
fn print_source(s: @Source) {
|
||||
info(s.name + ~" (" + s.url + ~")");
|
||||
|
||||
let pks = sort::merge_sort(s.packages.get(), sys::shape_lt);
|
||||
let l = vec::len(pks);
|
||||
|
||||
print(io::with_str_writer(|writer| {
|
||||
let mut list = ~" >> ";
|
||||
|
||||
for vec::eachi(pks) |i, pk| {
|
||||
if str::len(list) > 78u {
|
||||
writer.write_line(list);
|
||||
list = ~" >> ";
|
||||
}
|
||||
list += pk.name + (if l - 1u == i { ~"" } else { ~", " });
|
||||
}
|
||||
|
||||
writer.write_line(list);
|
||||
}));
|
||||
}
|
||||
|
||||
fn cmd_list(c: &Cargo) {
|
||||
sync(c);
|
||||
|
||||
if vec::len(c.opts.free) >= 3u {
|
||||
let v = vec::view(c.opts.free, 2u, vec::len(c.opts.free));
|
||||
for vec::each(v) |name| {
|
||||
if !valid_pkg_name(*name) {
|
||||
error(fmt!("'%s' is an invalid source name", *name));
|
||||
} else {
|
||||
match c.sources.find(*name) {
|
||||
Some(source) => {
|
||||
print_source(source);
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", *name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for c.sources.each_value |v| {
|
||||
print_source(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_search(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
sync(c);
|
||||
|
||||
let mut n = 0;
|
||||
let name = c.opts.free[2];
|
||||
let tags = vec::slice(c.opts.free, 3u, vec::len(c.opts.free));
|
||||
for_each_package(c, |s, p| {
|
||||
if (str::contains(p.name, name) || name == ~"*") &&
|
||||
vec::all(tags, |t| vec::contains(p.tags, t) ) {
|
||||
print_pkg(s, p);
|
||||
n += 1;
|
||||
}
|
||||
});
|
||||
info(fmt!("found %d packages", n));
|
||||
}
|
||||
|
||||
fn install_to_dir(srcfile: &Path, destdir: &Path) {
|
||||
let newfile = destdir.push(srcfile.filename().get());
|
||||
|
||||
let status = run::run_program(~"cp", ~[~"-r", srcfile.to_str(),
|
||||
newfile.to_str()]);
|
||||
if status == 0 {
|
||||
info(fmt!("installed: '%s'", newfile.to_str()));
|
||||
} else {
|
||||
error(fmt!("could not install: '%s'", newfile.to_str()));
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_cache(c: &Cargo) {
|
||||
need_dir(&c.root);
|
||||
|
||||
let out = c.root.push("cache.json");
|
||||
let _root = json::Object(~LinearMap());
|
||||
|
||||
if os::path_exists(&out) {
|
||||
copy_warn(&out, &c.root.push("cache.json.old"));
|
||||
}
|
||||
}
|
||||
fn dump_sources(c: &Cargo) {
|
||||
if c.sources.size() < 1u {
|
||||
return;
|
||||
}
|
||||
|
||||
need_dir(&c.root);
|
||||
|
||||
let out = c.root.push("sources.json");
|
||||
|
||||
if os::path_exists(&out) {
|
||||
copy_warn(&out, &c.root.push("sources.json.old"));
|
||||
}
|
||||
|
||||
match io::buffered_file_writer(&out) {
|
||||
result::Ok(writer) => {
|
||||
let mut hash = ~LinearMap();
|
||||
|
||||
for c.sources.each |k, v| {
|
||||
let mut chash = ~LinearMap();
|
||||
|
||||
chash.insert(~"url", json::String(v.url));
|
||||
chash.insert(~"method", json::String(v.method));
|
||||
|
||||
match copy v.key {
|
||||
Some(key) => {
|
||||
chash.insert(~"key", json::String(copy key));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match copy v.keyfp {
|
||||
Some(keyfp) => {
|
||||
chash.insert(~"keyfp", json::String(copy keyfp));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
hash.insert(copy k, json::Object(move chash));
|
||||
}
|
||||
|
||||
json::to_writer(writer, &json::Object(move hash))
|
||||
}
|
||||
result::Err(e) => {
|
||||
error(fmt!("could not dump sources: %s", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_warn(srcfile: &Path, destfile: &Path) {
|
||||
if !os::copy_file(srcfile, destfile) {
|
||||
warn(fmt!("copying %s to %s failed",
|
||||
srcfile.to_str(), destfile.to_str()));
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_sources(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
for c.sources.each_value |v| {
|
||||
info(fmt!("%s (%s) via %s",
|
||||
v.name, v.url, v.method));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let action = c.opts.free[2u];
|
||||
|
||||
match action {
|
||||
~"clear" => {
|
||||
for c.sources.each_key |k| {
|
||||
c.sources.remove(k);
|
||||
}
|
||||
|
||||
info(~"cleared sources");
|
||||
}
|
||||
~"add" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let url = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
if c.sources.contains_key(name) {
|
||||
error(fmt!("source already exists: %s", name));
|
||||
} else {
|
||||
c.sources.insert(name, @Source {
|
||||
name: name,
|
||||
mut url: url,
|
||||
mut method: assume_source_method(url),
|
||||
mut key: None,
|
||||
mut keyfp: None,
|
||||
packages: DVec()
|
||||
});
|
||||
info(fmt!("added source: %s", name));
|
||||
}
|
||||
}
|
||||
~"remove" => {
|
||||
if vec::len(c.opts.free) < 4u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
if c.sources.contains_key(name) {
|
||||
c.sources.remove(name);
|
||||
info(fmt!("removed source: %s", name));
|
||||
} else {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
~"set-url" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let url = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(name) {
|
||||
Some(source) => {
|
||||
let old = copy source.url;
|
||||
let method = assume_source_method(url);
|
||||
|
||||
source.url = url;
|
||||
source.method = method;
|
||||
|
||||
c.sources.insert(name, source);
|
||||
|
||||
info(fmt!("changed source url: '%s' to '%s'", old, url));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
~"set-method" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let method = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(name) {
|
||||
Some(source) => {
|
||||
let old = copy source.method;
|
||||
|
||||
source.method = match method {
|
||||
~"git" => ~"git",
|
||||
~"file" => ~"file",
|
||||
_ => ~"curl"
|
||||
};
|
||||
|
||||
c.sources.insert(name, source);
|
||||
|
||||
info(fmt!("changed source method: '%s' to '%s'", old,
|
||||
method));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
~"rename" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let newn = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
if !valid_pkg_name(newn) {
|
||||
error(fmt!("'%s' is an invalid source name", newn));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(name) {
|
||||
Some(source) => {
|
||||
c.sources.remove(name);
|
||||
c.sources.insert(newn, source);
|
||||
info(fmt!("renamed source: %s to %s", name, newn));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => cmd_usage()
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_usage() {
|
||||
print(~"Usage: cargo <cmd> [options] [args..]
|
||||
e.g. cargo install <name>
|
||||
|
||||
Where <cmd> is one of:
|
||||
init, install, list, search, sources,
|
||||
uninstall, usage
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help Display this message
|
||||
<cmd> -h, <cmd> --help Display help for <cmd>
|
||||
");
|
||||
}
|
||||
|
||||
fn cmd_usage_init() {
|
||||
print(~"cargo init
|
||||
|
||||
Re-initialize cargo in ~/.cargo. Clears all sources and then adds the
|
||||
default sources from <www.rust-lang.org/sources.json>.");
|
||||
}
|
||||
|
||||
fn cmd_usage_install() {
|
||||
print(~"cargo install
|
||||
cargo install [source/]<name>[@version]
|
||||
cargo install [source/]<uuid>[@version]
|
||||
cargo install <git url> [ref]
|
||||
cargo install <tarball url>
|
||||
cargo install <tarball file>
|
||||
|
||||
Options:
|
||||
--test Run crate tests before installing
|
||||
-g Install to the user level (~/.cargo/bin/ instead of
|
||||
locally in ./.cargo/bin/ by default)
|
||||
-G Install to the system level (/usr/local/lib/cargo/bin/)
|
||||
|
||||
Install a crate. If no arguments are supplied, it installs from
|
||||
the current working directory. If a source is provided, only install
|
||||
from that source, otherwise it installs from any source.");
|
||||
}
|
||||
|
||||
fn cmd_usage_uninstall() {
|
||||
print(~"cargo uninstall [source/]<name>[@version]
|
||||
cargo uninstall [source/]<uuid>[@version]
|
||||
cargo uninstall <meta-name>[@version]
|
||||
cargo uninstall <meta-uuid>[@version]
|
||||
|
||||
Options:
|
||||
-g Remove from the user level (~/.cargo/bin/ instead of
|
||||
locally in ./.cargo/bin/ by default)
|
||||
-G Remove from the system level (/usr/local/lib/cargo/bin/)
|
||||
|
||||
Remove a crate. If a source is provided, only remove
|
||||
from that source, otherwise it removes from any source.
|
||||
If a crate was installed directly (git, tarball, etc.), you can remove
|
||||
it by metadata.");
|
||||
}
|
||||
|
||||
fn cmd_usage_list() {
|
||||
print(~"cargo list [sources..]
|
||||
|
||||
If no arguments are provided, list all sources and their packages.
|
||||
If source names are provided, list those sources and their packages.
|
||||
");
|
||||
}
|
||||
|
||||
fn cmd_usage_search() {
|
||||
print(~"cargo search <query | '*'> [tags..]
|
||||
|
||||
Search packages.");
|
||||
}
|
||||
|
||||
fn cmd_usage_sources() {
|
||||
print(~"cargo sources
|
||||
cargo sources add <name> <url>
|
||||
cargo sources remove <name>
|
||||
cargo sources rename <name> <new>
|
||||
cargo sources set-url <name> <url>
|
||||
cargo sources set-method <name> <method>
|
||||
|
||||
If no arguments are supplied, list all sources (but not their packages).
|
||||
|
||||
Commands:
|
||||
add Add a source. The source method will be guessed
|
||||
from the URL.
|
||||
remove Remove a source.
|
||||
rename Rename a source.
|
||||
set-url Change the URL for a source.
|
||||
set-method Change the method for a source.");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let argv = os::args();
|
||||
let o = build_cargo_options(argv);
|
||||
|
||||
if vec::len(o.free) < 2u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
if o.help {
|
||||
match o.free[1] {
|
||||
~"init" => cmd_usage_init(),
|
||||
~"install" => cmd_usage_install(),
|
||||
~"uninstall" => cmd_usage_uninstall(),
|
||||
~"list" => cmd_usage_list(),
|
||||
~"search" => cmd_usage_search(),
|
||||
~"sources" => cmd_usage_sources(),
|
||||
_ => cmd_usage()
|
||||
}
|
||||
return;
|
||||
}
|
||||
if o.free[1] == ~"usage" {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let mut c = configure(o);
|
||||
let home = c.root;
|
||||
let first_time = os::path_exists(&home.push("sources.json"));
|
||||
|
||||
if !first_time && o.free[1] != ~"init" {
|
||||
cmd_init(&c);
|
||||
|
||||
// FIXME (#2662): shouldn't need to reconfigure
|
||||
c = configure(o);
|
||||
}
|
||||
|
||||
let c = &move c;
|
||||
|
||||
match o.free[1] {
|
||||
~"init" => cmd_init(c),
|
||||
~"install" => cmd_install(c),
|
||||
~"uninstall" => cmd_uninstall(c),
|
||||
~"list" => cmd_list(c),
|
||||
~"search" => cmd_search(c),
|
||||
~"sources" => cmd_sources(c),
|
||||
_ => cmd_usage()
|
||||
}
|
||||
|
||||
dump_cache(c);
|
||||
dump_sources(c);
|
||||
}
|
||||
|
||||
@@ -1,1982 +0,0 @@
|
||||
// cargo.rs - Rust package manager
|
||||
|
||||
#[legacy_exports];
|
||||
|
||||
use syntax::{ast, codemap, parse, visit, attr};
|
||||
use syntax::diagnostic::span_handler;
|
||||
use codemap::span;
|
||||
use rustc::metadata::filesearch::{get_cargo_root, get_cargo_root_nearest,
|
||||
get_cargo_sysroot, libdir};
|
||||
use syntax::diagnostic;
|
||||
|
||||
use result::{Ok, Err};
|
||||
use io::WriterUtil;
|
||||
use send_map::linear::LinearMap;
|
||||
use std::{map, json, tempfile, term, sort, getopts};
|
||||
use map::HashMap;
|
||||
use to_str::to_str;
|
||||
use getopts::{optflag, optopt, opt_present};
|
||||
use dvec::DVec;
|
||||
|
||||
struct Package {
|
||||
name: ~str,
|
||||
uuid: ~str,
|
||||
url: ~str,
|
||||
method: ~str,
|
||||
description: ~str,
|
||||
reference: Option<~str>,
|
||||
tags: ~[~str],
|
||||
versions: ~[(~str, ~str)]
|
||||
}
|
||||
|
||||
impl Package : cmp::Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &Package) -> bool {
|
||||
if self.name.lt(&(*other).name) { return true; }
|
||||
if (*other).name.lt(&self.name) { return false; }
|
||||
if self.uuid.lt(&(*other).uuid) { return true; }
|
||||
if (*other).uuid.lt(&self.uuid) { return false; }
|
||||
if self.url.lt(&(*other).url) { return true; }
|
||||
if (*other).url.lt(&self.url) { return false; }
|
||||
if self.method.lt(&(*other).method) { return true; }
|
||||
if (*other).method.lt(&self.method) { return false; }
|
||||
if self.description.lt(&(*other).description) { return true; }
|
||||
if (*other).description.lt(&self.description) { return false; }
|
||||
if self.tags.lt(&(*other).tags) { return true; }
|
||||
if (*other).tags.lt(&self.tags) { return false; }
|
||||
if self.versions.lt(&(*other).versions) { return true; }
|
||||
return false;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &Package) -> bool {
|
||||
if (*self).name.lt(&(*other).name) { return true; }
|
||||
if (*other).name.lt(&(*self).name) { return false; }
|
||||
if (*self).uuid.lt(&(*other).uuid) { return true; }
|
||||
if (*other).uuid.lt(&(*self).uuid) { return false; }
|
||||
if (*self).url.lt(&(*other).url) { return true; }
|
||||
if (*other).url.lt(&(*self).url) { return false; }
|
||||
if (*self).method.lt(&(*other).method) { return true; }
|
||||
if (*other).method.lt(&(*self).method) { return false; }
|
||||
if (*self).description.lt(&(*other).description) { return true; }
|
||||
if (*other).description.lt(&(*self).description) { return false; }
|
||||
if (*self).tags.lt(&(*other).tags) { return true; }
|
||||
if (*other).tags.lt(&(*self).tags) { return false; }
|
||||
if (*self).versions.lt(&(*other).versions) { return true; }
|
||||
return false;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &Package) -> bool { !(*other).lt(&self) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &Package) -> bool { !(*other).lt(&(*self)) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &Package) -> bool { !self.lt(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &Package) -> bool { !(*self).lt(other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &Package) -> bool { (*other).lt(&self) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &Package) -> bool { (*other).lt(&(*self)) }
|
||||
}
|
||||
|
||||
struct Source {
|
||||
name: ~str,
|
||||
mut url: ~str,
|
||||
mut method: ~str,
|
||||
mut key: Option<~str>,
|
||||
mut keyfp: Option<~str>,
|
||||
packages: DVec<Package>
|
||||
}
|
||||
|
||||
struct Cargo {
|
||||
pgp: bool,
|
||||
root: Path,
|
||||
installdir: Path,
|
||||
bindir: Path,
|
||||
libdir: Path,
|
||||
workdir: Path,
|
||||
sourcedir: Path,
|
||||
sources: map::HashMap<~str, @Source>,
|
||||
mut current_install: ~str,
|
||||
dep_cache: map::HashMap<~str, bool>,
|
||||
opts: Options
|
||||
}
|
||||
|
||||
struct Crate {
|
||||
name: ~str,
|
||||
vers: ~str,
|
||||
uuid: ~str,
|
||||
desc: Option<~str>,
|
||||
sigs: Option<~str>,
|
||||
crate_type: Option<~str>,
|
||||
deps: ~[~str]
|
||||
}
|
||||
|
||||
struct Options {
|
||||
test: bool,
|
||||
mode: Mode,
|
||||
free: ~[~str],
|
||||
help: bool,
|
||||
}
|
||||
|
||||
enum Mode { SystemMode, UserMode, LocalMode }
|
||||
|
||||
impl Mode : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Mode) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Mode) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Mode) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Mode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
fn opts() -> ~[getopts::Opt] {
|
||||
~[optflag(~"g"), optflag(~"G"), optflag(~"test"),
|
||||
optflag(~"h"), optflag(~"help")]
|
||||
}
|
||||
|
||||
fn info(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_green);
|
||||
out.write_str(~"info: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
} else { out.write_line(~"info: " + msg); }
|
||||
}
|
||||
|
||||
fn warn(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_yellow);
|
||||
out.write_str(~"warning: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
}else { out.write_line(~"warning: " + msg); }
|
||||
}
|
||||
|
||||
fn error(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_red);
|
||||
out.write_str(~"error: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
}
|
||||
else { out.write_line(~"error: " + msg); }
|
||||
}
|
||||
|
||||
fn is_uuid(id: ~str) -> bool {
|
||||
let parts = str::split_str(id, ~"-");
|
||||
if vec::len(parts) == 5u {
|
||||
let mut correct = 0u;
|
||||
for vec::eachi(parts) |i, part| {
|
||||
fn is_hex_digit(+ch: char) -> bool {
|
||||
('0' <= ch && ch <= '9') ||
|
||||
('a' <= ch && ch <= 'f') ||
|
||||
('A' <= ch && ch <= 'F')
|
||||
}
|
||||
|
||||
if !part.all(is_hex_digit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
match i {
|
||||
0u => {
|
||||
if part.len() == 8u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
1u | 2u | 3u => {
|
||||
if part.len() == 4u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
4u => {
|
||||
if part.len() == 12u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
if correct >= 5u {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_uuid() {
|
||||
assert is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaafAF09");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"");
|
||||
assert !is_uuid(~"aaaaaaaa-aaa -aaaa-aaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"aaaaaaaa-aaa!-aaaa-aaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa-a");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaป");
|
||||
}
|
||||
|
||||
// FIXME (#2661): implement url/URL parsing so we don't have to resort
|
||||
// to weak checks
|
||||
|
||||
fn has_archive_extension(p: ~str) -> bool {
|
||||
str::ends_with(p, ~".tar") ||
|
||||
str::ends_with(p, ~".tar.gz") ||
|
||||
str::ends_with(p, ~".tar.bz2") ||
|
||||
str::ends_with(p, ~".tar.Z") ||
|
||||
str::ends_with(p, ~".tar.lz") ||
|
||||
str::ends_with(p, ~".tar.xz") ||
|
||||
str::ends_with(p, ~".tgz") ||
|
||||
str::ends_with(p, ~".tbz") ||
|
||||
str::ends_with(p, ~".tbz2") ||
|
||||
str::ends_with(p, ~".tb2") ||
|
||||
str::ends_with(p, ~".taz") ||
|
||||
str::ends_with(p, ~".tlz") ||
|
||||
str::ends_with(p, ~".txz")
|
||||
}
|
||||
|
||||
fn is_archive_path(u: ~str) -> bool {
|
||||
has_archive_extension(u) && os::path_exists(&Path(u))
|
||||
}
|
||||
|
||||
fn is_archive_url(u: ~str) -> bool {
|
||||
// FIXME (#2661): this requires the protocol bit - if we had proper
|
||||
// url parsing, we wouldn't need it
|
||||
|
||||
match str::find_str(u, ~"://") {
|
||||
option::Some(_) => has_archive_extension(u),
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_git_url(url: ~str) -> bool {
|
||||
if str::ends_with(url, ~"/") { str::ends_with(url, ~".git/") }
|
||||
else {
|
||||
str::starts_with(url, ~"git://") || str::ends_with(url, ~".git")
|
||||
}
|
||||
}
|
||||
|
||||
fn assume_source_method(url: ~str) -> ~str {
|
||||
if is_git_url(url) {
|
||||
return ~"git";
|
||||
}
|
||||
if str::starts_with(url, ~"file://") || os::path_exists(&Path(url)) {
|
||||
return ~"file";
|
||||
}
|
||||
|
||||
~"curl"
|
||||
}
|
||||
|
||||
fn load_link(mis: ~[@ast::meta_item]) -> (Option<~str>,
|
||||
Option<~str>,
|
||||
Option<~str>) {
|
||||
let mut name = None;
|
||||
let mut vers = None;
|
||||
let mut uuid = None;
|
||||
for mis.each |a| {
|
||||
match a.node {
|
||||
ast::meta_name_value(v, {node: ast::lit_str(s), span: _}) => {
|
||||
match v {
|
||||
~"name" => name = Some(*s),
|
||||
~"vers" => vers = Some(*s),
|
||||
~"uuid" => uuid = Some(*s),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
_ => fail ~"load_link: meta items must be name-values"
|
||||
}
|
||||
}
|
||||
(name, vers, uuid)
|
||||
}
|
||||
|
||||
fn load_crate(filename: &Path) -> Option<Crate> {
|
||||
let sess = parse::new_parse_sess(None);
|
||||
let c = parse::parse_crate_from_crate_file(filename, ~[], sess);
|
||||
|
||||
let mut name = None;
|
||||
let mut vers = None;
|
||||
let mut uuid = None;
|
||||
let mut desc = None;
|
||||
let mut sigs = None;
|
||||
let mut crate_type = None;
|
||||
|
||||
for c.node.attrs.each |a| {
|
||||
match a.node.value.node {
|
||||
ast::meta_name_value(v, {node: ast::lit_str(_), span: _}) => {
|
||||
match v {
|
||||
~"desc" => desc = Some(v),
|
||||
~"sigs" => sigs = Some(v),
|
||||
~"crate_type" => crate_type = Some(v),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
ast::meta_list(v, mis) => {
|
||||
if v == ~"link" {
|
||||
let (n, v, u) = load_link(mis);
|
||||
name = n;
|
||||
vers = v;
|
||||
uuid = u;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
fail ~"crate attributes may not contain " +
|
||||
~"meta_words";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type env = @{
|
||||
mut deps: ~[~str]
|
||||
};
|
||||
|
||||
fn goto_view_item(ps: syntax::parse::parse_sess, e: env,
|
||||
i: @ast::view_item) {
|
||||
match i.node {
|
||||
ast::view_item_use(ident, metas, _) => {
|
||||
let name_items =
|
||||
attr::find_meta_items_by_name(metas, ~"name");
|
||||
let m = if name_items.is_empty() {
|
||||
metas + ~[attr::mk_name_value_item_str(
|
||||
~"name", *ps.interner.get(ident))]
|
||||
} else {
|
||||
metas
|
||||
};
|
||||
let mut attr_name = ident;
|
||||
let mut attr_vers = ~"";
|
||||
let mut attr_from = ~"";
|
||||
|
||||
for m.each |item| {
|
||||
match attr::get_meta_item_value_str(*item) {
|
||||
Some(value) => {
|
||||
let name = attr::get_meta_item_name(*item);
|
||||
|
||||
match name {
|
||||
~"vers" => attr_vers = value,
|
||||
~"from" => attr_from = value,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
let query = if !str::is_empty(attr_from) {
|
||||
attr_from
|
||||
} else {
|
||||
if !str::is_empty(attr_vers) {
|
||||
ps.interner.get(attr_name) + ~"@" + attr_vers
|
||||
} else { *ps.interner.get(attr_name) }
|
||||
};
|
||||
|
||||
match *ps.interner.get(attr_name) {
|
||||
~"std" | ~"core" => (),
|
||||
_ => e.deps.push(query)
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
fn goto_item(_e: env, _i: @ast::item) {
|
||||
}
|
||||
|
||||
let e = @{
|
||||
mut deps: ~[]
|
||||
};
|
||||
let v = visit::mk_simple_visitor(@{
|
||||
visit_view_item: |a| goto_view_item(sess, e, a),
|
||||
visit_item: |a| goto_item(e, a),
|
||||
.. *visit::default_simple_visitor()
|
||||
});
|
||||
|
||||
visit::visit_crate(*c, (), v);
|
||||
|
||||
let deps = copy e.deps;
|
||||
|
||||
match (name, vers, uuid) {
|
||||
(Some(name0), Some(vers0), Some(uuid0)) => {
|
||||
Some(Crate {
|
||||
name: name0,
|
||||
vers: vers0,
|
||||
uuid: uuid0,
|
||||
desc: desc,
|
||||
sigs: sigs,
|
||||
crate_type: crate_type,
|
||||
deps: deps })
|
||||
}
|
||||
_ => return None
|
||||
}
|
||||
}
|
||||
|
||||
fn print(s: ~str) {
|
||||
io::stdout().write_line(s);
|
||||
}
|
||||
|
||||
fn rest(s: ~str, start: uint) -> ~str {
|
||||
if (start >= str::len(s)) {
|
||||
~""
|
||||
} else {
|
||||
str::slice(s, start, str::len(s))
|
||||
}
|
||||
}
|
||||
|
||||
fn need_dir(s: &Path) {
|
||||
if os::path_is_dir(s) { return; }
|
||||
if !os::make_dir(s, 493_i32 /* oct: 755 */) {
|
||||
fail fmt!("can't make_dir %s", s.to_str());
|
||||
}
|
||||
}
|
||||
|
||||
fn valid_pkg_name(s: &str) -> bool {
|
||||
fn is_valid_digit(+c: char) -> bool {
|
||||
('0' <= c && c <= '9') ||
|
||||
('a' <= c && c <= 'z') ||
|
||||
('A' <= c && c <= 'Z') ||
|
||||
c == '-' ||
|
||||
c == '_'
|
||||
}
|
||||
|
||||
s.all(is_valid_digit)
|
||||
}
|
||||
|
||||
fn parse_source(name: ~str, j: &json::Json) -> @Source {
|
||||
if !valid_pkg_name(name) {
|
||||
fail fmt!("'%s' is an invalid source name", name);
|
||||
}
|
||||
|
||||
match *j {
|
||||
json::Object(j) => {
|
||||
let mut url = match j.find(&~"url") {
|
||||
Some(json::String(u)) => u,
|
||||
_ => fail ~"needed 'url' field in source"
|
||||
};
|
||||
let method = match j.find(&~"method") {
|
||||
Some(json::String(u)) => u,
|
||||
_ => assume_source_method(url)
|
||||
};
|
||||
let key = match j.find(&~"key") {
|
||||
Some(json::String(u)) => Some(u),
|
||||
_ => None
|
||||
};
|
||||
let keyfp = match j.find(&~"keyfp") {
|
||||
Some(json::String(u)) => Some(u),
|
||||
_ => None
|
||||
};
|
||||
if method == ~"file" {
|
||||
url = os::make_absolute(&Path(url)).to_str();
|
||||
}
|
||||
return @Source {
|
||||
name: name,
|
||||
mut url: url,
|
||||
mut method: method,
|
||||
mut key: key,
|
||||
mut keyfp: keyfp,
|
||||
packages: DVec() };
|
||||
}
|
||||
_ => fail ~"needed dict value in source"
|
||||
};
|
||||
}
|
||||
|
||||
fn try_parse_sources(filename: &Path, sources: map::HashMap<~str, @Source>) {
|
||||
if !os::path_exists(filename) { return; }
|
||||
let c = io::read_whole_file_str(filename);
|
||||
match json::from_str(c.get()) {
|
||||
Ok(json::Object(j)) => {
|
||||
for j.each |k, v| {
|
||||
sources.insert(copy *k, parse_source(*k, v));
|
||||
debug!("source: %s", *k);
|
||||
}
|
||||
}
|
||||
Ok(_) => fail ~"malformed sources.json",
|
||||
Err(e) => fail fmt!("%s:%s", filename.to_str(), e.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
fn load_one_source_package(src: @Source, p: &json::Object) {
|
||||
let name = match p.find(&~"name") {
|
||||
Some(json::String(n)) => {
|
||||
if !valid_pkg_name(n) {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~", '" + n + ~"'"+
|
||||
~" is an invalid name (alphanumeric, underscores and" +
|
||||
~" dashes only)");
|
||||
return;
|
||||
}
|
||||
n
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing name)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let uuid = match p.find(&~"uuid") {
|
||||
Some(json::String(n)) => {
|
||||
if !is_uuid(n) {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~", '" + n + ~"'"+
|
||||
~" is an invalid uuid");
|
||||
return;
|
||||
}
|
||||
n
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing uuid)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let url = match p.find(&~"url") {
|
||||
Some(json::String(n)) => n,
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing url)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let method = match p.find(&~"method") {
|
||||
Some(json::String(n)) => n,
|
||||
_ => {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~" (missing method)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let reference = match p.find(&~"ref") {
|
||||
Some(json::String(n)) => Some(n),
|
||||
_ => None
|
||||
};
|
||||
|
||||
let mut tags = ~[];
|
||||
match p.find(&~"tags") {
|
||||
Some(json::List(js)) => {
|
||||
for js.each |j| {
|
||||
match *j {
|
||||
json::String(ref j) => tags.grow(1u, j),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
let description = match p.find(&~"description") {
|
||||
Some(json::String(n)) => n,
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name
|
||||
+ ~" (missing description)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let newpkg = Package {
|
||||
name: name,
|
||||
uuid: uuid,
|
||||
url: url,
|
||||
method: method,
|
||||
description: description,
|
||||
reference: reference,
|
||||
tags: tags,
|
||||
versions: ~[]
|
||||
};
|
||||
|
||||
match src.packages.position(|pkg| pkg.uuid == uuid) {
|
||||
Some(idx) => {
|
||||
src.packages.set_elt(idx, newpkg);
|
||||
log(debug, ~" updated package: " + src.name + ~"/" + name);
|
||||
}
|
||||
None => {
|
||||
src.packages.push(newpkg);
|
||||
}
|
||||
}
|
||||
|
||||
log(debug, ~" loaded package: " + src.name + ~"/" + name);
|
||||
}
|
||||
|
||||
fn load_source_info(c: &Cargo, src: @Source) {
|
||||
let dir = c.sourcedir.push(src.name);
|
||||
let srcfile = dir.push("source.json");
|
||||
if !os::path_exists(&srcfile) { return; }
|
||||
let srcstr = io::read_whole_file_str(&srcfile);
|
||||
match json::from_str(srcstr.get()) {
|
||||
Ok(ref json @ json::Object(_)) => {
|
||||
let o = parse_source(src.name, json);
|
||||
|
||||
src.key = o.key;
|
||||
src.keyfp = o.keyfp;
|
||||
}
|
||||
Ok(_) => {
|
||||
warn(~"malformed source.json: " + src.name +
|
||||
~"(source info is not a dict)");
|
||||
}
|
||||
Err(e) => {
|
||||
warn(fmt!("%s:%s", src.name, e.to_str()));
|
||||
}
|
||||
};
|
||||
}
|
||||
fn load_source_packages(c: &Cargo, src: @Source) {
|
||||
log(debug, ~"loading source: " + src.name);
|
||||
let dir = c.sourcedir.push(src.name);
|
||||
let pkgfile = dir.push("packages.json");
|
||||
if !os::path_exists(&pkgfile) { return; }
|
||||
let pkgstr = io::read_whole_file_str(&pkgfile);
|
||||
match json::from_str(pkgstr.get()) {
|
||||
Ok(json::List(js)) => {
|
||||
for js.each |j| {
|
||||
match *j {
|
||||
json::Object(p) => {
|
||||
load_one_source_package(src, p);
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name +
|
||||
~" (non-dict pkg)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(_) => {
|
||||
warn(~"malformed packages.json: " + src.name +
|
||||
~"(packages is not a list)");
|
||||
}
|
||||
Err(e) => {
|
||||
warn(fmt!("%s:%s", src.name, e.to_str()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn build_cargo_options(argv: ~[~str]) -> Options {
|
||||
let matches = &match getopts::getopts(argv, opts()) {
|
||||
result::Ok(m) => m,
|
||||
result::Err(f) => {
|
||||
fail fmt!("%s", getopts::fail_str(f));
|
||||
}
|
||||
};
|
||||
|
||||
let test = opt_present(matches, ~"test");
|
||||
let G = opt_present(matches, ~"G");
|
||||
let g = opt_present(matches, ~"g");
|
||||
let help = opt_present(matches, ~"h") || opt_present(matches, ~"help");
|
||||
let len = vec::len(matches.free);
|
||||
|
||||
let is_install = len > 1u && matches.free[1] == ~"install";
|
||||
let is_uninstall = len > 1u && matches.free[1] == ~"uninstall";
|
||||
|
||||
if G && g { fail ~"-G and -g both provided"; }
|
||||
|
||||
if !is_install && !is_uninstall && (g || G) {
|
||||
fail ~"-g and -G are only valid for `install` and `uninstall|rm`";
|
||||
}
|
||||
|
||||
let mode =
|
||||
if (!is_install && !is_uninstall) || g { UserMode }
|
||||
else if G { SystemMode }
|
||||
else { LocalMode };
|
||||
|
||||
Options {test: test, mode: mode, free: matches.free, help: help}
|
||||
}
|
||||
|
||||
fn configure(opts: Options) -> Cargo {
|
||||
let home = match get_cargo_root() {
|
||||
Ok(home) => home,
|
||||
Err(_err) => get_cargo_sysroot().get()
|
||||
};
|
||||
|
||||
let get_cargo_dir = match opts.mode {
|
||||
SystemMode => get_cargo_sysroot,
|
||||
UserMode => get_cargo_root,
|
||||
LocalMode => get_cargo_root_nearest
|
||||
};
|
||||
|
||||
let p = get_cargo_dir().get();
|
||||
|
||||
let sources = HashMap();
|
||||
try_parse_sources(&home.push("sources.json"), sources);
|
||||
try_parse_sources(&home.push("local-sources.json"), sources);
|
||||
|
||||
let dep_cache = HashMap();
|
||||
|
||||
let mut c = Cargo {
|
||||
pgp: pgp::supported(),
|
||||
root: home,
|
||||
installdir: p,
|
||||
bindir: p.push("bin"),
|
||||
libdir: p.push("lib"),
|
||||
workdir: p.push("work"),
|
||||
sourcedir: home.push("sources"),
|
||||
sources: sources,
|
||||
mut current_install: ~"",
|
||||
dep_cache: dep_cache,
|
||||
opts: opts
|
||||
};
|
||||
|
||||
need_dir(&c.root);
|
||||
need_dir(&c.installdir);
|
||||
need_dir(&c.sourcedir);
|
||||
need_dir(&c.workdir);
|
||||
need_dir(&c.libdir);
|
||||
need_dir(&c.bindir);
|
||||
|
||||
for sources.each_key |k| {
|
||||
let mut s = sources.get(k);
|
||||
load_source_packages(&c, s);
|
||||
sources.insert(k, s);
|
||||
}
|
||||
|
||||
if c.pgp {
|
||||
pgp::init(&c.root);
|
||||
} else {
|
||||
warn(~"command `gpg` was not found");
|
||||
warn(~"you have to install gpg from source " +
|
||||
~" or package manager to get it to work correctly");
|
||||
}
|
||||
|
||||
move c
|
||||
}
|
||||
|
||||
fn for_each_package(c: &Cargo, b: fn(s: @Source, p: &Package)) {
|
||||
for c.sources.each_value |v| {
|
||||
for v.packages.each |p| {
|
||||
b(v, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Runs all programs in directory <buildpath>
|
||||
fn run_programs(buildpath: &Path) {
|
||||
let newv = os::list_dir_path(buildpath);
|
||||
for newv.each |ct| {
|
||||
run::run_program(ct.to_str(), ~[]);
|
||||
}
|
||||
}
|
||||
|
||||
// Runs rustc in <path + subdir> with the given flags
|
||||
// and returns <patho + subdir>
|
||||
fn run_in_buildpath(what: &str, path: &Path, subdir: &Path, cf: &Path,
|
||||
extra_flags: ~[~str]) -> Option<Path> {
|
||||
let buildpath = path.push_rel(subdir);
|
||||
need_dir(&buildpath);
|
||||
debug!("%s: %s -> %s", what, cf.to_str(), buildpath.to_str());
|
||||
let p = run::program_output(rustc_sysroot(),
|
||||
~[~"--out-dir",
|
||||
buildpath.to_str(),
|
||||
cf.to_str()] + extra_flags);
|
||||
if p.status != 0 {
|
||||
error(fmt!("rustc failed: %d\n%s\n%s", p.status, p.err, p.out));
|
||||
return None;
|
||||
}
|
||||
Some(buildpath)
|
||||
}
|
||||
|
||||
fn test_one_crate(_c: &Cargo, path: &Path, cf: &Path) {
|
||||
let buildpath = match run_in_buildpath(~"testing", path,
|
||||
&Path("test"),
|
||||
cf,
|
||||
~[ ~"--test"]) {
|
||||
None => return,
|
||||
Some(bp) => bp
|
||||
};
|
||||
run_programs(&buildpath);
|
||||
}
|
||||
|
||||
fn install_one_crate(c: &Cargo, path: &Path, cf: &Path) {
|
||||
let buildpath = match run_in_buildpath(~"installing", path,
|
||||
&Path("build"),
|
||||
cf, ~[]) {
|
||||
None => return,
|
||||
Some(bp) => bp
|
||||
};
|
||||
let newv = os::list_dir_path(&buildpath);
|
||||
let exec_suffix = os::exe_suffix();
|
||||
for newv.each |ct| {
|
||||
if (exec_suffix != ~"" && str::ends_with(ct.to_str(),
|
||||
exec_suffix)) ||
|
||||
(exec_suffix == ~"" &&
|
||||
!str::starts_with(ct.filename().get(),
|
||||
~"lib")) {
|
||||
debug!(" bin: %s", ct.to_str());
|
||||
install_to_dir(*ct, &c.bindir);
|
||||
if c.opts.mode == SystemMode {
|
||||
// FIXME (#2662): Put this file in PATH / symlink it so it can
|
||||
// be used as a generic executable
|
||||
// `cargo install -G rustray` and `rustray file.obj`
|
||||
}
|
||||
} else {
|
||||
debug!(" lib: %s", ct.to_str());
|
||||
install_to_dir(*ct, &c.libdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn rustc_sysroot() -> ~str {
|
||||
match os::self_exe_path() {
|
||||
Some(path) => {
|
||||
let rustc = path.push_many([~"..", ~"bin", ~"rustc"]);
|
||||
debug!(" rustc: %s", rustc.to_str());
|
||||
rustc.to_str()
|
||||
}
|
||||
None => ~"rustc"
|
||||
}
|
||||
}
|
||||
|
||||
fn install_source(c: &Cargo, path: &Path) {
|
||||
debug!("source: %s", path.to_str());
|
||||
os::change_dir(path);
|
||||
|
||||
let mut cratefiles = ~[];
|
||||
for os::walk_dir(&Path(".")) |p| {
|
||||
if p.filetype() == Some(~".rc") {
|
||||
cratefiles.push(*p);
|
||||
}
|
||||
}
|
||||
|
||||
if vec::is_empty(cratefiles) {
|
||||
fail ~"this doesn't look like a rust package (no .rc files)";
|
||||
}
|
||||
|
||||
for cratefiles.each |cf| {
|
||||
match load_crate(cf) {
|
||||
None => loop,
|
||||
Some(crate) => {
|
||||
for crate.deps.each |query| {
|
||||
// FIXME (#1356): handle cyclic dependencies
|
||||
// (n.b. #1356 says "Cyclic dependency is an error
|
||||
// condition")
|
||||
|
||||
let wd = get_temp_workdir(c);
|
||||
install_query(c, &wd, *query);
|
||||
}
|
||||
|
||||
os::change_dir(path);
|
||||
|
||||
if c.opts.test {
|
||||
test_one_crate(c, path, cf);
|
||||
}
|
||||
install_one_crate(c, path, cf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn install_git(c: &Cargo, wd: &Path, url: ~str, reference: Option<~str>) {
|
||||
run::program_output(~"git", ~[~"clone", url, wd.to_str()]);
|
||||
if reference.is_some() {
|
||||
let r = reference.get();
|
||||
os::change_dir(wd);
|
||||
run::run_program(~"git", ~[~"checkout", r]);
|
||||
}
|
||||
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
fn install_curl(c: &Cargo, wd: &Path, url: ~str) {
|
||||
let tarpath = wd.push("pkg.tar");
|
||||
let p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o",
|
||||
tarpath.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
fail fmt!("fetch of %s failed: %s", url, p.err);
|
||||
}
|
||||
run::run_program(~"tar", ~[~"-x", ~"--strip-components=1",
|
||||
~"-C", wd.to_str(),
|
||||
~"-f", tarpath.to_str()]);
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
fn install_file(c: &Cargo, wd: &Path, path: &Path) {
|
||||
run::program_output(~"tar", ~[~"-x", ~"--strip-components=1",
|
||||
~"-C", wd.to_str(),
|
||||
~"-f", path.to_str()]);
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
fn install_package(c: &Cargo, src: ~str, wd: &Path, pkg: Package) {
|
||||
let url = copy pkg.url;
|
||||
let method = match pkg.method {
|
||||
~"git" => ~"git",
|
||||
~"file" => ~"file",
|
||||
_ => ~"curl"
|
||||
};
|
||||
|
||||
info(fmt!("installing %s/%s via %s...", src, pkg.name, method));
|
||||
|
||||
match method {
|
||||
~"git" => install_git(c, wd, url, copy pkg.reference),
|
||||
~"file" => install_file(c, wd, &Path(url)),
|
||||
~"curl" => install_curl(c, wd, url),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
fn cargo_suggestion(c: &Cargo, fallback: fn())
|
||||
{
|
||||
if c.sources.size() == 0u {
|
||||
error(~"no sources defined - you may wish to run " +
|
||||
~"`cargo init`");
|
||||
return;
|
||||
}
|
||||
fallback();
|
||||
}
|
||||
|
||||
fn install_uuid(c: &Cargo, wd: &Path, uuid: ~str) {
|
||||
let mut ps = ~[];
|
||||
for_each_package(c, |s, p| {
|
||||
if p.uuid == uuid {
|
||||
vec::push(&mut ps, (s.name, copy *p));
|
||||
}
|
||||
});
|
||||
if vec::len(ps) == 1u {
|
||||
let (sname, p) = copy ps[0];
|
||||
install_package(c, sname, wd, p);
|
||||
return;
|
||||
} else if vec::len(ps) == 0u {
|
||||
cargo_suggestion(c, || {
|
||||
error(~"can't find package: " + uuid);
|
||||
});
|
||||
return;
|
||||
}
|
||||
error(~"found multiple packages:");
|
||||
for ps.each |elt| {
|
||||
let (sname,p) = copy *elt;
|
||||
info(~" " + sname + ~"/" + p.uuid + ~" (" + p.name + ~")");
|
||||
}
|
||||
}
|
||||
|
||||
fn install_named(c: &Cargo, wd: &Path, name: ~str) {
|
||||
let mut ps = ~[];
|
||||
for_each_package(c, |s, p| {
|
||||
if p.name == name {
|
||||
vec::push(&mut ps, (s.name, copy *p));
|
||||
}
|
||||
});
|
||||
if vec::len(ps) == 1u {
|
||||
let (sname, p) = copy ps[0];
|
||||
install_package(c, sname, wd, p);
|
||||
return;
|
||||
} else if vec::len(ps) == 0u {
|
||||
cargo_suggestion(c, || {
|
||||
error(~"can't find package: " + name);
|
||||
});
|
||||
return;
|
||||
}
|
||||
error(~"found multiple packages:");
|
||||
for ps.each |elt| {
|
||||
let (sname,p) = copy *elt;
|
||||
info(~" " + sname + ~"/" + p.uuid + ~" (" + p.name + ~")");
|
||||
}
|
||||
}
|
||||
|
||||
fn install_uuid_specific(c: &Cargo, wd: &Path, src: ~str, uuid: ~str) {
|
||||
match c.sources.find(src) {
|
||||
Some(s) => {
|
||||
for s.packages.each |p| {
|
||||
if p.uuid == uuid {
|
||||
install_package(c, src, wd, *p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
error(~"can't find package: " + src + ~"/" + uuid);
|
||||
}
|
||||
|
||||
fn install_named_specific(c: &Cargo, wd: &Path, src: ~str, name: ~str) {
|
||||
match c.sources.find(src) {
|
||||
Some(s) => {
|
||||
for s.packages.each |p| {
|
||||
if p.name == name {
|
||||
install_package(c, src, wd, *p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
error(~"can't find package: " + src + ~"/" + name);
|
||||
}
|
||||
|
||||
fn cmd_uninstall(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let lib = &c.libdir;
|
||||
let bin = &c.bindir;
|
||||
let target = c.opts.free[2u];
|
||||
|
||||
// FIXME (#2662): needs stronger pattern matching
|
||||
// FIXME (#2662): needs to uninstall from a specified location in a
|
||||
// cache instead of looking for it (binaries can be uninstalled by
|
||||
// name only)
|
||||
|
||||
fn try_uninstall(p: &Path) -> bool {
|
||||
if os::remove_file(p) {
|
||||
info(~"uninstalled: '" + p.to_str() + ~"'");
|
||||
true
|
||||
} else {
|
||||
error(~"could not uninstall: '" +
|
||||
p.to_str() + ~"'");
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
if is_uuid(target) {
|
||||
for os::list_dir(lib).each |file| {
|
||||
match str::find_str(*file, ~"-" + target + ~"-") {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
error(~"can't find package with uuid: " + target);
|
||||
} else {
|
||||
for os::list_dir(lib).each |file| {
|
||||
match str::find_str(*file, ~"lib" + target + ~"-") {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
for os::list_dir(bin).each |file| {
|
||||
match str::find_str(*file, target) {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
error(~"can't find package with name: " + target);
|
||||
}
|
||||
}
|
||||
|
||||
fn install_query(c: &Cargo, wd: &Path, target: ~str) {
|
||||
match c.dep_cache.find(target) {
|
||||
Some(inst) => {
|
||||
if inst {
|
||||
return;
|
||||
}
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
|
||||
c.dep_cache.insert(target, true);
|
||||
|
||||
if is_archive_path(target) {
|
||||
install_file(c, wd, &Path(target));
|
||||
return;
|
||||
} else if is_git_url(target) {
|
||||
let reference = if c.opts.free.len() >= 4u {
|
||||
Some(c.opts.free[3u])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
install_git(c, wd, target, reference);
|
||||
} else if !valid_pkg_name(target) && has_archive_extension(target) {
|
||||
install_curl(c, wd, target);
|
||||
return;
|
||||
} else {
|
||||
let mut ps = copy target;
|
||||
|
||||
match str::find_char(ps, '/') {
|
||||
option::Some(idx) => {
|
||||
let source = str::slice(ps, 0u, idx);
|
||||
ps = str::slice(ps, idx + 1u, str::len(ps));
|
||||
if is_uuid(ps) {
|
||||
install_uuid_specific(c, wd, source, ps);
|
||||
} else {
|
||||
install_named_specific(c, wd, source, ps);
|
||||
}
|
||||
}
|
||||
option::None => {
|
||||
if is_uuid(ps) {
|
||||
install_uuid(c, wd, ps);
|
||||
} else {
|
||||
install_named(c, wd, ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME (#2662): This whole dep_cache and current_install thing is
|
||||
// a bit of a hack. It should be cleaned up in the future.
|
||||
|
||||
if target == c.current_install {
|
||||
for c.dep_cache.each |k, _v| {
|
||||
c.dep_cache.remove(k);
|
||||
}
|
||||
|
||||
c.current_install = ~"";
|
||||
}
|
||||
}
|
||||
|
||||
fn get_temp_workdir(c: &Cargo) -> Path {
|
||||
match tempfile::mkdtemp(&c.workdir, "cargo") {
|
||||
Some(wd) => wd,
|
||||
None => fail fmt!("needed temp dir: %s",
|
||||
c.workdir.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_install(c: &Cargo) unsafe {
|
||||
let wd = get_temp_workdir(c);
|
||||
|
||||
if vec::len(c.opts.free) == 2u {
|
||||
let cwd = os::getcwd();
|
||||
let status = run::run_program(~"cp", ~[~"-R", cwd.to_str(),
|
||||
wd.to_str()]);
|
||||
|
||||
if status != 0 {
|
||||
fail fmt!("could not copy directory: %s", cwd.to_str());
|
||||
}
|
||||
|
||||
install_source(c, &wd);
|
||||
return;
|
||||
}
|
||||
|
||||
sync(c);
|
||||
|
||||
let query = c.opts.free[2];
|
||||
c.current_install = query.to_str();
|
||||
|
||||
install_query(c, &wd, query);
|
||||
}
|
||||
|
||||
fn sync(c: &Cargo) {
|
||||
for c.sources.each_key |k| {
|
||||
let mut s = c.sources.get(k);
|
||||
sync_one(c, s);
|
||||
c.sources.insert(k, s);
|
||||
}
|
||||
}
|
||||
|
||||
fn sync_one_file(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json.new");
|
||||
let destsrcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json.new");
|
||||
let destpkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let url = Path(src.url);
|
||||
let mut has_src_file = false;
|
||||
|
||||
if !os::copy_file(&url.push("packages.json"), &pkgfile) {
|
||||
error(fmt!("fetch for source %s (url %s) failed",
|
||||
name, url.to_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if os::copy_file(&url.push("source.json"), &srcfile) {
|
||||
has_src_file = false;
|
||||
}
|
||||
|
||||
os::copy_file(&url.push("source.json.sig"), &srcsigfile);
|
||||
os::copy_file(&url.push("packages.json.sig"), &sigfile);
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
|
||||
if has_src_file {
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(fmt!("signature verification failed for source %s \
|
||||
with key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
copy_warn(&pkgfile, &destpkgfile);
|
||||
|
||||
if has_src_file {
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&srcsigfile);
|
||||
os::remove_file(&pkgfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn sync_one_git(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let url = src.url;
|
||||
|
||||
fn rollback(name: ~str, dir: &Path, insecure: bool) {
|
||||
fn msg(name: ~str, insecure: bool) {
|
||||
error(fmt!("could not rollback source: %s", name));
|
||||
|
||||
if insecure {
|
||||
warn(~"a past security check failed on source " +
|
||||
name + ~" and rolling back the source failed -"
|
||||
+ ~" this source may be compromised");
|
||||
}
|
||||
}
|
||||
|
||||
if !os::change_dir(dir) {
|
||||
msg(name, insecure);
|
||||
}
|
||||
else {
|
||||
let p = run::program_output(~"git", ~[~"reset", ~"--hard",
|
||||
~"HEAD@{1}"]);
|
||||
|
||||
if p.status != 0 {
|
||||
msg(name, insecure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !os::path_exists(&dir.push(".git")) {
|
||||
let p = run::program_output(~"git", ~[~"clone", url, dir.to_str()]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if !os::change_dir(dir) {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let p = run::program_output(~"git", ~[~"pull"]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let has_src_file = os::path_exists(&srcfile);
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if has_src_file {
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(fmt!("signature verification failed for source %s \
|
||||
with key %s", name, f));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json.new");
|
||||
let destsrcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json.new");
|
||||
let destpkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let mut url = src.url;
|
||||
let smart = !str::ends_with(src.url, ~"packages.json");
|
||||
let mut has_src_file = false;
|
||||
|
||||
if smart {
|
||||
url += ~"/packages.json";
|
||||
}
|
||||
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", pkgfile.to_str(), url]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
if smart {
|
||||
url = src.url + ~"/source.json";
|
||||
let p =
|
||||
run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", srcfile.to_str(), url]);
|
||||
|
||||
if p.status == 0 {
|
||||
has_src_file = true;
|
||||
}
|
||||
}
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
if smart {
|
||||
url = src.url + ~"/packages.json.sig";
|
||||
}
|
||||
else {
|
||||
url = src.url + ~".sig";
|
||||
}
|
||||
|
||||
let mut p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s", ~"-o",
|
||||
sigfile.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (sig %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
|
||||
if smart && has_src_file {
|
||||
url = src.url + ~"/source.json.sig";
|
||||
|
||||
p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s", ~"-o",
|
||||
srcsigfile.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (sig %s) failed",
|
||||
name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(~"signature verification failed for " +
|
||||
~"source " + name + ~" with key " + f);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
copy_warn(&pkgfile, &destpkgfile);
|
||||
|
||||
if smart && has_src_file {
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&srcsigfile);
|
||||
os::remove_file(&pkgfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn sync_one(c: &Cargo, src: @Source) {
|
||||
let name = src.name;
|
||||
let dir = c.sourcedir.push(name);
|
||||
|
||||
info(fmt!("syncing source: %s...", name));
|
||||
|
||||
need_dir(&dir);
|
||||
|
||||
let result = match src.method {
|
||||
~"git" => sync_one_git(c, &dir, src),
|
||||
~"file" => sync_one_file(c, &dir, src),
|
||||
_ => sync_one_curl(c, &dir, src)
|
||||
};
|
||||
|
||||
if result {
|
||||
load_source_info(c, src);
|
||||
load_source_packages(c, src);
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_init(c: &Cargo) {
|
||||
let srcurl = ~"http://www.rust-lang.org/cargo/sources.json";
|
||||
let sigurl = ~"http://www.rust-lang.org/cargo/sources.json.sig";
|
||||
|
||||
let srcfile = c.root.push("sources.json.new");
|
||||
let sigfile = c.root.push("sources.json.sig");
|
||||
let destsrcfile = c.root.push("sources.json");
|
||||
|
||||
let p =
|
||||
run::program_output(~"curl", ~[~"-f", ~"-s",
|
||||
~"-o", srcfile.to_str(), srcurl]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch of sources.json failed: %s", p.out));
|
||||
return;
|
||||
}
|
||||
|
||||
let p =
|
||||
run::program_output(~"curl", ~[~"-f", ~"-s",
|
||||
~"-o", sigfile.to_str(), sigurl]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch of sources.json.sig failed: %s", p.out));
|
||||
return;
|
||||
}
|
||||
|
||||
let r = pgp::verify(&c.root, &srcfile, &sigfile);
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for '%s'",
|
||||
srcfile.to_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("initialized .cargo in %s", c.root.to_str()));
|
||||
}
|
||||
|
||||
fn print_pkg(s: @Source, p: &Package) {
|
||||
let mut m = s.name + ~"/" + p.name + ~" (" + p.uuid + ~")";
|
||||
if vec::len(p.tags) > 0u {
|
||||
m = m + ~" [" + str::connect(p.tags, ~", ") + ~"]";
|
||||
}
|
||||
info(m);
|
||||
if p.description != ~"" {
|
||||
print(~" >> " + p.description + ~"\n")
|
||||
}
|
||||
}
|
||||
|
||||
fn print_source(s: @Source) {
|
||||
info(s.name + ~" (" + s.url + ~")");
|
||||
|
||||
let pks = sort::merge_sort(s.packages.get(), sys::shape_lt);
|
||||
let l = vec::len(pks);
|
||||
|
||||
print(io::with_str_writer(|writer| {
|
||||
let mut list = ~" >> ";
|
||||
|
||||
for vec::eachi(pks) |i, pk| {
|
||||
if str::len(list) > 78u {
|
||||
writer.write_line(list);
|
||||
list = ~" >> ";
|
||||
}
|
||||
list += pk.name + (if l - 1u == i { ~"" } else { ~", " });
|
||||
}
|
||||
|
||||
writer.write_line(list);
|
||||
}));
|
||||
}
|
||||
|
||||
fn cmd_list(c: &Cargo) {
|
||||
sync(c);
|
||||
|
||||
if vec::len(c.opts.free) >= 3u {
|
||||
let v = vec::view(c.opts.free, 2u, vec::len(c.opts.free));
|
||||
for vec::each(v) |name| {
|
||||
if !valid_pkg_name(*name) {
|
||||
error(fmt!("'%s' is an invalid source name", *name));
|
||||
} else {
|
||||
match c.sources.find(*name) {
|
||||
Some(source) => {
|
||||
print_source(source);
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", *name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for c.sources.each_value |v| {
|
||||
print_source(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_search(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
sync(c);
|
||||
|
||||
let mut n = 0;
|
||||
let name = c.opts.free[2];
|
||||
let tags = vec::slice(c.opts.free, 3u, vec::len(c.opts.free));
|
||||
for_each_package(c, |s, p| {
|
||||
if (str::contains(p.name, name) || name == ~"*") &&
|
||||
vec::all(tags, |t| vec::contains(p.tags, t) ) {
|
||||
print_pkg(s, p);
|
||||
n += 1;
|
||||
}
|
||||
});
|
||||
info(fmt!("found %d packages", n));
|
||||
}
|
||||
|
||||
fn install_to_dir(srcfile: &Path, destdir: &Path) {
|
||||
let newfile = destdir.push(srcfile.filename().get());
|
||||
|
||||
let status = run::run_program(~"cp", ~[~"-r", srcfile.to_str(),
|
||||
newfile.to_str()]);
|
||||
if status == 0 {
|
||||
info(fmt!("installed: '%s'", newfile.to_str()));
|
||||
} else {
|
||||
error(fmt!("could not install: '%s'", newfile.to_str()));
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_cache(c: &Cargo) {
|
||||
need_dir(&c.root);
|
||||
|
||||
let out = c.root.push("cache.json");
|
||||
let _root = json::Object(~LinearMap());
|
||||
|
||||
if os::path_exists(&out) {
|
||||
copy_warn(&out, &c.root.push("cache.json.old"));
|
||||
}
|
||||
}
|
||||
fn dump_sources(c: &Cargo) {
|
||||
if c.sources.size() < 1u {
|
||||
return;
|
||||
}
|
||||
|
||||
need_dir(&c.root);
|
||||
|
||||
let out = c.root.push("sources.json");
|
||||
|
||||
if os::path_exists(&out) {
|
||||
copy_warn(&out, &c.root.push("sources.json.old"));
|
||||
}
|
||||
|
||||
match io::buffered_file_writer(&out) {
|
||||
result::Ok(writer) => {
|
||||
let mut hash = ~LinearMap();
|
||||
|
||||
for c.sources.each |k, v| {
|
||||
let mut chash = ~LinearMap();
|
||||
|
||||
chash.insert(~"url", json::String(v.url));
|
||||
chash.insert(~"method", json::String(v.method));
|
||||
|
||||
match copy v.key {
|
||||
Some(key) => {
|
||||
chash.insert(~"key", json::String(copy key));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match copy v.keyfp {
|
||||
Some(keyfp) => {
|
||||
chash.insert(~"keyfp", json::String(copy keyfp));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
hash.insert(copy k, json::Object(move chash));
|
||||
}
|
||||
|
||||
json::to_writer(writer, &json::Object(move hash))
|
||||
}
|
||||
result::Err(e) => {
|
||||
error(fmt!("could not dump sources: %s", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_warn(srcfile: &Path, destfile: &Path) {
|
||||
if !os::copy_file(srcfile, destfile) {
|
||||
warn(fmt!("copying %s to %s failed",
|
||||
srcfile.to_str(), destfile.to_str()));
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_sources(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
for c.sources.each_value |v| {
|
||||
info(fmt!("%s (%s) via %s",
|
||||
v.name, v.url, v.method));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let action = c.opts.free[2u];
|
||||
|
||||
match action {
|
||||
~"clear" => {
|
||||
for c.sources.each_key |k| {
|
||||
c.sources.remove(k);
|
||||
}
|
||||
|
||||
info(~"cleared sources");
|
||||
}
|
||||
~"add" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let url = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
if c.sources.contains_key(name) {
|
||||
error(fmt!("source already exists: %s", name));
|
||||
} else {
|
||||
c.sources.insert(name, @Source {
|
||||
name: name,
|
||||
mut url: url,
|
||||
mut method: assume_source_method(url),
|
||||
mut key: None,
|
||||
mut keyfp: None,
|
||||
packages: DVec()
|
||||
});
|
||||
info(fmt!("added source: %s", name));
|
||||
}
|
||||
}
|
||||
~"remove" => {
|
||||
if vec::len(c.opts.free) < 4u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
if c.sources.contains_key(name) {
|
||||
c.sources.remove(name);
|
||||
info(fmt!("removed source: %s", name));
|
||||
} else {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
~"set-url" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let url = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(name) {
|
||||
Some(source) => {
|
||||
let old = copy source.url;
|
||||
let method = assume_source_method(url);
|
||||
|
||||
source.url = url;
|
||||
source.method = method;
|
||||
|
||||
c.sources.insert(name, source);
|
||||
|
||||
info(fmt!("changed source url: '%s' to '%s'", old, url));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
~"set-method" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let method = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(name) {
|
||||
Some(source) => {
|
||||
let old = copy source.method;
|
||||
|
||||
source.method = match method {
|
||||
~"git" => ~"git",
|
||||
~"file" => ~"file",
|
||||
_ => ~"curl"
|
||||
};
|
||||
|
||||
c.sources.insert(name, source);
|
||||
|
||||
info(fmt!("changed source method: '%s' to '%s'", old,
|
||||
method));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
~"rename" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let newn = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
if !valid_pkg_name(newn) {
|
||||
error(fmt!("'%s' is an invalid source name", newn));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(name) {
|
||||
Some(source) => {
|
||||
c.sources.remove(name);
|
||||
c.sources.insert(newn, source);
|
||||
info(fmt!("renamed source: %s to %s", name, newn));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => cmd_usage()
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_usage() {
|
||||
print(~"Usage: cargo <cmd> [options] [args..]
|
||||
e.g. cargo install <name>
|
||||
|
||||
Where <cmd> is one of:
|
||||
init, install, list, search, sources,
|
||||
uninstall, usage
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help Display this message
|
||||
<cmd> -h, <cmd> --help Display help for <cmd>
|
||||
");
|
||||
}
|
||||
|
||||
fn cmd_usage_init() {
|
||||
print(~"cargo init
|
||||
|
||||
Re-initialize cargo in ~/.cargo. Clears all sources and then adds the
|
||||
default sources from <www.rust-lang.org/sources.json>.");
|
||||
}
|
||||
|
||||
fn cmd_usage_install() {
|
||||
print(~"cargo install
|
||||
cargo install [source/]<name>[@version]
|
||||
cargo install [source/]<uuid>[@version]
|
||||
cargo install <git url> [ref]
|
||||
cargo install <tarball url>
|
||||
cargo install <tarball file>
|
||||
|
||||
Options:
|
||||
--test Run crate tests before installing
|
||||
-g Install to the user level (~/.cargo/bin/ instead of
|
||||
locally in ./.cargo/bin/ by default)
|
||||
-G Install to the system level (/usr/local/lib/cargo/bin/)
|
||||
|
||||
Install a crate. If no arguments are supplied, it installs from
|
||||
the current working directory. If a source is provided, only install
|
||||
from that source, otherwise it installs from any source.");
|
||||
}
|
||||
|
||||
fn cmd_usage_uninstall() {
|
||||
print(~"cargo uninstall [source/]<name>[@version]
|
||||
cargo uninstall [source/]<uuid>[@version]
|
||||
cargo uninstall <meta-name>[@version]
|
||||
cargo uninstall <meta-uuid>[@version]
|
||||
|
||||
Options:
|
||||
-g Remove from the user level (~/.cargo/bin/ instead of
|
||||
locally in ./.cargo/bin/ by default)
|
||||
-G Remove from the system level (/usr/local/lib/cargo/bin/)
|
||||
|
||||
Remove a crate. If a source is provided, only remove
|
||||
from that source, otherwise it removes from any source.
|
||||
If a crate was installed directly (git, tarball, etc.), you can remove
|
||||
it by metadata.");
|
||||
}
|
||||
|
||||
fn cmd_usage_list() {
|
||||
print(~"cargo list [sources..]
|
||||
|
||||
If no arguments are provided, list all sources and their packages.
|
||||
If source names are provided, list those sources and their packages.
|
||||
");
|
||||
}
|
||||
|
||||
fn cmd_usage_search() {
|
||||
print(~"cargo search <query | '*'> [tags..]
|
||||
|
||||
Search packages.");
|
||||
}
|
||||
|
||||
fn cmd_usage_sources() {
|
||||
print(~"cargo sources
|
||||
cargo sources add <name> <url>
|
||||
cargo sources remove <name>
|
||||
cargo sources rename <name> <new>
|
||||
cargo sources set-url <name> <url>
|
||||
cargo sources set-method <name> <method>
|
||||
|
||||
If no arguments are supplied, list all sources (but not their packages).
|
||||
|
||||
Commands:
|
||||
add Add a source. The source method will be guessed
|
||||
from the URL.
|
||||
remove Remove a source.
|
||||
rename Rename a source.
|
||||
set-url Change the URL for a source.
|
||||
set-method Change the method for a source.");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let argv = os::args();
|
||||
let o = build_cargo_options(argv);
|
||||
|
||||
if vec::len(o.free) < 2u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
if o.help {
|
||||
match o.free[1] {
|
||||
~"init" => cmd_usage_init(),
|
||||
~"install" => cmd_usage_install(),
|
||||
~"uninstall" => cmd_usage_uninstall(),
|
||||
~"list" => cmd_usage_list(),
|
||||
~"search" => cmd_usage_search(),
|
||||
~"sources" => cmd_usage_sources(),
|
||||
_ => cmd_usage()
|
||||
}
|
||||
return;
|
||||
}
|
||||
if o.free[1] == ~"usage" {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let mut c = configure(o);
|
||||
let home = c.root;
|
||||
let first_time = os::path_exists(&home.push("sources.json"));
|
||||
|
||||
if !first_time && o.free[1] != ~"init" {
|
||||
cmd_init(&c);
|
||||
|
||||
// FIXME (#2662): shouldn't need to reconfigure
|
||||
c = configure(o);
|
||||
}
|
||||
|
||||
let c = &move c;
|
||||
|
||||
match o.free[1] {
|
||||
~"init" => cmd_init(c),
|
||||
~"install" => cmd_install(c),
|
||||
~"uninstall" => cmd_uninstall(c),
|
||||
~"list" => cmd_list(c),
|
||||
~"search" => cmd_search(c),
|
||||
~"sources" => cmd_sources(c),
|
||||
_ => cmd_usage()
|
||||
}
|
||||
|
||||
dump_cache(c);
|
||||
dump_sources(c);
|
||||
}
|
||||
@@ -66,15 +66,7 @@ pub fn all_values(blk: fn(v: bool)) {
|
||||
pub pure fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } }
|
||||
|
||||
impl bool : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &bool) -> bool { self == (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &bool) -> bool { (*self) == (*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &bool) -> bool { self != (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &bool) -> bool { (*self) != (*other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -28,38 +28,14 @@ pub struct BoxRepr {
|
||||
}
|
||||
|
||||
impl<T:Eq> @const T : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &@const T) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &@const T) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &@const T) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &@const T) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
impl<T:Ord> @const T : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &@const T) -> bool { *self < *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &@const T) -> bool { *(*self) < *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &@const T) -> bool { *self <= *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &@const T) -> bool { *(*self) <= *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &@const T) -> bool { *self >= *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &@const T) -> bool { *(*self) >= *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &@const T) -> bool { *self > *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &@const T) -> bool { *(*self) > *(*other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -181,15 +181,7 @@
|
||||
}
|
||||
|
||||
impl char : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &char) -> bool { self == (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &char) -> bool { (*self) == (*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &char) -> bool { self != (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &char) -> bool { (*self) != (*other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -30,17 +30,6 @@ mod nounittest {
|
||||
* default implementations.
|
||||
*/
|
||||
#[lang="ord"]
|
||||
#[cfg(stage0)]
|
||||
pub trait Ord {
|
||||
pure fn lt(other: &self) -> bool;
|
||||
pure fn le(other: &self) -> bool;
|
||||
pure fn ge(other: &self) -> bool;
|
||||
pure fn gt(other: &self) -> bool;
|
||||
}
|
||||
|
||||
#[lang="ord"]
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pub trait Ord {
|
||||
pure fn lt(&self, other: &self) -> bool;
|
||||
pure fn le(&self, other: &self) -> bool;
|
||||
@@ -58,15 +47,6 @@ pub trait Ord {
|
||||
* a default implementation.
|
||||
*/
|
||||
#[lang="eq"]
|
||||
#[cfg(stage0)]
|
||||
pub trait Eq {
|
||||
pure fn eq(other: &self) -> bool;
|
||||
pure fn ne(other: &self) -> bool;
|
||||
}
|
||||
|
||||
#[lang="eq"]
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pub trait Eq {
|
||||
pure fn eq(&self, other: &self) -> bool;
|
||||
pure fn ne(&self, other: &self) -> bool;
|
||||
@@ -81,16 +61,6 @@ mod nounittest {
|
||||
mod unittest {
|
||||
#[legacy_exports];
|
||||
|
||||
#[cfg(stage0)]
|
||||
pub trait Ord {
|
||||
pure fn lt(other: &self) -> bool;
|
||||
pure fn le(other: &self) -> bool;
|
||||
pure fn ge(other: &self) -> bool;
|
||||
pure fn gt(other: &self) -> bool;
|
||||
}
|
||||
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pub trait Ord {
|
||||
pure fn lt(&self, other: &self) -> bool;
|
||||
pure fn le(&self, other: &self) -> bool;
|
||||
@@ -98,14 +68,6 @@ pub trait Ord {
|
||||
pure fn gt(&self, other: &self) -> bool;
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
pub trait Eq {
|
||||
pure fn eq(other: &self) -> bool;
|
||||
pure fn ne(other: &self) -> bool;
|
||||
}
|
||||
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pub trait Eq {
|
||||
pure fn eq(&self, other: &self) -> bool;
|
||||
pure fn ne(&self, other: &self) -> bool;
|
||||
|
||||
+127
-77
@@ -45,80 +45,54 @@ Implicitly, all crates behave as if they included the following prologue:
|
||||
// Built-in-type support modules
|
||||
|
||||
/// Operations and constants for `int`
|
||||
#[path = "int-template"]
|
||||
pub mod int {
|
||||
pub use inst::{ pow };
|
||||
#[path = "int.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "int-template.rs"]
|
||||
#[merge = "int-template/intb.rs"]
|
||||
pub mod int;
|
||||
|
||||
/// Operations and constants for `i8`
|
||||
#[path = "int-template"]
|
||||
pub mod i8 {
|
||||
#[path = "i8.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "int-template.rs"]
|
||||
#[merge = "int-template/i8b.rs"]
|
||||
pub mod i8;
|
||||
|
||||
/// Operations and constants for `i16`
|
||||
#[path = "int-template"]
|
||||
pub mod i16 {
|
||||
#[path = "i16.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "int-template.rs"]
|
||||
#[merge = "int-template/i16b.rs"]
|
||||
pub mod i16;
|
||||
|
||||
/// Operations and constants for `i32`
|
||||
#[path = "int-template"]
|
||||
pub mod i32 {
|
||||
#[path = "i32.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "int-template.rs"]
|
||||
#[merge = "int-template/i32b.rs"]
|
||||
pub mod i32;
|
||||
|
||||
/// Operations and constants for `i64`
|
||||
#[path = "int-template"]
|
||||
pub mod i64 {
|
||||
#[path = "i64.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "int-template.rs"]
|
||||
#[merge = "int-template/i64b.rs"]
|
||||
pub mod i64;
|
||||
|
||||
/// Operations and constants for `uint`
|
||||
#[path = "uint-template"]
|
||||
pub mod uint {
|
||||
pub use inst::{
|
||||
div_ceil, div_round, div_floor, iterate,
|
||||
next_power_of_two
|
||||
};
|
||||
#[path = "uint.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "uint-template.rs"]
|
||||
#[merge = "uint-template/uintb.rs"]
|
||||
pub mod uint;
|
||||
|
||||
/// Operations and constants for `u8`
|
||||
#[path = "uint-template"]
|
||||
pub mod u8 {
|
||||
pub use inst::is_ascii;
|
||||
#[path = "u8.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "uint-template.rs"]
|
||||
#[merge = "uint-template/u8b.rs"]
|
||||
pub mod u8;
|
||||
|
||||
/// Operations and constants for `u16`
|
||||
#[path = "uint-template"]
|
||||
pub mod u16 {
|
||||
#[path = "u16.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "uint-template.rs"]
|
||||
#[merge = "uint-template/u16b.rs"]
|
||||
pub mod u16;
|
||||
|
||||
/// Operations and constants for `u32`
|
||||
#[path = "uint-template"]
|
||||
pub mod u32 {
|
||||
#[path = "u32.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "uint-template.rs"]
|
||||
#[merge = "uint-template/u32b.rs"]
|
||||
pub mod u32;
|
||||
|
||||
/// Operations and constants for `u64`
|
||||
#[path = "uint-template"]
|
||||
pub mod u64 {
|
||||
#[path = "u64.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path = "uint-template.rs"]
|
||||
#[merge = "uint-template/u64b.rs"]
|
||||
pub mod u64;
|
||||
|
||||
|
||||
pub mod box;
|
||||
@@ -146,11 +120,9 @@ pub mod either;
|
||||
pub mod iter;
|
||||
pub mod logging;
|
||||
pub mod option;
|
||||
#[path="iter-trait"]
|
||||
pub mod option_iter {
|
||||
#[path = "option.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path="iter-trait.rs"]
|
||||
#[merge = "iter-trait/optionb.rs"]
|
||||
pub mod option_iter;
|
||||
pub mod result;
|
||||
pub mod to_str;
|
||||
pub mod to_bytes;
|
||||
@@ -161,27 +133,19 @@ pub mod clone;
|
||||
// Data structure modules
|
||||
|
||||
pub mod dvec;
|
||||
#[path="iter-trait"]
|
||||
pub mod dvec_iter {
|
||||
#[path = "dvec.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path="iter-trait.rs"]
|
||||
#[merge = "iter-trait/dvecb.rs"]
|
||||
pub mod dvec_iter;
|
||||
pub mod dlist;
|
||||
#[path="iter-trait"]
|
||||
pub mod dlist_iter {
|
||||
#[path ="dlist.rs"]
|
||||
pub mod inst;
|
||||
}
|
||||
#[path="iter-trait.rs"]
|
||||
#[merge = "iter-trait/dlistb.rs"]
|
||||
pub mod dlist_iter;
|
||||
pub mod send_map;
|
||||
|
||||
// Concurrency
|
||||
pub mod comm;
|
||||
pub mod task {
|
||||
pub mod local_data;
|
||||
mod local_data_priv;
|
||||
pub mod spawn;
|
||||
pub mod rt;
|
||||
}
|
||||
#[merge = "task/mod.rs"]
|
||||
pub mod task;
|
||||
pub mod pipes;
|
||||
|
||||
// Runtime and language-primitive support
|
||||
@@ -219,6 +183,92 @@ mod unicode;
|
||||
mod cmath;
|
||||
mod stackwalk;
|
||||
|
||||
// Top-level, visible-everywhere definitions.
|
||||
|
||||
// Export various ubiquitous types, constructors, methods.
|
||||
|
||||
pub use option::{Some, None};
|
||||
pub use Option = option::Option;
|
||||
pub use result::{Result, Ok, Err};
|
||||
|
||||
pub use Path = path::Path;
|
||||
pub use GenericPath = path::GenericPath;
|
||||
pub use WindowsPath = path::WindowsPath;
|
||||
pub use PosixPath = path::PosixPath;
|
||||
|
||||
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
|
||||
pub use str::{StrSlice, Trimmable};
|
||||
pub use vec::{ConstVector, CopyableVector, ImmutableVector};
|
||||
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
|
||||
pub use vec::{MutableVector, MutableCopyableVector};
|
||||
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
|
||||
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
|
||||
pub use num::Num;
|
||||
pub use ptr::Ptr;
|
||||
pub use to_str::ToStr;
|
||||
|
||||
// The following exports are the core operators and kinds
|
||||
// The compiler has special knowlege of these so we must not duplicate them
|
||||
// when compiling for testing
|
||||
#[cfg(notest)]
|
||||
pub use ops::{Const, Copy, Send, Owned};
|
||||
#[cfg(notest)]
|
||||
pub use ops::{Drop};
|
||||
#[cfg(notest)]
|
||||
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
|
||||
#[cfg(notest)]
|
||||
pub use ops::{Shl, Shr, Index};
|
||||
|
||||
#[cfg(test)]
|
||||
extern mod coreops(name = "core", vers = "0.5");
|
||||
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Const, Copy, Send, Owned};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Drop};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{BitXor};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Shl, Shr, Index};
|
||||
|
||||
#[cfg(notest)]
|
||||
pub use clone::Clone;
|
||||
#[cfg(test)]
|
||||
pub use coreops::clone::Clone;
|
||||
|
||||
// Export the log levels as global constants. Higher levels mean
|
||||
// more-verbosity. Error is the bottom level, default logging level is
|
||||
// warn-and-below.
|
||||
|
||||
/// The error log level
|
||||
pub const error : u32 = 1_u32;
|
||||
/// The warning log level
|
||||
pub const warn : u32 = 2_u32;
|
||||
/// The info log level
|
||||
pub const info : u32 = 3_u32;
|
||||
/// The debug log level
|
||||
pub const debug : u32 = 4_u32;
|
||||
|
||||
// A curious inner-module that's not exported that contains the binding
|
||||
// 'core' so that macro-expanded references to core::error and such
|
||||
// can be resolved within libcore.
|
||||
#[doc(hidden)] // FIXME #3538
|
||||
mod core {
|
||||
pub const error : u32 = 1_u32;
|
||||
pub const warn : u32 = 2_u32;
|
||||
pub const info : u32 = 3_u32;
|
||||
pub const debug : u32 = 4_u32;
|
||||
}
|
||||
|
||||
// Similar to above. Some magic to make core testable.
|
||||
#[cfg(test)]
|
||||
mod std {
|
||||
extern mod std(vers = "0.5");
|
||||
pub use std::test;
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
// fill-column: 78;
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
// Top-level, visible-everywhere definitions.
|
||||
|
||||
// Export various ubiquitous types, constructors, methods.
|
||||
|
||||
pub use option::{Some, None};
|
||||
pub use Option = option::Option;
|
||||
pub use result::{Result, Ok, Err};
|
||||
|
||||
pub use Path = path::Path;
|
||||
pub use GenericPath = path::GenericPath;
|
||||
pub use WindowsPath = path::WindowsPath;
|
||||
pub use PosixPath = path::PosixPath;
|
||||
|
||||
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
|
||||
pub use str::{StrSlice, Trimmable};
|
||||
pub use vec::{ConstVector, CopyableVector, ImmutableVector};
|
||||
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
|
||||
pub use vec::{MutableVector, MutableCopyableVector};
|
||||
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
|
||||
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
|
||||
pub use num::Num;
|
||||
pub use ptr::Ptr;
|
||||
pub use to_str::ToStr;
|
||||
|
||||
// The following exports are the core operators and kinds
|
||||
// The compiler has special knowlege of these so we must not duplicate them
|
||||
// when compiling for testing
|
||||
#[cfg(notest)]
|
||||
pub use ops::{Const, Copy, Send, Owned};
|
||||
#[cfg(notest)]
|
||||
pub use ops::{Drop};
|
||||
#[cfg(notest)]
|
||||
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
|
||||
#[cfg(notest)]
|
||||
pub use ops::{Shl, Shr, Index};
|
||||
|
||||
#[cfg(test)]
|
||||
extern mod coreops(name = "core", vers = "0.5");
|
||||
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Const, Copy, Send, Owned};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Drop};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{BitXor};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Shl, Shr, Index};
|
||||
|
||||
#[cfg(notest)]
|
||||
pub use clone::Clone;
|
||||
#[cfg(test)]
|
||||
pub use coreops::clone::Clone;
|
||||
|
||||
// Export the log levels as global constants. Higher levels mean
|
||||
// more-verbosity. Error is the bottom level, default logging level is
|
||||
// warn-and-below.
|
||||
|
||||
/// The error log level
|
||||
pub const error : u32 = 1_u32;
|
||||
/// The warning log level
|
||||
pub const warn : u32 = 2_u32;
|
||||
/// The info log level
|
||||
pub const info : u32 = 3_u32;
|
||||
/// The debug log level
|
||||
pub const debug : u32 = 4_u32;
|
||||
|
||||
// A curious inner-module that's not exported that contains the binding
|
||||
// 'core' so that macro-expanded references to core::error and such
|
||||
// can be resolved within libcore.
|
||||
#[doc(hidden)] // FIXME #3538
|
||||
mod core {
|
||||
pub const error : u32 = 1_u32;
|
||||
pub const warn : u32 = 2_u32;
|
||||
pub const info : u32 = 3_u32;
|
||||
pub const debug : u32 = 4_u32;
|
||||
}
|
||||
|
||||
// Similar to above. Some magic to make core testable.
|
||||
#[cfg(test)]
|
||||
mod std {
|
||||
extern mod std(vers = "0.5");
|
||||
pub use std::test;
|
||||
}
|
||||
@@ -132,25 +132,6 @@ pub fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
|
||||
}
|
||||
|
||||
impl<T:Eq,U:Eq> Either<T,U> : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Either<T,U>) -> bool {
|
||||
match self {
|
||||
Left(ref a) => {
|
||||
match (*other) {
|
||||
Left(ref b) => (*a).eq(b),
|
||||
Right(_) => false
|
||||
}
|
||||
}
|
||||
Right(ref a) => {
|
||||
match (*other) {
|
||||
Left(_) => false,
|
||||
Right(ref b) => (*a).eq(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Either<T,U>) -> bool {
|
||||
match (*self) {
|
||||
Left(ref a) => {
|
||||
@@ -167,10 +148,6 @@ impl<T:Eq,U:Eq> Either<T,U> : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Either<T,U>) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Either<T,U>) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -438,21 +438,6 @@ pub enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, }
|
||||
pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
|
||||
|
||||
pub impl PadMode : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &PadMode) -> bool {
|
||||
match (self, (*other)) {
|
||||
(PadSigned, PadSigned) => true,
|
||||
(PadUnsigned, PadUnsigned) => true,
|
||||
(PadNozero, PadNozero) => true,
|
||||
(PadFloat, PadFloat) => true,
|
||||
(PadSigned, _) => false,
|
||||
(PadUnsigned, _) => false,
|
||||
(PadNozero, _) => false,
|
||||
(PadFloat, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &PadMode) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(PadSigned, PadSigned) => true,
|
||||
@@ -465,10 +450,6 @@ pub impl PadMode : Eq {
|
||||
(PadFloat, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &PadMode) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &PadMode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -400,38 +400,14 @@ pub fn from_str(num: &str) -> Option<float> {
|
||||
pub pure fn tan(x: float) -> float { f64::tan(x as f64) as float }
|
||||
|
||||
impl float : Eq {
|
||||
#[cfg(stage0)]
|
||||
pub pure fn eq(other: &float) -> bool { self == (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &float) -> bool { (*self) == (*other) }
|
||||
#[cfg(stage0)]
|
||||
pub pure fn ne(other: &float) -> bool { self != (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &float) -> bool { (*self) != (*other) }
|
||||
}
|
||||
|
||||
impl float : Ord {
|
||||
#[cfg(stage0)]
|
||||
pub pure fn lt(other: &float) -> bool { self < (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &float) -> bool { (*self) < (*other) }
|
||||
#[cfg(stage0)]
|
||||
pub pure fn le(other: &float) -> bool { self <= (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &float) -> bool { (*self) <= (*other) }
|
||||
#[cfg(stage0)]
|
||||
pub pure fn ge(other: &float) -> bool { self >= (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &float) -> bool { (*self) >= (*other) }
|
||||
#[cfg(stage0)]
|
||||
pub pure fn gt(other: &float) -> bool { self > (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &float) -> bool { (*self) > (*other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -55,38 +55,14 @@ pub fn range(lo: T, hi: T, it: fn(T) -> bool) {
|
||||
}
|
||||
|
||||
impl T : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &T) -> bool { return self < (*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &T) -> bool { return (*self) < (*other); }
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &T) -> bool { return self <= (*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &T) -> bool { return (*self) <= (*other); }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &T) -> bool { return self >= (*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &T) -> bool { return (*self) >= (*other); }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &T) -> bool { return self > (*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &T) -> bool { return (*self) > (*other); }
|
||||
}
|
||||
|
||||
impl T : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &T) -> bool { return self == (*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &T) -> bool { return self != (*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
mod inst {
|
||||
pub type T = i16;
|
||||
pub const bits: uint = u16::bits;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
mod inst {
|
||||
pub type T = i32;
|
||||
pub const bits: uint = u32::bits;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
mod inst {
|
||||
pub type T = i64;
|
||||
pub const bits: uint = u64::bits;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
mod inst {
|
||||
pub type T = i8;
|
||||
pub const bits: uint = u8::bits;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
pub use inst::pow;
|
||||
|
||||
mod inst {
|
||||
pub type T = int;
|
||||
pub const bits: uint = uint::bits;
|
||||
|
||||
/// Returns `base` raised to the power of `exponent`
|
||||
pub fn pow(base: int, exponent: uint) -> int {
|
||||
if exponent == 0u {
|
||||
//Not mathemtically true if ~[base == 0]
|
||||
return 1;
|
||||
}
|
||||
if base == 0 { return 0; }
|
||||
let mut my_pow = exponent;
|
||||
let mut acc = 1;
|
||||
let mut multiplier = base;
|
||||
while(my_pow > 0u) {
|
||||
if my_pow % 2u == 1u {
|
||||
acc *= multiplier;
|
||||
}
|
||||
my_pow /= 2u;
|
||||
multiplier *= multiplier;
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pow() {
|
||||
assert (pow(0, 0u) == 1);
|
||||
assert (pow(0, 1u) == 0);
|
||||
assert (pow(0, 2u) == 0);
|
||||
assert (pow(-1, 0u) == 1);
|
||||
assert (pow(1, 0u) == 1);
|
||||
assert (pow(-3, 2u) == 9);
|
||||
assert (pow(-3, 3u) == -27);
|
||||
assert (pow(4, 9u) == 262144);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_overflows() {
|
||||
assert (max_value > 0);
|
||||
assert (min_value <= 0);
|
||||
assert (min_value + max_value + 1 == 0);
|
||||
}
|
||||
}
|
||||
@@ -516,25 +516,12 @@ pub enum FileFlag { Append, Create, Truncate, NoFlag, }
|
||||
pub enum WriterType { Screen, File }
|
||||
|
||||
pub impl WriterType : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &WriterType) -> bool {
|
||||
match (self, (*other)) {
|
||||
(Screen, Screen) | (File, File) => true,
|
||||
(Screen, _) | (File, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &WriterType) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(Screen, Screen) | (File, File) => true,
|
||||
(Screen, _) | (File, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &WriterType) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &WriterType) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
mod inst {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type IMPL_T<A> = dlist::DList<A>;
|
||||
|
||||
/**
|
||||
* Iterates through the current contents.
|
||||
*
|
||||
* Attempts to access this dlist during iteration are allowed (to
|
||||
* allow for e.g. breadth-first search with in-place enqueues), but
|
||||
* removing the current node is forbidden.
|
||||
*/
|
||||
pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
|
||||
let mut link = self.peek_n();
|
||||
while option::is_some(&link) {
|
||||
let nobe = option::get(link);
|
||||
assert nobe.linked;
|
||||
if !f(&nobe.data) { break; }
|
||||
// Check (weakly) that the user didn't do a remove.
|
||||
if self.size == 0 {
|
||||
fail ~"The dlist became empty during iteration??"
|
||||
}
|
||||
if !nobe.linked ||
|
||||
(!((nobe.prev.is_some()
|
||||
|| box::ptr_eq(*self.hd.expect(~"headless dlist?"),
|
||||
*nobe))
|
||||
&& (nobe.next.is_some()
|
||||
|| box::ptr_eq(*self.tl.expect(~"tailless dlist?"),
|
||||
*nobe)))) {
|
||||
fail ~"Removing a dlist node during iteration is forbidden!"
|
||||
}
|
||||
link = nobe.next_link();
|
||||
}
|
||||
}
|
||||
|
||||
pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
|
||||
Some(self.len())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
mod inst {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type IMPL_T<A> = dvec::DVec<A>;
|
||||
|
||||
/**
|
||||
* Iterates through the current contents.
|
||||
*
|
||||
* Attempts to access this dvec during iteration will fail.
|
||||
*/
|
||||
pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
|
||||
unsafe {
|
||||
do self.swap |v| {
|
||||
v.each(f);
|
||||
move v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
|
||||
Some(self.len())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
mod inst {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type IMPL_T<A> = Option<A>;
|
||||
|
||||
pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
|
||||
match *self {
|
||||
None => (),
|
||||
Some(ref a) => { f(a); }
|
||||
}
|
||||
}
|
||||
|
||||
pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
|
||||
match *self {
|
||||
None => Some(0),
|
||||
Some(_) => Some(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,26 +301,6 @@ impl<T: Copy> Option<T> {
|
||||
}
|
||||
|
||||
impl<T: Eq> Option<T> : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Option<T>) -> bool {
|
||||
match self {
|
||||
None => {
|
||||
match (*other) {
|
||||
None => true,
|
||||
Some(_) => false
|
||||
}
|
||||
}
|
||||
Some(ref self_contents) => {
|
||||
match (*other) {
|
||||
None => false,
|
||||
Some(ref other_contents) =>
|
||||
(*self_contents).eq(other_contents)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Option<T>) -> bool {
|
||||
match (*self) {
|
||||
None => {
|
||||
@@ -338,10 +318,6 @@ impl<T: Eq> Option<T> : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Option<T>) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Option<T>) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -7,38 +7,14 @@
|
||||
use cmp::{Eq, Ord};
|
||||
|
||||
impl<T:Eq> ~const T : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &~const T) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &~const T) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &~const T) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &~const T) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
impl<T:Ord> ~const T : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &~const T) -> bool { *self < *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &~const T) -> bool { *(*self) < *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &~const T) -> bool { *self <= *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &~const T) -> bool { *(*self) <= *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &~const T) -> bool { *self >= *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &~const T) -> bool { *(*self) >= *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &~const T) -> bool { *self > *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &~const T) -> bool { *(*self) > *(*other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -344,44 +344,20 @@ impl PosixPath : ToStr {
|
||||
}
|
||||
|
||||
impl PosixPath : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &PosixPath) -> bool {
|
||||
return self.is_absolute == (*other).is_absolute &&
|
||||
self.components == (*other).components;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &PosixPath) -> bool {
|
||||
return (*self).is_absolute == (*other).is_absolute &&
|
||||
(*self).components == (*other).components;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &PosixPath) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &PosixPath) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl WindowsPath : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &WindowsPath) -> bool {
|
||||
return self.host == (*other).host &&
|
||||
self.device == (*other).device &&
|
||||
self.is_absolute == (*other).is_absolute &&
|
||||
self.components == (*other).components;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &WindowsPath) -> bool {
|
||||
return (*self).host == (*other).host &&
|
||||
(*self).device == (*other).device &&
|
||||
(*self).is_absolute == (*other).is_absolute &&
|
||||
(*self).components == (*other).components;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &WindowsPath) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &WindowsPath) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -98,19 +98,9 @@ enum State {
|
||||
}
|
||||
|
||||
impl State : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &State) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &State) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &State) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &State) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -208,75 +208,31 @@ impl<T> *mut T: Ptr<T> {
|
||||
|
||||
// Equality for pointers
|
||||
impl<T> *const T : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&self);
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a == b;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&(*self));
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a == b;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &*const T) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &*const T) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
// Comparison for pointers
|
||||
impl<T> *const T : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&self);
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a < b;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&(*self));
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a < b;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&self);
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a <= b;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&(*self));
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a <= b;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&self);
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a >= b;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&(*self));
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a >= b;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&self);
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
return a > b;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &*const T) -> bool unsafe {
|
||||
let a: uint = cast::reinterpret_cast(&(*self));
|
||||
let b: uint = cast::reinterpret_cast(&(*other));
|
||||
@@ -286,17 +242,9 @@ impl<T> *const T : Ord {
|
||||
|
||||
// Equality for region pointers
|
||||
impl<T:Eq> &const T : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: & &self/const T) -> bool { return *self == *(*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: & &self/const T) -> bool {
|
||||
return *(*self) == *(*other);
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: & &self/const T) -> bool { return *self != *(*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: & &self/const T) -> bool {
|
||||
return *(*self) != *(*other);
|
||||
}
|
||||
@@ -304,31 +252,15 @@ impl<T:Eq> &const T : Eq {
|
||||
|
||||
// Comparison for region pointers
|
||||
impl<T:Ord> &const T : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: & &self/const T) -> bool { *self < *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: & &self/const T) -> bool {
|
||||
*(*self) < *(*other)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: & &self/const T) -> bool { *self <= *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: & &self/const T) -> bool {
|
||||
*(*self) <= *(*other)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: & &self/const T) -> bool { *self >= *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: & &self/const T) -> bool {
|
||||
*(*self) >= *(*other)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: & &self/const T) -> bool { *self > *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: & &self/const T) -> bool {
|
||||
*(*self) > *(*other)
|
||||
}
|
||||
|
||||
@@ -516,19 +516,9 @@ enum EnumVisitState {
|
||||
}
|
||||
|
||||
impl EnumVisitState : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &EnumVisitState) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &EnumVisitState) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &EnumVisitState) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &EnumVisitState) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -365,25 +365,6 @@ pub fn unwrap_err<T, U>(res: Result<T, U>) -> U {
|
||||
}
|
||||
|
||||
impl<T:Eq,U:Eq> Result<T,U> : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Result<T,U>) -> bool {
|
||||
match self {
|
||||
Ok(ref e0a) => {
|
||||
match (*other) {
|
||||
Ok(ref e0b) => *e0a == *e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
Err(ref e0a) => {
|
||||
match (*other) {
|
||||
Err(ref e0b) => *e0a == *e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Result<T,U>) -> bool {
|
||||
match (*self) {
|
||||
Ok(ref e0a) => {
|
||||
@@ -400,10 +381,6 @@ impl<T:Eq,U:Eq> Result<T,U> : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Result<T,U>) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Result<T,U>) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -737,139 +737,61 @@ pub fn split_within(ss: &str, lim: uint) -> ~[~str] {
|
||||
|
||||
impl &str : Eq {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: & &self/str) -> bool {
|
||||
eq_slice(self, (*other))
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: & &self/str) -> bool {
|
||||
eq_slice((*self), (*other))
|
||||
}
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: & &self/str) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: & &self/str) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl ~str : Eq {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &~str) -> bool {
|
||||
eq_slice(self, (*other))
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &~str) -> bool {
|
||||
eq_slice((*self), (*other))
|
||||
}
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &~str) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &~str) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl @str : Eq {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &@str) -> bool {
|
||||
eq_slice(self, (*other))
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &@str) -> bool {
|
||||
eq_slice((*self), (*other))
|
||||
}
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &@str) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &@str) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl ~str : Ord {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &~str) -> bool { lt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &~str) -> bool { lt((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &~str) -> bool { le(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &~str) -> bool { le((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &~str) -> bool { ge(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &~str) -> bool { ge((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &~str) -> bool { gt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &~str) -> bool { gt((*self), (*other)) }
|
||||
}
|
||||
|
||||
impl &str : Ord {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: & &self/str) -> bool { lt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: & &self/str) -> bool { lt((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: & &self/str) -> bool { le(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: & &self/str) -> bool { le((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: & &self/str) -> bool { ge(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: & &self/str) -> bool { ge((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: & &self/str) -> bool { gt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: & &self/str) -> bool { gt((*self), (*other)) }
|
||||
}
|
||||
|
||||
impl @str : Ord {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &@str) -> bool { lt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &@str) -> bool { lt((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &@str) -> bool { le(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &@str) -> bool { le((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &@str) -> bool { ge(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &@str) -> bool { ge((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &@str) -> bool { gt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) }
|
||||
}
|
||||
|
||||
|
||||
@@ -43,15 +43,7 @@ pub enum Task {
|
||||
}
|
||||
|
||||
impl Task : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Task) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Task) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Task) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Task) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -72,25 +64,12 @@ pub enum TaskResult {
|
||||
}
|
||||
|
||||
impl TaskResult : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &TaskResult) -> bool {
|
||||
match (self, (*other)) {
|
||||
(Success, Success) | (Failure, Failure) => true,
|
||||
(Success, _) | (Failure, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &TaskResult) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(Success, Success) | (Failure, Failure) => true,
|
||||
(Success, _) | (Failure, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &TaskResult) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &TaskResult) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -114,43 +93,6 @@ pub enum SchedMode {
|
||||
}
|
||||
|
||||
impl SchedMode : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &SchedMode) -> bool {
|
||||
match self {
|
||||
SingleThreaded => {
|
||||
match (*other) {
|
||||
SingleThreaded => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ThreadPerCore => {
|
||||
match (*other) {
|
||||
ThreadPerCore => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ThreadPerTask => {
|
||||
match (*other) {
|
||||
ThreadPerTask => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ManualThreads(e0a) => {
|
||||
match (*other) {
|
||||
ManualThreads(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
PlatformThread => {
|
||||
match (*other) {
|
||||
PlatformThread => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &SchedMode) -> bool {
|
||||
match (*self) {
|
||||
SingleThreaded => {
|
||||
@@ -185,12 +127,6 @@ impl SchedMode : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &SchedMode) -> bool {
|
||||
!self.eq(other)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &SchedMode) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
|
||||
@@ -7,23 +7,11 @@ pub trait LocalData { }
|
||||
impl<T: Owned> @T: LocalData { }
|
||||
|
||||
impl LocalData: Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &@LocalData) -> bool unsafe {
|
||||
let ptr_a: (uint, uint) = cast::reinterpret_cast(&self);
|
||||
let ptr_b: (uint, uint) = cast::reinterpret_cast(other);
|
||||
return ptr_a == ptr_b;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &@LocalData) -> bool unsafe {
|
||||
let ptr_a: (uint, uint) = cast::reinterpret_cast(&(*self));
|
||||
let ptr_b: (uint, uint) = cast::reinterpret_cast(other);
|
||||
return ptr_a == ptr_b;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &@LocalData) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &@LocalData) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
mod local_data_priv;
|
||||
|
||||
pub mod local_data;
|
||||
|
||||
pub mod rt;
|
||||
|
||||
pub mod spawn;
|
||||
@@ -95,18 +95,6 @@ fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
|
||||
}
|
||||
|
||||
impl<A: Eq, B: Eq> (A, B) : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &(A, B)) -> bool {
|
||||
match self {
|
||||
(ref self_a, ref self_b) => match other {
|
||||
&(ref other_a, ref other_b) => {
|
||||
(*self_a).eq(other_a) && (*self_b).eq(other_b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &(A, B)) -> bool {
|
||||
match (*self) {
|
||||
(ref self_a, ref self_b) => match other {
|
||||
@@ -116,31 +104,10 @@ impl<A: Eq, B: Eq> (A, B) : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &(A, B)) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &(A, B)) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl<A: Ord, B: Ord> (A, B) : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &(A, B)) -> bool {
|
||||
match self {
|
||||
(ref self_a, ref self_b) => {
|
||||
match (*other) {
|
||||
(ref other_a, ref other_b) => {
|
||||
if (*self_a).lt(other_a) { return true; }
|
||||
if (*other_a).lt(self_a) { return false; }
|
||||
if (*self_b).lt(other_b) { return true; }
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &(A, B)) -> bool {
|
||||
match (*self) {
|
||||
(ref self_a, ref self_b) => {
|
||||
@@ -155,37 +122,12 @@ impl<A: Ord, B: Ord> (A, B) : Ord {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &(A, B)) -> bool { !(*other).lt(&self) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &(A, B)) -> bool { !(*other).lt(&(*self)) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &(A, B)) -> bool { !self.lt(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &(A, B)) -> bool { !(*self).lt(other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &(A, B)) -> bool { (*other).lt(&self) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &(A, B)) -> bool { (*other).lt(&(*self)) }
|
||||
}
|
||||
|
||||
impl<A: Eq, B: Eq, C: Eq> (A, B, C) : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &(A, B, C)) -> bool {
|
||||
match self {
|
||||
(ref self_a, ref self_b, ref self_c) => match other {
|
||||
&(ref other_a, ref other_b, ref other_c) => {
|
||||
(*self_a).eq(other_a) && (*self_b).eq(other_b)
|
||||
&& (*self_c).eq(other_c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &(A, B, C)) -> bool {
|
||||
match (*self) {
|
||||
(ref self_a, ref self_b, ref self_c) => match other {
|
||||
@@ -196,33 +138,10 @@ impl<A: Eq, B: Eq, C: Eq> (A, B, C) : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &(A, B, C)) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &(A, B, C)) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl<A: Ord, B: Ord, C: Ord> (A, B, C) : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &(A, B, C)) -> bool {
|
||||
match self {
|
||||
(ref self_a, ref self_b, ref self_c) => {
|
||||
match (*other) {
|
||||
(ref other_a, ref other_b, ref other_c) => {
|
||||
if (*self_a).lt(other_a) { return true; }
|
||||
if (*other_a).lt(self_a) { return false; }
|
||||
if (*self_b).lt(other_b) { return true; }
|
||||
if (*other_b).lt(self_b) { return false; }
|
||||
if (*self_c).lt(other_c) { return true; }
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &(A, B, C)) -> bool {
|
||||
match (*self) {
|
||||
(ref self_a, ref self_b, ref self_c) => {
|
||||
@@ -239,20 +158,8 @@ impl<A: Ord, B: Ord, C: Ord> (A, B, C) : Ord {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &(A, B, C)) -> bool { !(*other).lt(&self) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &(A, B, C)) -> bool { !(*other).lt(&(*self)) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &(A, B, C)) -> bool { !self.lt(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &(A, B, C)) -> bool { !(*self).lt(other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &(A, B, C)) -> bool { (*other).lt(&self) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &(A, B, C)) -> bool { (*other).lt(&(*self)) }
|
||||
}
|
||||
|
||||
|
||||
@@ -49,38 +49,14 @@
|
||||
}
|
||||
|
||||
impl T : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &T) -> bool { self < (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &T) -> bool { (*self) < (*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &T) -> bool { self <= (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &T) -> bool { (*self) <= (*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &T) -> bool { self >= (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &T) -> bool { (*self) >= (*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &T) -> bool { self > (*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &T) -> bool { (*self) > (*other) }
|
||||
}
|
||||
|
||||
impl T : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &T) -> bool { return self == (*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &T) -> bool { return self != (*other); }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
mod inst {
|
||||
pub type T = u16;
|
||||
pub const bits: uint = 16;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
mod inst {
|
||||
pub type T = u32;
|
||||
pub const bits: uint = 32;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
mod inst {
|
||||
pub type T = u64;
|
||||
pub const bits: uint = 64;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
pub use inst::is_ascii;
|
||||
|
||||
mod inst {
|
||||
pub type T = u8;
|
||||
pub const bits: uint = 8;
|
||||
|
||||
// Type-specific functions here. These must be reexported by the
|
||||
// parent module so that they appear in core::u8 and not core::u8::u8;
|
||||
|
||||
pub pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; }
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
pub use inst::{
|
||||
div_ceil, div_round, div_floor, iterate,
|
||||
next_power_of_two
|
||||
};
|
||||
|
||||
mod inst {
|
||||
pub type T = uint;
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "arm")]
|
||||
pub const bits: uint = 32;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub const bits: uint = 64;
|
||||
|
||||
/**
|
||||
* Divide two numbers, return the result, rounded up.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * x - an integer
|
||||
* * y - an integer distinct from 0u
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* The smallest integer `q` such that `x/y <= q`.
|
||||
*/
|
||||
pub pure fn div_ceil(x: uint, y: uint) -> uint {
|
||||
let div = x / y;
|
||||
if x % y == 0u { div }
|
||||
else { div + 1u }
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide two numbers, return the result, rounded to the closest integer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * x - an integer
|
||||
* * y - an integer distinct from 0u
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* The integer `q` closest to `x/y`.
|
||||
*/
|
||||
pub pure fn div_round(x: uint, y: uint) -> uint {
|
||||
let div = x / y;
|
||||
if x % y * 2u < y { div }
|
||||
else { div + 1u }
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide two numbers, return the result, rounded down.
|
||||
*
|
||||
* Note: This is the same function as `div`.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * x - an integer
|
||||
* * y - an integer distinct from 0u
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* The smallest integer `q` such that `x/y <= q`. This
|
||||
* is either `x/y` or `x/y + 1`.
|
||||
*/
|
||||
pub pure fn div_floor(x: uint, y: uint) -> uint { return x / y; }
|
||||
|
||||
/**
|
||||
* Iterate over the range [`lo`..`hi`), or stop when requested
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * lo - The integer at which to start the loop (included)
|
||||
* * hi - The integer at which to stop the loop (excluded)
|
||||
* * it - A block to execute with each consecutive integer of the range.
|
||||
* Return `true` to continue, `false` to stop.
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* `true` If execution proceeded correctly, `false` if it was interrupted,
|
||||
* that is if `it` returned `false` at any point.
|
||||
*/
|
||||
pub pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
|
||||
let mut i = lo;
|
||||
while i < hi {
|
||||
if (!it(i)) { return false; }
|
||||
i += 1u;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Returns the smallest power of 2 greater than or equal to `n`
|
||||
#[inline(always)]
|
||||
pub fn next_power_of_two(n: uint) -> uint {
|
||||
let halfbits: uint = sys::size_of::<uint>() * 4u;
|
||||
let mut tmp: uint = n - 1u;
|
||||
let mut shift: uint = 1u;
|
||||
while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
|
||||
return tmp + 1u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_next_power_of_two() {
|
||||
assert (uint::next_power_of_two(0u) == 0u);
|
||||
assert (uint::next_power_of_two(1u) == 1u);
|
||||
assert (uint::next_power_of_two(2u) == 2u);
|
||||
assert (uint::next_power_of_two(3u) == 4u);
|
||||
assert (uint::next_power_of_two(4u) == 4u);
|
||||
assert (uint::next_power_of_two(5u) == 8u);
|
||||
assert (uint::next_power_of_two(6u) == 8u);
|
||||
assert (uint::next_power_of_two(7u) == 8u);
|
||||
assert (uint::next_power_of_two(8u) == 8u);
|
||||
assert (uint::next_power_of_two(9u) == 16u);
|
||||
assert (uint::next_power_of_two(10u) == 16u);
|
||||
assert (uint::next_power_of_two(11u) == 16u);
|
||||
assert (uint::next_power_of_two(12u) == 16u);
|
||||
assert (uint::next_power_of_two(13u) == 16u);
|
||||
assert (uint::next_power_of_two(14u) == 16u);
|
||||
assert (uint::next_power_of_two(15u) == 16u);
|
||||
assert (uint::next_power_of_two(16u) == 16u);
|
||||
assert (uint::next_power_of_two(17u) == 32u);
|
||||
assert (uint::next_power_of_two(18u) == 32u);
|
||||
assert (uint::next_power_of_two(19u) == 32u);
|
||||
assert (uint::next_power_of_two(20u) == 32u);
|
||||
assert (uint::next_power_of_two(21u) == 32u);
|
||||
assert (uint::next_power_of_two(22u) == 32u);
|
||||
assert (uint::next_power_of_two(23u) == 32u);
|
||||
assert (uint::next_power_of_two(24u) == 32u);
|
||||
assert (uint::next_power_of_two(25u) == 32u);
|
||||
assert (uint::next_power_of_two(26u) == 32u);
|
||||
assert (uint::next_power_of_two(27u) == 32u);
|
||||
assert (uint::next_power_of_two(28u) == 32u);
|
||||
assert (uint::next_power_of_two(29u) == 32u);
|
||||
assert (uint::next_power_of_two(30u) == 32u);
|
||||
assert (uint::next_power_of_two(31u) == 32u);
|
||||
assert (uint::next_power_of_two(32u) == 32u);
|
||||
assert (uint::next_power_of_two(33u) == 64u);
|
||||
assert (uint::next_power_of_two(34u) == 64u);
|
||||
assert (uint::next_power_of_two(35u) == 64u);
|
||||
assert (uint::next_power_of_two(36u) == 64u);
|
||||
assert (uint::next_power_of_two(37u) == 64u);
|
||||
assert (uint::next_power_of_two(38u) == 64u);
|
||||
assert (uint::next_power_of_two(39u) == 64u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_overflows() {
|
||||
assert (uint::max_value > 0u);
|
||||
assert (uint::min_value <= 0u);
|
||||
assert (uint::min_value + uint::max_value + 1u == 0u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_div() {
|
||||
assert(uint::div_floor(3u, 4u) == 0u);
|
||||
assert(uint::div_ceil(3u, 4u) == 1u);
|
||||
assert(uint::div_round(3u, 4u) == 1u);
|
||||
}
|
||||
}
|
||||
@@ -11,38 +11,14 @@
|
||||
use cmp::{Eq, Ord};
|
||||
|
||||
impl () : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(_other: &()) -> bool { true }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, _other: &()) -> bool { true }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(_other: &()) -> bool { false }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, _other: &()) -> bool { false }
|
||||
}
|
||||
|
||||
impl () : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(_other: &()) -> bool { false }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, _other: &()) -> bool { false }
|
||||
#[cfg(stage0)]
|
||||
pure fn le(_other: &()) -> bool { true }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, _other: &()) -> bool { true }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(_other: &()) -> bool { true }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, _other: &()) -> bool { true }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(_other: &()) -> bool { false }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, _other: &()) -> bool { false }
|
||||
}
|
||||
|
||||
|
||||
@@ -1347,47 +1347,23 @@ pub fn each2<U, T>(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) {
|
||||
|
||||
impl<T: Eq> &[T] : Eq {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: & &self/[T]) -> bool { eq(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: & &self/[T]) -> bool { eq((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: & &self/[T]) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: & &self/[T]) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
impl<T: Eq> ~[T] : Eq {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &~[T]) -> bool { eq(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &~[T]) -> bool { eq((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &~[T]) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &~[T]) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl<T: Eq> @[T] : Eq {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &@[T]) -> bool { eq(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &@[T]) -> bool { eq((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &@[T]) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &@[T]) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1414,82 +1390,34 @@ impl<T: Eq> @[T] : Eq {
|
||||
|
||||
impl<T: Ord> &[T] : Ord {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: & &self/[T]) -> bool { lt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: & &self/[T]) -> bool { lt((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: & &self/[T]) -> bool { le(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: & &self/[T]) -> bool { le((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: & &self/[T]) -> bool { ge(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: & &self/[T]) -> bool { ge((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: & &self/[T]) -> bool { gt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: & &self/[T]) -> bool { gt((*self), (*other)) }
|
||||
}
|
||||
|
||||
impl<T: Ord> ~[T] : Ord {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &~[T]) -> bool { lt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &~[T]) -> bool { le(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &~[T]) -> bool { ge(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &~[T]) -> bool { gt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) }
|
||||
}
|
||||
|
||||
impl<T: Ord> @[T] : Ord {
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &@[T]) -> bool { lt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &@[T]) -> bool { le(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &@[T]) -> bool { ge(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) }
|
||||
#[inline(always)]
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &@[T]) -> bool { gt(self, (*other)) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) }
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,625 @@ extern mod syntax(vers = "0.5");
|
||||
|
||||
use core::*;
|
||||
|
||||
use io::WriterUtil;
|
||||
|
||||
use syntax::{ast, ast_util, fold, visit, codemap};
|
||||
use syntax::parse;
|
||||
use syntax::print::pprust;
|
||||
use syntax::diagnostic;
|
||||
|
||||
enum test_mode { tm_converge, tm_run, }
|
||||
type context = { mode: test_mode }; // + rng
|
||||
|
||||
impl test_mode : cmp::Eq {
|
||||
pure fn eq(&self, other: &test_mode) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
pure fn ne(&self, other: &test_mode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
fn write_file(filename: &Path, content: ~str) {
|
||||
result::get(
|
||||
&io::file_writer(filename, ~[io::Create, io::Truncate]))
|
||||
.write_str(content);
|
||||
}
|
||||
|
||||
fn contains(haystack: ~str, needle: ~str) -> bool {
|
||||
str::contains(haystack, needle)
|
||||
}
|
||||
|
||||
fn find_rust_files(files: &mut ~[Path], path: &Path) {
|
||||
if path.filetype() == Some(~".rs") && !contains(path.to_str(), ~"utf8") {
|
||||
// ignoring "utf8" tests because something is broken
|
||||
files.push(*path);
|
||||
} else if os::path_is_dir(path)
|
||||
&& !contains(path.to_str(), ~"compile-fail")
|
||||
&& !contains(path.to_str(), ~"build") {
|
||||
for os::list_dir_path(path).each |p| {
|
||||
find_rust_files(files, *p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn common_exprs() -> ~[ast::expr] {
|
||||
fn dse(e: ast::expr_) -> ast::expr {
|
||||
{ id: 0, callee_id: -1, node: e, span: ast_util::dummy_sp() }
|
||||
}
|
||||
|
||||
fn dsl(l: ast::lit_) -> ast::lit {
|
||||
{ node: l, span: ast_util::dummy_sp() }
|
||||
}
|
||||
|
||||
~[dse(ast::expr_break(option::None)),
|
||||
dse(ast::expr_again(option::None)),
|
||||
dse(ast::expr_fail(option::None)),
|
||||
dse(ast::expr_fail(option::Some(
|
||||
@dse(ast::expr_lit(@dsl(ast::lit_str(@~"boo"))))))),
|
||||
dse(ast::expr_ret(option::None)),
|
||||
dse(ast::expr_lit(@dsl(ast::lit_nil))),
|
||||
dse(ast::expr_lit(@dsl(ast::lit_bool(false)))),
|
||||
dse(ast::expr_lit(@dsl(ast::lit_bool(true)))),
|
||||
dse(ast::expr_unary(ast::box(ast::m_imm),
|
||||
@dse(ast::expr_lit(@dsl(ast::lit_bool(true)))))),
|
||||
dse(ast::expr_unary(ast::uniq(ast::m_imm),
|
||||
@dse(ast::expr_lit(@dsl(ast::lit_bool(true))))))
|
||||
]
|
||||
}
|
||||
|
||||
pure fn safe_to_steal_expr(e: @ast::expr, tm: test_mode) -> bool {
|
||||
safe_to_use_expr(*e, tm)
|
||||
}
|
||||
|
||||
pure fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool {
|
||||
match tm {
|
||||
tm_converge => {
|
||||
match e.node {
|
||||
// If the fuzzer moves a block-ending-in-semicolon into callee
|
||||
// position, the pretty-printer can't preserve this even by
|
||||
// parenthesizing!! See email to marijn.
|
||||
ast::expr_if(*) | ast::expr_block(*)
|
||||
| ast::expr_match(*) | ast::expr_while(*) => { false }
|
||||
|
||||
// https://github.com/mozilla/rust/issues/929
|
||||
ast::expr_cast(*) | ast::expr_assert(*) |
|
||||
ast::expr_binary(*) | ast::expr_assign(*) |
|
||||
ast::expr_assign_op(*) => { false }
|
||||
|
||||
ast::expr_fail(option::None) |
|
||||
ast::expr_ret(option::None) => { false }
|
||||
|
||||
// https://github.com/mozilla/rust/issues/953
|
||||
ast::expr_fail(option::Some(_)) => { false }
|
||||
|
||||
// https://github.com/mozilla/rust/issues/928
|
||||
//ast::expr_cast(_, _) { false }
|
||||
|
||||
// https://github.com/mozilla/rust/issues/1458
|
||||
ast::expr_call(_, _, _) => { false }
|
||||
|
||||
_ => { true }
|
||||
}
|
||||
}
|
||||
tm_run => { true }
|
||||
}
|
||||
}
|
||||
|
||||
fn safe_to_steal_ty(t: @ast::Ty, tm: test_mode) -> bool {
|
||||
// Restrictions happen to be the same.
|
||||
safe_to_replace_ty(t.node, tm)
|
||||
}
|
||||
|
||||
// Not type-parameterized: https://github.com/mozilla/rust/issues/898 (FIXED)
|
||||
fn stash_expr_if(c: fn@(@ast::expr, test_mode)->bool,
|
||||
es: @mut ~[ast::expr],
|
||||
e: @ast::expr,
|
||||
tm: test_mode) {
|
||||
if c(e, tm) {
|
||||
*es += ~[*e];
|
||||
} else {/* now my indices are wrong :( */ }
|
||||
}
|
||||
|
||||
fn stash_ty_if(c: fn@(@ast::Ty, test_mode)->bool,
|
||||
es: @mut ~[ast::Ty],
|
||||
e: @ast::Ty,
|
||||
tm: test_mode) {
|
||||
if c(e, tm) {
|
||||
es.push(*e);
|
||||
} else {/* now my indices are wrong :( */ }
|
||||
}
|
||||
|
||||
type stolen_stuff = {exprs: ~[ast::expr], tys: ~[ast::Ty]};
|
||||
|
||||
fn steal(crate: ast::crate, tm: test_mode) -> stolen_stuff {
|
||||
let exprs = @mut ~[];
|
||||
let tys = @mut ~[];
|
||||
let v = visit::mk_simple_visitor(@{
|
||||
visit_expr: |a| stash_expr_if(safe_to_steal_expr, exprs, a, tm),
|
||||
visit_ty: |a| stash_ty_if(safe_to_steal_ty, tys, a, tm),
|
||||
.. *visit::default_simple_visitor()
|
||||
});
|
||||
visit::visit_crate(crate, (), v);
|
||||
{exprs: *exprs, tys: *tys}
|
||||
}
|
||||
|
||||
|
||||
fn safe_to_replace_expr(e: ast::expr_, _tm: test_mode) -> bool {
|
||||
match e {
|
||||
// https://github.com/mozilla/rust/issues/652
|
||||
ast::expr_if(*) => { false }
|
||||
ast::expr_block(_) => { false }
|
||||
|
||||
// expr_call is also missing a constraint
|
||||
ast::expr_fn_block(*) => { false }
|
||||
|
||||
_ => { true }
|
||||
}
|
||||
}
|
||||
|
||||
fn safe_to_replace_ty(t: ast::ty_, _tm: test_mode) -> bool {
|
||||
match t {
|
||||
ast::ty_infer => { false } // always implicit, always top level
|
||||
ast::ty_bot => { false } // in source, can only appear
|
||||
// as the out type of a function
|
||||
ast::ty_mac(_) => { false }
|
||||
_ => { true }
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the |i|th expr (in fold order) of |crate| with |newexpr|.
|
||||
fn replace_expr_in_crate(crate: ast::crate, i: uint,
|
||||
newexpr: ast::expr, tm: test_mode) ->
|
||||
ast::crate {
|
||||
let j: @mut uint = @mut 0u;
|
||||
fn fold_expr_rep(j_: @mut uint, i_: uint, newexpr_: ast::expr_,
|
||||
original: ast::expr_, fld: fold::ast_fold,
|
||||
tm_: test_mode) ->
|
||||
ast::expr_ {
|
||||
*j_ += 1u;
|
||||
if i_ + 1u == *j_ && safe_to_replace_expr(original, tm_) {
|
||||
newexpr_
|
||||
} else {
|
||||
fold::noop_fold_expr(original, fld)
|
||||
}
|
||||
}
|
||||
let afp = @{
|
||||
fold_expr: fold::wrap(|a,b| {
|
||||
fold_expr_rep(j, i, newexpr.node, a, b, tm)
|
||||
}),
|
||||
.. *fold::default_ast_fold()
|
||||
};
|
||||
let af = fold::make_fold(afp);
|
||||
let crate2: @ast::crate = @af.fold_crate(crate);
|
||||
*crate2
|
||||
}
|
||||
|
||||
|
||||
// Replace the |i|th ty (in fold order) of |crate| with |newty|.
|
||||
fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::Ty,
|
||||
tm: test_mode) -> ast::crate {
|
||||
let j: @mut uint = @mut 0u;
|
||||
fn fold_ty_rep(j_: @mut uint, i_: uint, newty_: ast::ty_,
|
||||
original: ast::ty_, fld: fold::ast_fold,
|
||||
tm_: test_mode) ->
|
||||
ast::ty_ {
|
||||
*j_ += 1u;
|
||||
if i_ + 1u == *j_ && safe_to_replace_ty(original, tm_) {
|
||||
newty_
|
||||
} else { fold::noop_fold_ty(original, fld) }
|
||||
}
|
||||
let afp = @{
|
||||
fold_ty: fold::wrap(|a,b| fold_ty_rep(j, i, newty.node, a, b, tm) ),
|
||||
.. *fold::default_ast_fold()
|
||||
};
|
||||
let af = fold::make_fold(afp);
|
||||
let crate2: @ast::crate = @af.fold_crate(crate);
|
||||
*crate2
|
||||
}
|
||||
|
||||
fn under(n: uint, it: fn(uint)) {
|
||||
let mut i: uint = 0u;
|
||||
while i < n { it(i); i += 1u; }
|
||||
}
|
||||
|
||||
fn as_str(f: fn@(+x: io::Writer)) -> ~str {
|
||||
io::with_str_writer(f)
|
||||
}
|
||||
|
||||
fn check_variants_of_ast(crate: ast::crate, codemap: @codemap::CodeMap,
|
||||
filename: &Path, cx: context) {
|
||||
let stolen = steal(crate, cx.mode);
|
||||
let extra_exprs = vec::filter(common_exprs(),
|
||||
|a| safe_to_use_expr(*a, cx.mode) );
|
||||
check_variants_T(crate, codemap, filename, ~"expr",
|
||||
extra_exprs + stolen.exprs, pprust::expr_to_str,
|
||||
replace_expr_in_crate, cx);
|
||||
check_variants_T(crate, codemap, filename, ~"ty", stolen.tys,
|
||||
pprust::ty_to_str, replace_ty_in_crate, cx);
|
||||
}
|
||||
|
||||
fn check_variants_T<T: Copy>(
|
||||
crate: ast::crate,
|
||||
codemap: @codemap::CodeMap,
|
||||
filename: &Path,
|
||||
thing_label: ~str,
|
||||
things: ~[T],
|
||||
stringifier: fn@(@T, @syntax::parse::token::ident_interner) -> ~str,
|
||||
replacer: fn@(ast::crate, uint, T, test_mode) -> ast::crate,
|
||||
cx: context
|
||||
) {
|
||||
error!("%s contains %u %s objects", filename.to_str(),
|
||||
things.len(), thing_label);
|
||||
|
||||
// Assuming we're not generating any token_trees
|
||||
let intr = syntax::parse::token::mk_fake_ident_interner();
|
||||
|
||||
let L = things.len();
|
||||
|
||||
if L < 100 {
|
||||
do under(uint::min(L, 20)) |i| {
|
||||
log(error, ~"Replacing... #" + uint::str(i));
|
||||
let fname = str::from_slice(filename.to_str());
|
||||
do under(uint::min(L, 30)) |j| {
|
||||
log(error, ~"With... " + stringifier(@things[j], intr));
|
||||
let crate2 = @replacer(crate, i, things[j], cx.mode);
|
||||
// It would be best to test the *crate* for stability, but
|
||||
// testing the string for stability is easier and ok for now.
|
||||
let handler = diagnostic::mk_handler(None);
|
||||
let str3 = do io::with_str_reader("") |rdr| {
|
||||
@as_str(|a|pprust::print_crate(
|
||||
codemap,
|
||||
intr,
|
||||
diagnostic::mk_span_handler(handler, codemap),
|
||||
crate2,
|
||||
fname,
|
||||
rdr, a,
|
||||
pprust::no_ann(),
|
||||
false))
|
||||
};
|
||||
match cx.mode {
|
||||
tm_converge => {
|
||||
check_roundtrip_convergence(str3, 1u);
|
||||
}
|
||||
tm_run => {
|
||||
let file_label = fmt!("rusttmp/%s_%s_%u_%u",
|
||||
last_part(filename.to_str()),
|
||||
thing_label, i, j);
|
||||
let safe_to_run = !(content_is_dangerous_to_run(*str3)
|
||||
|| has_raw_pointers(*crate2));
|
||||
check_whole_compiler(*str3, &Path(file_label),
|
||||
safe_to_run);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn last_part(filename: ~str) -> ~str {
|
||||
let ix = option::get(str::rfind_char(filename, '/'));
|
||||
str::slice(filename, ix + 1u, str::len(filename) - 3u)
|
||||
}
|
||||
|
||||
enum happiness {
|
||||
passed,
|
||||
cleanly_rejected(~str),
|
||||
known_bug(~str),
|
||||
failed(~str),
|
||||
}
|
||||
|
||||
// We'd find more bugs if we could take an AST here, but
|
||||
// - that would find many "false positives" or unimportant bugs
|
||||
// - that would be tricky, requiring use of tasks or serialization
|
||||
// or randomness.
|
||||
// This seems to find plenty of bugs as it is :)
|
||||
fn check_whole_compiler(code: ~str, suggested_filename_prefix: &Path,
|
||||
allow_running: bool) {
|
||||
let filename = &suggested_filename_prefix.with_filetype("rs");
|
||||
write_file(filename, code);
|
||||
|
||||
let compile_result = check_compiling(filename);
|
||||
|
||||
let run_result = match (compile_result, allow_running) {
|
||||
(passed, true) => { check_running(suggested_filename_prefix) }
|
||||
(h, _) => { h }
|
||||
};
|
||||
|
||||
match run_result {
|
||||
passed | cleanly_rejected(_) | known_bug(_) => {
|
||||
removeIfExists(suggested_filename_prefix);
|
||||
removeIfExists(&suggested_filename_prefix.with_filetype("rs"));
|
||||
removeDirIfExists(&suggested_filename_prefix.with_filetype("dSYM"));
|
||||
}
|
||||
failed(s) => {
|
||||
log(error, ~"check_whole_compiler failure: " + s);
|
||||
log(error, ~"Saved as: " + filename.to_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn removeIfExists(filename: &Path) {
|
||||
// So sketchy!
|
||||
assert !contains(filename.to_str(), ~" ");
|
||||
run::program_output(~"bash", ~[~"-c", ~"rm " + filename.to_str()]);
|
||||
}
|
||||
|
||||
fn removeDirIfExists(filename: &Path) {
|
||||
// So sketchy!
|
||||
assert !contains(filename.to_str(), ~" ");
|
||||
run::program_output(~"bash", ~[~"-c", ~"rm -r " + filename.to_str()]);
|
||||
}
|
||||
|
||||
fn check_running(exe_filename: &Path) -> happiness {
|
||||
let p = run::program_output(
|
||||
~"/Users/jruderman/scripts/timed_run_rust_program.py",
|
||||
~[exe_filename.to_str()]);
|
||||
let comb = p.out + ~"\n" + p.err;
|
||||
if str::len(comb) > 1u {
|
||||
log(error, ~"comb comb comb: " + comb);
|
||||
}
|
||||
|
||||
if contains(comb, ~"Assertion failed:") {
|
||||
failed(~"C++ assertion failure")
|
||||
} else if contains(comb, ~"leaked memory in rust main loop") {
|
||||
// might also use exit code 134
|
||||
//failed("Leaked")
|
||||
known_bug(~"https://github.com/mozilla/rust/issues/910")
|
||||
} else if contains(comb, ~"src/rt/") {
|
||||
failed(~"Mentioned src/rt/")
|
||||
} else if contains(comb, ~"malloc") {
|
||||
failed(~"Mentioned malloc")
|
||||
} else {
|
||||
match p.status {
|
||||
0 => { passed }
|
||||
100 => { cleanly_rejected(~"running: explicit fail") }
|
||||
101 | 247 => { cleanly_rejected(~"running: timed out") }
|
||||
245 | 246 | 138 | 252 => {
|
||||
known_bug(~"https://github.com/mozilla/rust/issues/1466")
|
||||
}
|
||||
136 | 248 => {
|
||||
known_bug(
|
||||
~"SIGFPE - https://github.com/mozilla/rust/issues/944")
|
||||
}
|
||||
rc => {
|
||||
failed(~"Rust program ran but exited with status " +
|
||||
int::str(rc))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_compiling(filename: &Path) -> happiness {
|
||||
let p = run::program_output(
|
||||
~"/Users/jruderman/code/rust/build/x86_64-apple-darwin/\
|
||||
stage1/bin/rustc",
|
||||
~[filename.to_str()]);
|
||||
|
||||
//error!("Status: %d", p.status);
|
||||
if p.status == 0 {
|
||||
passed
|
||||
} else if p.err != ~"" {
|
||||
if contains(p.err, ~"error:") {
|
||||
cleanly_rejected(~"rejected with span_error")
|
||||
} else {
|
||||
log(error, ~"Stderr: " + p.err);
|
||||
failed(~"Unfamiliar error message")
|
||||
}
|
||||
} else if contains(p.out, ~"Assertion") && contains(p.out, ~"failed") {
|
||||
log(error, ~"Stdout: " + p.out);
|
||||
failed(~"Looks like an llvm assertion failure")
|
||||
} else if contains(p.out, ~"internal compiler error unimplemented") {
|
||||
known_bug(~"Something unimplemented")
|
||||
} else if contains(p.out, ~"internal compiler error") {
|
||||
log(error, ~"Stdout: " + p.out);
|
||||
failed(~"internal compiler error")
|
||||
|
||||
} else {
|
||||
log(error, p.status);
|
||||
log(error, ~"!Stdout: " + p.out);
|
||||
failed(~"What happened?")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn parse_and_print(code: @~str) -> ~str {
|
||||
let filename = Path("tmp.rs");
|
||||
let sess = parse::new_parse_sess(option::None);
|
||||
write_file(&filename, *code);
|
||||
let crate = parse::parse_crate_from_source_str(
|
||||
filename.to_str(), code, ~[], sess);
|
||||
do io::with_str_reader(*code) |rdr| {
|
||||
as_str(|a|
|
||||
pprust::print_crate(
|
||||
sess.cm,
|
||||
// Assuming there are no token_trees
|
||||
syntax::parse::token::mk_fake_ident_interner(),
|
||||
sess.span_diagnostic,
|
||||
crate,
|
||||
filename.to_str(),
|
||||
rdr, a,
|
||||
pprust::no_ann(),
|
||||
false) )
|
||||
}
|
||||
}
|
||||
|
||||
fn has_raw_pointers(c: ast::crate) -> bool {
|
||||
let has_rp = @mut false;
|
||||
fn visit_ty(flag: @mut bool, t: @ast::Ty) {
|
||||
match t.node {
|
||||
ast::ty_ptr(_) => { *flag = true; }
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
let v =
|
||||
visit::mk_simple_visitor(@{visit_ty: |a| visit_ty(has_rp, a),
|
||||
.. *visit::default_simple_visitor()});
|
||||
visit::visit_crate(c, (), v);
|
||||
return *has_rp;
|
||||
}
|
||||
|
||||
fn content_is_dangerous_to_run(code: ~str) -> bool {
|
||||
let dangerous_patterns =
|
||||
~[~"xfail-test",
|
||||
~"import", // espeically fs, run
|
||||
~"extern",
|
||||
~"unsafe",
|
||||
~"log"]; // python --> rust pipe deadlock?
|
||||
|
||||
for dangerous_patterns.each |p| { if contains(code, *p) { return true; } }
|
||||
return false;
|
||||
}
|
||||
|
||||
fn content_is_dangerous_to_compile(code: ~str) -> bool {
|
||||
let dangerous_patterns =
|
||||
~[~"xfail-test"];
|
||||
|
||||
for dangerous_patterns.each |p| { if contains(code, *p) { return true; } }
|
||||
return false;
|
||||
}
|
||||
|
||||
fn content_might_not_converge(code: ~str) -> bool {
|
||||
let confusing_patterns =
|
||||
~[~"xfail-test",
|
||||
~"xfail-pretty",
|
||||
~"self", // crazy rules enforced by parser not typechecker?
|
||||
~"spawn", // precedence issues?
|
||||
~"bind", // precedence issues?
|
||||
~" be ", // don't want to replace its child with a non-call:
|
||||
// "Non-call expression in tail call"
|
||||
~"\n\n\n\n\n" // https://github.com/mozilla/rust/issues/850
|
||||
];
|
||||
|
||||
for confusing_patterns.each |p| { if contains(code, *p) { return true; } }
|
||||
return false;
|
||||
}
|
||||
|
||||
fn file_might_not_converge(filename: &Path) -> bool {
|
||||
let confusing_files = ~[
|
||||
~"expr-alt.rs", // pretty-printing "(a = b) = c"
|
||||
// vs "a = b = c" and wrapping
|
||||
~"block-arg-in-ternary.rs", // wrapping
|
||||
~"move-3-unique.rs", // 0 becomes (0), but both seem reasonable. wtf?
|
||||
~"move-3.rs" // 0 becomes (0), but both seem reasonable. wtf?
|
||||
];
|
||||
|
||||
|
||||
for confusing_files.each |f| {
|
||||
if contains(filename.to_str(), *f) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
fn check_roundtrip_convergence(code: @~str, maxIters: uint) {
|
||||
|
||||
let mut i = 0u;
|
||||
let mut newv = code;
|
||||
let mut oldv = code;
|
||||
|
||||
while i < maxIters {
|
||||
oldv = newv;
|
||||
if content_might_not_converge(*oldv) { return; }
|
||||
newv = @parse_and_print(oldv);
|
||||
if oldv == newv { break; }
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
if oldv == newv {
|
||||
error!("Converged after %u iterations", i);
|
||||
} else {
|
||||
error!("Did not converge after %u iterations!", i);
|
||||
write_file(&Path("round-trip-a.rs"), *oldv);
|
||||
write_file(&Path("round-trip-b.rs"), *newv);
|
||||
run::run_program(~"diff",
|
||||
~[~"-w", ~"-u", ~"round-trip-a.rs",
|
||||
~"round-trip-b.rs"]);
|
||||
fail ~"Mismatch";
|
||||
}
|
||||
}
|
||||
|
||||
fn check_convergence(files: &[Path]) {
|
||||
error!("pp convergence tests: %u files", vec::len(files));
|
||||
for files.each |file| {
|
||||
if !file_might_not_converge(file) {
|
||||
let s = @result::get(&io::read_whole_file_str(file));
|
||||
if !content_might_not_converge(*s) {
|
||||
error!("pp converge: %s", file.to_str());
|
||||
// Change from 7u to 2u once
|
||||
// https://github.com/mozilla/rust/issues/850 is fixed
|
||||
check_roundtrip_convergence(s, 7u);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_variants(files: &[Path], cx: context) {
|
||||
for files.each |file| {
|
||||
if cx.mode == tm_converge &&
|
||||
file_might_not_converge(file) {
|
||||
error!("Skipping convergence test based on\
|
||||
file_might_not_converge");
|
||||
loop;
|
||||
}
|
||||
|
||||
let s = @result::get(&io::read_whole_file_str(file));
|
||||
if contains(*s, ~"#") {
|
||||
loop; // Macros are confusing
|
||||
}
|
||||
if cx.mode == tm_converge && content_might_not_converge(*s) {
|
||||
loop;
|
||||
}
|
||||
if cx.mode == tm_run && content_is_dangerous_to_compile(*s) {
|
||||
loop;
|
||||
}
|
||||
|
||||
let file_str = file.to_str();
|
||||
|
||||
log(error, ~"check_variants: " + file_str);
|
||||
let sess = parse::new_parse_sess(option::None);
|
||||
let crate =
|
||||
parse::parse_crate_from_source_str(
|
||||
file_str,
|
||||
s, ~[], sess);
|
||||
io::with_str_reader(*s, |rdr| {
|
||||
error!("%s",
|
||||
as_str(|a| pprust::print_crate(
|
||||
sess.cm,
|
||||
// Assuming no token_trees
|
||||
syntax::parse::token::mk_fake_ident_interner(),
|
||||
sess.span_diagnostic,
|
||||
crate,
|
||||
file_str,
|
||||
rdr, a,
|
||||
pprust::no_ann(),
|
||||
false)))
|
||||
});
|
||||
check_variants_of_ast(*crate, sess.cm, file, cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = os::args();
|
||||
if vec::len(args) != 2u {
|
||||
error!("usage: %s <testdir>", args[0]);
|
||||
return;
|
||||
}
|
||||
let mut files = ~[];
|
||||
let root = Path(args[1]);
|
||||
|
||||
find_rust_files(&mut files, &root);
|
||||
error!("== check_convergence ==");
|
||||
check_convergence(files);
|
||||
error!("== check_variants: converge ==");
|
||||
check_variants(files, { mode: tm_converge });
|
||||
error!("== check_variants: run ==");
|
||||
check_variants(files, { mode: tm_run });
|
||||
|
||||
error!("Fuzzer done");
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
|
||||
@@ -1,638 +0,0 @@
|
||||
#[legacy_exports];
|
||||
|
||||
use io::WriterUtil;
|
||||
|
||||
use syntax::{ast, ast_util, fold, visit, codemap};
|
||||
use syntax::parse;
|
||||
use syntax::print::pprust;
|
||||
use syntax::diagnostic;
|
||||
|
||||
enum test_mode { tm_converge, tm_run, }
|
||||
type context = { mode: test_mode }; // + rng
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl test_mode : cmp::Eq {
|
||||
pure fn eq(other: &test_mode) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
pure fn ne(other: &test_mode) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
impl test_mode : cmp::Eq {
|
||||
pure fn eq(&self, other: &test_mode) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
pure fn ne(&self, other: &test_mode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
fn write_file(filename: &Path, content: ~str) {
|
||||
result::get(
|
||||
&io::file_writer(filename, ~[io::Create, io::Truncate]))
|
||||
.write_str(content);
|
||||
}
|
||||
|
||||
fn contains(haystack: ~str, needle: ~str) -> bool {
|
||||
str::contains(haystack, needle)
|
||||
}
|
||||
|
||||
fn find_rust_files(files: &mut ~[Path], path: &Path) {
|
||||
if path.filetype() == Some(~".rs") && !contains(path.to_str(), ~"utf8") {
|
||||
// ignoring "utf8" tests because something is broken
|
||||
files.push(*path);
|
||||
} else if os::path_is_dir(path)
|
||||
&& !contains(path.to_str(), ~"compile-fail")
|
||||
&& !contains(path.to_str(), ~"build") {
|
||||
for os::list_dir_path(path).each |p| {
|
||||
find_rust_files(files, *p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn common_exprs() -> ~[ast::expr] {
|
||||
fn dse(e: ast::expr_) -> ast::expr {
|
||||
{ id: 0, callee_id: -1, node: e, span: ast_util::dummy_sp() }
|
||||
}
|
||||
|
||||
fn dsl(l: ast::lit_) -> ast::lit {
|
||||
{ node: l, span: ast_util::dummy_sp() }
|
||||
}
|
||||
|
||||
~[dse(ast::expr_break(option::None)),
|
||||
dse(ast::expr_again(option::None)),
|
||||
dse(ast::expr_fail(option::None)),
|
||||
dse(ast::expr_fail(option::Some(
|
||||
@dse(ast::expr_lit(@dsl(ast::lit_str(@~"boo"))))))),
|
||||
dse(ast::expr_ret(option::None)),
|
||||
dse(ast::expr_lit(@dsl(ast::lit_nil))),
|
||||
dse(ast::expr_lit(@dsl(ast::lit_bool(false)))),
|
||||
dse(ast::expr_lit(@dsl(ast::lit_bool(true)))),
|
||||
dse(ast::expr_unary(ast::box(ast::m_imm),
|
||||
@dse(ast::expr_lit(@dsl(ast::lit_bool(true)))))),
|
||||
dse(ast::expr_unary(ast::uniq(ast::m_imm),
|
||||
@dse(ast::expr_lit(@dsl(ast::lit_bool(true))))))
|
||||
]
|
||||
}
|
||||
|
||||
pure fn safe_to_steal_expr(e: @ast::expr, tm: test_mode) -> bool {
|
||||
safe_to_use_expr(*e, tm)
|
||||
}
|
||||
|
||||
pure fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool {
|
||||
match tm {
|
||||
tm_converge => {
|
||||
match e.node {
|
||||
// If the fuzzer moves a block-ending-in-semicolon into callee
|
||||
// position, the pretty-printer can't preserve this even by
|
||||
// parenthesizing!! See email to marijn.
|
||||
ast::expr_if(*) | ast::expr_block(*)
|
||||
| ast::expr_match(*) | ast::expr_while(*) => { false }
|
||||
|
||||
// https://github.com/mozilla/rust/issues/929
|
||||
ast::expr_cast(*) | ast::expr_assert(*) |
|
||||
ast::expr_binary(*) | ast::expr_assign(*) |
|
||||
ast::expr_assign_op(*) => { false }
|
||||
|
||||
ast::expr_fail(option::None) |
|
||||
ast::expr_ret(option::None) => { false }
|
||||
|
||||
// https://github.com/mozilla/rust/issues/953
|
||||
ast::expr_fail(option::Some(_)) => { false }
|
||||
|
||||
// https://github.com/mozilla/rust/issues/928
|
||||
//ast::expr_cast(_, _) { false }
|
||||
|
||||
// https://github.com/mozilla/rust/issues/1458
|
||||
ast::expr_call(_, _, _) => { false }
|
||||
|
||||
_ => { true }
|
||||
}
|
||||
}
|
||||
tm_run => { true }
|
||||
}
|
||||
}
|
||||
|
||||
fn safe_to_steal_ty(t: @ast::Ty, tm: test_mode) -> bool {
|
||||
// Restrictions happen to be the same.
|
||||
safe_to_replace_ty(t.node, tm)
|
||||
}
|
||||
|
||||
// Not type-parameterized: https://github.com/mozilla/rust/issues/898 (FIXED)
|
||||
fn stash_expr_if(c: fn@(@ast::expr, test_mode)->bool,
|
||||
es: @mut ~[ast::expr],
|
||||
e: @ast::expr,
|
||||
tm: test_mode) {
|
||||
if c(e, tm) {
|
||||
*es += ~[*e];
|
||||
} else {/* now my indices are wrong :( */ }
|
||||
}
|
||||
|
||||
fn stash_ty_if(c: fn@(@ast::Ty, test_mode)->bool,
|
||||
es: @mut ~[ast::Ty],
|
||||
e: @ast::Ty,
|
||||
tm: test_mode) {
|
||||
if c(e, tm) {
|
||||
es.push(*e);
|
||||
} else {/* now my indices are wrong :( */ }
|
||||
}
|
||||
|
||||
type stolen_stuff = {exprs: ~[ast::expr], tys: ~[ast::Ty]};
|
||||
|
||||
fn steal(crate: ast::crate, tm: test_mode) -> stolen_stuff {
|
||||
let exprs = @mut ~[];
|
||||
let tys = @mut ~[];
|
||||
let v = visit::mk_simple_visitor(@{
|
||||
visit_expr: |a| stash_expr_if(safe_to_steal_expr, exprs, a, tm),
|
||||
visit_ty: |a| stash_ty_if(safe_to_steal_ty, tys, a, tm),
|
||||
.. *visit::default_simple_visitor()
|
||||
});
|
||||
visit::visit_crate(crate, (), v);
|
||||
{exprs: *exprs, tys: *tys}
|
||||
}
|
||||
|
||||
|
||||
fn safe_to_replace_expr(e: ast::expr_, _tm: test_mode) -> bool {
|
||||
match e {
|
||||
// https://github.com/mozilla/rust/issues/652
|
||||
ast::expr_if(*) => { false }
|
||||
ast::expr_block(_) => { false }
|
||||
|
||||
// expr_call is also missing a constraint
|
||||
ast::expr_fn_block(*) => { false }
|
||||
|
||||
_ => { true }
|
||||
}
|
||||
}
|
||||
|
||||
fn safe_to_replace_ty(t: ast::ty_, _tm: test_mode) -> bool {
|
||||
match t {
|
||||
ast::ty_infer => { false } // always implicit, always top level
|
||||
ast::ty_bot => { false } // in source, can only appear
|
||||
// as the out type of a function
|
||||
ast::ty_mac(_) => { false }
|
||||
_ => { true }
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the |i|th expr (in fold order) of |crate| with |newexpr|.
|
||||
fn replace_expr_in_crate(crate: ast::crate, i: uint,
|
||||
newexpr: ast::expr, tm: test_mode) ->
|
||||
ast::crate {
|
||||
let j: @mut uint = @mut 0u;
|
||||
fn fold_expr_rep(j_: @mut uint, i_: uint, newexpr_: ast::expr_,
|
||||
original: ast::expr_, fld: fold::ast_fold,
|
||||
tm_: test_mode) ->
|
||||
ast::expr_ {
|
||||
*j_ += 1u;
|
||||
if i_ + 1u == *j_ && safe_to_replace_expr(original, tm_) {
|
||||
newexpr_
|
||||
} else {
|
||||
fold::noop_fold_expr(original, fld)
|
||||
}
|
||||
}
|
||||
let afp = @{
|
||||
fold_expr: fold::wrap(|a,b| {
|
||||
fold_expr_rep(j, i, newexpr.node, a, b, tm)
|
||||
}),
|
||||
.. *fold::default_ast_fold()
|
||||
};
|
||||
let af = fold::make_fold(afp);
|
||||
let crate2: @ast::crate = @af.fold_crate(crate);
|
||||
*crate2
|
||||
}
|
||||
|
||||
|
||||
// Replace the |i|th ty (in fold order) of |crate| with |newty|.
|
||||
fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::Ty,
|
||||
tm: test_mode) -> ast::crate {
|
||||
let j: @mut uint = @mut 0u;
|
||||
fn fold_ty_rep(j_: @mut uint, i_: uint, newty_: ast::ty_,
|
||||
original: ast::ty_, fld: fold::ast_fold,
|
||||
tm_: test_mode) ->
|
||||
ast::ty_ {
|
||||
*j_ += 1u;
|
||||
if i_ + 1u == *j_ && safe_to_replace_ty(original, tm_) {
|
||||
newty_
|
||||
} else { fold::noop_fold_ty(original, fld) }
|
||||
}
|
||||
let afp = @{
|
||||
fold_ty: fold::wrap(|a,b| fold_ty_rep(j, i, newty.node, a, b, tm) ),
|
||||
.. *fold::default_ast_fold()
|
||||
};
|
||||
let af = fold::make_fold(afp);
|
||||
let crate2: @ast::crate = @af.fold_crate(crate);
|
||||
*crate2
|
||||
}
|
||||
|
||||
fn under(n: uint, it: fn(uint)) {
|
||||
let mut i: uint = 0u;
|
||||
while i < n { it(i); i += 1u; }
|
||||
}
|
||||
|
||||
fn as_str(f: fn@(+x: io::Writer)) -> ~str {
|
||||
io::with_str_writer(f)
|
||||
}
|
||||
|
||||
fn check_variants_of_ast(crate: ast::crate, codemap: @codemap::CodeMap,
|
||||
filename: &Path, cx: context) {
|
||||
let stolen = steal(crate, cx.mode);
|
||||
let extra_exprs = vec::filter(common_exprs(),
|
||||
|a| safe_to_use_expr(*a, cx.mode) );
|
||||
check_variants_T(crate, codemap, filename, ~"expr",
|
||||
extra_exprs + stolen.exprs, pprust::expr_to_str,
|
||||
replace_expr_in_crate, cx);
|
||||
check_variants_T(crate, codemap, filename, ~"ty", stolen.tys,
|
||||
pprust::ty_to_str, replace_ty_in_crate, cx);
|
||||
}
|
||||
|
||||
fn check_variants_T<T: Copy>(
|
||||
crate: ast::crate,
|
||||
codemap: @codemap::CodeMap,
|
||||
filename: &Path,
|
||||
thing_label: ~str,
|
||||
things: ~[T],
|
||||
stringifier: fn@(@T, @syntax::parse::token::ident_interner) -> ~str,
|
||||
replacer: fn@(ast::crate, uint, T, test_mode) -> ast::crate,
|
||||
cx: context
|
||||
) {
|
||||
error!("%s contains %u %s objects", filename.to_str(),
|
||||
things.len(), thing_label);
|
||||
|
||||
// Assuming we're not generating any token_trees
|
||||
let intr = syntax::parse::token::mk_fake_ident_interner();
|
||||
|
||||
let L = things.len();
|
||||
|
||||
if L < 100 {
|
||||
do under(uint::min(L, 20)) |i| {
|
||||
log(error, ~"Replacing... #" + uint::str(i));
|
||||
let fname = str::from_slice(filename.to_str());
|
||||
do under(uint::min(L, 30)) |j| {
|
||||
log(error, ~"With... " + stringifier(@things[j], intr));
|
||||
let crate2 = @replacer(crate, i, things[j], cx.mode);
|
||||
// It would be best to test the *crate* for stability, but
|
||||
// testing the string for stability is easier and ok for now.
|
||||
let handler = diagnostic::mk_handler(None);
|
||||
let str3 = do io::with_str_reader("") |rdr| {
|
||||
@as_str(|a|pprust::print_crate(
|
||||
codemap,
|
||||
intr,
|
||||
diagnostic::mk_span_handler(handler, codemap),
|
||||
crate2,
|
||||
fname,
|
||||
rdr, a,
|
||||
pprust::no_ann(),
|
||||
false))
|
||||
};
|
||||
match cx.mode {
|
||||
tm_converge => {
|
||||
check_roundtrip_convergence(str3, 1u);
|
||||
}
|
||||
tm_run => {
|
||||
let file_label = fmt!("rusttmp/%s_%s_%u_%u",
|
||||
last_part(filename.to_str()),
|
||||
thing_label, i, j);
|
||||
let safe_to_run = !(content_is_dangerous_to_run(*str3)
|
||||
|| has_raw_pointers(*crate2));
|
||||
check_whole_compiler(*str3, &Path(file_label),
|
||||
safe_to_run);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn last_part(filename: ~str) -> ~str {
|
||||
let ix = option::get(str::rfind_char(filename, '/'));
|
||||
str::slice(filename, ix + 1u, str::len(filename) - 3u)
|
||||
}
|
||||
|
||||
enum happiness {
|
||||
passed,
|
||||
cleanly_rejected(~str),
|
||||
known_bug(~str),
|
||||
failed(~str),
|
||||
}
|
||||
|
||||
// We'd find more bugs if we could take an AST here, but
|
||||
// - that would find many "false positives" or unimportant bugs
|
||||
// - that would be tricky, requiring use of tasks or serialization
|
||||
// or randomness.
|
||||
// This seems to find plenty of bugs as it is :)
|
||||
fn check_whole_compiler(code: ~str, suggested_filename_prefix: &Path,
|
||||
allow_running: bool) {
|
||||
let filename = &suggested_filename_prefix.with_filetype("rs");
|
||||
write_file(filename, code);
|
||||
|
||||
let compile_result = check_compiling(filename);
|
||||
|
||||
let run_result = match (compile_result, allow_running) {
|
||||
(passed, true) => { check_running(suggested_filename_prefix) }
|
||||
(h, _) => { h }
|
||||
};
|
||||
|
||||
match run_result {
|
||||
passed | cleanly_rejected(_) | known_bug(_) => {
|
||||
removeIfExists(suggested_filename_prefix);
|
||||
removeIfExists(&suggested_filename_prefix.with_filetype("rs"));
|
||||
removeDirIfExists(&suggested_filename_prefix.with_filetype("dSYM"));
|
||||
}
|
||||
failed(s) => {
|
||||
log(error, ~"check_whole_compiler failure: " + s);
|
||||
log(error, ~"Saved as: " + filename.to_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn removeIfExists(filename: &Path) {
|
||||
// So sketchy!
|
||||
assert !contains(filename.to_str(), ~" ");
|
||||
run::program_output(~"bash", ~[~"-c", ~"rm " + filename.to_str()]);
|
||||
}
|
||||
|
||||
fn removeDirIfExists(filename: &Path) {
|
||||
// So sketchy!
|
||||
assert !contains(filename.to_str(), ~" ");
|
||||
run::program_output(~"bash", ~[~"-c", ~"rm -r " + filename.to_str()]);
|
||||
}
|
||||
|
||||
fn check_running(exe_filename: &Path) -> happiness {
|
||||
let p = run::program_output(
|
||||
~"/Users/jruderman/scripts/timed_run_rust_program.py",
|
||||
~[exe_filename.to_str()]);
|
||||
let comb = p.out + ~"\n" + p.err;
|
||||
if str::len(comb) > 1u {
|
||||
log(error, ~"comb comb comb: " + comb);
|
||||
}
|
||||
|
||||
if contains(comb, ~"Assertion failed:") {
|
||||
failed(~"C++ assertion failure")
|
||||
} else if contains(comb, ~"leaked memory in rust main loop") {
|
||||
// might also use exit code 134
|
||||
//failed("Leaked")
|
||||
known_bug(~"https://github.com/mozilla/rust/issues/910")
|
||||
} else if contains(comb, ~"src/rt/") {
|
||||
failed(~"Mentioned src/rt/")
|
||||
} else if contains(comb, ~"malloc") {
|
||||
failed(~"Mentioned malloc")
|
||||
} else {
|
||||
match p.status {
|
||||
0 => { passed }
|
||||
100 => { cleanly_rejected(~"running: explicit fail") }
|
||||
101 | 247 => { cleanly_rejected(~"running: timed out") }
|
||||
245 | 246 | 138 | 252 => {
|
||||
known_bug(~"https://github.com/mozilla/rust/issues/1466")
|
||||
}
|
||||
136 | 248 => {
|
||||
known_bug(
|
||||
~"SIGFPE - https://github.com/mozilla/rust/issues/944")
|
||||
}
|
||||
rc => {
|
||||
failed(~"Rust program ran but exited with status " +
|
||||
int::str(rc))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_compiling(filename: &Path) -> happiness {
|
||||
let p = run::program_output(
|
||||
~"/Users/jruderman/code/rust/build/x86_64-apple-darwin/\
|
||||
stage1/bin/rustc",
|
||||
~[filename.to_str()]);
|
||||
|
||||
//error!("Status: %d", p.status);
|
||||
if p.status == 0 {
|
||||
passed
|
||||
} else if p.err != ~"" {
|
||||
if contains(p.err, ~"error:") {
|
||||
cleanly_rejected(~"rejected with span_error")
|
||||
} else {
|
||||
log(error, ~"Stderr: " + p.err);
|
||||
failed(~"Unfamiliar error message")
|
||||
}
|
||||
} else if contains(p.out, ~"Assertion") && contains(p.out, ~"failed") {
|
||||
log(error, ~"Stdout: " + p.out);
|
||||
failed(~"Looks like an llvm assertion failure")
|
||||
} else if contains(p.out, ~"internal compiler error unimplemented") {
|
||||
known_bug(~"Something unimplemented")
|
||||
} else if contains(p.out, ~"internal compiler error") {
|
||||
log(error, ~"Stdout: " + p.out);
|
||||
failed(~"internal compiler error")
|
||||
|
||||
} else {
|
||||
log(error, p.status);
|
||||
log(error, ~"!Stdout: " + p.out);
|
||||
failed(~"What happened?")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn parse_and_print(code: @~str) -> ~str {
|
||||
let filename = Path("tmp.rs");
|
||||
let sess = parse::new_parse_sess(option::None);
|
||||
write_file(&filename, *code);
|
||||
let crate = parse::parse_crate_from_source_str(
|
||||
filename.to_str(), code, ~[], sess);
|
||||
do io::with_str_reader(*code) |rdr| {
|
||||
as_str(|a|
|
||||
pprust::print_crate(
|
||||
sess.cm,
|
||||
// Assuming there are no token_trees
|
||||
syntax::parse::token::mk_fake_ident_interner(),
|
||||
sess.span_diagnostic,
|
||||
crate,
|
||||
filename.to_str(),
|
||||
rdr, a,
|
||||
pprust::no_ann(),
|
||||
false) )
|
||||
}
|
||||
}
|
||||
|
||||
fn has_raw_pointers(c: ast::crate) -> bool {
|
||||
let has_rp = @mut false;
|
||||
fn visit_ty(flag: @mut bool, t: @ast::Ty) {
|
||||
match t.node {
|
||||
ast::ty_ptr(_) => { *flag = true; }
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
let v =
|
||||
visit::mk_simple_visitor(@{visit_ty: |a| visit_ty(has_rp, a),
|
||||
.. *visit::default_simple_visitor()});
|
||||
visit::visit_crate(c, (), v);
|
||||
return *has_rp;
|
||||
}
|
||||
|
||||
fn content_is_dangerous_to_run(code: ~str) -> bool {
|
||||
let dangerous_patterns =
|
||||
~[~"xfail-test",
|
||||
~"import", // espeically fs, run
|
||||
~"extern",
|
||||
~"unsafe",
|
||||
~"log"]; // python --> rust pipe deadlock?
|
||||
|
||||
for dangerous_patterns.each |p| { if contains(code, *p) { return true; } }
|
||||
return false;
|
||||
}
|
||||
|
||||
fn content_is_dangerous_to_compile(code: ~str) -> bool {
|
||||
let dangerous_patterns =
|
||||
~[~"xfail-test"];
|
||||
|
||||
for dangerous_patterns.each |p| { if contains(code, *p) { return true; } }
|
||||
return false;
|
||||
}
|
||||
|
||||
fn content_might_not_converge(code: ~str) -> bool {
|
||||
let confusing_patterns =
|
||||
~[~"xfail-test",
|
||||
~"xfail-pretty",
|
||||
~"self", // crazy rules enforced by parser not typechecker?
|
||||
~"spawn", // precedence issues?
|
||||
~"bind", // precedence issues?
|
||||
~" be ", // don't want to replace its child with a non-call:
|
||||
// "Non-call expression in tail call"
|
||||
~"\n\n\n\n\n" // https://github.com/mozilla/rust/issues/850
|
||||
];
|
||||
|
||||
for confusing_patterns.each |p| { if contains(code, *p) { return true; } }
|
||||
return false;
|
||||
}
|
||||
|
||||
fn file_might_not_converge(filename: &Path) -> bool {
|
||||
let confusing_files = ~[
|
||||
~"expr-alt.rs", // pretty-printing "(a = b) = c"
|
||||
// vs "a = b = c" and wrapping
|
||||
~"block-arg-in-ternary.rs", // wrapping
|
||||
~"move-3-unique.rs", // 0 becomes (0), but both seem reasonable. wtf?
|
||||
~"move-3.rs" // 0 becomes (0), but both seem reasonable. wtf?
|
||||
];
|
||||
|
||||
|
||||
for confusing_files.each |f| {
|
||||
if contains(filename.to_str(), *f) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
fn check_roundtrip_convergence(code: @~str, maxIters: uint) {
|
||||
|
||||
let mut i = 0u;
|
||||
let mut newv = code;
|
||||
let mut oldv = code;
|
||||
|
||||
while i < maxIters {
|
||||
oldv = newv;
|
||||
if content_might_not_converge(*oldv) { return; }
|
||||
newv = @parse_and_print(oldv);
|
||||
if oldv == newv { break; }
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
if oldv == newv {
|
||||
error!("Converged after %u iterations", i);
|
||||
} else {
|
||||
error!("Did not converge after %u iterations!", i);
|
||||
write_file(&Path("round-trip-a.rs"), *oldv);
|
||||
write_file(&Path("round-trip-b.rs"), *newv);
|
||||
run::run_program(~"diff",
|
||||
~[~"-w", ~"-u", ~"round-trip-a.rs",
|
||||
~"round-trip-b.rs"]);
|
||||
fail ~"Mismatch";
|
||||
}
|
||||
}
|
||||
|
||||
fn check_convergence(files: &[Path]) {
|
||||
error!("pp convergence tests: %u files", vec::len(files));
|
||||
for files.each |file| {
|
||||
if !file_might_not_converge(file) {
|
||||
let s = @result::get(&io::read_whole_file_str(file));
|
||||
if !content_might_not_converge(*s) {
|
||||
error!("pp converge: %s", file.to_str());
|
||||
// Change from 7u to 2u once
|
||||
// https://github.com/mozilla/rust/issues/850 is fixed
|
||||
check_roundtrip_convergence(s, 7u);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_variants(files: &[Path], cx: context) {
|
||||
for files.each |file| {
|
||||
if cx.mode == tm_converge &&
|
||||
file_might_not_converge(file) {
|
||||
error!("Skipping convergence test based on\
|
||||
file_might_not_converge");
|
||||
loop;
|
||||
}
|
||||
|
||||
let s = @result::get(&io::read_whole_file_str(file));
|
||||
if contains(*s, ~"#") {
|
||||
loop; // Macros are confusing
|
||||
}
|
||||
if cx.mode == tm_converge && content_might_not_converge(*s) {
|
||||
loop;
|
||||
}
|
||||
if cx.mode == tm_run && content_is_dangerous_to_compile(*s) {
|
||||
loop;
|
||||
}
|
||||
|
||||
let file_str = file.to_str();
|
||||
|
||||
log(error, ~"check_variants: " + file_str);
|
||||
let sess = parse::new_parse_sess(option::None);
|
||||
let crate =
|
||||
parse::parse_crate_from_source_str(
|
||||
file_str,
|
||||
s, ~[], sess);
|
||||
io::with_str_reader(*s, |rdr| {
|
||||
error!("%s",
|
||||
as_str(|a| pprust::print_crate(
|
||||
sess.cm,
|
||||
// Assuming no token_trees
|
||||
syntax::parse::token::mk_fake_ident_interner(),
|
||||
sess.span_diagnostic,
|
||||
crate,
|
||||
file_str,
|
||||
rdr, a,
|
||||
pprust::no_ann(),
|
||||
false)))
|
||||
});
|
||||
check_variants_of_ast(*crate, sess.cm, file, cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = os::args();
|
||||
if vec::len(args) != 2u {
|
||||
error!("usage: %s <testdir>", args[0]);
|
||||
return;
|
||||
}
|
||||
let mut files = ~[];
|
||||
let root = Path(args[1]);
|
||||
|
||||
find_rust_files(&mut files, &root);
|
||||
error!("== check_convergence ==");
|
||||
check_convergence(files);
|
||||
error!("== check_variants: converge ==");
|
||||
check_variants(files, { mode: tm_converge });
|
||||
error!("== check_variants: run ==");
|
||||
check_variants(files, { mode: tm_run });
|
||||
|
||||
error!("Fuzzer done");
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// End:
|
||||
@@ -27,19 +27,9 @@ enum output_type {
|
||||
}
|
||||
|
||||
impl output_type : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &output_type) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &output_type) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &output_type) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &output_type) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -141,19 +141,9 @@ enum compile_upto {
|
||||
}
|
||||
|
||||
impl compile_upto : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &compile_upto) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &compile_upto) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &compile_upto) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &compile_upto) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
mod driver;
|
||||
#[legacy_exports]
|
||||
mod session;
|
||||
@@ -13,38 +13,18 @@
|
||||
enum os { os_win32, os_macos, os_linux, os_freebsd, }
|
||||
|
||||
impl os : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &os) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &os) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &os) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &os) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
enum arch { arch_x86, arch_x86_64, arch_arm, }
|
||||
|
||||
impl arch : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &arch) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &arch) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &arch) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &arch) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -111,19 +91,9 @@ enum OptLevel {
|
||||
}
|
||||
|
||||
impl OptLevel : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &OptLevel) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &OptLevel) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &OptLevel) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &OptLevel) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -357,7 +327,6 @@ fn make_crate(with_bin: bool, with_lib: bool) -> @ast::crate {
|
||||
if with_bin { attrs += ~[make_crate_type_attr(~"bin")]; }
|
||||
if with_lib { attrs += ~[make_crate_type_attr(~"lib")]; }
|
||||
@ast_util::respan(ast_util::dummy_sp(), {
|
||||
directives: ~[],
|
||||
module: {view_items: ~[], items: ~[]},
|
||||
attrs: attrs,
|
||||
config: ~[]
|
||||
|
||||
@@ -131,45 +131,6 @@ enum TypeKind {
|
||||
}
|
||||
|
||||
impl TypeKind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &TypeKind) -> bool {
|
||||
match (self, (*other)) {
|
||||
(Void, Void) => true,
|
||||
(Half, Half) => true,
|
||||
(Float, Float) => true,
|
||||
(Double, Double) => true,
|
||||
(X86_FP80, X86_FP80) => true,
|
||||
(FP128, FP128) => true,
|
||||
(PPC_FP128, PPC_FP128) => true,
|
||||
(Label, Label) => true,
|
||||
(Integer, Integer) => true,
|
||||
(Function, Function) => true,
|
||||
(Struct, Struct) => true,
|
||||
(Array, Array) => true,
|
||||
(Pointer, Pointer) => true,
|
||||
(Vector, Vector) => true,
|
||||
(Metadata, Metadata) => true,
|
||||
(X86_MMX, X86_MMX) => true,
|
||||
(Void, _) => false,
|
||||
(Half, _) => false,
|
||||
(Float, _) => false,
|
||||
(Double, _) => false,
|
||||
(X86_FP80, _) => false,
|
||||
(FP128, _) => false,
|
||||
(PPC_FP128, _) => false,
|
||||
(Label, _) => false,
|
||||
(Integer, _) => false,
|
||||
(Function, _) => false,
|
||||
(Struct, _) => false,
|
||||
(Array, _) => false,
|
||||
(Pointer, _) => false,
|
||||
(Vector, _) => false,
|
||||
(Metadata, _) => false,
|
||||
(X86_MMX, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &TypeKind) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(Void, Void) => true,
|
||||
@@ -206,10 +167,6 @@ impl TypeKind : cmp::Eq {
|
||||
(X86_MMX, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &TypeKind) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &TypeKind) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -140,19 +140,9 @@ enum Family {
|
||||
}
|
||||
|
||||
impl Family : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Family) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Family) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Family) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Family) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#[legacy_exports];
|
||||
export encoder;
|
||||
export creader;
|
||||
export cstore;
|
||||
export csearch;
|
||||
export common;
|
||||
export decoder;
|
||||
export tyencode;
|
||||
export tydecode;
|
||||
export loader;
|
||||
export filesearch;
|
||||
|
||||
#[legacy_exports]
|
||||
mod common;
|
||||
#[legacy_exports]
|
||||
mod tyencode;
|
||||
#[legacy_exports]
|
||||
mod tydecode;
|
||||
#[legacy_exports]
|
||||
mod encoder;
|
||||
#[legacy_exports]
|
||||
mod decoder;
|
||||
#[legacy_exports]
|
||||
mod creader;
|
||||
#[legacy_exports]
|
||||
mod cstore;
|
||||
#[legacy_exports]
|
||||
mod csearch;
|
||||
#[legacy_exports]
|
||||
mod loader;
|
||||
#[legacy_exports]
|
||||
mod filesearch;
|
||||
@@ -323,50 +323,6 @@ enum bckerr_code {
|
||||
}
|
||||
|
||||
impl bckerr_code : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &bckerr_code) -> bool {
|
||||
match self {
|
||||
err_mut_uniq => {
|
||||
match (*other) {
|
||||
err_mut_uniq => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
err_mut_variant => {
|
||||
match (*other) {
|
||||
err_mut_variant => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
err_root_not_permitted => {
|
||||
match (*other) {
|
||||
err_root_not_permitted => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
err_mutbl(e0a) => {
|
||||
match (*other) {
|
||||
err_mutbl(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
err_out_of_root_scope(e0a, e1a) => {
|
||||
match (*other) {
|
||||
err_out_of_root_scope(e0b, e1b) =>
|
||||
e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
err_out_of_scope(e0a, e1a) => {
|
||||
match (*other) {
|
||||
err_out_of_scope(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &bckerr_code) -> bool {
|
||||
match (*self) {
|
||||
err_mut_uniq => {
|
||||
@@ -408,10 +364,6 @@ impl bckerr_code : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &bckerr_code) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &bckerr_code) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -420,19 +372,9 @@ impl bckerr_code : cmp::Eq {
|
||||
type bckerr = {cmt: cmt, code: bckerr_code};
|
||||
|
||||
impl bckerr : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &bckerr) -> bool {
|
||||
self.cmt == (*other).cmt && self.code == (*other).code
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &bckerr) -> bool {
|
||||
(*self).cmt == (*other).cmt && (*self).code == (*other).code
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &bckerr) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &bckerr) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -463,21 +405,9 @@ fn save_and_restore<T:Copy,U>(save_and_restore_t: &mut T, f: fn() -> U) -> U {
|
||||
/// Creates and returns a new root_map
|
||||
|
||||
impl root_map_key : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &root_map_key) -> bool {
|
||||
self.id == (*other).id && self.derefs == (*other).derefs
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &root_map_key) -> bool {
|
||||
(*self).id == (*other).id && (*self).derefs == (*other).derefs
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &root_map_key) -> bool {
|
||||
! (self == (*other))
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &root_map_key) -> bool {
|
||||
! ((*self) == (*other))
|
||||
}
|
||||
|
||||
@@ -33,25 +33,6 @@ enum purity_cause {
|
||||
}
|
||||
|
||||
impl purity_cause : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &purity_cause) -> bool {
|
||||
match self {
|
||||
pc_pure_fn => {
|
||||
match (*other) {
|
||||
pc_pure_fn => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
pc_cmt(e0a) => {
|
||||
match (*other) {
|
||||
pc_cmt(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &purity_cause) -> bool {
|
||||
match (*self) {
|
||||
pc_pure_fn => {
|
||||
@@ -68,10 +49,6 @@ impl purity_cause : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &purity_cause) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &purity_cause) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -97,19 +74,9 @@ enum assignment_type {
|
||||
}
|
||||
|
||||
impl assignment_type : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &assignment_type) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &assignment_type) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &assignment_type) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &assignment_type) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
mod check_loans;
|
||||
#[legacy_exports]
|
||||
mod gather_loans;
|
||||
#[legacy_exports]
|
||||
mod loan;
|
||||
#[legacy_exports]
|
||||
mod preserve;
|
||||
@@ -126,22 +126,6 @@ enum ctor {
|
||||
}
|
||||
|
||||
impl ctor : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ctor) -> bool {
|
||||
match (self, (*other)) {
|
||||
(single, single) => true,
|
||||
(variant(did_self), variant(did_other)) => did_self == did_other,
|
||||
(val(cv_self), val(cv_other)) => cv_self == cv_other,
|
||||
(range(cv0_self, cv1_self), range(cv0_other, cv1_other)) => {
|
||||
cv0_self == cv0_other && cv1_self == cv1_other
|
||||
}
|
||||
(single, _) | (variant(_), _) | (val(_), _) | (range(*), _) => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ctor) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(single, single) => true,
|
||||
@@ -155,10 +139,6 @@ impl ctor : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ctor) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ctor) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -207,20 +207,6 @@ enum const_val {
|
||||
}
|
||||
|
||||
impl const_val : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &const_val) -> bool {
|
||||
match (self, (*other)) {
|
||||
(const_float(a), const_float(b)) => a == b,
|
||||
(const_int(a), const_int(b)) => a == b,
|
||||
(const_uint(a), const_uint(b)) => a == b,
|
||||
(const_str(a), const_str(b)) => a == b,
|
||||
(const_bool(a), const_bool(b)) => a == b,
|
||||
(const_float(_), _) | (const_int(_), _) | (const_uint(_), _) |
|
||||
(const_str(_), _) | (const_bool(_), _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &const_val) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(const_float(a), const_float(b)) => a == b,
|
||||
@@ -232,10 +218,6 @@ impl const_val : cmp::Eq {
|
||||
(const_str(_), _) | (const_bool(_), _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &const_val) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &const_val) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -68,19 +68,9 @@ enum lint {
|
||||
}
|
||||
|
||||
impl lint : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &lint) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &lint) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &lint) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &lint) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -98,19 +88,9 @@ enum level {
|
||||
}
|
||||
|
||||
impl level : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &level) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &level) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &level) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &level) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -119,28 +119,12 @@
|
||||
enum LiveNode = uint;
|
||||
|
||||
impl Variable : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Variable) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Variable) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Variable) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Variable) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
impl LiveNode : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &LiveNode) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &LiveNode) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &LiveNode) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &LiveNode) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
@@ -152,37 +136,6 @@ enum LiveNodeKind {
|
||||
}
|
||||
|
||||
impl LiveNodeKind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &LiveNodeKind) -> bool {
|
||||
match self {
|
||||
FreeVarNode(e0a) => {
|
||||
match (*other) {
|
||||
FreeVarNode(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ExprNode(e0a) => {
|
||||
match (*other) {
|
||||
ExprNode(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
VarDefNode(e0a) => {
|
||||
match (*other) {
|
||||
VarDefNode(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ExitNode => {
|
||||
match (*other) {
|
||||
ExitNode => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &LiveNodeKind) -> bool {
|
||||
match (*self) {
|
||||
FreeVarNode(e0a) => {
|
||||
@@ -211,10 +164,6 @@ impl LiveNodeKind : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &LiveNodeKind) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &LiveNodeKind) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -56,68 +56,6 @@ enum categorization {
|
||||
}
|
||||
|
||||
impl categorization : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &categorization) -> bool {
|
||||
match self {
|
||||
cat_rvalue => {
|
||||
match (*other) {
|
||||
cat_rvalue => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
cat_special(e0a) => {
|
||||
match (*other) {
|
||||
cat_special(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
cat_local(e0a) => {
|
||||
match (*other) {
|
||||
cat_local(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
cat_binding(e0a) => {
|
||||
match (*other) {
|
||||
cat_binding(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
cat_arg(e0a) => {
|
||||
match (*other) {
|
||||
cat_arg(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
cat_stack_upvar(e0a) => {
|
||||
match (*other) {
|
||||
cat_stack_upvar(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
cat_deref(e0a, e1a, e2a) => {
|
||||
match (*other) {
|
||||
cat_deref(e0b, e1b, e2b) =>
|
||||
e0a == e0b && e1a == e1b && e2a == e2b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
cat_comp(e0a, e1a) => {
|
||||
match (*other) {
|
||||
cat_comp(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
cat_discr(e0a, e1a) => {
|
||||
match (*other) {
|
||||
cat_discr(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &categorization) -> bool {
|
||||
match (*self) {
|
||||
cat_rvalue => {
|
||||
@@ -177,10 +115,6 @@ impl categorization : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &categorization) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &categorization) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -193,37 +127,6 @@ enum ptr_kind {
|
||||
}
|
||||
|
||||
impl ptr_kind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ptr_kind) -> bool {
|
||||
match self {
|
||||
uniq_ptr => {
|
||||
match (*other) {
|
||||
uniq_ptr => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
gc_ptr => {
|
||||
match (*other) {
|
||||
gc_ptr => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
region_ptr(e0a) => {
|
||||
match (*other) {
|
||||
region_ptr(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
unsafe_ptr => {
|
||||
match (*other) {
|
||||
unsafe_ptr => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ptr_kind) -> bool {
|
||||
match (*self) {
|
||||
uniq_ptr => {
|
||||
@@ -252,10 +155,6 @@ impl ptr_kind : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ptr_kind) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ptr_kind) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -273,43 +172,6 @@ enum comp_kind {
|
||||
}
|
||||
|
||||
impl comp_kind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &comp_kind) -> bool {
|
||||
match self {
|
||||
comp_tuple => {
|
||||
match (*other) {
|
||||
comp_tuple => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
comp_anon_field => {
|
||||
match (*other) {
|
||||
comp_anon_field => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
comp_variant(e0a) => {
|
||||
match (*other) {
|
||||
comp_variant(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
comp_field(e0a, e1a) => {
|
||||
match (*other) {
|
||||
comp_field(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
comp_index(e0a, e1a) => {
|
||||
match (*other) {
|
||||
comp_index(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &comp_kind) -> bool {
|
||||
match (*self) {
|
||||
comp_tuple => {
|
||||
@@ -344,10 +206,6 @@ impl comp_kind : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &comp_kind) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &comp_kind) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -360,19 +218,9 @@ enum special_kind {
|
||||
}
|
||||
|
||||
impl special_kind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &special_kind) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &special_kind) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &special_kind) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &special_kind) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -389,17 +237,6 @@ impl special_kind : cmp::Eq {
|
||||
type cmt = @cmt_;
|
||||
|
||||
impl cmt_ : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &cmt_) -> bool {
|
||||
self.id == (*other).id &&
|
||||
self.span == (*other).span &&
|
||||
self.cat == (*other).cat &&
|
||||
self.lp == (*other).lp &&
|
||||
self.mutbl == (*other).mutbl &&
|
||||
self.ty == (*other).ty
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &cmt_) -> bool {
|
||||
(*self).id == (*other).id &&
|
||||
(*self).span == (*other).span &&
|
||||
@@ -408,10 +245,6 @@ impl cmt_ : cmp::Eq {
|
||||
(*self).mutbl == (*other).mutbl &&
|
||||
(*self).ty == (*other).ty
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &cmt_) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &cmt_) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -426,37 +259,6 @@ enum loan_path {
|
||||
}
|
||||
|
||||
impl loan_path : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &loan_path) -> bool {
|
||||
match self {
|
||||
lp_local(e0a) => {
|
||||
match (*other) {
|
||||
lp_local(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
lp_arg(e0a) => {
|
||||
match (*other) {
|
||||
lp_arg(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
lp_deref(e0a, e1a) => {
|
||||
match (*other) {
|
||||
lp_deref(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
lp_comp(e0a, e1a) => {
|
||||
match (*other) {
|
||||
lp_comp(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &loan_path) -> bool {
|
||||
match (*self) {
|
||||
lp_local(e0a) => {
|
||||
@@ -485,10 +287,6 @@ impl loan_path : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &loan_path) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &loan_path) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -148,6 +148,9 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
|
||||
|
||||
visit::visit_mod(the_module, span, node_id, method_map, visitor);
|
||||
|
||||
// FIXME #4054: n_added gets corrupted without this log statement
|
||||
debug!("%i", n_added);
|
||||
|
||||
for n_added.times {
|
||||
ignore(privileged_items.pop());
|
||||
}
|
||||
|
||||
@@ -374,21 +374,10 @@ fn resolve_crate(sess: Session, def_map: resolve::DefMap,
|
||||
type dep_map = HashMap<ast::node_id, @DVec<region_dep>>;
|
||||
|
||||
impl region_dep : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: ®ion_dep) -> bool {
|
||||
self.ambient_variance == (*other).ambient_variance &&
|
||||
self.id == (*other).id
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: ®ion_dep) -> bool {
|
||||
(*self).ambient_variance == (*other).ambient_variance &&
|
||||
(*self).id == (*other).id
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: ®ion_dep) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: ®ion_dep) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -108,31 +108,6 @@ enum PatternBindingMode {
|
||||
}
|
||||
|
||||
impl PatternBindingMode : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &PatternBindingMode) -> bool {
|
||||
match self {
|
||||
RefutableMode => {
|
||||
match *other {
|
||||
RefutableMode => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
LocalIrrefutableMode => {
|
||||
match *other {
|
||||
LocalIrrefutableMode => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ArgumentIrrefutableMode(mode_a) => {
|
||||
match *other {
|
||||
ArgumentIrrefutableMode(mode_b) => mode_a == mode_b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &PatternBindingMode) -> bool {
|
||||
match (*self) {
|
||||
RefutableMode => {
|
||||
@@ -155,10 +130,6 @@ impl PatternBindingMode : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &PatternBindingMode) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &PatternBindingMode) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
@@ -198,19 +169,9 @@ enum Mutability {
|
||||
}
|
||||
|
||||
impl Mutability : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Mutability) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Mutability) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Mutability) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Mutability) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -232,19 +193,9 @@ enum ImportDirectiveNS {
|
||||
}
|
||||
|
||||
impl ImportDirectiveNS : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ImportDirectiveNS) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ImportDirectiveNS) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ImportDirectiveNS) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ImportDirectiveNS) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
@@ -343,19 +294,9 @@ enum XrayFlag {
|
||||
}
|
||||
|
||||
impl XrayFlag : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &XrayFlag) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &XrayFlag) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &XrayFlag) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &XrayFlag) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -365,19 +306,9 @@ enum AllowCapturingSelfFlag {
|
||||
}
|
||||
|
||||
impl AllowCapturingSelfFlag : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &AllowCapturingSelfFlag) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &AllowCapturingSelfFlag) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &AllowCapturingSelfFlag) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &AllowCapturingSelfFlag) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
@@ -400,19 +331,9 @@ enum DuplicateCheckingMode {
|
||||
}
|
||||
|
||||
impl DuplicateCheckingMode : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &DuplicateCheckingMode) -> bool {
|
||||
(self as uint) == (*other as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &DuplicateCheckingMode) -> bool {
|
||||
((*self) as uint) == (*other as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &DuplicateCheckingMode) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &DuplicateCheckingMode) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
@@ -619,19 +540,9 @@ enum Privacy {
|
||||
}
|
||||
|
||||
impl Privacy : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Privacy) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Privacy) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Privacy) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Privacy) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -907,19 +907,9 @@ fn score(p: @ast::pat) -> uint {
|
||||
enum branch_kind { no_branch, single, switch, compare, }
|
||||
|
||||
impl branch_kind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &branch_kind) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &branch_kind) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &branch_kind) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &branch_kind) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -296,25 +296,6 @@ enum cleanup {
|
||||
}
|
||||
|
||||
impl cleantype : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &cleantype) -> bool {
|
||||
match self {
|
||||
normal_exit_only => {
|
||||
match (*other) {
|
||||
normal_exit_only => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
normal_exit_and_unwind => {
|
||||
match (*other) {
|
||||
normal_exit_and_unwind => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &cleantype) -> bool {
|
||||
match (*self) {
|
||||
normal_exit_only => {
|
||||
@@ -331,10 +312,6 @@ impl cleantype : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &cleantype) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &cleantype) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1167,25 +1144,6 @@ enum mono_param_id {
|
||||
type mono_id = @mono_id_;
|
||||
|
||||
impl mono_param_id : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &mono_param_id) -> bool {
|
||||
match (self, (*other)) {
|
||||
(mono_precise(ty_a, ids_a), mono_precise(ty_b, ids_b)) => {
|
||||
ty_a == ty_b && ids_a == ids_b
|
||||
}
|
||||
(mono_any, mono_any) => true,
|
||||
(mono_repr(size_a, align_a, is_float_a, mode_a),
|
||||
mono_repr(size_b, align_b, is_float_b, mode_b)) => {
|
||||
size_a == size_b && align_a == align_b &&
|
||||
is_float_a == is_float_b && mode_a == mode_b
|
||||
}
|
||||
(mono_precise(*), _) => false,
|
||||
(mono_any, _) => false,
|
||||
(mono_repr(*), _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &mono_param_id) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(mono_precise(ty_a, ids_a), mono_precise(ty_b, ids_b)) => {
|
||||
@@ -1202,27 +1160,13 @@ impl mono_param_id : cmp::Eq {
|
||||
(mono_repr(*), _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &mono_param_id) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &mono_param_id) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl mono_id_ : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &mono_id_) -> bool {
|
||||
self.def == (*other).def && self.params == (*other).params
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &mono_id_) -> bool {
|
||||
(*self).def == (*other).def && (*self).params == (*other).params
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &mono_id_) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &mono_id_) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -139,19 +139,9 @@ fn is_by_value() -> bool {
|
||||
}
|
||||
|
||||
impl DatumMode: cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &DatumMode) -> bool {
|
||||
self as uint == (*other as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &DatumMode) -> bool {
|
||||
(*self) as uint == (*other as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &DatumMode) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &DatumMode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -817,17 +807,6 @@ fn to_str() -> ~str {
|
||||
}
|
||||
|
||||
impl CopyAction : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &CopyAction) -> bool {
|
||||
match (self, (*other)) {
|
||||
(INIT, INIT) => true,
|
||||
(DROP_EXISTING, DROP_EXISTING) => true,
|
||||
(INIT, _) => false,
|
||||
(DROP_EXISTING, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &CopyAction) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(INIT, INIT) => true,
|
||||
@@ -836,9 +815,5 @@ impl CopyAction : cmp::Eq {
|
||||
(DROP_EXISTING, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &CopyAction) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &CopyAction) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -148,17 +148,6 @@ fn to_str(ccx: @crate_ctxt) -> ~str {
|
||||
}
|
||||
|
||||
impl Dest : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Dest) -> bool {
|
||||
match (self, (*other)) {
|
||||
(SaveIn(e0a), SaveIn(e0b)) => e0a == e0b,
|
||||
(Ignore, Ignore) => true,
|
||||
(SaveIn(*), _) => false,
|
||||
(Ignore, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Dest) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(SaveIn(e0a), SaveIn(e0b)) => e0a == e0b,
|
||||
@@ -167,10 +156,6 @@ impl Dest : cmp::Eq {
|
||||
(Ignore, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Dest) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Dest) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1445,23 +1430,6 @@ enum cast_kind {
|
||||
}
|
||||
|
||||
impl cast_kind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &cast_kind) -> bool {
|
||||
match (self, (*other)) {
|
||||
(cast_pointer, cast_pointer) => true,
|
||||
(cast_integral, cast_integral) => true,
|
||||
(cast_float, cast_float) => true,
|
||||
(cast_enum, cast_enum) => true,
|
||||
(cast_other, cast_other) => true,
|
||||
(cast_pointer, _) => false,
|
||||
(cast_integral, _) => false,
|
||||
(cast_float, _) => false,
|
||||
(cast_enum, _) => false,
|
||||
(cast_other, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &cast_kind) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(cast_pointer, cast_pointer) => true,
|
||||
@@ -1476,10 +1444,6 @@ impl cast_kind : cmp::Eq {
|
||||
(cast_other, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &cast_kind) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &cast_kind) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -41,19 +41,9 @@ enum x86_64_reg_class {
|
||||
}
|
||||
|
||||
impl x86_64_reg_class : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &x86_64_reg_class) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &x86_64_reg_class) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &x86_64_reg_class) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &x86_64_reg_class) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
+1
-526
@@ -245,25 +245,11 @@ enum vstore {
|
||||
type creader_cache = HashMap<creader_cache_key, t>;
|
||||
|
||||
impl creader_cache_key : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &creader_cache_key) -> bool {
|
||||
self.cnum == (*other).cnum &&
|
||||
self.pos == (*other).pos &&
|
||||
self.len == (*other).len
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &creader_cache_key) -> bool {
|
||||
(*self).cnum == (*other).cnum &&
|
||||
(*self).pos == (*other).pos &&
|
||||
(*self).len == (*other).len
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &creader_cache_key) -> bool {
|
||||
!(self == (*other))
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &creader_cache_key) -> bool {
|
||||
!((*self) == (*other))
|
||||
}
|
||||
@@ -286,19 +272,9 @@ impl creader_cache_key : to_bytes::IterBytes {
|
||||
type intern_key = {sty: sty, o_def_id: Option<ast::def_id>};
|
||||
|
||||
impl intern_key : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &intern_key) -> bool {
|
||||
self.sty == (*other).sty && self.o_def_id == (*other).o_def_id
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &intern_key) -> bool {
|
||||
(*self).sty == (*other).sty && (*self).o_def_id == (*other).o_def_id
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &intern_key) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &intern_key) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -328,19 +304,6 @@ enum ast_ty_to_ty_cache_entry {
|
||||
enum region_variance { rv_covariant, rv_invariant, rv_contravariant }
|
||||
|
||||
impl region_variance : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: ®ion_variance) -> bool {
|
||||
match (self, (*other)) {
|
||||
(rv_covariant, rv_covariant) => true,
|
||||
(rv_invariant, rv_invariant) => true,
|
||||
(rv_contravariant, rv_contravariant) => true,
|
||||
(rv_covariant, _) => false,
|
||||
(rv_invariant, _) => false,
|
||||
(rv_contravariant, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: ®ion_variance) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(rv_covariant, rv_covariant) => true,
|
||||
@@ -351,10 +314,6 @@ impl region_variance : cmp::Eq {
|
||||
(rv_contravariant, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: ®ion_variance) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: ®ion_variance) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -563,19 +522,9 @@ struct FnTyBase<M: cmp::Eq> {
|
||||
type param_ty = {idx: uint, def_id: def_id};
|
||||
|
||||
impl param_ty : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: ¶m_ty) -> bool {
|
||||
self.idx == (*other).idx && self.def_id == (*other).def_id
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: ¶m_ty) -> bool {
|
||||
(*self).idx == (*other).idx && (*self).def_id == (*other).def_id
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: ¶m_ty) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: ¶m_ty) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -823,20 +772,6 @@ impl InferRegion : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl InferRegion : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &InferRegion) -> bool {
|
||||
match (self, *other) {
|
||||
(ReVar(rva), ReVar(rvb)) => {
|
||||
rva == rvb
|
||||
}
|
||||
(ReSkolemized(rva, _), ReSkolemized(rvb, _)) => {
|
||||
rva == rvb
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &InferRegion) -> bool {
|
||||
match ((*self), *other) {
|
||||
(ReVar(rva), ReVar(rvb)) => {
|
||||
@@ -848,12 +783,6 @@ impl InferRegion : cmp::Eq {
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &InferRegion) -> bool {
|
||||
!(self == (*other))
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &InferRegion) -> bool {
|
||||
!((*self) == (*other))
|
||||
}
|
||||
@@ -4579,88 +4508,27 @@ fn eval_repeat_count(tcx: ctxt, count_expr: @ast::expr, span: span) -> uint {
|
||||
}
|
||||
|
||||
impl mt : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &mt) -> bool {
|
||||
self.ty == (*other).ty && self.mutbl == (*other).mutbl
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &mt) -> bool {
|
||||
(*self).ty == (*other).ty && (*self).mutbl == (*other).mutbl
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &mt) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &mt) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl arg : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &arg) -> bool {
|
||||
self.mode == (*other).mode && self.ty == (*other).ty
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &arg) -> bool {
|
||||
(*self).mode == (*other).mode && (*self).ty == (*other).ty
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &arg) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &arg) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl field : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &field) -> bool {
|
||||
self.ident == (*other).ident && self.mt == (*other).mt
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &field) -> bool {
|
||||
(*self).ident == (*other).ident && (*self).mt == (*other).mt
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &field) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &field) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl vstore : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &vstore) -> bool {
|
||||
match self {
|
||||
vstore_fixed(e0a) => {
|
||||
match (*other) {
|
||||
vstore_fixed(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
vstore_uniq => {
|
||||
match (*other) {
|
||||
vstore_uniq => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
vstore_box => {
|
||||
match (*other) {
|
||||
vstore_box => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
vstore_slice(e0a) => {
|
||||
match (*other) {
|
||||
vstore_slice(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &vstore) -> bool {
|
||||
match (*self) {
|
||||
vstore_fixed(e0a) => {
|
||||
@@ -4689,175 +4557,60 @@ impl vstore : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &vstore) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &vstore) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl FnMeta : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &FnMeta) -> bool {
|
||||
self.purity == (*other).purity &&
|
||||
self.proto == (*other).proto &&
|
||||
self.bounds == (*other).bounds &&
|
||||
self.ret_style == (*other).ret_style
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &FnMeta) -> bool {
|
||||
(*self).purity == (*other).purity &&
|
||||
(*self).proto == (*other).proto &&
|
||||
(*self).bounds == (*other).bounds &&
|
||||
(*self).ret_style == (*other).ret_style
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &FnMeta) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &FnMeta) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl FnSig : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &FnSig) -> bool {
|
||||
self.inputs == (*other).inputs &&
|
||||
self.output == (*other).output
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &FnSig) -> bool {
|
||||
(*self).inputs == (*other).inputs &&
|
||||
(*self).output == (*other).output
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &FnSig) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &FnSig) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl<M: cmp::Eq> FnTyBase<M> : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &FnTyBase<M>) -> bool {
|
||||
self.meta == (*other).meta && self.sig == (*other).sig
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &FnTyBase<M>) -> bool {
|
||||
(*self).meta == (*other).meta && (*self).sig == (*other).sig
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &FnTyBase<M>) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &FnTyBase<M>) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl TyVid : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &TyVid) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &TyVid) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &TyVid) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &TyVid) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
impl IntVid : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &IntVid) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &IntVid) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &IntVid) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &IntVid) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
impl FloatVid : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &FloatVid) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &FloatVid) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &FloatVid) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &FloatVid) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
impl FnVid : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &FnVid) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &FnVid) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &FnVid) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &FnVid) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
impl RegionVid : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &RegionVid) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &RegionVid) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &RegionVid) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &RegionVid) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
impl Region : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Region) -> bool {
|
||||
match self {
|
||||
re_bound(e0a) => {
|
||||
match (*other) {
|
||||
re_bound(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
re_free(e0a, e1a) => {
|
||||
match (*other) {
|
||||
re_free(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
re_scope(e0a) => {
|
||||
match (*other) {
|
||||
re_scope(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
re_static => {
|
||||
match (*other) {
|
||||
re_static => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
re_infer(e0a) => {
|
||||
match (*other) {
|
||||
re_infer(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Region) -> bool {
|
||||
match (*self) {
|
||||
re_bound(e0a) => {
|
||||
@@ -4892,45 +4645,10 @@ impl Region : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Region) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Region) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl bound_region : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &bound_region) -> bool {
|
||||
match self {
|
||||
br_self => {
|
||||
match (*other) {
|
||||
br_self => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
br_anon(e0a) => {
|
||||
match (*other) {
|
||||
br_anon(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
br_named(e0a) => {
|
||||
match (*other) {
|
||||
br_named(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
br_cap_avoid(e0a, e1a) => {
|
||||
match (*other) {
|
||||
br_cap_avoid(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &bound_region) -> bool {
|
||||
match (*self) {
|
||||
br_self => {
|
||||
@@ -4959,216 +4677,26 @@ impl bound_region : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &bound_region) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &bound_region) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl substs : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &substs) -> bool {
|
||||
self.self_r == (*other).self_r &&
|
||||
self.self_ty == (*other).self_ty &&
|
||||
self.tps == (*other).tps
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &substs) -> bool {
|
||||
(*self).self_r == (*other).self_r &&
|
||||
(*self).self_ty == (*other).self_ty &&
|
||||
(*self).tps == (*other).tps
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &substs) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &substs) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl InferTy : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &InferTy) -> bool {
|
||||
self.to_hash() == (*other).to_hash()
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &InferTy) -> bool {
|
||||
(*self).to_hash() == (*other).to_hash()
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &InferTy) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &InferTy) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl sty : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &sty) -> bool {
|
||||
match self {
|
||||
ty_nil => {
|
||||
match (*other) {
|
||||
ty_nil => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_bot => {
|
||||
match (*other) {
|
||||
ty_bot => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_bool => {
|
||||
match (*other) {
|
||||
ty_bool => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_int(e0a) => {
|
||||
match (*other) {
|
||||
ty_int(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_uint(e0a) => {
|
||||
match (*other) {
|
||||
ty_uint(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_float(e0a) => {
|
||||
match (*other) {
|
||||
ty_float(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_estr(e0a) => {
|
||||
match (*other) {
|
||||
ty_estr(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_enum(e0a, e1a) => {
|
||||
match (*other) {
|
||||
ty_enum(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_box(e0a) => {
|
||||
match (*other) {
|
||||
ty_box(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_uniq(e0a) => {
|
||||
match (*other) {
|
||||
ty_uniq(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_evec(e0a, e1a) => {
|
||||
match (*other) {
|
||||
ty_evec(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_ptr(e0a) => {
|
||||
match (*other) {
|
||||
ty_ptr(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_rptr(e0a, e1a) => {
|
||||
match (*other) {
|
||||
ty_rptr(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_rec(e0a) => {
|
||||
match (*other) {
|
||||
ty_rec(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_fn(e0a) => {
|
||||
match (*other) {
|
||||
ty_fn(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_trait(e0a, e1a, e2a) => {
|
||||
match (*other) {
|
||||
ty_trait(e0b, e1b, e2b) =>
|
||||
e0a == e0b && e1a == e1b && e2a == e2b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_class(e0a, e1a) => {
|
||||
match (*other) {
|
||||
ty_class(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_tup(e0a) => {
|
||||
match (*other) {
|
||||
ty_tup(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_infer(e0a) => {
|
||||
match (*other) {
|
||||
ty_infer(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_err => {
|
||||
match (*other) {
|
||||
ty_err => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_param(e0a) => {
|
||||
match (*other) {
|
||||
ty_param(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_self => {
|
||||
match (*other) {
|
||||
ty_self => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_type => {
|
||||
match (*other) {
|
||||
ty_type => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_opaque_box => {
|
||||
match (*other) {
|
||||
ty_opaque_box => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_opaque_closure_ptr(e0a) => {
|
||||
match (*other) {
|
||||
ty_opaque_closure_ptr(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_unboxed_vec(e0a) => {
|
||||
match (*other) {
|
||||
ty_unboxed_vec(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &sty) -> bool {
|
||||
match (*self) {
|
||||
ty_nil => {
|
||||
@@ -5330,51 +4858,10 @@ impl sty : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &sty) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &sty) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl param_bound : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: ¶m_bound) -> bool {
|
||||
match self {
|
||||
bound_copy => {
|
||||
match (*other) {
|
||||
bound_copy => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
bound_owned => {
|
||||
match (*other) {
|
||||
bound_owned => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
bound_send => {
|
||||
match (*other) {
|
||||
bound_send => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
bound_const => {
|
||||
match (*other) {
|
||||
bound_const => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
bound_trait(e0a) => {
|
||||
match (*other) {
|
||||
bound_trait(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: ¶m_bound) -> bool {
|
||||
match (*self) {
|
||||
bound_copy => {
|
||||
@@ -5409,23 +4896,11 @@ impl param_bound : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: ¶m_bound) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: ¶m_bound) -> bool { !(*self).eq(other) }
|
||||
pure fn ne(&self, other: ¶m_bound) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
impl Kind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Kind) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Kind) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Kind) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Kind) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#[legacy_exports]
|
||||
mod alt;
|
||||
#[legacy_exports]
|
||||
mod vtable;
|
||||
#[legacy_exports]
|
||||
mod writeback;
|
||||
#[legacy_exports]
|
||||
mod regionmanip;
|
||||
#[legacy_exports]
|
||||
mod regionck;
|
||||
#[legacy_exports]
|
||||
mod demand;
|
||||
#[legacy_exports]
|
||||
pub mod method;
|
||||
@@ -0,0 +1,24 @@
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
mod assignment;
|
||||
#[legacy_exports]
|
||||
mod combine;
|
||||
#[legacy_exports]
|
||||
mod glb;
|
||||
#[legacy_exports]
|
||||
mod integral;
|
||||
mod floating;
|
||||
#[legacy_exports]
|
||||
mod lattice;
|
||||
#[legacy_exports]
|
||||
mod lub;
|
||||
#[legacy_exports]
|
||||
mod region_inference;
|
||||
#[legacy_exports]
|
||||
mod resolve;
|
||||
#[legacy_exports]
|
||||
mod sub;
|
||||
#[legacy_exports]
|
||||
mod to_str;
|
||||
#[legacy_exports]
|
||||
mod unify;
|
||||
@@ -469,25 +469,6 @@ enum Constraint {
|
||||
}
|
||||
|
||||
impl Constraint : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Constraint) -> bool {
|
||||
match (self, (*other)) {
|
||||
(ConstrainVarSubVar(v0a, v1a), ConstrainVarSubVar(v0b, v1b)) => {
|
||||
v0a == v0b && v1a == v1b
|
||||
}
|
||||
(ConstrainRegSubVar(ra, va), ConstrainRegSubVar(rb, vb)) => {
|
||||
ra == rb && va == vb
|
||||
}
|
||||
(ConstrainVarSubReg(va, ra), ConstrainVarSubReg(vb, rb)) => {
|
||||
va == vb && ra == rb
|
||||
}
|
||||
(ConstrainVarSubVar(*), _) => false,
|
||||
(ConstrainRegSubVar(*), _) => false,
|
||||
(ConstrainVarSubReg(*), _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Constraint) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(ConstrainVarSubVar(v0a, v1a), ConstrainVarSubVar(v0b, v1b)) => {
|
||||
@@ -504,10 +485,6 @@ impl Constraint : cmp::Eq {
|
||||
(ConstrainVarSubReg(*), _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Constraint) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Constraint) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -549,19 +526,9 @@ struct TwoRegions {
|
||||
}
|
||||
|
||||
impl TwoRegions : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &TwoRegions) -> bool {
|
||||
self.a == (*other).a && self.b == (*other).b
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &TwoRegions) -> bool {
|
||||
(*self).a == (*other).a && (*self).b == (*other).b
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &TwoRegions) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &TwoRegions) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1093,38 +1060,18 @@ fn report_type_error(&self, span: span, terr: &ty::type_err) {
|
||||
enum Direction { Incoming = 0, Outgoing = 1 }
|
||||
|
||||
impl Direction : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Direction) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Direction) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Direction) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Direction) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
enum Classification { Expanding, Contracting }
|
||||
|
||||
impl Classification : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Classification) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Classification) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Classification) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Classification) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#[legacy_exports];
|
||||
|
||||
#[legacy_exports]
|
||||
#[merge = "check/mod.rs"]
|
||||
pub mod check;
|
||||
#[legacy_exports]
|
||||
mod rscope;
|
||||
#[legacy_exports]
|
||||
mod astconv;
|
||||
#[merge = "infer/mod.rs"]
|
||||
mod infer;
|
||||
#[legacy_exports]
|
||||
mod collect;
|
||||
#[legacy_exports]
|
||||
mod coherence;
|
||||
mod deriving;
|
||||
+310
-110
@@ -43,246 +43,446 @@ mod middle {
|
||||
mod trans {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/inline.rs"]
|
||||
mod inline;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/monomorphize.rs"]
|
||||
mod monomorphize;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/controlflow.rs"]
|
||||
mod controlflow;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/glue.rs"]
|
||||
mod glue;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/datum.rs"]
|
||||
mod datum;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/callee.rs"]
|
||||
mod callee;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/expr.rs"]
|
||||
mod expr;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/common.rs"]
|
||||
mod common;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/consts.rs"]
|
||||
mod consts;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/type_of.rs"]
|
||||
mod type_of;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/build.rs"]
|
||||
mod build;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/base.rs"]
|
||||
mod base;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/alt.rs"]
|
||||
mod alt;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/uniq.rs"]
|
||||
mod uniq;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/closure.rs"]
|
||||
mod closure;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/tvec.rs"]
|
||||
mod tvec;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/meth.rs"]
|
||||
mod meth;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/foreign.rs"]
|
||||
mod foreign;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/reflect.rs"]
|
||||
mod reflect;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/shape.rs"]
|
||||
mod shape;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/debuginfo.rs"]
|
||||
mod debuginfo;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/type_use.rs"]
|
||||
mod type_use;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/trans/reachable.rs"]
|
||||
mod reachable;
|
||||
#[path = "middle/trans/machine.rs"]
|
||||
mod machine;
|
||||
#[path = "middle/trans/deriving.rs"]
|
||||
mod deriving;
|
||||
}
|
||||
#[legacy_exports]
|
||||
#[path = "middle/ty.rs"]
|
||||
mod ty;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/resolve.rs"]
|
||||
mod resolve;
|
||||
pub mod typeck {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
pub mod check {
|
||||
#[legacy_exports]
|
||||
mod alt;
|
||||
#[legacy_exports]
|
||||
mod vtable;
|
||||
#[legacy_exports]
|
||||
mod writeback;
|
||||
#[legacy_exports]
|
||||
mod regionmanip;
|
||||
#[legacy_exports]
|
||||
mod regionck;
|
||||
#[legacy_exports]
|
||||
mod demand;
|
||||
#[legacy_exports]
|
||||
pub mod method;
|
||||
}
|
||||
#[legacy_exports]
|
||||
mod rscope;
|
||||
#[legacy_exports]
|
||||
mod astconv;
|
||||
mod infer {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
mod assignment;
|
||||
#[legacy_exports]
|
||||
mod combine;
|
||||
#[legacy_exports]
|
||||
mod glb;
|
||||
#[legacy_exports]
|
||||
mod integral;
|
||||
mod floating;
|
||||
#[legacy_exports]
|
||||
mod lattice;
|
||||
#[legacy_exports]
|
||||
mod lub;
|
||||
#[legacy_exports]
|
||||
mod region_inference;
|
||||
#[legacy_exports]
|
||||
mod resolve;
|
||||
#[legacy_exports]
|
||||
mod sub;
|
||||
#[legacy_exports]
|
||||
mod to_str;
|
||||
#[legacy_exports]
|
||||
mod unify;
|
||||
#[cfg(test)]
|
||||
#[legacy_exports]
|
||||
mod test;
|
||||
}
|
||||
#[legacy_exports]
|
||||
mod collect;
|
||||
#[legacy_exports]
|
||||
mod coherence;
|
||||
mod deriving;
|
||||
}
|
||||
#[path = "middle/typeck.rs"]
|
||||
#[merge = "middle/typeck/mod.rs"]
|
||||
pub mod typeck;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/check_loop.rs"]
|
||||
mod check_loop;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/check_alt.rs"]
|
||||
mod check_alt;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/check_const.rs"]
|
||||
mod check_const;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/lint.rs"]
|
||||
mod lint;
|
||||
mod borrowck {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
mod check_loans;
|
||||
#[legacy_exports]
|
||||
mod gather_loans;
|
||||
#[legacy_exports]
|
||||
mod loan;
|
||||
#[legacy_exports]
|
||||
mod preserve;
|
||||
}
|
||||
#[path = "middle/borrowck.rs"]
|
||||
#[merge = "middle/borrowck/mod.rs"]
|
||||
mod borrowck;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/mem_categorization.rs"]
|
||||
mod mem_categorization;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/liveness.rs"]
|
||||
mod liveness;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/kind.rs"]
|
||||
mod kind;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/freevars.rs"]
|
||||
mod freevars;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/capture.rs"]
|
||||
mod capture;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/pat_util.rs"]
|
||||
mod pat_util;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/region.rs"]
|
||||
mod region;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/const_eval.rs"]
|
||||
mod const_eval;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/astencode.rs"]
|
||||
mod astencode;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/lang_items.rs"]
|
||||
mod lang_items;
|
||||
#[legacy_exports]
|
||||
#[path = "middle/privacy.rs"]
|
||||
mod privacy;
|
||||
}
|
||||
|
||||
mod front {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
#[path = "front/config.rs"]
|
||||
mod config;
|
||||
#[legacy_exports]
|
||||
#[path = "front/test.rs"]
|
||||
mod test;
|
||||
#[legacy_exports]
|
||||
#[path = "front/core_inject.rs"]
|
||||
mod core_inject;
|
||||
#[legacy_exports]
|
||||
#[path = "front/intrinsic_inject.rs"]
|
||||
mod intrinsic_inject;
|
||||
}
|
||||
|
||||
mod back {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
#[path = "back/link.rs"]
|
||||
mod link;
|
||||
#[legacy_exports]
|
||||
#[path = "back/abi.rs"]
|
||||
mod abi;
|
||||
#[legacy_exports]
|
||||
#[path = "back/upcall.rs"]
|
||||
mod upcall;
|
||||
#[legacy_exports]
|
||||
#[path = "back/x86.rs"]
|
||||
mod x86;
|
||||
#[legacy_exports]
|
||||
#[path = "back/x86_64.rs"]
|
||||
mod x86_64;
|
||||
#[legacy_exports]
|
||||
#[path = "back/rpath.rs"]
|
||||
mod rpath;
|
||||
#[legacy_exports]
|
||||
#[path = "back/target_strs.rs"]
|
||||
mod target_strs;
|
||||
}
|
||||
|
||||
mod metadata {
|
||||
#[legacy_exports];
|
||||
export encoder;
|
||||
export creader;
|
||||
export cstore;
|
||||
export csearch;
|
||||
export common;
|
||||
export decoder;
|
||||
export tyencode;
|
||||
export tydecode;
|
||||
export loader;
|
||||
export filesearch;
|
||||
#[merge = "metadata/mod.rs"]
|
||||
mod metadata;
|
||||
|
||||
#[legacy_exports]
|
||||
mod common;
|
||||
#[legacy_exports]
|
||||
mod tyencode;
|
||||
#[legacy_exports]
|
||||
mod tydecode;
|
||||
#[legacy_exports]
|
||||
mod encoder;
|
||||
#[legacy_exports]
|
||||
mod decoder;
|
||||
#[legacy_exports]
|
||||
mod creader;
|
||||
#[legacy_exports]
|
||||
mod cstore;
|
||||
#[legacy_exports]
|
||||
mod csearch;
|
||||
#[legacy_exports]
|
||||
mod loader;
|
||||
#[legacy_exports]
|
||||
mod filesearch;
|
||||
}
|
||||
|
||||
mod driver {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
mod driver;
|
||||
#[legacy_exports]
|
||||
mod session;
|
||||
}
|
||||
#[merge = "driver/mod.rs"]
|
||||
mod driver;
|
||||
|
||||
mod util {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
#[path = "util/common.rs"]
|
||||
mod common;
|
||||
#[legacy_exports]
|
||||
#[path = "util/ppaux.rs"]
|
||||
mod ppaux;
|
||||
}
|
||||
|
||||
mod lib {
|
||||
#[legacy_exports];
|
||||
#[legacy_exports]
|
||||
#[path = "lib/llvm.rs"]
|
||||
mod llvm;
|
||||
}
|
||||
|
||||
use result::{Ok, Err};
|
||||
use io::ReaderUtil;
|
||||
use std::getopts;
|
||||
use std::map::HashMap;
|
||||
use getopts::{opt_present};
|
||||
use getopts::groups;
|
||||
use syntax::codemap;
|
||||
use syntax::diagnostic;
|
||||
use driver::driver::{host_triple, optgroups, early_error,
|
||||
str_input, file_input, build_session_options,
|
||||
build_session, build_configuration, parse_pretty,
|
||||
pp_mode, pretty_print_input, list_metadata,
|
||||
compile_input};
|
||||
use driver::session;
|
||||
use middle::lint;
|
||||
|
||||
fn version(argv0: &str) {
|
||||
let mut vers = ~"unknown version";
|
||||
let env_vers = env!("CFG_VERSION");
|
||||
if env_vers.len() != 0 { vers = env_vers; }
|
||||
io::println(fmt!("%s %s", argv0, vers));
|
||||
io::println(fmt!("host: %s", host_triple()));
|
||||
}
|
||||
|
||||
fn usage(argv0: &str) {
|
||||
let message = fmt!("Usage: %s [OPTIONS] INPUT", argv0);
|
||||
io::println(groups::usage(message, optgroups()) +
|
||||
~"Additional help:
|
||||
-W help Print 'lint' options and default settings
|
||||
-Z help Print internal options for debugging rustc
|
||||
");
|
||||
}
|
||||
|
||||
fn describe_warnings() {
|
||||
io::println(fmt!("
|
||||
Available lint options:
|
||||
-W <foo> Warn about <foo>
|
||||
-A <foo> Allow <foo>
|
||||
-D <foo> Deny <foo>
|
||||
-F <foo> Forbid <foo> (deny, and deny all overrides)
|
||||
"));
|
||||
|
||||
let lint_dict = lint::get_lint_dict();
|
||||
let mut max_key = 0;
|
||||
for lint_dict.each_key |k| { max_key = uint::max(k.len(), max_key); }
|
||||
fn padded(max: uint, s: &str) -> ~str {
|
||||
str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s
|
||||
}
|
||||
io::println(fmt!("\nAvailable lint checks:\n"));
|
||||
io::println(fmt!(" %s %7.7s %s",
|
||||
padded(max_key, ~"name"), ~"default", ~"meaning"));
|
||||
io::println(fmt!(" %s %7.7s %s\n",
|
||||
padded(max_key, ~"----"), ~"-------", ~"-------"));
|
||||
for lint_dict.each |k, v| {
|
||||
let k = str::replace(k, ~"_", ~"-");
|
||||
io::println(fmt!(" %s %7.7s %s",
|
||||
padded(max_key, k),
|
||||
match v.default {
|
||||
lint::allow => ~"allow",
|
||||
lint::warn => ~"warn",
|
||||
lint::deny => ~"deny",
|
||||
lint::forbid => ~"forbid"
|
||||
},
|
||||
v.desc));
|
||||
}
|
||||
io::println(~"");
|
||||
}
|
||||
|
||||
fn describe_debug_flags() {
|
||||
io::println(fmt!("\nAvailable debug options:\n"));
|
||||
for session::debugging_opts_map().each |pair| {
|
||||
let (name, desc, _) = *pair;
|
||||
io::println(fmt!(" -Z %-20s -- %s", name, desc));
|
||||
}
|
||||
}
|
||||
|
||||
fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
|
||||
// Don't display log spew by default. Can override with RUST_LOG.
|
||||
logging::console_off();
|
||||
|
||||
let mut args = *args;
|
||||
let binary = args.shift();
|
||||
|
||||
if args.is_empty() { usage(binary); return; }
|
||||
|
||||
let matches =
|
||||
&match getopts::groups::getopts(args, optgroups()) {
|
||||
Ok(m) => m,
|
||||
Err(f) => {
|
||||
early_error(demitter, getopts::fail_str(f))
|
||||
}
|
||||
};
|
||||
|
||||
if opt_present(matches, ~"h") || opt_present(matches, ~"help") {
|
||||
usage(binary);
|
||||
return;
|
||||
}
|
||||
|
||||
let lint_flags = vec::append(getopts::opt_strs(matches, ~"W"),
|
||||
getopts::opt_strs(matches, ~"warn"));
|
||||
if lint_flags.contains(&~"help") {
|
||||
describe_warnings();
|
||||
return;
|
||||
}
|
||||
|
||||
if getopts::opt_strs(matches, ~"Z").contains(&~"help") {
|
||||
describe_debug_flags();
|
||||
return;
|
||||
}
|
||||
|
||||
if opt_present(matches, ~"v") || opt_present(matches, ~"version") {
|
||||
version(binary);
|
||||
return;
|
||||
}
|
||||
let input = match vec::len(matches.free) {
|
||||
0u => early_error(demitter, ~"no input filename given"),
|
||||
1u => {
|
||||
let ifile = matches.free[0];
|
||||
if ifile == ~"-" {
|
||||
let src = str::from_bytes(io::stdin().read_whole_stream());
|
||||
str_input(src)
|
||||
} else {
|
||||
file_input(Path(ifile))
|
||||
}
|
||||
}
|
||||
_ => early_error(demitter, ~"multiple input filenames provided")
|
||||
};
|
||||
|
||||
let sopts = build_session_options(binary, matches, demitter);
|
||||
let sess = build_session(sopts, demitter);
|
||||
let odir = getopts::opt_maybe_str(matches, ~"out-dir");
|
||||
let odir = odir.map(|o| Path(*o));
|
||||
let ofile = getopts::opt_maybe_str(matches, ~"o");
|
||||
let ofile = ofile.map(|o| Path(*o));
|
||||
let cfg = build_configuration(sess, binary, input);
|
||||
let pretty =
|
||||
option::map(&getopts::opt_default(matches, ~"pretty",
|
||||
~"normal"),
|
||||
|a| parse_pretty(sess, *a) );
|
||||
match pretty {
|
||||
Some::<pp_mode>(ppm) => {
|
||||
pretty_print_input(sess, cfg, input, ppm);
|
||||
return;
|
||||
}
|
||||
None::<pp_mode> => {/* continue */ }
|
||||
}
|
||||
let ls = opt_present(matches, ~"ls");
|
||||
if ls {
|
||||
match input {
|
||||
file_input(ifile) => {
|
||||
list_metadata(sess, &ifile, io::stdout());
|
||||
}
|
||||
str_input(_) => {
|
||||
early_error(demitter, ~"can not list metadata for stdin");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
compile_input(sess, cfg, input, &odir, &ofile);
|
||||
}
|
||||
|
||||
enum monitor_msg {
|
||||
fatal,
|
||||
done,
|
||||
}
|
||||
|
||||
impl monitor_msg : cmp::Eq {
|
||||
pure fn eq(&self, other: &monitor_msg) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
pure fn ne(&self, other: &monitor_msg) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
/*
|
||||
This is a sanity check that any failure of the compiler is performed
|
||||
through the diagnostic module and reported properly - we shouldn't be calling
|
||||
plain-old-fail on any execution path that might be taken. Since we have
|
||||
console logging off by default, hitting a plain fail statement would make the
|
||||
compiler silently exit, which would be terrible.
|
||||
|
||||
This method wraps the compiler in a subtask and injects a function into the
|
||||
diagnostic emitter which records when we hit a fatal error. If the task
|
||||
fails without recording a fatal error then we've encountered a compiler
|
||||
bug and need to present an error.
|
||||
*/
|
||||
fn monitor(+f: fn~(diagnostic::emitter)) {
|
||||
let p = comm::Port();
|
||||
let ch = comm::Chan(&p);
|
||||
|
||||
match do task::try |move f| {
|
||||
|
||||
// The 'diagnostics emitter'. Every error, warning, etc. should
|
||||
// go through this function.
|
||||
let demitter = fn@(cmsp: Option<(@codemap::CodeMap, codemap::span)>,
|
||||
msg: &str, lvl: diagnostic::level) {
|
||||
if lvl == diagnostic::fatal {
|
||||
comm::send(ch, fatal);
|
||||
}
|
||||
diagnostic::emit(cmsp, msg, lvl);
|
||||
};
|
||||
|
||||
struct finally {
|
||||
ch: comm::Chan<monitor_msg>,
|
||||
drop { comm::send(self.ch, done); }
|
||||
}
|
||||
|
||||
let _finally = finally { ch: ch };
|
||||
|
||||
f(demitter)
|
||||
} {
|
||||
result::Ok(_) => { /* fallthrough */ }
|
||||
result::Err(_) => {
|
||||
// Task failed without emitting a fatal diagnostic
|
||||
if comm::recv(p) == done {
|
||||
diagnostic::emit(
|
||||
None,
|
||||
diagnostic::ice_msg(~"unexpected failure"),
|
||||
diagnostic::error);
|
||||
|
||||
for [
|
||||
~"the compiler hit an unexpected failure path. \
|
||||
this is a bug",
|
||||
~"try running with RUST_LOG=rustc=1,::rt::backtrace \
|
||||
to get further details and report the results \
|
||||
to github.com/mozilla/rust/issues"
|
||||
].each |note| {
|
||||
diagnostic::emit(None, *note, diagnostic::note)
|
||||
}
|
||||
}
|
||||
// Fail so the process returns a failure code
|
||||
fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = os::args();
|
||||
do monitor |move args, demitter| {
|
||||
run_compiler(&args, demitter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
// -*- rust -*-
|
||||
use result::{Ok, Err};
|
||||
use io::ReaderUtil;
|
||||
use std::getopts;
|
||||
use std::map::HashMap;
|
||||
use getopts::{opt_present};
|
||||
use getopts::groups;
|
||||
use syntax::codemap;
|
||||
use syntax::diagnostic;
|
||||
use driver::driver::{host_triple, optgroups, early_error,
|
||||
str_input, file_input, build_session_options,
|
||||
build_session, build_configuration, parse_pretty,
|
||||
pp_mode, pretty_print_input, list_metadata,
|
||||
compile_input};
|
||||
use driver::session;
|
||||
use middle::lint;
|
||||
|
||||
fn version(argv0: &str) {
|
||||
let mut vers = ~"unknown version";
|
||||
let env_vers = env!("CFG_VERSION");
|
||||
if env_vers.len() != 0 { vers = env_vers; }
|
||||
io::println(fmt!("%s %s", argv0, vers));
|
||||
io::println(fmt!("host: %s", host_triple()));
|
||||
}
|
||||
|
||||
fn usage(argv0: &str) {
|
||||
let message = fmt!("Usage: %s [OPTIONS] INPUT", argv0);
|
||||
io::println(groups::usage(message, optgroups()) +
|
||||
~"Additional help:
|
||||
-W help Print 'lint' options and default settings
|
||||
-Z help Print internal options for debugging rustc
|
||||
");
|
||||
}
|
||||
|
||||
fn describe_warnings() {
|
||||
io::println(fmt!("
|
||||
Available lint options:
|
||||
-W <foo> Warn about <foo>
|
||||
-A <foo> Allow <foo>
|
||||
-D <foo> Deny <foo>
|
||||
-F <foo> Forbid <foo> (deny, and deny all overrides)
|
||||
"));
|
||||
|
||||
let lint_dict = lint::get_lint_dict();
|
||||
let mut max_key = 0;
|
||||
for lint_dict.each_key |k| { max_key = uint::max(k.len(), max_key); }
|
||||
fn padded(max: uint, s: &str) -> ~str {
|
||||
str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s
|
||||
}
|
||||
io::println(fmt!("\nAvailable lint checks:\n"));
|
||||
io::println(fmt!(" %s %7.7s %s",
|
||||
padded(max_key, ~"name"), ~"default", ~"meaning"));
|
||||
io::println(fmt!(" %s %7.7s %s\n",
|
||||
padded(max_key, ~"----"), ~"-------", ~"-------"));
|
||||
for lint_dict.each |k, v| {
|
||||
let k = str::replace(k, ~"_", ~"-");
|
||||
io::println(fmt!(" %s %7.7s %s",
|
||||
padded(max_key, k),
|
||||
match v.default {
|
||||
lint::allow => ~"allow",
|
||||
lint::warn => ~"warn",
|
||||
lint::deny => ~"deny",
|
||||
lint::forbid => ~"forbid"
|
||||
},
|
||||
v.desc));
|
||||
}
|
||||
io::println(~"");
|
||||
}
|
||||
|
||||
fn describe_debug_flags() {
|
||||
io::println(fmt!("\nAvailable debug options:\n"));
|
||||
for session::debugging_opts_map().each |pair| {
|
||||
let (name, desc, _) = *pair;
|
||||
io::println(fmt!(" -Z %-20s -- %s", name, desc));
|
||||
}
|
||||
}
|
||||
|
||||
fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
|
||||
// Don't display log spew by default. Can override with RUST_LOG.
|
||||
logging::console_off();
|
||||
|
||||
let mut args = *args;
|
||||
let binary = args.shift();
|
||||
|
||||
if args.is_empty() { usage(binary); return; }
|
||||
|
||||
let matches =
|
||||
&match getopts::groups::getopts(args, optgroups()) {
|
||||
Ok(m) => m,
|
||||
Err(f) => {
|
||||
early_error(demitter, getopts::fail_str(f))
|
||||
}
|
||||
};
|
||||
|
||||
if opt_present(matches, ~"h") || opt_present(matches, ~"help") {
|
||||
usage(binary);
|
||||
return;
|
||||
}
|
||||
|
||||
let lint_flags = vec::append(getopts::opt_strs(matches, ~"W"),
|
||||
getopts::opt_strs(matches, ~"warn"));
|
||||
if lint_flags.contains(&~"help") {
|
||||
describe_warnings();
|
||||
return;
|
||||
}
|
||||
|
||||
if getopts::opt_strs(matches, ~"Z").contains(&~"help") {
|
||||
describe_debug_flags();
|
||||
return;
|
||||
}
|
||||
|
||||
if opt_present(matches, ~"v") || opt_present(matches, ~"version") {
|
||||
version(binary);
|
||||
return;
|
||||
}
|
||||
let input = match vec::len(matches.free) {
|
||||
0u => early_error(demitter, ~"no input filename given"),
|
||||
1u => {
|
||||
let ifile = matches.free[0];
|
||||
if ifile == ~"-" {
|
||||
let src = str::from_bytes(io::stdin().read_whole_stream());
|
||||
str_input(src)
|
||||
} else {
|
||||
file_input(Path(ifile))
|
||||
}
|
||||
}
|
||||
_ => early_error(demitter, ~"multiple input filenames provided")
|
||||
};
|
||||
|
||||
let sopts = build_session_options(binary, matches, demitter);
|
||||
let sess = build_session(sopts, demitter);
|
||||
let odir = getopts::opt_maybe_str(matches, ~"out-dir");
|
||||
let odir = odir.map(|o| Path(*o));
|
||||
let ofile = getopts::opt_maybe_str(matches, ~"o");
|
||||
let ofile = ofile.map(|o| Path(*o));
|
||||
let cfg = build_configuration(sess, binary, input);
|
||||
let pretty =
|
||||
option::map(&getopts::opt_default(matches, ~"pretty",
|
||||
~"normal"),
|
||||
|a| parse_pretty(sess, *a) );
|
||||
match pretty {
|
||||
Some::<pp_mode>(ppm) => {
|
||||
pretty_print_input(sess, cfg, input, ppm);
|
||||
return;
|
||||
}
|
||||
None::<pp_mode> => {/* continue */ }
|
||||
}
|
||||
let ls = opt_present(matches, ~"ls");
|
||||
if ls {
|
||||
match input {
|
||||
file_input(ifile) => {
|
||||
list_metadata(sess, &ifile, io::stdout());
|
||||
}
|
||||
str_input(_) => {
|
||||
early_error(demitter, ~"can not list metadata for stdin");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
compile_input(sess, cfg, input, &odir, &ofile);
|
||||
}
|
||||
|
||||
enum monitor_msg {
|
||||
fatal,
|
||||
done,
|
||||
}
|
||||
|
||||
impl monitor_msg : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &monitor_msg) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &monitor_msg) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &monitor_msg) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &monitor_msg) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
/*
|
||||
This is a sanity check that any failure of the compiler is performed
|
||||
through the diagnostic module and reported properly - we shouldn't be calling
|
||||
plain-old-fail on any execution path that might be taken. Since we have
|
||||
console logging off by default, hitting a plain fail statement would make the
|
||||
compiler silently exit, which would be terrible.
|
||||
|
||||
This method wraps the compiler in a subtask and injects a function into the
|
||||
diagnostic emitter which records when we hit a fatal error. If the task
|
||||
fails without recording a fatal error then we've encountered a compiler
|
||||
bug and need to present an error.
|
||||
*/
|
||||
fn monitor(+f: fn~(diagnostic::emitter)) {
|
||||
let p = comm::Port();
|
||||
let ch = comm::Chan(&p);
|
||||
|
||||
match do task::try |move f| {
|
||||
|
||||
// The 'diagnostics emitter'. Every error, warning, etc. should
|
||||
// go through this function.
|
||||
let demitter = fn@(cmsp: Option<(@codemap::CodeMap, codemap::span)>,
|
||||
msg: &str, lvl: diagnostic::level) {
|
||||
if lvl == diagnostic::fatal {
|
||||
comm::send(ch, fatal);
|
||||
}
|
||||
diagnostic::emit(cmsp, msg, lvl);
|
||||
};
|
||||
|
||||
struct finally {
|
||||
ch: comm::Chan<monitor_msg>,
|
||||
drop { comm::send(self.ch, done); }
|
||||
}
|
||||
|
||||
let _finally = finally { ch: ch };
|
||||
|
||||
f(demitter)
|
||||
} {
|
||||
result::Ok(_) => { /* fallthrough */ }
|
||||
result::Err(_) => {
|
||||
// Task failed without emitting a fatal diagnostic
|
||||
if comm::recv(p) == done {
|
||||
diagnostic::emit(
|
||||
None,
|
||||
diagnostic::ice_msg(~"unexpected failure"),
|
||||
diagnostic::error);
|
||||
|
||||
for [
|
||||
~"the compiler hit an unexpected failure path. \
|
||||
this is a bug",
|
||||
~"try running with RUST_LOG=rustc=1,::rt::backtrace \
|
||||
to get further details and report the results \
|
||||
to github.com/mozilla/rust/issues"
|
||||
].each |note| {
|
||||
diagnostic::emit(None, *note, diagnostic::note)
|
||||
}
|
||||
}
|
||||
// Fail so the process returns a failure code
|
||||
fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = os::args();
|
||||
do monitor |move args, demitter| {
|
||||
run_compiler(&args, demitter);
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// End:
|
||||
@@ -11,19 +11,9 @@ pub enum OutputFormat {
|
||||
}
|
||||
|
||||
impl OutputFormat : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &OutputFormat) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &OutputFormat) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &OutputFormat) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &OutputFormat) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -36,19 +26,9 @@ pub enum OutputStyle {
|
||||
}
|
||||
|
||||
impl OutputStyle : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &OutputStyle) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &OutputStyle) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &OutputStyle) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &OutputStyle) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -7,19 +7,9 @@
|
||||
};
|
||||
|
||||
impl Doc_ : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Doc_) -> bool {
|
||||
self.pages == (*other).pages
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Doc_) -> bool {
|
||||
(*self).pages == (*other).pages
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Doc_) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Doc_) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -28,15 +18,7 @@ pub enum Doc {
|
||||
}
|
||||
|
||||
impl Doc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Doc) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Doc) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Doc) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Doc) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
@@ -46,25 +28,6 @@ pub enum Page {
|
||||
}
|
||||
|
||||
impl Page : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Page) -> bool {
|
||||
match self {
|
||||
CratePage(e0a) => {
|
||||
match (*other) {
|
||||
CratePage(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ItemPage(e0a) => {
|
||||
match (*other) {
|
||||
ItemPage(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Page) -> bool {
|
||||
match (*self) {
|
||||
CratePage(e0a) => {
|
||||
@@ -81,10 +44,6 @@ impl Page : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Page) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Page) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -94,19 +53,9 @@ pub enum Implementation {
|
||||
}
|
||||
|
||||
impl Implementation : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Implementation) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Implementation) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Implementation) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Implementation) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -121,19 +70,9 @@ impl Implementation : cmp::Eq {
|
||||
};
|
||||
|
||||
impl Section : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Section) -> bool {
|
||||
self.header == (*other).header && self.body == (*other).body
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Section) -> bool {
|
||||
(*self).header == (*other).header && (*self).body == (*other).body
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Section) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Section) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -145,19 +84,9 @@ impl Section : cmp::Eq {
|
||||
};
|
||||
|
||||
impl CrateDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &CrateDoc) -> bool {
|
||||
self.topmod == (*other).topmod
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &CrateDoc) -> bool {
|
||||
(*self).topmod == (*other).topmod
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &CrateDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &CrateDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -174,67 +103,6 @@ pub enum ItemTag {
|
||||
}
|
||||
|
||||
impl ItemTag : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ItemTag) -> bool {
|
||||
match self {
|
||||
ModTag(e0a) => {
|
||||
match (*other) {
|
||||
ModTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
NmodTag(e0a) => {
|
||||
match (*other) {
|
||||
NmodTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ConstTag(e0a) => {
|
||||
match (*other) {
|
||||
ConstTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
FnTag(e0a) => {
|
||||
match (*other) {
|
||||
FnTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
EnumTag(e0a) => {
|
||||
match (*other) {
|
||||
EnumTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
TraitTag(e0a) => {
|
||||
match (*other) {
|
||||
TraitTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ImplTag(e0a) => {
|
||||
match (*other) {
|
||||
ImplTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
TyTag(e0a) => {
|
||||
match (*other) {
|
||||
TyTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
StructTag(e0a) => {
|
||||
match (*other) {
|
||||
StructTag(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ItemTag) -> bool {
|
||||
match (*self) {
|
||||
ModTag(e0a) => {
|
||||
@@ -293,10 +161,6 @@ impl ItemTag : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ItemTag) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ItemTag) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -312,18 +176,6 @@ impl ItemTag : cmp::Eq {
|
||||
};
|
||||
|
||||
impl ItemDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ItemDoc) -> bool {
|
||||
self.id == (*other).id &&
|
||||
self.name == (*other).name &&
|
||||
self.path == (*other).path &&
|
||||
self.brief == (*other).brief &&
|
||||
self.desc == (*other).desc &&
|
||||
self.sections == (*other).sections &&
|
||||
self.reexport == (*other).reexport
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ItemDoc) -> bool {
|
||||
(*self).id == (*other).id &&
|
||||
(*self).name == (*other).name &&
|
||||
@@ -333,10 +185,6 @@ impl ItemDoc : cmp::Eq {
|
||||
(*self).sections == (*other).sections &&
|
||||
(*self).reexport == (*other).reexport
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ItemDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ItemDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -346,19 +194,9 @@ impl ItemDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl SimpleItemDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &SimpleItemDoc) -> bool {
|
||||
self.item == (*other).item && self.sig == (*other).sig
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &SimpleItemDoc) -> bool {
|
||||
(*self).item == (*other).item && (*self).sig == (*other).sig
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &SimpleItemDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &SimpleItemDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -369,23 +207,11 @@ impl SimpleItemDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl ModDoc_ : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ModDoc_) -> bool {
|
||||
self.item == (*other).item &&
|
||||
self.items == (*other).items &&
|
||||
self.index == (*other).index
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ModDoc_) -> bool {
|
||||
(*self).item == (*other).item &&
|
||||
(*self).items == (*other).items &&
|
||||
(*self).index == (*other).index
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ModDoc_) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ModDoc_) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -394,15 +220,7 @@ pub enum ModDoc {
|
||||
}
|
||||
|
||||
impl ModDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ModDoc) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ModDoc) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ModDoc) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ModDoc) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
@@ -413,23 +231,11 @@ impl ModDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl NmodDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &NmodDoc) -> bool {
|
||||
self.item == (*other).item &&
|
||||
self.fns == (*other).fns &&
|
||||
self.index == (*other).index
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &NmodDoc) -> bool {
|
||||
(*self).item == (*other).item &&
|
||||
(*self).fns == (*other).fns &&
|
||||
(*self).index == (*other).index
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &NmodDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &NmodDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -443,19 +249,9 @@ impl NmodDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl EnumDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &EnumDoc) -> bool {
|
||||
self.item == (*other).item && self.variants == (*other).variants
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &EnumDoc) -> bool {
|
||||
(*self).item == (*other).item && (*self).variants == (*other).variants
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &EnumDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &EnumDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -466,23 +262,11 @@ impl EnumDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl VariantDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &VariantDoc) -> bool {
|
||||
self.name == (*other).name &&
|
||||
self.desc == (*other).desc &&
|
||||
self.sig == (*other).sig
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &VariantDoc) -> bool {
|
||||
(*self).name == (*other).name &&
|
||||
(*self).desc == (*other).desc &&
|
||||
(*self).sig == (*other).sig
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &VariantDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &VariantDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -492,19 +276,9 @@ impl VariantDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl TraitDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &TraitDoc) -> bool {
|
||||
self.item == (*other).item && self.methods == (*other).methods
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &TraitDoc) -> bool {
|
||||
(*self).item == (*other).item && (*self).methods == (*other).methods
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &TraitDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &TraitDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -518,17 +292,6 @@ impl TraitDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl MethodDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &MethodDoc) -> bool {
|
||||
self.name == (*other).name &&
|
||||
self.brief == (*other).brief &&
|
||||
self.desc == (*other).desc &&
|
||||
self.sections == (*other).sections &&
|
||||
self.sig == (*other).sig &&
|
||||
self.implementation == (*other).implementation
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &MethodDoc) -> bool {
|
||||
(*self).name == (*other).name &&
|
||||
(*self).brief == (*other).brief &&
|
||||
@@ -537,10 +300,6 @@ impl MethodDoc : cmp::Eq {
|
||||
(*self).sig == (*other).sig &&
|
||||
(*self).implementation == (*other).implementation
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &MethodDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &MethodDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -552,25 +311,12 @@ impl MethodDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl ImplDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ImplDoc) -> bool {
|
||||
self.item == (*other).item &&
|
||||
self.trait_types == (*other).trait_types &&
|
||||
self.self_ty == (*other).self_ty &&
|
||||
self.methods == (*other).methods
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ImplDoc) -> bool {
|
||||
(*self).item == (*other).item &&
|
||||
(*self).trait_types == (*other).trait_types &&
|
||||
(*self).self_ty == (*other).self_ty &&
|
||||
(*self).methods == (*other).methods
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ImplDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ImplDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -583,23 +329,11 @@ impl ImplDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl StructDoc : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &StructDoc) -> bool {
|
||||
return self.item == other.item
|
||||
&& self.fields == other.fields
|
||||
&& self.sig == other.sig;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &StructDoc) -> bool {
|
||||
return (*self).item == other.item
|
||||
&& (*self).fields == other.fields
|
||||
&& (*self).sig == other.sig;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &StructDoc) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &StructDoc) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -608,19 +342,9 @@ impl StructDoc : cmp::Eq {
|
||||
};
|
||||
|
||||
impl Index : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Index) -> bool {
|
||||
self.entries == (*other).entries
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Index) -> bool {
|
||||
(*self).entries == (*other).entries
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Index) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Index) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -642,25 +366,12 @@ impl Index : cmp::Eq {
|
||||
};
|
||||
|
||||
impl IndexEntry : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &IndexEntry) -> bool {
|
||||
self.kind == (*other).kind &&
|
||||
self.name == (*other).name &&
|
||||
self.brief == (*other).brief &&
|
||||
self.link == (*other).link
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &IndexEntry) -> bool {
|
||||
(*self).kind == (*other).kind &&
|
||||
(*self).name == (*other).name &&
|
||||
(*self).brief == (*other).brief &&
|
||||
(*self).link == (*other).link
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &IndexEntry) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &IndexEntry) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -52,4 +52,96 @@ mod page_pass;
|
||||
mod sectionalize_pass;
|
||||
mod escape_pass;
|
||||
mod prune_private_pass;
|
||||
mod util;
|
||||
mod util;
|
||||
|
||||
use doc::ItemUtils;
|
||||
use doc::Item;
|
||||
use pass::Pass;
|
||||
use config::Config;
|
||||
|
||||
fn main() {
|
||||
let args = os::args();
|
||||
|
||||
if args.contains(&~"-h") || args.contains(&~"--help") {
|
||||
config::usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let config = match config::parse_config(args) {
|
||||
Ok(config) => config,
|
||||
Err(err) => {
|
||||
io::println(fmt!("error: %s", err));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
run(config);
|
||||
}
|
||||
|
||||
/// Runs rustdoc over the given file
|
||||
fn run(config: Config) {
|
||||
|
||||
let source_file = config.input_crate;
|
||||
|
||||
// Create an AST service from the source code
|
||||
do astsrv::from_file(source_file.to_str()) |srv| {
|
||||
|
||||
// Just time how long it takes for the AST to become available
|
||||
do time(~"wait_ast") {
|
||||
do astsrv::exec(srv) |_ctxt| { }
|
||||
};
|
||||
|
||||
// Extract the initial doc tree from the AST. This contains
|
||||
// just names and node ids.
|
||||
let doc = time(~"extract", || {
|
||||
let default_name = source_file;
|
||||
extract::from_srv(srv, default_name.to_str())
|
||||
});
|
||||
|
||||
// Refine and publish the document
|
||||
pass::run_passes(srv, doc, ~[
|
||||
// Generate type and signature strings
|
||||
tystr_pass::mk_pass(),
|
||||
// Record the full paths to various nodes
|
||||
path_pass::mk_pass(),
|
||||
// Extract the docs attributes and attach them to doc nodes
|
||||
attr_pass::mk_pass(),
|
||||
// Perform various text escaping
|
||||
escape_pass::mk_pass(),
|
||||
// Remove things marked doc(hidden)
|
||||
prune_hidden_pass::mk_pass(),
|
||||
// Remove things that are private
|
||||
// XXX enable this after 'export' is removed in favor of 'pub'
|
||||
// prune_private_pass::mk_pass(),
|
||||
// Extract brief documentation from the full descriptions
|
||||
desc_to_brief_pass::mk_pass(),
|
||||
// Massage the text to remove extra indentation
|
||||
unindent_pass::mk_pass(),
|
||||
// Split text into multiple sections according to headers
|
||||
sectionalize_pass::mk_pass(),
|
||||
// Trim extra spaces from text
|
||||
trim_pass::mk_pass(),
|
||||
// Sort items by name
|
||||
sort_item_name_pass::mk_pass(),
|
||||
// Sort items again by kind
|
||||
sort_item_type_pass::mk_pass(),
|
||||
// Create indexes appropriate for markdown
|
||||
markdown_index_pass::mk_pass(config),
|
||||
// Break the document into pages if required by the
|
||||
// output format
|
||||
page_pass::mk_pass(config.output_style),
|
||||
// Render
|
||||
markdown_pass::mk_pass(
|
||||
markdown_writer::make_writer_factory(config)
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
fn time<T>(what: ~str, f: fn() -> T) -> T {
|
||||
let start = std::time::precise_time_s();
|
||||
let rv = f();
|
||||
let end = std::time::precise_time_s();
|
||||
info!("time: %3.3f s %s", end - start, what);
|
||||
move rv
|
||||
}
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
use doc::ItemUtils;
|
||||
use doc::Item;
|
||||
use pass::Pass;
|
||||
use config::Config;
|
||||
|
||||
fn main() {
|
||||
let args = os::args();
|
||||
|
||||
if args.contains(&~"-h") || args.contains(&~"--help") {
|
||||
config::usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let config = match config::parse_config(args) {
|
||||
Ok(config) => config,
|
||||
Err(err) => {
|
||||
io::println(fmt!("error: %s", err));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
run(config);
|
||||
}
|
||||
|
||||
/// Runs rustdoc over the given file
|
||||
fn run(config: Config) {
|
||||
|
||||
let source_file = config.input_crate;
|
||||
|
||||
// Create an AST service from the source code
|
||||
do astsrv::from_file(source_file.to_str()) |srv| {
|
||||
|
||||
// Just time how long it takes for the AST to become available
|
||||
do time(~"wait_ast") {
|
||||
do astsrv::exec(srv) |_ctxt| { }
|
||||
};
|
||||
|
||||
// Extract the initial doc tree from the AST. This contains
|
||||
// just names and node ids.
|
||||
let doc = time(~"extract", || {
|
||||
let default_name = source_file;
|
||||
extract::from_srv(srv, default_name.to_str())
|
||||
});
|
||||
|
||||
// Refine and publish the document
|
||||
pass::run_passes(srv, doc, ~[
|
||||
// Generate type and signature strings
|
||||
tystr_pass::mk_pass(),
|
||||
// Record the full paths to various nodes
|
||||
path_pass::mk_pass(),
|
||||
// Extract the docs attributes and attach them to doc nodes
|
||||
attr_pass::mk_pass(),
|
||||
// Perform various text escaping
|
||||
escape_pass::mk_pass(),
|
||||
// Remove things marked doc(hidden)
|
||||
prune_hidden_pass::mk_pass(),
|
||||
// Remove things that are private
|
||||
// XXX enable this after 'export' is removed in favor of 'pub'
|
||||
// prune_private_pass::mk_pass(),
|
||||
// Extract brief documentation from the full descriptions
|
||||
desc_to_brief_pass::mk_pass(),
|
||||
// Massage the text to remove extra indentation
|
||||
unindent_pass::mk_pass(),
|
||||
// Split text into multiple sections according to headers
|
||||
sectionalize_pass::mk_pass(),
|
||||
// Trim extra spaces from text
|
||||
trim_pass::mk_pass(),
|
||||
// Sort items by name
|
||||
sort_item_name_pass::mk_pass(),
|
||||
// Sort items again by kind
|
||||
sort_item_type_pass::mk_pass(),
|
||||
// Create indexes appropriate for markdown
|
||||
markdown_index_pass::mk_pass(config),
|
||||
// Break the document into pages if required by the
|
||||
// output format
|
||||
page_pass::mk_pass(config.output_style),
|
||||
// Render
|
||||
markdown_pass::mk_pass(
|
||||
markdown_writer::make_writer_factory(config)
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
fn time<T>(what: ~str, f: fn() -> T) -> T {
|
||||
let start = std::time::precise_time_s();
|
||||
let rv = f();
|
||||
let end = std::time::precise_time_s();
|
||||
info!("time: %3.3f s %s", end - start, what);
|
||||
move rv
|
||||
}
|
||||
@@ -31,3 +31,385 @@ use syntax::ast_util::*;
|
||||
use parse::token;
|
||||
use print::{pp, pprust};
|
||||
use std::rl;
|
||||
|
||||
/**
|
||||
* A structure shared across REPL instances for storing history
|
||||
* such as statements and view items. I wish the AST was sendable.
|
||||
*/
|
||||
struct Repl {
|
||||
prompt: ~str,
|
||||
binary: ~str,
|
||||
running: bool,
|
||||
view_items: ~str,
|
||||
stmts: ~str
|
||||
}
|
||||
|
||||
// Action to do after reading a :command
|
||||
enum CmdAction {
|
||||
action_none,
|
||||
action_run_line(~str),
|
||||
}
|
||||
|
||||
/// A utility function that hands off a pretty printer to a callback.
|
||||
fn with_pp(intr: @token::ident_interner,
|
||||
cb: fn(pprust::ps, io::Writer)) -> ~str {
|
||||
do io::with_str_writer |writer| {
|
||||
let pp = pprust::rust_printer(writer, intr);
|
||||
|
||||
cb(pp, writer);
|
||||
pp::eof(pp.s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The AST (or the rest of rustc) are not sendable yet,
|
||||
* so recorded things are printed to strings. A terrible hack that
|
||||
* needs changes to rustc in order to be outed. This is unfortunately
|
||||
* going to cause the REPL to regress in parser performance,
|
||||
* because it has to parse the statements and view_items on each
|
||||
* input.
|
||||
*/
|
||||
fn record(repl: Repl, blk: @ast::blk, intr: @token::ident_interner) -> Repl {
|
||||
let view_items = if blk.node.view_items.len() > 0 {
|
||||
let new_view_items = do with_pp(intr) |pp, writer| {
|
||||
for blk.node.view_items.each |view_item| {
|
||||
pprust::print_view_item(pp, *view_item);
|
||||
writer.write_line(~"");
|
||||
}
|
||||
};
|
||||
|
||||
debug!("new view items %s", new_view_items);
|
||||
|
||||
repl.view_items + "\n" + new_view_items
|
||||
} else { repl.view_items };
|
||||
let stmts = if blk.node.stmts.len() > 0 {
|
||||
let new_stmts = do with_pp(intr) |pp, writer| {
|
||||
for blk.node.stmts.each |stmt| {
|
||||
match stmt.node {
|
||||
ast::stmt_decl(*) => {
|
||||
pprust::print_stmt(pp, **stmt);
|
||||
writer.write_line(~"");
|
||||
}
|
||||
ast::stmt_expr(expr, _) | ast::stmt_semi(expr, _) => {
|
||||
match expr.node {
|
||||
ast::expr_assign(*) |
|
||||
ast::expr_assign_op(*) |
|
||||
ast::expr_swap(*) => {
|
||||
pprust::print_stmt(pp, **stmt);
|
||||
writer.write_line(~"");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
debug!("new stmts %s", new_stmts);
|
||||
|
||||
repl.stmts + "\n" + new_stmts
|
||||
} else { repl.stmts };
|
||||
|
||||
Repl{
|
||||
view_items: view_items,
|
||||
stmts: stmts,
|
||||
.. repl
|
||||
}
|
||||
}
|
||||
|
||||
/// Run an input string in a Repl, returning the new Repl.
|
||||
fn run(repl: Repl, input: ~str) -> Repl {
|
||||
let options: @session::options = @{
|
||||
crate_type: session::unknown_crate,
|
||||
binary: repl.binary,
|
||||
addl_lib_search_paths: ~[os::getcwd()],
|
||||
.. *session::basic_options()
|
||||
};
|
||||
|
||||
debug!("building driver input");
|
||||
let head = include_str!("wrapper.rs");
|
||||
let foot = fmt!("%s\nfn main() {\n%s\n\nprint({\n%s\n})\n}",
|
||||
repl.view_items, repl.stmts, input);
|
||||
let wrapped = driver::str_input(head + foot);
|
||||
|
||||
debug!("inputting %s", head + foot);
|
||||
|
||||
debug!("building a driver session");
|
||||
let sess = driver::build_session(options, diagnostic::emit);
|
||||
|
||||
debug!("building driver configuration");
|
||||
let cfg = driver::build_configuration(sess,
|
||||
repl.binary,
|
||||
wrapped);
|
||||
|
||||
debug!("parsing");
|
||||
let mut crate = driver::parse_input(sess, cfg, wrapped);
|
||||
let mut opt = None;
|
||||
|
||||
for crate.node.module.items.each |item| {
|
||||
match item.node {
|
||||
ast::item_fn(_, _, _, blk) => {
|
||||
if item.ident == sess.ident_of(~"main") {
|
||||
opt = blk.node.expr;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let blk = match opt.get().node {
|
||||
ast::expr_call(_, exprs, _) => {
|
||||
match exprs[0].node {
|
||||
ast::expr_block(blk) => @blk,
|
||||
_ => fail
|
||||
}
|
||||
}
|
||||
_ => fail
|
||||
};
|
||||
|
||||
debug!("configuration");
|
||||
crate = front::config::strip_unconfigured_items(crate);
|
||||
|
||||
debug!("maybe building test harness");
|
||||
crate = front::test::modify_for_testing(sess, crate);
|
||||
|
||||
debug!("expansion");
|
||||
crate = syntax::ext::expand::expand_crate(sess.parse_sess,
|
||||
sess.opts.cfg,
|
||||
crate);
|
||||
|
||||
debug!("intrinsic injection");
|
||||
crate = front::intrinsic_inject::inject_intrinsic(sess, crate);
|
||||
|
||||
debug!("core injection");
|
||||
crate = front::core_inject::maybe_inject_libcore_ref(sess, crate);
|
||||
|
||||
debug!("building lint settings table");
|
||||
lint::build_settings_crate(sess, crate);
|
||||
|
||||
debug!("ast indexing");
|
||||
let ast_map = syntax::ast_map::map_crate(sess.diagnostic(), *crate);
|
||||
|
||||
debug!("external crate/lib resolution");
|
||||
creader::read_crates(sess.diagnostic(), *crate, sess.cstore,
|
||||
sess.filesearch,
|
||||
session::sess_os_to_meta_os(sess.targ_cfg.os),
|
||||
sess.opts.static, sess.parse_sess.interner);
|
||||
|
||||
debug!("language item collection");
|
||||
let lang_items = middle::lang_items::collect_language_items(crate, sess);
|
||||
|
||||
debug!("resolution");
|
||||
let {def_map: def_map,
|
||||
exp_map2: exp_map2,
|
||||
trait_map: trait_map} = middle::resolve::resolve_crate(sess,
|
||||
lang_items,
|
||||
crate);
|
||||
|
||||
debug!("freevar finding");
|
||||
let freevars = freevars::annotate_freevars(def_map, crate);
|
||||
|
||||
debug!("region_resolution");
|
||||
let region_map = middle::region::resolve_crate(sess, def_map, crate);
|
||||
|
||||
debug!("region paramaterization inference");
|
||||
let rp_set = middle::region::determine_rp_in_crate(sess, ast_map,
|
||||
def_map, crate);
|
||||
|
||||
debug!("typechecking");
|
||||
let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars,
|
||||
region_map, rp_set, move lang_items, crate);
|
||||
let (method_map, vtable_map) = typeck::check_crate(ty_cx, trait_map,
|
||||
crate);
|
||||
|
||||
debug!("const marking");
|
||||
middle::const_eval::process_crate(crate, def_map, ty_cx);
|
||||
|
||||
debug!("const checking");
|
||||
middle::check_const::check_crate(sess, crate, ast_map, def_map,
|
||||
method_map, ty_cx);
|
||||
|
||||
debug!("privacy checking");
|
||||
middle::privacy::check_crate(ty_cx, &method_map, crate);
|
||||
|
||||
debug!("loop checking");
|
||||
middle::check_loop::check_crate(ty_cx, crate);
|
||||
|
||||
debug!("alt checking");
|
||||
middle::check_alt::check_crate(ty_cx, crate);
|
||||
|
||||
debug!("liveness checking");
|
||||
let last_use_map = middle::liveness::check_crate(ty_cx,
|
||||
method_map, crate);
|
||||
|
||||
debug!("borrow checking");
|
||||
let (root_map, mutbl_map) = middle::borrowck::check_crate(ty_cx,
|
||||
method_map,
|
||||
last_use_map,
|
||||
crate);
|
||||
|
||||
debug!("kind checking");
|
||||
kind::check_crate(ty_cx, method_map, last_use_map, crate);
|
||||
|
||||
debug!("lint checking");
|
||||
lint::check_crate(ty_cx, crate);
|
||||
|
||||
let maps = {mutbl_map: mutbl_map,
|
||||
root_map: root_map,
|
||||
last_use_map: last_use_map,
|
||||
method_map: method_map,
|
||||
vtable_map: vtable_map};
|
||||
|
||||
debug!("translation");
|
||||
let (llmod, _) = trans::base::trans_crate(sess, crate, ty_cx,
|
||||
~path::from_str("<repl>"),
|
||||
exp_map2, maps);
|
||||
let pm = llvm::LLVMCreatePassManager();
|
||||
|
||||
debug!("executing jit");
|
||||
back::link::jit::exec(sess, pm, llmod, 0, false);
|
||||
llvm::LLVMDisposePassManager(pm);
|
||||
|
||||
debug!("recording input into repl history");
|
||||
record(repl, blk, sess.parse_sess.interner)
|
||||
}
|
||||
|
||||
/// Tries to get a line from rl after outputting a prompt. Returns
|
||||
/// None if no input was read (e.g. EOF was reached).
|
||||
fn get_line(prompt: ~str) -> Option<~str> {
|
||||
let result = unsafe { rl::read(prompt) };
|
||||
|
||||
if result.is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let line = result.get();
|
||||
|
||||
unsafe { rl::add_history(line) };
|
||||
|
||||
return Some(line);
|
||||
}
|
||||
|
||||
/// Run a command, e.g. :clear, :exit, etc.
|
||||
fn run_cmd(repl: &mut Repl, _in: io::Reader, _out: io::Writer,
|
||||
cmd: ~str, _args: ~[~str]) -> CmdAction {
|
||||
let mut action = action_none;
|
||||
match cmd {
|
||||
~"exit" => repl.running = false,
|
||||
~"clear" => {
|
||||
repl.view_items = ~"";
|
||||
repl.stmts = ~"";
|
||||
|
||||
// XXX: Win32 version of linenoise can't do this
|
||||
//rl::clear();
|
||||
}
|
||||
~"help" => {
|
||||
io::println(
|
||||
~":{\\n ..lines.. \\n:}\\n - execute multiline command\n" +
|
||||
~":clear - clear the screen\n" +
|
||||
~":exit - exit from the repl\n" +
|
||||
~":help - show this message");
|
||||
}
|
||||
~"{" => {
|
||||
let mut multiline_cmd = ~"";
|
||||
let mut end_multiline = false;
|
||||
while (!end_multiline) {
|
||||
match get_line(~"rusti| ") {
|
||||
None => fail ~"unterminated multiline command :{ .. :}",
|
||||
Some(line) => {
|
||||
if str::trim(line) == ~":}" {
|
||||
end_multiline = true;
|
||||
} else {
|
||||
multiline_cmd += line + ~"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
action = action_run_line(multiline_cmd);
|
||||
}
|
||||
_ => io::println(~"unknown cmd: " + cmd)
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
/// Executes a line of input, which may either be rust code or a
|
||||
/// :command. Returns a new Repl if it has changed.
|
||||
fn run_line(repl: &mut Repl, in: io::Reader, out: io::Writer, line: ~str)
|
||||
-> Option<Repl> {
|
||||
if line.starts_with(~":") {
|
||||
let full = line.substr(1, line.len() - 1);
|
||||
let split = str::words(full);
|
||||
let len = split.len();
|
||||
|
||||
if len > 0 {
|
||||
let cmd = split[0];
|
||||
|
||||
if !cmd.is_empty() {
|
||||
let args = if len > 1 {
|
||||
do vec::view(split, 1, len - 1).map |arg| {
|
||||
*arg
|
||||
}
|
||||
} else { ~[] };
|
||||
|
||||
match run_cmd(repl, in, out, cmd, args) {
|
||||
action_none => { }
|
||||
action_run_line(multiline_cmd) => {
|
||||
if !multiline_cmd.is_empty() {
|
||||
return run_line(repl, in, out, multiline_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let r = *repl;
|
||||
let result = do task::try |copy r| {
|
||||
run(r, line)
|
||||
};
|
||||
|
||||
if result.is_ok() {
|
||||
return Some(result.get());
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let args = os::args();
|
||||
let in = io::stdin();
|
||||
let out = io::stdout();
|
||||
let mut repl = Repl {
|
||||
prompt: ~"rusti> ",
|
||||
binary: args[0],
|
||||
running: true,
|
||||
view_items: ~"",
|
||||
stmts: ~""
|
||||
};
|
||||
|
||||
unsafe {
|
||||
do rl::complete |line, suggest| {
|
||||
if line.starts_with(":") {
|
||||
suggest(~":clear");
|
||||
suggest(~":exit");
|
||||
suggest(~":help");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while repl.running {
|
||||
match get_line(repl.prompt) {
|
||||
None => break,
|
||||
Some(line) => {
|
||||
if line.is_empty() {
|
||||
io::println(~"()");
|
||||
loop;
|
||||
}
|
||||
match run_line(&mut repl, in, out, line) {
|
||||
Some(new_repl) => repl = new_repl,
|
||||
None => { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
/**
|
||||
* A structure shared across REPL instances for storing history
|
||||
* such as statements and view items. I wish the AST was sendable.
|
||||
*/
|
||||
struct Repl {
|
||||
prompt: ~str,
|
||||
binary: ~str,
|
||||
running: bool,
|
||||
view_items: ~str,
|
||||
stmts: ~str
|
||||
}
|
||||
|
||||
// Action to do after reading a :command
|
||||
enum CmdAction {
|
||||
action_none,
|
||||
action_run_line(~str),
|
||||
}
|
||||
|
||||
/// A utility function that hands off a pretty printer to a callback.
|
||||
fn with_pp(intr: @token::ident_interner,
|
||||
cb: fn(pprust::ps, io::Writer)) -> ~str {
|
||||
do io::with_str_writer |writer| {
|
||||
let pp = pprust::rust_printer(writer, intr);
|
||||
|
||||
cb(pp, writer);
|
||||
pp::eof(pp.s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The AST (or the rest of rustc) are not sendable yet,
|
||||
* so recorded things are printed to strings. A terrible hack that
|
||||
* needs changes to rustc in order to be outed. This is unfortunately
|
||||
* going to cause the REPL to regress in parser performance,
|
||||
* because it has to parse the statements and view_items on each
|
||||
* input.
|
||||
*/
|
||||
fn record(repl: Repl, blk: @ast::blk, intr: @token::ident_interner) -> Repl {
|
||||
let view_items = if blk.node.view_items.len() > 0 {
|
||||
let new_view_items = do with_pp(intr) |pp, writer| {
|
||||
for blk.node.view_items.each |view_item| {
|
||||
pprust::print_view_item(pp, *view_item);
|
||||
writer.write_line(~"");
|
||||
}
|
||||
};
|
||||
|
||||
debug!("new view items %s", new_view_items);
|
||||
|
||||
repl.view_items + "\n" + new_view_items
|
||||
} else { repl.view_items };
|
||||
let stmts = if blk.node.stmts.len() > 0 {
|
||||
let new_stmts = do with_pp(intr) |pp, writer| {
|
||||
for blk.node.stmts.each |stmt| {
|
||||
match stmt.node {
|
||||
ast::stmt_decl(*) => {
|
||||
pprust::print_stmt(pp, **stmt);
|
||||
writer.write_line(~"");
|
||||
}
|
||||
ast::stmt_expr(expr, _) | ast::stmt_semi(expr, _) => {
|
||||
match expr.node {
|
||||
ast::expr_assign(*) |
|
||||
ast::expr_assign_op(*) |
|
||||
ast::expr_swap(*) => {
|
||||
pprust::print_stmt(pp, **stmt);
|
||||
writer.write_line(~"");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
debug!("new stmts %s", new_stmts);
|
||||
|
||||
repl.stmts + "\n" + new_stmts
|
||||
} else { repl.stmts };
|
||||
|
||||
Repl{
|
||||
view_items: view_items,
|
||||
stmts: stmts,
|
||||
.. repl
|
||||
}
|
||||
}
|
||||
|
||||
/// Run an input string in a Repl, returning the new Repl.
|
||||
fn run(repl: Repl, input: ~str) -> Repl {
|
||||
let options: @session::options = @{
|
||||
crate_type: session::unknown_crate,
|
||||
binary: repl.binary,
|
||||
addl_lib_search_paths: ~[os::getcwd()],
|
||||
.. *session::basic_options()
|
||||
};
|
||||
|
||||
debug!("building driver input");
|
||||
let head = include_str!("wrapper.rs");
|
||||
let foot = fmt!("%s\nfn main() {\n%s\n\nprint({\n%s\n})\n}",
|
||||
repl.view_items, repl.stmts, input);
|
||||
let wrapped = driver::str_input(head + foot);
|
||||
|
||||
debug!("inputting %s", head + foot);
|
||||
|
||||
debug!("building a driver session");
|
||||
let sess = driver::build_session(options, diagnostic::emit);
|
||||
|
||||
debug!("building driver configuration");
|
||||
let cfg = driver::build_configuration(sess,
|
||||
repl.binary,
|
||||
wrapped);
|
||||
|
||||
debug!("parsing");
|
||||
let mut crate = driver::parse_input(sess, cfg, wrapped);
|
||||
let mut opt = None;
|
||||
|
||||
for crate.node.module.items.each |item| {
|
||||
match item.node {
|
||||
ast::item_fn(_, _, _, blk) => {
|
||||
if item.ident == sess.ident_of(~"main") {
|
||||
opt = blk.node.expr;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let blk = match opt.get().node {
|
||||
ast::expr_call(_, exprs, _) => {
|
||||
match exprs[0].node {
|
||||
ast::expr_block(blk) => @blk,
|
||||
_ => fail
|
||||
}
|
||||
}
|
||||
_ => fail
|
||||
};
|
||||
|
||||
debug!("configuration");
|
||||
crate = front::config::strip_unconfigured_items(crate);
|
||||
|
||||
debug!("maybe building test harness");
|
||||
crate = front::test::modify_for_testing(sess, crate);
|
||||
|
||||
debug!("expansion");
|
||||
crate = syntax::ext::expand::expand_crate(sess.parse_sess,
|
||||
sess.opts.cfg,
|
||||
crate);
|
||||
|
||||
debug!("intrinsic injection");
|
||||
crate = front::intrinsic_inject::inject_intrinsic(sess, crate);
|
||||
|
||||
debug!("core injection");
|
||||
crate = front::core_inject::maybe_inject_libcore_ref(sess, crate);
|
||||
|
||||
debug!("building lint settings table");
|
||||
lint::build_settings_crate(sess, crate);
|
||||
|
||||
debug!("ast indexing");
|
||||
let ast_map = syntax::ast_map::map_crate(sess.diagnostic(), *crate);
|
||||
|
||||
debug!("external crate/lib resolution");
|
||||
creader::read_crates(sess.diagnostic(), *crate, sess.cstore,
|
||||
sess.filesearch,
|
||||
session::sess_os_to_meta_os(sess.targ_cfg.os),
|
||||
sess.opts.static, sess.parse_sess.interner);
|
||||
|
||||
debug!("language item collection");
|
||||
let lang_items = middle::lang_items::collect_language_items(crate, sess);
|
||||
|
||||
debug!("resolution");
|
||||
let {def_map: def_map,
|
||||
exp_map2: exp_map2,
|
||||
trait_map: trait_map} = middle::resolve::resolve_crate(sess,
|
||||
lang_items,
|
||||
crate);
|
||||
|
||||
debug!("freevar finding");
|
||||
let freevars = freevars::annotate_freevars(def_map, crate);
|
||||
|
||||
debug!("region_resolution");
|
||||
let region_map = middle::region::resolve_crate(sess, def_map, crate);
|
||||
|
||||
debug!("region paramaterization inference");
|
||||
let rp_set = middle::region::determine_rp_in_crate(sess, ast_map,
|
||||
def_map, crate);
|
||||
|
||||
debug!("typechecking");
|
||||
let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars,
|
||||
region_map, rp_set, move lang_items, crate);
|
||||
let (method_map, vtable_map) = typeck::check_crate(ty_cx, trait_map,
|
||||
crate);
|
||||
|
||||
debug!("const marking");
|
||||
middle::const_eval::process_crate(crate, def_map, ty_cx);
|
||||
|
||||
debug!("const checking");
|
||||
middle::check_const::check_crate(sess, crate, ast_map, def_map,
|
||||
method_map, ty_cx);
|
||||
|
||||
debug!("privacy checking");
|
||||
middle::privacy::check_crate(ty_cx, &method_map, crate);
|
||||
|
||||
debug!("loop checking");
|
||||
middle::check_loop::check_crate(ty_cx, crate);
|
||||
|
||||
debug!("alt checking");
|
||||
middle::check_alt::check_crate(ty_cx, crate);
|
||||
|
||||
debug!("liveness checking");
|
||||
let last_use_map = middle::liveness::check_crate(ty_cx,
|
||||
method_map, crate);
|
||||
|
||||
debug!("borrow checking");
|
||||
let (root_map, mutbl_map) = middle::borrowck::check_crate(ty_cx,
|
||||
method_map,
|
||||
last_use_map,
|
||||
crate);
|
||||
|
||||
debug!("kind checking");
|
||||
kind::check_crate(ty_cx, method_map, last_use_map, crate);
|
||||
|
||||
debug!("lint checking");
|
||||
lint::check_crate(ty_cx, crate);
|
||||
|
||||
let maps = {mutbl_map: mutbl_map,
|
||||
root_map: root_map,
|
||||
last_use_map: last_use_map,
|
||||
method_map: method_map,
|
||||
vtable_map: vtable_map};
|
||||
|
||||
debug!("translation");
|
||||
let (llmod, _) = trans::base::trans_crate(sess, crate, ty_cx,
|
||||
~path::from_str("<repl>"),
|
||||
exp_map2, maps);
|
||||
let pm = llvm::LLVMCreatePassManager();
|
||||
|
||||
debug!("executing jit");
|
||||
back::link::jit::exec(sess, pm, llmod, 0, false);
|
||||
llvm::LLVMDisposePassManager(pm);
|
||||
|
||||
debug!("recording input into repl history");
|
||||
record(repl, blk, sess.parse_sess.interner)
|
||||
}
|
||||
|
||||
/// Tries to get a line from rl after outputting a prompt. Returns
|
||||
/// None if no input was read (e.g. EOF was reached).
|
||||
fn get_line(prompt: ~str) -> Option<~str> {
|
||||
let result = unsafe { rl::read(prompt) };
|
||||
|
||||
if result.is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let line = result.get();
|
||||
|
||||
unsafe { rl::add_history(line) };
|
||||
|
||||
return Some(line);
|
||||
}
|
||||
|
||||
/// Run a command, e.g. :clear, :exit, etc.
|
||||
fn run_cmd(repl: &mut Repl, _in: io::Reader, _out: io::Writer,
|
||||
cmd: ~str, _args: ~[~str]) -> CmdAction {
|
||||
let mut action = action_none;
|
||||
match cmd {
|
||||
~"exit" => repl.running = false,
|
||||
~"clear" => {
|
||||
repl.view_items = ~"";
|
||||
repl.stmts = ~"";
|
||||
|
||||
// XXX: Win32 version of linenoise can't do this
|
||||
//rl::clear();
|
||||
}
|
||||
~"help" => {
|
||||
io::println(
|
||||
~":{\\n ..lines.. \\n:}\\n - execute multiline command\n" +
|
||||
~":clear - clear the screen\n" +
|
||||
~":exit - exit from the repl\n" +
|
||||
~":help - show this message");
|
||||
}
|
||||
~"{" => {
|
||||
let mut multiline_cmd = ~"";
|
||||
let mut end_multiline = false;
|
||||
while (!end_multiline) {
|
||||
match get_line(~"rusti| ") {
|
||||
None => fail ~"unterminated multiline command :{ .. :}",
|
||||
Some(line) => {
|
||||
if str::trim(line) == ~":}" {
|
||||
end_multiline = true;
|
||||
} else {
|
||||
multiline_cmd += line + ~"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
action = action_run_line(multiline_cmd);
|
||||
}
|
||||
_ => io::println(~"unknown cmd: " + cmd)
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
/// Executes a line of input, which may either be rust code or a
|
||||
/// :command. Returns a new Repl if it has changed.
|
||||
fn run_line(repl: &mut Repl, in: io::Reader, out: io::Writer, line: ~str)
|
||||
-> Option<Repl> {
|
||||
if line.starts_with(~":") {
|
||||
let full = line.substr(1, line.len() - 1);
|
||||
let split = str::words(full);
|
||||
let len = split.len();
|
||||
|
||||
if len > 0 {
|
||||
let cmd = split[0];
|
||||
|
||||
if !cmd.is_empty() {
|
||||
let args = if len > 1 {
|
||||
do vec::view(split, 1, len - 1).map |arg| {
|
||||
*arg
|
||||
}
|
||||
} else { ~[] };
|
||||
|
||||
match run_cmd(repl, in, out, cmd, args) {
|
||||
action_none => { }
|
||||
action_run_line(multiline_cmd) => {
|
||||
if !multiline_cmd.is_empty() {
|
||||
return run_line(repl, in, out, multiline_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let r = *repl;
|
||||
let result = do task::try |copy r| {
|
||||
run(r, line)
|
||||
};
|
||||
|
||||
if result.is_ok() {
|
||||
return Some(result.get());
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let args = os::args();
|
||||
let in = io::stdin();
|
||||
let out = io::stdout();
|
||||
let mut repl = Repl {
|
||||
prompt: ~"rusti> ",
|
||||
binary: args[0],
|
||||
running: true,
|
||||
view_items: ~"",
|
||||
stmts: ~""
|
||||
};
|
||||
|
||||
unsafe {
|
||||
do rl::complete |line, suggest| {
|
||||
if line.starts_with(":") {
|
||||
suggest(~":clear");
|
||||
suggest(~":exit");
|
||||
suggest(~":help");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while repl.running {
|
||||
match get_line(repl.prompt) {
|
||||
None => break,
|
||||
Some(line) => {
|
||||
if line.is_empty() {
|
||||
io::println(~"()");
|
||||
loop;
|
||||
}
|
||||
match run_line(&mut repl, in, out, line) {
|
||||
Some(new_repl) => repl = new_repl,
|
||||
None => { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,25 +239,6 @@ enum Taggypar<T> {
|
||||
type RecCy = {x: int, y: int, t: Taggy};
|
||||
|
||||
impl Taggy : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Taggy) -> bool {
|
||||
match self {
|
||||
One(a1) => match (*other) {
|
||||
One(b1) => return a1 == b1,
|
||||
_ => return false
|
||||
},
|
||||
Two(a1, a2) => match (*other) {
|
||||
Two(b1, b2) => return a1 == b1 && a2 == b2,
|
||||
_ => return false
|
||||
},
|
||||
Three(a1, a2, a3) => match (*other) {
|
||||
Three(b1, b2, b3) => return a1 == b1 && a2 == b2 && a3 == b3,
|
||||
_ => return false
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Taggy) -> bool {
|
||||
match (*self) {
|
||||
One(a1) => match (*other) {
|
||||
@@ -274,36 +255,11 @@ impl Taggy : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Taggy) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Taggy) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl Taggypar<int> : Eq {
|
||||
//let eq4: EqFn<Taggypar<int>> = |x,y| taggypareq::<int>(x, y);
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Taggypar<int>) -> bool {
|
||||
match self {
|
||||
Onepar::<int>(a1) => match (*other) {
|
||||
Onepar::<int>(b1) => return a1 == b1,
|
||||
_ => return false
|
||||
},
|
||||
Twopar::<int>(a1, a2) => match (*other) {
|
||||
Twopar::<int>(b1, b2) => return a1 == b1 && a2 == b2,
|
||||
_ => return false
|
||||
},
|
||||
Threepar::<int>(a1, a2, a3) => match (*other) {
|
||||
Threepar::<int>(b1, b2, b3) => {
|
||||
return a1 == b1 && a2 == b2 && a3 == b3
|
||||
}
|
||||
_ => return false
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Taggypar<int>) -> bool {
|
||||
match (*self) {
|
||||
Onepar::<int>(a1) => match (*other) {
|
||||
@@ -322,33 +278,16 @@ impl Taggypar<int> : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Taggypar<int>) -> bool {
|
||||
!self.eq(other)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Taggypar<int>) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl RecCy : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &RecCy) -> bool {
|
||||
return self.x == (*other).x && self.y == (*other).y &&
|
||||
self.t == (*other).t;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &RecCy) -> bool {
|
||||
return (*self).x == (*other).x && (*self).y == (*other).y &&
|
||||
(*self).t == (*other).t;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &RecCy) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &RecCy) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
+3
-139
@@ -88,25 +88,6 @@ fn mkname(nm: &str) -> Name {
|
||||
}
|
||||
|
||||
impl Name : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Name) -> bool {
|
||||
match self {
|
||||
Long(ref e0a) => {
|
||||
match (*other) {
|
||||
Long(ref e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
Short(e0a) => {
|
||||
match (*other) {
|
||||
Short(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Name) -> bool {
|
||||
match (*self) {
|
||||
Long(ref e0a) => {
|
||||
@@ -123,65 +104,29 @@ impl Name : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Name) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Name) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl Occur : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Occur) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Occur) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Occur) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Occur) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl HasArg : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &HasArg) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &HasArg) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &HasArg) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &HasArg) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl Opt : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Opt) -> bool {
|
||||
self.name == (*other).name &&
|
||||
self.hasarg == (*other).hasarg &&
|
||||
self.occur == (*other).occur
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Opt) -> bool {
|
||||
(*self).name == (*other).name &&
|
||||
(*self).hasarg == (*other).hasarg &&
|
||||
(*self).occur == (*other).occur
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Opt) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Opt) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -227,17 +172,6 @@ enum Optval { Val(~str), Given, }
|
||||
pub type Matches = {opts: ~[Opt], vals: ~[~[Optval]], free: ~[~str]};
|
||||
|
||||
impl Optval : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Optval) -> bool {
|
||||
match self {
|
||||
Val(ref s) => match *other { Val (ref os) => s == os,
|
||||
Given => false },
|
||||
Given => match *other { Val(_) => false,
|
||||
Given => true }
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Optval) -> bool {
|
||||
match (*self) {
|
||||
Val(ref s) => match *other { Val (ref os) => s == os,
|
||||
@@ -246,31 +180,15 @@ impl Optval : Eq {
|
||||
Given => true }
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Optval) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Optval) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl Matches : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Matches) -> bool {
|
||||
self.opts == (*other).opts &&
|
||||
self.vals == (*other).vals &&
|
||||
self.free == (*other).free
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Matches) -> bool {
|
||||
(*self).opts == (*other).opts &&
|
||||
(*self).vals == (*other).vals &&
|
||||
(*self).free == (*other).free
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Matches) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Matches) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -303,33 +221,6 @@ pub enum Fail_ {
|
||||
|
||||
impl Fail_ : Eq {
|
||||
// this whole thing should be easy to infer...
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Fail_) -> bool {
|
||||
match self {
|
||||
ArgumentMissing(ref s) => {
|
||||
match *other { ArgumentMissing(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
UnrecognizedOption(ref s) => {
|
||||
match *other { UnrecognizedOption(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
OptionMissing(ref s) => {
|
||||
match *other { OptionMissing(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
OptionDuplicated(ref s) => {
|
||||
match *other { OptionDuplicated(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
UnexpectedArgument(ref s) => {
|
||||
match *other { UnexpectedArgument(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Fail_) -> bool {
|
||||
match (*self) {
|
||||
ArgumentMissing(ref s) => {
|
||||
@@ -354,10 +245,6 @@ impl Fail_ : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Fail_) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Fail_) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -627,19 +514,9 @@ enum FailType {
|
||||
}
|
||||
|
||||
impl FailType : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &FailType) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &FailType) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &FailType) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &FailType) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -661,17 +538,6 @@ pub mod groups {
|
||||
};
|
||||
|
||||
impl OptGroup : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &OptGroup) -> bool {
|
||||
self.short_name == (*other).short_name &&
|
||||
self.long_name == (*other).long_name &&
|
||||
self.hint == (*other).hint &&
|
||||
self.desc == (*other).desc &&
|
||||
self.hasarg == (*other).hasarg &&
|
||||
self.occur == (*other).occur
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &OptGroup) -> bool {
|
||||
(*self).short_name == (*other).short_name &&
|
||||
(*self).long_name == (*other).long_name &&
|
||||
@@ -680,11 +546,9 @@ impl OptGroup : Eq {
|
||||
(*self).hasarg == (*other).hasarg &&
|
||||
(*self).occur == (*other).occur
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &OptGroup) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &OptGroup) -> bool { !(*self).eq(other) }
|
||||
pure fn ne(&self, other: &OptGroup) -> bool {
|
||||
!self.eq(other)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a long option that is required and takes an argument
|
||||
|
||||
@@ -905,44 +905,6 @@ fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
|
||||
}
|
||||
|
||||
impl Json : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Json) -> bool {
|
||||
// XXX: This is ugly because matching on references is broken, and
|
||||
// we can't match on dereferenced tuples without a copy.
|
||||
match self {
|
||||
Number(f0) =>
|
||||
match *other { Number(f1) => f0 == f1, _ => false },
|
||||
String(ref s0) =>
|
||||
match *other { String(ref s1) => s0 == s1, _ => false },
|
||||
Boolean(b0) =>
|
||||
match *other { Boolean(b1) => b0 == b1, _ => false },
|
||||
Null =>
|
||||
match *other { Null => true, _ => false },
|
||||
List(v0) =>
|
||||
match *other { List(v1) => v0 == v1, _ => false },
|
||||
Object(ref d0) => {
|
||||
match *other {
|
||||
Object(ref d1) => {
|
||||
if d0.len() == d1.len() {
|
||||
let mut equal = true;
|
||||
for d0.each |k, v0| {
|
||||
match d1.find_ref(k) {
|
||||
Some(v1) if v0 == v1 => { },
|
||||
_ => { equal = false; break }
|
||||
}
|
||||
};
|
||||
equal
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Json) -> bool {
|
||||
// XXX: This is ugly because matching on references is broken, and
|
||||
// we can't match on dereferenced tuples without a copy.
|
||||
@@ -978,88 +940,11 @@ impl Json : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Json) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Json) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
/// Test if two json values are less than one another
|
||||
impl Json : Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &Json) -> bool {
|
||||
match self {
|
||||
Number(f0) => {
|
||||
match *other {
|
||||
Number(f1) => f0 < f1,
|
||||
String(_) | Boolean(_) | List(_) | Object(_) |
|
||||
Null => true
|
||||
}
|
||||
}
|
||||
|
||||
String(ref s0) => {
|
||||
match *other {
|
||||
Number(_) => false,
|
||||
String(ref s1) => s0 < s1,
|
||||
Boolean(_) | List(_) | Object(_) | Null => true
|
||||
}
|
||||
}
|
||||
|
||||
Boolean(b0) => {
|
||||
match *other {
|
||||
Number(_) | String(_) => false,
|
||||
Boolean(b1) => b0 < b1,
|
||||
List(_) | Object(_) | Null => true
|
||||
}
|
||||
}
|
||||
|
||||
List(l0) => {
|
||||
match *other {
|
||||
Number(_) | String(_) | Boolean(_) => false,
|
||||
List(l1) => l0 < l1,
|
||||
Object(_) | Null => true
|
||||
}
|
||||
}
|
||||
|
||||
Object(ref d0) => {
|
||||
match *other {
|
||||
Number(_) | String(_) | Boolean(_) | List(_) => false,
|
||||
Object(ref d1) => {
|
||||
unsafe {
|
||||
let mut d0_flat = ~[];
|
||||
let mut d1_flat = ~[];
|
||||
|
||||
// XXX: this is horribly inefficient...
|
||||
for d0.each |k, v| {
|
||||
d0_flat.push((@copy *k, @copy *v));
|
||||
}
|
||||
d0_flat.qsort();
|
||||
|
||||
for d1.each |k, v| {
|
||||
d1_flat.push((@copy *k, @copy *v));
|
||||
}
|
||||
d1_flat.qsort();
|
||||
|
||||
d0_flat < d1_flat
|
||||
}
|
||||
}
|
||||
Null => true
|
||||
}
|
||||
}
|
||||
|
||||
Null => {
|
||||
match *other {
|
||||
Number(_) | String(_) | Boolean(_) | List(_) |
|
||||
Object(_) =>
|
||||
false,
|
||||
Null => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &Json) -> bool {
|
||||
match (*self) {
|
||||
Number(f0) => {
|
||||
@@ -1130,41 +1015,17 @@ impl Json : Ord {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &Json) -> bool { !(*other).lt(&self) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &Json) -> bool { !(*other).lt(&(*self)) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &Json) -> bool { !self.lt(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &Json) -> bool { !(*self).lt(other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &Json) -> bool { (*other).lt(&self) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &Json) -> bool { (*other).lt(&(*self)) }
|
||||
}
|
||||
|
||||
impl Error : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Error) -> bool {
|
||||
self.line == other.line &&
|
||||
self.col == other.col &&
|
||||
self.msg == other.msg
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Error) -> bool {
|
||||
(*self).line == other.line &&
|
||||
(*self).col == other.col &&
|
||||
(*self).msg == other.msg
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Error) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Error) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -148,25 +148,6 @@ pub fn each<T>(l: @List<T>, f: fn(&T) -> bool) {
|
||||
}
|
||||
|
||||
impl<T:Eq> List<T> : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &List<T>) -> bool {
|
||||
match self {
|
||||
Cons(ref e0a, e1a) => {
|
||||
match (*other) {
|
||||
Cons(ref e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
Nil => {
|
||||
match (*other) {
|
||||
Nil => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &List<T>) -> bool {
|
||||
match (*self) {
|
||||
Cons(ref e0a, e1a) => {
|
||||
@@ -183,10 +164,6 @@ impl<T:Eq> List<T> : Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &List<T>) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &List<T>) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -315,19 +315,9 @@ pub fn decode_form_urlencoded(s: ~[u8]) ->
|
||||
}
|
||||
|
||||
impl UserInfo : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &UserInfo) -> bool {
|
||||
self.user == (*other).user && self.pass == (*other).pass
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &UserInfo) -> bool {
|
||||
(*self).user == (*other).user && (*self).pass == (*other).pass
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &UserInfo) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &UserInfo) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -389,19 +379,6 @@ enum Input {
|
||||
}
|
||||
|
||||
impl Input : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Input) -> bool {
|
||||
match (self, (*other)) {
|
||||
(Digit, Digit) => true,
|
||||
(Hex, Hex) => true,
|
||||
(Unreserved, Unreserved) => true,
|
||||
(Digit, _) => false,
|
||||
(Hex, _) => false,
|
||||
(Unreserved, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Input) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(Digit, Digit) => true,
|
||||
@@ -412,10 +389,6 @@ impl Input : Eq {
|
||||
(Unreserved, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Input) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Input) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -749,18 +722,6 @@ impl Url: to_str::ToStr {
|
||||
}
|
||||
|
||||
impl Url : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Url) -> bool {
|
||||
self.scheme == (*other).scheme
|
||||
&& self.user == (*other).user
|
||||
&& self.host == (*other).host
|
||||
&& self.port == (*other).port
|
||||
&& self.path == (*other).path
|
||||
&& self.query == (*other).query
|
||||
&& self.fragment == (*other).fragment
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Url) -> bool {
|
||||
(*self).scheme == (*other).scheme
|
||||
&& (*self).user == (*other).user
|
||||
@@ -771,12 +732,6 @@ impl Url : Eq {
|
||||
&& (*self).fragment == (*other).fragment
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Url) -> bool {
|
||||
!self.eq(other)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Url) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
|
||||
@@ -871,16 +871,6 @@ struct CVal {
|
||||
}
|
||||
|
||||
impl CVal: Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &CVal) -> bool {
|
||||
unsafe {
|
||||
let rng = rand::Rng();
|
||||
if rng.gen_float() > 0.995 { fail ~"It's happening!!!"; }
|
||||
}
|
||||
self.val < other.val
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &CVal) -> bool {
|
||||
unsafe {
|
||||
let rng = rand::Rng();
|
||||
@@ -888,20 +878,8 @@ impl CVal: Ord {
|
||||
}
|
||||
(*self).val < other.val
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &CVal) -> bool { self.val <= other.val }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &CVal) -> bool { (*self).val <= other.val }
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &CVal) -> bool { self.val > other.val }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &CVal) -> bool { (*self).val > other.val }
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &CVal) -> bool { self.val >= other.val }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &CVal) -> bool { (*self).val >= other.val }
|
||||
}
|
||||
|
||||
@@ -957,16 +935,6 @@ fn crash_test() {
|
||||
|
||||
struct DVal { val: uint }
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl DVal: Ord {
|
||||
pure fn lt(_x: &DVal) -> bool { true }
|
||||
pure fn le(_x: &DVal) -> bool { true }
|
||||
pure fn gt(_x: &DVal) -> bool { true }
|
||||
pure fn ge(_x: &DVal) -> bool { true }
|
||||
}
|
||||
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
impl DVal: Ord {
|
||||
pure fn lt(&self, _x: &DVal) -> bool { true }
|
||||
pure fn le(&self, _x: &DVal) -> bool { true }
|
||||
@@ -1183,39 +1151,15 @@ fn finalize() {
|
||||
}
|
||||
|
||||
impl LVal: Ord {
|
||||
#[cfg(stage0)]
|
||||
pure fn lt(other: &a/LVal/&self) -> bool {
|
||||
self.val < other.val
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn lt(&self, other: &a/LVal/&self) -> bool {
|
||||
(*self).val < other.val
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn le(other: &a/LVal/&self) -> bool {
|
||||
self.val <= other.val
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn le(&self, other: &a/LVal/&self) -> bool {
|
||||
(*self).val <= other.val
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn gt(other: &a/LVal/&self) -> bool {
|
||||
self.val > other.val
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn gt(&self, other: &a/LVal/&self) -> bool {
|
||||
(*self).val > other.val
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ge(other: &a/LVal/&self) -> bool {
|
||||
self.val >= other.val
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ge(&self, other: &a/LVal/&self) -> bool {
|
||||
(*self).val >= other.val
|
||||
}
|
||||
|
||||
@@ -85,19 +85,9 @@ fn parse_opts(args: &[~str]) -> OptRes {
|
||||
pub enum TestResult { TrOk, TrFailed, TrIgnored, }
|
||||
|
||||
impl TestResult : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &TestResult) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &TestResult) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &TestResult) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &TestResult) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -24,19 +24,9 @@
|
||||
pub type Timespec = {sec: i64, nsec: i32};
|
||||
|
||||
impl Timespec : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Timespec) -> bool {
|
||||
self.sec == (*other).sec && self.nsec == (*other).nsec
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Timespec) -> bool {
|
||||
(*self).sec == (*other).sec && (*self).nsec == (*other).nsec
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Timespec) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Timespec) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -91,23 +81,6 @@ pub fn tzset() {
|
||||
};
|
||||
|
||||
impl Tm_ : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Tm_) -> bool {
|
||||
self.tm_sec == (*other).tm_sec &&
|
||||
self.tm_min == (*other).tm_min &&
|
||||
self.tm_hour == (*other).tm_hour &&
|
||||
self.tm_mday == (*other).tm_mday &&
|
||||
self.tm_mon == (*other).tm_mon &&
|
||||
self.tm_year == (*other).tm_year &&
|
||||
self.tm_wday == (*other).tm_wday &&
|
||||
self.tm_yday == (*other).tm_yday &&
|
||||
self.tm_isdst == (*other).tm_isdst &&
|
||||
self.tm_gmtoff == (*other).tm_gmtoff &&
|
||||
self.tm_zone == (*other).tm_zone &&
|
||||
self.tm_nsec == (*other).tm_nsec
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Tm_) -> bool {
|
||||
(*self).tm_sec == (*other).tm_sec &&
|
||||
(*self).tm_min == (*other).tm_min &&
|
||||
@@ -122,10 +95,6 @@ impl Tm_ : Eq {
|
||||
(*self).tm_zone == (*other).tm_zone &&
|
||||
(*self).tm_nsec == (*other).tm_nsec
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Tm_) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Tm_) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -134,15 +103,7 @@ pub enum Tm {
|
||||
}
|
||||
|
||||
impl Tm : Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Tm) -> bool { *self == *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Tm) -> bool { *(*self) == *(*other) }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Tm) -> bool { *self != *(*other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Tm) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
|
||||
+1
-656
@@ -50,15 +50,7 @@ impl<D: Deserializer> ident: Deserializable<D> {
|
||||
}
|
||||
|
||||
impl ident: cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ident) -> bool { self.repr == other.repr }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ident) -> bool { (*self).repr == other.repr }
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ident) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ident) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -97,19 +89,9 @@ impl ident: to_bytes::IterBytes {
|
||||
type def_id = {crate: crate_num, node: node_id};
|
||||
|
||||
impl def_id : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &def_id) -> bool {
|
||||
self.crate == (*other).crate && self.node == (*other).node
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &def_id) -> bool {
|
||||
(*self).crate == (*other).crate && (*self).node == (*other).node
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &def_id) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &def_id) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -158,129 +140,6 @@ enum def {
|
||||
}
|
||||
|
||||
impl def : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &def) -> bool {
|
||||
match self {
|
||||
def_fn(e0a, e1a) => {
|
||||
match (*other) {
|
||||
def_fn(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_static_method(e0a, e1a, e2a) => {
|
||||
match (*other) {
|
||||
def_static_method(e0b, e1b, e2b) =>
|
||||
e0a == e0b && e1a == e1b && e2a == e2b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_self(e0a) => {
|
||||
match (*other) {
|
||||
def_self(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_mod(e0a) => {
|
||||
match (*other) {
|
||||
def_mod(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_foreign_mod(e0a) => {
|
||||
match (*other) {
|
||||
def_foreign_mod(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_const(e0a) => {
|
||||
match (*other) {
|
||||
def_const(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_arg(e0a, e1a) => {
|
||||
match (*other) {
|
||||
def_arg(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_local(e0a, e1a) => {
|
||||
match (*other) {
|
||||
def_local(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_variant(e0a, e1a) => {
|
||||
match (*other) {
|
||||
def_variant(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_ty(e0a) => {
|
||||
match (*other) {
|
||||
def_ty(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_prim_ty(e0a) => {
|
||||
match (*other) {
|
||||
def_prim_ty(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_ty_param(e0a, e1a) => {
|
||||
match (*other) {
|
||||
def_ty_param(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_binding(e0a, e1a) => {
|
||||
match (*other) {
|
||||
def_binding(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_use(e0a) => {
|
||||
match (*other) {
|
||||
def_use(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_upvar(e0a, e1a, e2a, e3a) => {
|
||||
match (*other) {
|
||||
def_upvar(e0b, e1b, e2b, e3b) =>
|
||||
e0a == e0b && e1a == e1b && e2a == e2b && e3a == e3b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_class(e0a) => {
|
||||
match (*other) {
|
||||
def_class(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_typaram_binder(e0a) => {
|
||||
match (*other) {
|
||||
def_typaram_binder(e1a) => e0a == e1a,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_region(e0a) => {
|
||||
match (*other) {
|
||||
def_region(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
def_label(e0a) => {
|
||||
match (*other) {
|
||||
def_label(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &def) -> bool {
|
||||
match (*self) {
|
||||
def_fn(e0a, e1a) => {
|
||||
@@ -401,10 +260,6 @@ impl def : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &def) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &def) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -415,25 +270,10 @@ impl def : cmp::Eq {
|
||||
type crate = spanned<crate_>;
|
||||
|
||||
type crate_ =
|
||||
{directives: ~[@crate_directive],
|
||||
module: _mod,
|
||||
{module: _mod,
|
||||
attrs: ~[attribute],
|
||||
config: crate_cfg};
|
||||
|
||||
enum crate_directive_ {
|
||||
cdir_src_mod(visibility, ident, ~[attribute]),
|
||||
cdir_dir_mod(visibility, ident, ~[@crate_directive], ~[attribute]),
|
||||
|
||||
// NB: cdir_view_item is *not* processed by the rest of the compiler, the
|
||||
// attached view_items are sunk into the crate's module during parsing,
|
||||
// and processed (resolved, imported, etc.) there. This enum-variant
|
||||
// exists only to preserve the view items in order in case we decide to
|
||||
// pretty-print crates in the future.
|
||||
cdir_view_item(@view_item),
|
||||
}
|
||||
|
||||
type crate_directive = spanned<crate_directive_>;
|
||||
|
||||
type meta_item = spanned<meta_item_>;
|
||||
|
||||
#[auto_serialize]
|
||||
@@ -507,37 +347,6 @@ impl binding_mode : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl binding_mode : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &binding_mode) -> bool {
|
||||
match self {
|
||||
bind_by_value => {
|
||||
match (*other) {
|
||||
bind_by_value => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
bind_by_move => {
|
||||
match (*other) {
|
||||
bind_by_move => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
bind_by_ref(e0a) => {
|
||||
match (*other) {
|
||||
bind_by_ref(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
bind_by_implicit_ref => {
|
||||
match (*other) {
|
||||
bind_by_implicit_ref => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &binding_mode) -> bool {
|
||||
match (*self) {
|
||||
bind_by_value => {
|
||||
@@ -566,10 +375,6 @@ impl binding_mode : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &binding_mode) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &binding_mode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -617,19 +422,9 @@ impl mutability : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl mutability : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &mutability) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &mutability) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &mutability) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &mutability) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -643,19 +438,9 @@ pub enum Proto {
|
||||
}
|
||||
|
||||
impl Proto : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Proto) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Proto) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Proto) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Proto) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -726,19 +511,9 @@ enum binop {
|
||||
}
|
||||
|
||||
impl binop : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &binop) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &binop) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &binop) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &binop) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -753,43 +528,6 @@ enum unop {
|
||||
}
|
||||
|
||||
impl unop : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &unop) -> bool {
|
||||
match self {
|
||||
box(e0a) => {
|
||||
match (*other) {
|
||||
box(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
uniq(e0a) => {
|
||||
match (*other) {
|
||||
uniq(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
deref => {
|
||||
match (*other) {
|
||||
deref => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
not => {
|
||||
match (*other) {
|
||||
not => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
neg => {
|
||||
match (*other) {
|
||||
neg => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &unop) -> bool {
|
||||
match (*self) {
|
||||
box(e0a) => {
|
||||
@@ -824,12 +562,6 @@ impl unop : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &unop) -> bool {
|
||||
!self.eq(other)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &unop) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
@@ -872,25 +604,6 @@ impl<T: to_bytes::IterBytes> inferable<T> : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl<T:cmp::Eq> inferable<T> : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &inferable<T>) -> bool {
|
||||
match self {
|
||||
expl(e0a) => {
|
||||
match (*other) {
|
||||
expl(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
infer(e0a) => {
|
||||
match (*other) {
|
||||
infer(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &inferable<T>) -> bool {
|
||||
match (*self) {
|
||||
expl(e0a) => {
|
||||
@@ -907,10 +620,6 @@ impl<T:cmp::Eq> inferable<T> : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &inferable<T>) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &inferable<T>) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -935,19 +644,9 @@ impl rmode : to_bytes::IterBytes {
|
||||
|
||||
|
||||
impl rmode : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &rmode) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &rmode) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &rmode) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &rmode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -998,17 +697,6 @@ enum decl_ { decl_local(~[@local]), decl_item(@item), }
|
||||
enum blk_check_mode { default_blk, unsafe_blk, }
|
||||
|
||||
impl blk_check_mode : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &blk_check_mode) -> bool {
|
||||
match (self, (*other)) {
|
||||
(default_blk, default_blk) => true,
|
||||
(unsafe_blk, unsafe_blk) => true,
|
||||
(default_blk, _) => false,
|
||||
(unsafe_blk, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &blk_check_mode) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(default_blk, default_blk) => true,
|
||||
@@ -1017,10 +705,6 @@ impl blk_check_mode : cmp::Eq {
|
||||
(unsafe_blk, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &blk_check_mode) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &blk_check_mode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1237,35 +921,6 @@ enum lit_ {
|
||||
}
|
||||
|
||||
impl ast::lit_: cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ast::lit_) -> bool {
|
||||
match (self, *other) {
|
||||
(lit_str(a), lit_str(b)) => a == b,
|
||||
(lit_int(val_a, ty_a), lit_int(val_b, ty_b)) => {
|
||||
val_a == val_b && ty_a == ty_b
|
||||
}
|
||||
(lit_uint(val_a, ty_a), lit_uint(val_b, ty_b)) => {
|
||||
val_a == val_b && ty_a == ty_b
|
||||
}
|
||||
(lit_int_unsuffixed(a), lit_int_unsuffixed(b)) => a == b,
|
||||
(lit_float(val_a, ty_a), lit_float(val_b, ty_b)) => {
|
||||
val_a == val_b && ty_a == ty_b
|
||||
}
|
||||
(lit_float_unsuffixed(a), lit_float_unsuffixed(b)) => a == b,
|
||||
(lit_nil, lit_nil) => true,
|
||||
(lit_bool(a), lit_bool(b)) => a == b,
|
||||
(lit_str(_), _) => false,
|
||||
(lit_int(*), _) => false,
|
||||
(lit_uint(*), _) => false,
|
||||
(lit_int_unsuffixed(*), _) => false,
|
||||
(lit_float(*), _) => false,
|
||||
(lit_float_unsuffixed(*), _) => false,
|
||||
(lit_nil, _) => false,
|
||||
(lit_bool(_), _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ast::lit_) -> bool {
|
||||
match ((*self), *other) {
|
||||
(lit_str(a), lit_str(b)) => a == b,
|
||||
@@ -1292,10 +947,6 @@ impl ast::lit_: cmp::Eq {
|
||||
(lit_bool(_), _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ast::lit_) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ast::lit_) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1346,25 +997,6 @@ impl int_ty : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl int_ty : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &int_ty) -> bool {
|
||||
match (self, (*other)) {
|
||||
(ty_i, ty_i) => true,
|
||||
(ty_char, ty_char) => true,
|
||||
(ty_i8, ty_i8) => true,
|
||||
(ty_i16, ty_i16) => true,
|
||||
(ty_i32, ty_i32) => true,
|
||||
(ty_i64, ty_i64) => true,
|
||||
(ty_i, _) => false,
|
||||
(ty_char, _) => false,
|
||||
(ty_i8, _) => false,
|
||||
(ty_i16, _) => false,
|
||||
(ty_i32, _) => false,
|
||||
(ty_i64, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &int_ty) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(ty_i, ty_i) => true,
|
||||
@@ -1381,10 +1013,6 @@ impl int_ty : cmp::Eq {
|
||||
(ty_i64, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &int_ty) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &int_ty) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1407,23 +1035,6 @@ impl uint_ty : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl uint_ty : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &uint_ty) -> bool {
|
||||
match (self, (*other)) {
|
||||
(ty_u, ty_u) => true,
|
||||
(ty_u8, ty_u8) => true,
|
||||
(ty_u16, ty_u16) => true,
|
||||
(ty_u32, ty_u32) => true,
|
||||
(ty_u64, ty_u64) => true,
|
||||
(ty_u, _) => false,
|
||||
(ty_u8, _) => false,
|
||||
(ty_u16, _) => false,
|
||||
(ty_u32, _) => false,
|
||||
(ty_u64, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &uint_ty) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(ty_u, ty_u) => true,
|
||||
@@ -1438,10 +1049,6 @@ impl uint_ty : cmp::Eq {
|
||||
(ty_u64, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &uint_ty) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &uint_ty) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1464,25 +1071,12 @@ impl float_ty : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl float_ty : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &float_ty) -> bool {
|
||||
match (self, (*other)) {
|
||||
(ty_f, ty_f) | (ty_f32, ty_f32) | (ty_f64, ty_f64) => true,
|
||||
(ty_f, _) | (ty_f32, _) | (ty_f64, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &float_ty) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(ty_f, ty_f) | (ty_f32, ty_f32) | (ty_f64, ty_f64) => true,
|
||||
(ty_f, _) | (ty_f32, _) | (ty_f64, _) => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &float_ty) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &float_ty) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1502,43 +1096,6 @@ enum prim_ty {
|
||||
}
|
||||
|
||||
impl prim_ty : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &prim_ty) -> bool {
|
||||
match self {
|
||||
ty_int(e0a) => {
|
||||
match (*other) {
|
||||
ty_int(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_uint(e0a) => {
|
||||
match (*other) {
|
||||
ty_uint(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_float(e0a) => {
|
||||
match (*other) {
|
||||
ty_float(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_str => {
|
||||
match (*other) {
|
||||
ty_str => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
ty_bool => {
|
||||
match (*other) {
|
||||
ty_bool => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &prim_ty) -> bool {
|
||||
match (*self) {
|
||||
ty_int(e0a) => {
|
||||
@@ -1573,10 +1130,6 @@ impl prim_ty : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &prim_ty) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &prim_ty) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1601,27 +1154,12 @@ enum Onceness {
|
||||
}
|
||||
|
||||
impl Onceness : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Onceness) -> bool {
|
||||
match (self, *other) {
|
||||
(Once, Once) | (Many, Many) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Onceness) -> bool {
|
||||
match ((*self), *other) {
|
||||
(Once, Once) | (Many, Many) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Onceness) -> bool {
|
||||
!self.eq(other)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Onceness) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
@@ -1663,21 +1201,9 @@ enum ty_ {
|
||||
// Equality and byte-iter (hashing) can be quite approximate for AST types.
|
||||
// since we only care about this for normalizing them to "real" types.
|
||||
impl Ty : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &Ty) -> bool {
|
||||
ptr::addr_of(&self) == ptr::addr_of(&(*other))
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &Ty) -> bool {
|
||||
ptr::addr_of(&(*self)) == ptr::addr_of(&(*other))
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &Ty) -> bool {
|
||||
ptr::addr_of(&self) != ptr::addr_of(&(*other))
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &Ty) -> bool {
|
||||
ptr::addr_of(&(*self)) != ptr::addr_of(&(*other))
|
||||
}
|
||||
@@ -1735,19 +1261,9 @@ impl purity : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl purity : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &purity) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &purity) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &purity) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &purity) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1774,17 +1290,6 @@ impl ret_style : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl ret_style : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &ret_style) -> bool {
|
||||
match (self, (*other)) {
|
||||
(noreturn, noreturn) => true,
|
||||
(return_val, return_val) => true,
|
||||
(noreturn, _) => false,
|
||||
(return_val, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &ret_style) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(noreturn, noreturn) => true,
|
||||
@@ -1793,10 +1298,6 @@ impl ret_style : cmp::Eq {
|
||||
(return_val, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &ret_style) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &ret_style) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1812,49 +1313,6 @@ enum self_ty_ {
|
||||
}
|
||||
|
||||
impl self_ty_ : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &self_ty_) -> bool {
|
||||
match self {
|
||||
sty_static => {
|
||||
match (*other) {
|
||||
sty_static => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
sty_by_ref => {
|
||||
match (*other) {
|
||||
sty_by_ref => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
sty_value => {
|
||||
match (*other) {
|
||||
sty_value => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
sty_region(e0a) => {
|
||||
match (*other) {
|
||||
sty_region(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
sty_box(e0a) => {
|
||||
match (*other) {
|
||||
sty_box(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
sty_uniq(e0a) => {
|
||||
match (*other) {
|
||||
sty_uniq(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &self_ty_) -> bool {
|
||||
match (*self) {
|
||||
sty_static => {
|
||||
@@ -1895,10 +1353,6 @@ impl self_ty_ : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &self_ty_) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &self_ty_) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -1930,36 +1384,13 @@ enum foreign_abi {
|
||||
enum foreign_mod_sort { named, anonymous }
|
||||
|
||||
impl foreign_mod_sort : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &foreign_mod_sort) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &foreign_mod_sort) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &foreign_mod_sort) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &foreign_mod_sort) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
impl foreign_abi : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &foreign_abi) -> bool {
|
||||
match (self, (*other)) {
|
||||
(foreign_abi_rust_intrinsic, foreign_abi_rust_intrinsic) => true,
|
||||
(foreign_abi_cdecl, foreign_abi_cdecl) => true,
|
||||
(foreign_abi_stdcall, foreign_abi_stdcall) => true,
|
||||
(foreign_abi_rust_intrinsic, _) => false,
|
||||
(foreign_abi_cdecl, _) => false,
|
||||
(foreign_abi_stdcall, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &foreign_abi) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(foreign_abi_rust_intrinsic, foreign_abi_rust_intrinsic) => true,
|
||||
@@ -1970,10 +1401,6 @@ impl foreign_abi : cmp::Eq {
|
||||
(foreign_abi_stdcall, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &foreign_abi) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &foreign_abi) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -2023,19 +1450,9 @@ enum variant_kind {
|
||||
enum namespace { module_ns, type_value_ns }
|
||||
|
||||
impl namespace : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &namespace) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &namespace) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &namespace) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &namespace) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -2083,19 +1500,9 @@ enum view_item_ {
|
||||
enum attr_style { attr_outer, attr_inner, }
|
||||
|
||||
impl attr_style : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &attr_style) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &attr_style) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &attr_style) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &attr_style) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -2122,19 +1529,6 @@ impl attr_style : cmp::Eq {
|
||||
enum visibility { public, private, inherited }
|
||||
|
||||
impl visibility : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &visibility) -> bool {
|
||||
match (self, (*other)) {
|
||||
(public, public) => true,
|
||||
(private, private) => true,
|
||||
(inherited, inherited) => true,
|
||||
(public, _) => false,
|
||||
(private, _) => false,
|
||||
(inherited, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &visibility) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(public, public) => true,
|
||||
@@ -2145,10 +1539,6 @@ impl visibility : cmp::Eq {
|
||||
(inherited, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &visibility) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &visibility) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
@@ -2170,30 +1560,6 @@ enum struct_field_kind {
|
||||
}
|
||||
|
||||
impl struct_field_kind : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &struct_field_kind) -> bool {
|
||||
match self {
|
||||
named_field(ident_a, class_mutability_a, visibility_a) => {
|
||||
match *other {
|
||||
named_field(ident_b, class_mutability_b, visibility_b)
|
||||
=> {
|
||||
ident_a == ident_b &&
|
||||
class_mutability_a == class_mutability_b &&
|
||||
visibility_a == visibility_b
|
||||
}
|
||||
unnamed_field => false
|
||||
}
|
||||
}
|
||||
unnamed_field => {
|
||||
match *other {
|
||||
named_field(*) => false,
|
||||
unnamed_field => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &struct_field_kind) -> bool {
|
||||
match (*self) {
|
||||
named_field(ident_a, class_mutability_a, visibility_a) => {
|
||||
@@ -2215,12 +1581,6 @@ impl struct_field_kind : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &struct_field_kind) -> bool {
|
||||
!self.eq(other)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &struct_field_kind) -> bool {
|
||||
!(*self).eq(other)
|
||||
}
|
||||
@@ -2287,17 +1647,6 @@ impl class_mutability : to_bytes::IterBytes {
|
||||
}
|
||||
|
||||
impl class_mutability : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &class_mutability) -> bool {
|
||||
match (self, (*other)) {
|
||||
(class_mutable, class_mutable) => true,
|
||||
(class_immutable, class_immutable) => true,
|
||||
(class_mutable, _) => false,
|
||||
(class_immutable, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &class_mutability) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(class_mutable, class_mutable) => true,
|
||||
@@ -2306,10 +1655,6 @@ impl class_mutability : cmp::Eq {
|
||||
(class_immutable, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &class_mutability) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &class_mutability) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -12,25 +12,6 @@ enum path_elt {
|
||||
}
|
||||
|
||||
impl path_elt : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &path_elt) -> bool {
|
||||
match self {
|
||||
path_mod(e0a) => {
|
||||
match (*other) {
|
||||
path_mod(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
path_name(e0a) => {
|
||||
match (*other) {
|
||||
path_name(e0b) => e0a == e0b,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &path_elt) -> bool {
|
||||
match (*self) {
|
||||
path_mod(e0a) => {
|
||||
@@ -47,10 +28,6 @@ impl path_elt : cmp::Eq {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &path_elt) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &path_elt) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -338,19 +338,9 @@ enum inline_attr {
|
||||
}
|
||||
|
||||
impl inline_attr : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &inline_attr) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &inline_attr) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &inline_attr) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &inline_attr) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -37,29 +37,11 @@ impl BytePos: Pos {
|
||||
pure fn to_uint(&self) -> uint { **self }
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl BytePos: cmp::Eq {
|
||||
pure fn eq(other: &BytePos) -> bool { *self == **other }
|
||||
pure fn ne(other: &BytePos) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
impl BytePos: cmp::Eq {
|
||||
pure fn eq(&self, other: &BytePos) -> bool { **self == **other }
|
||||
pure fn ne(&self, other: &BytePos) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl BytePos: cmp::Ord {
|
||||
pure fn lt(other: &BytePos) -> bool { *self < **other }
|
||||
pure fn le(other: &BytePos) -> bool { *self <= **other }
|
||||
pure fn ge(other: &BytePos) -> bool { *self >= **other }
|
||||
pure fn gt(other: &BytePos) -> bool { *self > **other }
|
||||
}
|
||||
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
impl BytePos: cmp::Ord {
|
||||
pure fn lt(&self, other: &BytePos) -> bool { **self < **other }
|
||||
pure fn le(&self, other: &BytePos) -> bool { **self <= **other }
|
||||
@@ -110,29 +92,11 @@ impl CharPos: Pos {
|
||||
pure fn to_uint(&self) -> uint { **self }
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl CharPos: cmp::Eq {
|
||||
pure fn eq(other: &CharPos) -> bool { *self == **other }
|
||||
pure fn ne(other: &CharPos) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
impl CharPos: cmp::Eq {
|
||||
pure fn eq(&self, other: &CharPos) -> bool { **self == **other }
|
||||
pure fn ne(&self, other: &CharPos) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl CharPos: cmp::Ord {
|
||||
pure fn lt(other: &CharPos) -> bool { *self < **other }
|
||||
pure fn le(other: &CharPos) -> bool { *self <= **other }
|
||||
pure fn ge(other: &CharPos) -> bool { *self >= **other }
|
||||
pure fn gt(other: &CharPos) -> bool { *self > **other }
|
||||
}
|
||||
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
impl CharPos: cmp::Ord {
|
||||
pure fn lt(&self, other: &CharPos) -> bool { **self < **other }
|
||||
pure fn le(&self, other: &CharPos) -> bool { **self <= **other }
|
||||
@@ -190,19 +154,9 @@ pub struct span {
|
||||
}
|
||||
|
||||
impl span : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &span) -> bool {
|
||||
return self.lo == (*other).lo && self.hi == (*other).hi;
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &span) -> bool {
|
||||
return (*self).lo == (*other).lo && (*self).hi == (*other).hi;
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &span) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &span) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -149,19 +149,9 @@ enum level {
|
||||
}
|
||||
|
||||
impl level : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &level) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &level) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &level) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &level) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#[legacy_exports]
|
||||
mod ast_builder;
|
||||
#[legacy_exports]
|
||||
mod parse_proto;
|
||||
#[legacy_exports]
|
||||
mod pipec;
|
||||
#[legacy_exports]
|
||||
mod proto;
|
||||
#[legacy_exports]
|
||||
mod check;
|
||||
#[legacy_exports]
|
||||
mod liveness;
|
||||
@@ -6,17 +6,6 @@
|
||||
enum direction { send, recv }
|
||||
|
||||
impl direction : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &direction) -> bool {
|
||||
match (self, (*other)) {
|
||||
(send, send) => true,
|
||||
(recv, recv) => true,
|
||||
(send, _) => false,
|
||||
(recv, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &direction) -> bool {
|
||||
match ((*self), (*other)) {
|
||||
(send, send) => true,
|
||||
@@ -25,10 +14,6 @@ impl direction : cmp::Eq {
|
||||
(recv, _) => false,
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &direction) -> bool { !self.eq(other) }
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &direction) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
trait ast_fold {
|
||||
fn fold_crate(crate) -> crate;
|
||||
fn fold_crate_directive(&&v: @crate_directive) -> @crate_directive;
|
||||
fn fold_view_item(&&v: @view_item) -> @view_item;
|
||||
fn fold_foreign_item(&&v: @foreign_item) -> @foreign_item;
|
||||
fn fold_item(&&v: @item) -> Option<@item>;
|
||||
@@ -51,8 +50,6 @@ trait ast_fold {
|
||||
type ast_fold_precursor = @{
|
||||
//unlike the others, item_ is non-trivial
|
||||
fold_crate: fn@(crate_, span, ast_fold) -> (crate_, span),
|
||||
fold_crate_directive: fn@(crate_directive_, span,
|
||||
ast_fold) -> (crate_directive_, span),
|
||||
fold_view_item: fn@(view_item_, ast_fold) -> view_item_,
|
||||
fold_foreign_item: fn@(&&v: @foreign_item, ast_fold) -> @foreign_item,
|
||||
fold_item: fn@(&&v: @item, ast_fold) -> Option<@item>,
|
||||
@@ -150,29 +147,12 @@ fn noop_fold_crate(c: crate_, fld: ast_fold) -> crate_ {
|
||||
let fold_attribute = |x| fold_attribute_(x, fld);
|
||||
|
||||
return {
|
||||
directives: vec::map(c.directives, |x| fld.fold_crate_directive(*x)),
|
||||
module: fld.fold_mod(c.module),
|
||||
attrs: vec::map(c.attrs, |x| fold_attribute(*x)),
|
||||
config: vec::map(c.config, |x| fold_meta_item(*x))
|
||||
};
|
||||
}
|
||||
|
||||
fn noop_fold_crate_directive(cd: crate_directive_, fld: ast_fold) ->
|
||||
crate_directive_ {
|
||||
return match cd {
|
||||
cdir_src_mod(vis, id, attrs) => {
|
||||
cdir_src_mod(vis, fld.fold_ident(id),
|
||||
/* FIXME (#2543) */ copy attrs)
|
||||
}
|
||||
cdir_dir_mod(vis, id, cds, attrs) => {
|
||||
cdir_dir_mod(vis, fld.fold_ident(id),
|
||||
vec::map(cds, |x| fld.fold_crate_directive(*x)),
|
||||
/* FIXME (#2543) */ copy attrs)
|
||||
}
|
||||
cdir_view_item(vi) => cdir_view_item(fld.fold_view_item(vi)),
|
||||
}
|
||||
}
|
||||
|
||||
fn noop_fold_view_item(vi: view_item_, _fld: ast_fold) -> view_item_ {
|
||||
return /* FIXME (#2543) */ copy vi;
|
||||
}
|
||||
@@ -636,7 +616,6 @@ fn noop_map_exprs(f: fn@(&&v: @expr) -> @expr, es: ~[@expr]) -> ~[@expr] {
|
||||
|
||||
fn default_ast_fold() -> ast_fold_precursor {
|
||||
return @{fold_crate: wrap(noop_fold_crate),
|
||||
fold_crate_directive: wrap(noop_fold_crate_directive),
|
||||
fold_view_item: noop_fold_view_item,
|
||||
fold_foreign_item: noop_fold_foreign_item,
|
||||
fold_item: noop_fold_item,
|
||||
@@ -667,12 +646,6 @@ fn fold_crate(c: crate) -> crate {
|
||||
let (n, s) = self.fold_crate(c.node, c.span, self as ast_fold);
|
||||
return {node: n, span: self.new_span(s)};
|
||||
}
|
||||
fn fold_crate_directive(&&c: @crate_directive) -> @crate_directive {
|
||||
let (n, s) = self.fold_crate_directive(c.node, c.span,
|
||||
self as ast_fold);
|
||||
return @{node: n,
|
||||
span: self.new_span(s)};
|
||||
}
|
||||
fn fold_view_item(&&x: @view_item) ->
|
||||
@view_item {
|
||||
return @{node: self.fold_view_item(x.node, self as ast_fold),
|
||||
|
||||
+23
-34
@@ -1,5 +1,16 @@
|
||||
//! The main parser interface
|
||||
|
||||
#[legacy_exports];
|
||||
|
||||
export parser;
|
||||
export common;
|
||||
export lexer;
|
||||
export token;
|
||||
export comments;
|
||||
export prec;
|
||||
export classify;
|
||||
export attr;
|
||||
|
||||
export parse_sess;
|
||||
export new_parse_sess, new_parse_sess_special_handler;
|
||||
export next_node_id;
|
||||
@@ -51,40 +62,6 @@ fn new_parse_sess_special_handler(sh: span_handler, cm: @codemap::CodeMap)
|
||||
|
||||
fn parse_crate_from_file(input: &Path, cfg: ast::crate_cfg,
|
||||
sess: parse_sess) -> @ast::crate {
|
||||
if input.filetype() == Some(~".rc") {
|
||||
parse_crate_from_crate_file(input, cfg, sess)
|
||||
} else if input.filetype() == Some(~".rs") {
|
||||
parse_crate_from_source_file(input, cfg, sess)
|
||||
} else {
|
||||
sess.span_diagnostic.handler().fatal(~"unknown input file type: " +
|
||||
input.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_crate_from_crate_file(input: &Path, cfg: ast::crate_cfg,
|
||||
sess: parse_sess) -> @ast::crate {
|
||||
let p = new_crate_parser_from_file(sess, cfg, input);
|
||||
let lo = p.span.lo;
|
||||
let prefix = input.dir_path();
|
||||
let leading_attrs = p.parse_inner_attrs_and_next();
|
||||
let { inner: crate_attrs, next: first_cdir_attr } = leading_attrs;
|
||||
let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr);
|
||||
let cx = @{sess: sess, cfg: /* FIXME (#2543) */ copy p.cfg};
|
||||
let companionmod = input.filestem().map(|s| Path(*s));
|
||||
let (m, attrs) = eval::eval_crate_directives_to_mod(
|
||||
cx, cdirs, &prefix, &companionmod);
|
||||
let mut hi = p.span.hi;
|
||||
p.expect(token::EOF);
|
||||
p.abort_if_errors();
|
||||
return @ast_util::respan(ast_util::mk_sp(lo, hi),
|
||||
{directives: cdirs,
|
||||
module: m,
|
||||
attrs: vec::append(crate_attrs, attrs),
|
||||
config: /* FIXME (#2543) */ copy p.cfg});
|
||||
}
|
||||
|
||||
fn parse_crate_from_source_file(input: &Path, cfg: ast::crate_cfg,
|
||||
sess: parse_sess) -> @ast::crate {
|
||||
let p = new_crate_parser_from_file(sess, cfg, input);
|
||||
let r = p.parse_crate_mod(cfg);
|
||||
return r;
|
||||
@@ -175,6 +152,18 @@ fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
|
||||
path: &Path) -> Result<Parser, ~str> {
|
||||
match io::read_whole_file_str(path) {
|
||||
result::Ok(move src) => {
|
||||
|
||||
// HACK: If the file contains a special token use a different
|
||||
// source file. Used to send the stage1+ parser (the stage0 parser
|
||||
// doesn't have this hack) to a different crate file.
|
||||
// Transitional. Remove me.
|
||||
let src = if src.starts_with("// DIVERT") {
|
||||
let actual_path = &path.with_filestem("alternate_crate");
|
||||
result::unwrap(io::read_whole_file_str(actual_path))
|
||||
} else {
|
||||
move src
|
||||
};
|
||||
|
||||
let filemap = sess.cm.new_filemap(path.to_str(), @move src);
|
||||
let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
|
||||
sess.interner);
|
||||
|
||||
@@ -20,21 +20,9 @@ enum cmnt_style {
|
||||
}
|
||||
|
||||
impl cmnt_style : cmp::Eq {
|
||||
#[cfg(stage0)]
|
||||
pure fn eq(other: &cmnt_style) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn eq(&self, other: &cmnt_style) -> bool {
|
||||
((*self) as uint) == ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
pure fn ne(other: &cmnt_style) -> bool {
|
||||
(self as uint) != ((*other) as uint)
|
||||
}
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
pure fn ne(&self, other: &cmnt_style) -> bool {
|
||||
((*self) as uint) != ((*other) as uint)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user