Merge remote-tracking branch 'remotes/origin/master' into remove-str-trailing-nulls
This commit is contained in:
commit
5eaa4d1d2f
137 changed files with 1293 additions and 1227 deletions
|
@ -48,7 +48,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \
|
||||||
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(2)),$$(notdir $$@))
|
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(2)),$$(notdir $$@))
|
||||||
$$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@
|
$$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
|
||||||
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(2)),$$(notdir $$@))
|
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(2)),$$(notdir $$@))
|
||||||
|
|
||||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \
|
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \
|
||||||
|
@ -58,7 +58,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \
|
||||||
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(2)),$$(notdir $$@))
|
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(2)),$$(notdir $$@))
|
||||||
$$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@
|
$$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
|
||||||
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(2)),$$(notdir $$@))
|
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(2)),$$(notdir $$@))
|
||||||
|
|
||||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \
|
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \
|
||||||
|
@ -69,7 +69,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \
|
||||||
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(2)),$$(notdir $$@))
|
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(2)),$$(notdir $$@))
|
||||||
$$(STAGE$(1)_T_$(2)_H_$(3)) $(BORROWCK) -o $$@ $$< && touch $$@
|
$$(STAGE$(1)_T_$(2)_H_$(3)) $(BORROWCK) --out-dir $$(@D) $$< && touch $$@
|
||||||
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(2)),$$(notdir $$@))
|
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(2)),$$(notdir $$@))
|
||||||
|
|
||||||
# Only build the compiler for host triples
|
# Only build the compiler for host triples
|
||||||
|
@ -90,7 +90,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)): \
|
||||||
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
|
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
|
||||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< && touch $$@
|
$$(STAGE$(1)_T_$(2)_H_$(3)) --out-dir $$(@D) $$< && touch $$@
|
||||||
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
|
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
|
||||||
|
|
||||||
$$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)): \
|
$$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)): \
|
||||||
|
|
|
@ -49,7 +49,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)): \
|
||||||
| $$(TLIB$(1)_T_$(4)_H_$(3))/
|
| $$(TLIB$(1)_T_$(4)_H_$(3))/
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTPKG_GLOB_$(4)),$$(notdir $$@))
|
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTPKG_GLOB_$(4)),$$(notdir $$@))
|
||||||
$$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@
|
$$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
|
||||||
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTPKG_GLOB_$(4)),$$(notdir $$@))
|
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTPKG_GLOB_$(4)),$$(notdir $$@))
|
||||||
|
|
||||||
$$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)): \
|
$$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)): \
|
||||||
|
@ -67,7 +67,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)): \
|
||||||
| $$(TLIB$(1)_T_$(4)_H_$(3))/
|
| $$(TLIB$(1)_T_$(4)_H_$(3))/
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOC_GLOB_$(4)),$$(notdir $$@))
|
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOC_GLOB_$(4)),$$(notdir $$@))
|
||||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
|
$$(STAGE$(1)_T_$(4)_H_$(3)) --out-dir $$(@D) $$< && touch $$@
|
||||||
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOC_GLOB_$(4)),$$(notdir $$@))
|
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOC_GLOB_$(4)),$$(notdir $$@))
|
||||||
|
|
||||||
$$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)): \
|
$$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)): \
|
||||||
|
@ -85,7 +85,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)): \
|
||||||
| $$(TLIB$(1)_T_$(4)_H_$(3))/
|
| $$(TLIB$(1)_T_$(4)_H_$(3))/
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTI_GLOB_$(4)),$$(notdir $$@))
|
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTI_GLOB_$(4)),$$(notdir $$@))
|
||||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
|
$$(STAGE$(1)_T_$(4)_H_$(3)) --out-dir $$(@D) $$< && touch $$@
|
||||||
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTI_GLOB_$(4)),$$(notdir $$@))
|
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTI_GLOB_$(4)),$$(notdir $$@))
|
||||||
|
|
||||||
$$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X_$(4)): \
|
$$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X_$(4)): \
|
||||||
|
@ -106,7 +106,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)): \
|
||||||
| $$(TLIB$(1)_T_$(4)_H_$(3))/
|
| $$(TLIB$(1)_T_$(4)_H_$(3))/
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUST_GLOB_$(4)),$$(notdir $$@))
|
$$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUST_GLOB_$(4)),$$(notdir $$@))
|
||||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
|
$$(STAGE$(1)_T_$(4)_H_$(3)) --out-dir $$(@D) $$< && touch $$@
|
||||||
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUST_GLOB_$(4)),$$(notdir $$@))
|
$$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUST_GLOB_$(4)),$$(notdir $$@))
|
||||||
|
|
||||||
$$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X_$(4)): \
|
$$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X_$(4)): \
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#[crate_type = "bin"];
|
#[crate_type = "bin"];
|
||||||
|
|
||||||
#[allow(non_camel_case_types)];
|
#[allow(non_camel_case_types)];
|
||||||
#[allow(unrecognized_lint)]; // NOTE: remove after snapshot
|
|
||||||
#[deny(warnings)];
|
#[deny(warnings)];
|
||||||
|
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
@ -131,7 +130,7 @@ pub fn parse_config(args: ~[~str]) -> config {
|
||||||
ratchet_noise_percent:
|
ratchet_noise_percent:
|
||||||
getopts::opt_maybe_str(matches,
|
getopts::opt_maybe_str(matches,
|
||||||
"ratchet-noise-percent").map(|s|
|
"ratchet-noise-percent").map(|s|
|
||||||
f64::from_str(*s).get()),
|
f64::from_str(*s).unwrap()),
|
||||||
runtool: getopts::opt_maybe_str(matches, "runtool"),
|
runtool: getopts::opt_maybe_str(matches, "runtool"),
|
||||||
rustcflags: getopts::opt_maybe_str(matches, "rustcflags"),
|
rustcflags: getopts::opt_maybe_str(matches, "rustcflags"),
|
||||||
jit: getopts::opt_present(matches, "jit"),
|
jit: getopts::opt_present(matches, "jit"),
|
||||||
|
@ -267,7 +266,7 @@ pub fn is_test(config: &config, testfile: &Path) -> bool {
|
||||||
_ => ~[~".rc", ~".rs"]
|
_ => ~[~".rc", ~".rs"]
|
||||||
};
|
};
|
||||||
let invalid_prefixes = ~[~".", ~"#", ~"~"];
|
let invalid_prefixes = ~[~".", ~"#", ~"~"];
|
||||||
let name = testfile.filename().get();
|
let name = testfile.filename().unwrap();
|
||||||
|
|
||||||
let mut valid = false;
|
let mut valid = false;
|
||||||
|
|
||||||
|
@ -300,7 +299,7 @@ pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName {
|
||||||
fn shorten(path: &Path) -> ~str {
|
fn shorten(path: &Path) -> ~str {
|
||||||
let filename = path.filename();
|
let filename = path.filename();
|
||||||
let dir = path.pop().filename();
|
let dir = path.pop().filename();
|
||||||
fmt!("%s/%s", dir.get_or_default(~""), filename.get_or_default(~""))
|
fmt!("%s/%s", dir.unwrap_or_default(~""), filename.unwrap_or_default(~""))
|
||||||
}
|
}
|
||||||
|
|
||||||
test::DynTestName(fmt!("[%s] %s",
|
test::DynTestName(fmt!("[%s] %s",
|
||||||
|
|
|
@ -145,7 +145,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
|
||||||
let rounds =
|
let rounds =
|
||||||
match props.pp_exact { Some(_) => 1, None => 2 };
|
match props.pp_exact { Some(_) => 1, None => 2 };
|
||||||
|
|
||||||
let mut srcs = ~[io::read_whole_file_str(testfile).get()];
|
let mut srcs = ~[io::read_whole_file_str(testfile).unwrap()];
|
||||||
|
|
||||||
let mut round = 0;
|
let mut round = 0;
|
||||||
while round < rounds {
|
while round < rounds {
|
||||||
|
@ -166,7 +166,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
|
||||||
match props.pp_exact {
|
match props.pp_exact {
|
||||||
Some(ref file) => {
|
Some(ref file) => {
|
||||||
let filepath = testfile.dir_path().push_rel(file);
|
let filepath = testfile.dir_path().push_rel(file);
|
||||||
io::read_whole_file_str(&filepath).get()
|
io::read_whole_file_str(&filepath).unwrap()
|
||||||
}
|
}
|
||||||
None => { srcs[srcs.len() - 2u].clone() }
|
None => { srcs[srcs.len() - 2u].clone() }
|
||||||
};
|
};
|
||||||
|
@ -448,7 +448,7 @@ fn scan_until_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
|
||||||
if opt.is_none() {
|
if opt.is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*idx = opt.get();
|
*idx = opt.unwrap();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,7 +709,7 @@ fn aux_output_dir_name(config: &config, testfile: &Path) -> Path {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_testname(testfile: &Path) -> Path {
|
fn output_testname(testfile: &Path) -> Path {
|
||||||
Path(testfile.filestem().get())
|
Path(testfile.filestem().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_base_name(config: &config, testfile: &Path) -> Path {
|
fn output_base_name(config: &config, testfile: &Path) -> Path {
|
||||||
|
@ -878,7 +878,7 @@ fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path {
|
||||||
if suffix.len() == 0 {
|
if suffix.len() == 0 {
|
||||||
(*p).clone()
|
(*p).clone()
|
||||||
} else {
|
} else {
|
||||||
let stem = p.filestem().get();
|
let stem = p.filestem().unwrap();
|
||||||
p.with_filestem(stem + "-" + suffix)
|
p.with_filestem(stem + "-" + suffix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,7 +938,7 @@ fn disassemble_extract(config: &config, _props: &TestProps,
|
||||||
|
|
||||||
|
|
||||||
fn count_extracted_lines(p: &Path) -> uint {
|
fn count_extracted_lines(p: &Path) -> uint {
|
||||||
let x = io::read_whole_file_str(&p.with_filetype("ll")).get();
|
let x = io::read_whole_file_str(&p.with_filetype("ll")).unwrap();
|
||||||
x.line_iter().len_()
|
x.line_iter().len_()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -322,24 +322,24 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_base64_basic() {
|
fn test_from_base64_basic() {
|
||||||
assert_eq!("".from_base64().get(), "".as_bytes().to_owned());
|
assert_eq!("".from_base64().unwrap(), "".as_bytes().to_owned());
|
||||||
assert_eq!("Zg==".from_base64().get(), "f".as_bytes().to_owned());
|
assert_eq!("Zg==".from_base64().unwrap(), "f".as_bytes().to_owned());
|
||||||
assert_eq!("Zm8=".from_base64().get(), "fo".as_bytes().to_owned());
|
assert_eq!("Zm8=".from_base64().unwrap(), "fo".as_bytes().to_owned());
|
||||||
assert_eq!("Zm9v".from_base64().get(), "foo".as_bytes().to_owned());
|
assert_eq!("Zm9v".from_base64().unwrap(), "foo".as_bytes().to_owned());
|
||||||
assert_eq!("Zm9vYg==".from_base64().get(), "foob".as_bytes().to_owned());
|
assert_eq!("Zm9vYg==".from_base64().unwrap(), "foob".as_bytes().to_owned());
|
||||||
assert_eq!("Zm9vYmE=".from_base64().get(), "fooba".as_bytes().to_owned());
|
assert_eq!("Zm9vYmE=".from_base64().unwrap(), "fooba".as_bytes().to_owned());
|
||||||
assert_eq!("Zm9vYmFy".from_base64().get(), "foobar".as_bytes().to_owned());
|
assert_eq!("Zm9vYmFy".from_base64().unwrap(), "foobar".as_bytes().to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_base64_newlines() {
|
fn test_from_base64_newlines() {
|
||||||
assert_eq!("Zm9v\r\nYmFy".from_base64().get(),
|
assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap(),
|
||||||
"foobar".as_bytes().to_owned());
|
"foobar".as_bytes().to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_base64_urlsafe() {
|
fn test_from_base64_urlsafe() {
|
||||||
assert_eq!("-_8".from_base64().get(), "+/8=".from_base64().get());
|
assert_eq!("-_8".from_base64().unwrap(), "+/8=".from_base64().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -364,7 +364,7 @@ mod test {
|
||||||
push(random());
|
push(random());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
assert_eq!(v.to_base64(STANDARD).from_base64().get(), v);
|
assert_eq!(v.to_base64(STANDARD).from_base64().unwrap(), v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::iterator::RandomAccessIterator;
|
use std::iterator::RandomAccessIterator;
|
||||||
use std::iterator::{Invert, Enumerate};
|
use std::iterator::{Invert, Enumerate, Repeat, Map, Zip};
|
||||||
use std::num;
|
use std::num;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
use std::uint;
|
use std::uint;
|
||||||
|
@ -206,16 +206,15 @@ impl BigBitv {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
|
pub fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
|
||||||
let len = b.storage.len();
|
let len = b.storage.len();
|
||||||
do uint::iterate(0, len) |i| {
|
for i in range(0, len) {
|
||||||
let mask = big_mask(nbits, i);
|
let mask = big_mask(nbits, i);
|
||||||
if mask & self.storage[i] != mask & b.storage[i] {
|
if mask & self.storage[i] != mask & b.storage[i] {
|
||||||
false
|
return false;
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
enum BitvVariant { Big(BigBitv), Small(SmallBitv) }
|
enum BitvVariant { Big(BigBitv), Small(SmallBitv) }
|
||||||
|
@ -864,13 +863,12 @@ impl BitvSet {
|
||||||
/// w1, w2) where the bit location is the number of bits offset so far,
|
/// w1, w2) where the bit location is the number of bits offset so far,
|
||||||
/// and w1/w2 are the words coming from the two vectors self, other.
|
/// and w1/w2 are the words coming from the two vectors self, other.
|
||||||
fn common_iter<'a>(&'a self, other: &'a BitvSet)
|
fn common_iter<'a>(&'a self, other: &'a BitvSet)
|
||||||
-> MapE<(uint,&uint),(uint,uint,uint), &'a ~[uint],Enumerate<vec::VecIterator<'a,uint>>> {
|
-> Map<'static, ((uint, &'a uint), &'a ~[uint]), (uint, uint, uint),
|
||||||
let min = num::min(self.bitv.storage.len(),
|
Zip<Enumerate<vec::VecIterator<'a, uint>>, Repeat<&'a ~[uint]>>> {
|
||||||
other.bitv.storage.len());
|
let min = num::min(self.bitv.storage.len(), other.bitv.storage.len());
|
||||||
MapE{iter: self.bitv.storage.slice(0, min).iter().enumerate(),
|
self.bitv.storage.slice(0, min).iter().enumerate()
|
||||||
env: &other.bitv.storage,
|
.zip(Repeat::new(&other.bitv.storage))
|
||||||
f: |(i, &w): (uint, &uint), o_store| (i * uint::bits, w, o_store[i])
|
.transform(|((i, &w), o_store)| (i * uint::bits, w, o_store[i]))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visits each word in self or other that extends beyond the other. This
|
/// Visits each word in self or other that extends beyond the other. This
|
||||||
|
@ -881,46 +879,22 @@ impl BitvSet {
|
||||||
/// is true if the word comes from 'self', and false if it comes from
|
/// is true if the word comes from 'self', and false if it comes from
|
||||||
/// 'other'.
|
/// 'other'.
|
||||||
fn outlier_iter<'a>(&'a self, other: &'a BitvSet)
|
fn outlier_iter<'a>(&'a self, other: &'a BitvSet)
|
||||||
-> MapE<(uint, &uint),(bool, uint, uint), uint, Enumerate<vec::VecIterator<'a, uint>>> {
|
-> Map<'static, ((uint, &'a uint), uint), (bool, uint, uint),
|
||||||
let len1 = self.bitv.storage.len();
|
Zip<Enumerate<vec::VecIterator<'a, uint>>, Repeat<uint>>> {
|
||||||
let len2 = other.bitv.storage.len();
|
let slen = self.bitv.storage.len();
|
||||||
let min = num::min(len1, len2);
|
let olen = other.bitv.storage.len();
|
||||||
|
|
||||||
if min < len1 {
|
if olen < slen {
|
||||||
MapE{iter: self.bitv.storage.slice(min, len1).iter().enumerate(),
|
self.bitv.storage.slice_from(olen).iter().enumerate()
|
||||||
env: min,
|
.zip(Repeat::new(olen))
|
||||||
f: |(i, &w): (uint, &uint), min| (true, (i + min) * uint::bits, w)
|
.transform(|((i, &w), min)| (true, (i + min) * uint::bits, w))
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
MapE{iter: other.bitv.storage.slice(min, len2).iter().enumerate(),
|
other.bitv.storage.slice_from(slen).iter().enumerate()
|
||||||
env: min,
|
.zip(Repeat::new(slen))
|
||||||
f: |(i, &w): (uint, &uint), min| (false, (i + min) * uint::bits, w)
|
.transform(|((i, &w), min)| (false, (i + min) * uint::bits, w))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Like iterator::Map with explicit env capture
|
|
||||||
struct MapE<A, B, Env, I> {
|
|
||||||
priv env: Env,
|
|
||||||
priv f: &'static fn(A, Env) -> B,
|
|
||||||
priv iter: I,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'self, A, B, Env: Clone, I: Iterator<A>> Iterator<B> for MapE<A, B, Env, I> {
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<B> {
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(elt) => Some((self.f)(elt, self.env.clone())),
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
||||||
self.iter.size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BitvSetIterator<'self> {
|
pub struct BitvSetIterator<'self> {
|
||||||
priv set: &'self BitvSet,
|
priv set: &'self BitvSet,
|
||||||
|
|
|
@ -10,15 +10,19 @@
|
||||||
|
|
||||||
use std::iterator::Iterator;
|
use std::iterator::Iterator;
|
||||||
|
|
||||||
#[deriving(Clone, Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes, ToStr)]
|
||||||
|
/// A specialized Set implementation to use enum types.
|
||||||
pub struct EnumSet<E> {
|
pub struct EnumSet<E> {
|
||||||
// We must maintain the invariant that no bits are set
|
// We must maintain the invariant that no bits are set
|
||||||
// for which no variant exists
|
// for which no variant exists
|
||||||
priv bits: uint
|
priv bits: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterface for casting C-like enum to uint and back.
|
||||||
pub trait CLike {
|
pub trait CLike {
|
||||||
|
/// Converts C-like enum to uint.
|
||||||
pub fn to_uint(&self) -> uint;
|
pub fn to_uint(&self) -> uint;
|
||||||
|
/// Converts uint to C-like enum.
|
||||||
pub fn from_uint(uint) -> Self;
|
pub fn from_uint(uint) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,54 +31,47 @@ fn bit<E:CLike>(e: E) -> uint {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E:CLike> EnumSet<E> {
|
impl<E:CLike> EnumSet<E> {
|
||||||
|
/// Returns an empty EnumSet.
|
||||||
pub fn empty() -> EnumSet<E> {
|
pub fn empty() -> EnumSet<E> {
|
||||||
EnumSet {bits: 0}
|
EnumSet {bits: 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if an EnumSet is empty.
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.bits == 0
|
self.bits == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if an EnumSet contains any enum of a given EnumSet
|
||||||
pub fn intersects(&self, e: EnumSet<E>) -> bool {
|
pub fn intersects(&self, e: EnumSet<E>) -> bool {
|
||||||
(self.bits & e.bits) != 0
|
(self.bits & e.bits) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an intersection of both EnumSets.
|
||||||
pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
|
pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
|
||||||
EnumSet {bits: self.bits & e.bits}
|
EnumSet {bits: self.bits & e.bits}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if a given EnumSet is included in an EnumSet.
|
||||||
pub fn contains(&self, e: EnumSet<E>) -> bool {
|
pub fn contains(&self, e: EnumSet<E>) -> bool {
|
||||||
(self.bits & e.bits) == e.bits
|
(self.bits & e.bits) == e.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a union of both EnumSets.
|
||||||
pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
|
pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
|
||||||
EnumSet {bits: self.bits | e.bits}
|
EnumSet {bits: self.bits | e.bits}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an enum to an EnumSet
|
||||||
pub fn add(&mut self, e: E) {
|
pub fn add(&mut self, e: E) {
|
||||||
self.bits |= bit(e);
|
self.bits |= bit(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if an EnumSet contains a given enum
|
||||||
pub fn contains_elem(&self, e: E) -> bool {
|
pub fn contains_elem(&self, e: E) -> bool {
|
||||||
(self.bits & bit(e)) != 0
|
(self.bits & bit(e)) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn each(&self, f: &fn(E) -> bool) -> bool {
|
/// Returns an iterator over an EnumSet
|
||||||
let mut bits = self.bits;
|
|
||||||
let mut index = 0;
|
|
||||||
while bits != 0 {
|
|
||||||
if (bits & 1) != 0 {
|
|
||||||
let e = CLike::from_uint(index);
|
|
||||||
if !f(e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index += 1;
|
|
||||||
bits >>= 1;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> EnumSetIterator<E> {
|
pub fn iter(&self) -> EnumSetIterator<E> {
|
||||||
EnumSetIterator::new(self.bits)
|
EnumSetIterator::new(self.bits)
|
||||||
}
|
}
|
||||||
|
@ -98,6 +95,7 @@ impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator over an EnumSet
|
||||||
pub struct EnumSetIterator<E> {
|
pub struct EnumSetIterator<E> {
|
||||||
priv index: uint,
|
priv index: uint,
|
||||||
priv bits: uint,
|
priv bits: uint,
|
||||||
|
@ -136,7 +134,7 @@ mod test {
|
||||||
|
|
||||||
use std::cast;
|
use std::cast;
|
||||||
|
|
||||||
use util::enum_set::*;
|
use enum_set::*;
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
enum Foo {
|
enum Foo {
|
||||||
|
@ -236,7 +234,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// iter / each
|
// iter
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator() {
|
fn test_iterator() {
|
||||||
|
@ -262,34 +260,6 @@ mod test {
|
||||||
assert_eq!(~[A,B,C], elems)
|
assert_eq!(~[A,B,C], elems)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_each() {
|
|
||||||
let mut e1: EnumSet<Foo> = EnumSet::empty();
|
|
||||||
|
|
||||||
assert_eq!(~[], collect(e1))
|
|
||||||
|
|
||||||
e1.add(A);
|
|
||||||
assert_eq!(~[A], collect(e1))
|
|
||||||
|
|
||||||
e1.add(C);
|
|
||||||
assert_eq!(~[A,C], collect(e1))
|
|
||||||
|
|
||||||
e1.add(C);
|
|
||||||
assert_eq!(~[A,C], collect(e1))
|
|
||||||
|
|
||||||
e1.add(B);
|
|
||||||
assert_eq!(~[A,B,C], collect(e1))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collect(e: EnumSet<Foo>) -> ~[Foo] {
|
|
||||||
let mut elems = ~[];
|
|
||||||
e.each(|elem| {
|
|
||||||
elems.push(elem);
|
|
||||||
true
|
|
||||||
});
|
|
||||||
elems
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// operators
|
// operators
|
||||||
|
|
|
@ -91,6 +91,7 @@ pub mod par;
|
||||||
pub mod base64;
|
pub mod base64;
|
||||||
pub mod rl;
|
pub mod rl;
|
||||||
pub mod workcache;
|
pub mod workcache;
|
||||||
|
pub mod enum_set;
|
||||||
#[path="num/bigint.rs"]
|
#[path="num/bigint.rs"]
|
||||||
pub mod bigint;
|
pub mod bigint;
|
||||||
#[path="num/rational.rs"]
|
#[path="num/rational.rs"]
|
||||||
|
|
|
@ -526,8 +526,8 @@ mod test {
|
||||||
|
|
||||||
do input_vec_state(filenames) |line, state| {
|
do input_vec_state(filenames) |line, state| {
|
||||||
let nums: ~[&str] = line.split_iter(' ').collect();
|
let nums: ~[&str] = line.split_iter(' ').collect();
|
||||||
let file_num = uint::from_str(nums[0]).get();
|
let file_num = uint::from_str(nums[0]).unwrap();
|
||||||
let line_num = uint::from_str(nums[1]).get();
|
let line_num = uint::from_str(nums[1]).unwrap();
|
||||||
assert_eq!(line_num, state.line_num_file);
|
assert_eq!(line_num, state.line_num_file);
|
||||||
assert_eq!(file_num * 3 + line_num, state.line_num);
|
assert_eq!(file_num * 3 + line_num, state.line_num);
|
||||||
true
|
true
|
||||||
|
|
|
@ -196,7 +196,7 @@ fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
|
||||||
* The type returned when the command line does not conform to the
|
* The type returned when the command line does not conform to the
|
||||||
* expected format. Pass this value to <fail_str> to get an error message.
|
* expected format. Pass this value to <fail_str> to get an error message.
|
||||||
*/
|
*/
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq, ToStr)]
|
||||||
pub enum Fail_ {
|
pub enum Fail_ {
|
||||||
ArgumentMissing(~str),
|
ArgumentMissing(~str),
|
||||||
UnrecognizedOption(~str),
|
UnrecognizedOption(~str),
|
||||||
|
@ -288,7 +288,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
||||||
None => {
|
None => {
|
||||||
let arg_follows =
|
let arg_follows =
|
||||||
last_valid_opt_id.is_some() &&
|
last_valid_opt_id.is_some() &&
|
||||||
match opts[last_valid_opt_id.get()]
|
match opts[last_valid_opt_id.unwrap()]
|
||||||
.hasarg {
|
.hasarg {
|
||||||
|
|
||||||
Yes | Maybe => true,
|
Yes | Maybe => true,
|
||||||
|
@ -322,7 +322,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
||||||
}
|
}
|
||||||
Maybe => {
|
Maybe => {
|
||||||
if !i_arg.is_none() {
|
if !i_arg.is_none() {
|
||||||
vals[optid].push(Val((i_arg.clone()).get()));
|
vals[optid].push(Val((i_arg.clone()).unwrap()));
|
||||||
} else if name_pos < names.len() ||
|
} else if name_pos < names.len() ||
|
||||||
i + 1 == l || is_arg(args[i + 1]) {
|
i + 1 == l || is_arg(args[i + 1]) {
|
||||||
vals[optid].push(Given);
|
vals[optid].push(Given);
|
||||||
|
@ -330,7 +330,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
||||||
}
|
}
|
||||||
Yes => {
|
Yes => {
|
||||||
if !i_arg.is_none() {
|
if !i_arg.is_none() {
|
||||||
vals[optid].push(Val(i_arg.clone().get()));
|
vals[optid].push(Val(i_arg.clone().unwrap()));
|
||||||
} else if i + 1 == l {
|
} else if i + 1 == l {
|
||||||
return Err(ArgumentMissing(name_str(nm)));
|
return Err(ArgumentMissing(name_str(nm)));
|
||||||
} else { i += 1; vals[optid].push(Val(args[i].clone())); }
|
} else { i += 1; vals[optid].push(Val(args[i].clone())); }
|
||||||
|
|
|
@ -26,7 +26,6 @@ use std::to_str;
|
||||||
|
|
||||||
use serialize::Encodable;
|
use serialize::Encodable;
|
||||||
use serialize;
|
use serialize;
|
||||||
use sort::Sort;
|
|
||||||
use treemap::TreeMap;
|
use treemap::TreeMap;
|
||||||
|
|
||||||
/// Represents a json value
|
/// Represents a json value
|
||||||
|
@ -1152,23 +1151,7 @@ impl Ord for Json {
|
||||||
Object(ref d0) => {
|
Object(ref d0) => {
|
||||||
match *other {
|
match *other {
|
||||||
Number(_) | String(_) | Boolean(_) | List(_) => false,
|
Number(_) | String(_) | Boolean(_) | List(_) => false,
|
||||||
Object(ref d1) => {
|
Object(ref d1) => d0 < d1,
|
||||||
let mut d0_flat = ~[];
|
|
||||||
let mut d1_flat = ~[];
|
|
||||||
|
|
||||||
// FIXME #4430: this is horribly inefficient...
|
|
||||||
for (k, v) in d0.iter() {
|
|
||||||
d0_flat.push((@(*k).clone(), @(*v).clone()));
|
|
||||||
}
|
|
||||||
d0_flat.qsort();
|
|
||||||
|
|
||||||
for (k, v) in d1.iter() {
|
|
||||||
d1_flat.push((@(*k).clone(), @(*v).clone()));
|
|
||||||
}
|
|
||||||
d1_flat.qsort();
|
|
||||||
|
|
||||||
d0_flat < d1_flat
|
|
||||||
}
|
|
||||||
Null => true
|
Null => true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1510,11 +1510,11 @@ mod biguint_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_even() {
|
fn test_is_even() {
|
||||||
assert!(FromStr::from_str::<BigUint>("1").get().is_odd());
|
assert!(FromStr::from_str::<BigUint>("1").unwrap().is_odd());
|
||||||
assert!(FromStr::from_str::<BigUint>("2").get().is_even());
|
assert!(FromStr::from_str::<BigUint>("2").unwrap().is_even());
|
||||||
assert!(FromStr::from_str::<BigUint>("1000").get().is_even());
|
assert!(FromStr::from_str::<BigUint>("1000").unwrap().is_even());
|
||||||
assert!(FromStr::from_str::<BigUint>("1000000000000000000000").get().is_even());
|
assert!(FromStr::from_str::<BigUint>("1000000000000000000000").unwrap().is_even());
|
||||||
assert!(FromStr::from_str::<BigUint>("1000000000000000000001").get().is_odd());
|
assert!(FromStr::from_str::<BigUint>("1000000000000000000001").unwrap().is_odd());
|
||||||
assert!((BigUint::from_uint(1) << 64).is_even());
|
assert!((BigUint::from_uint(1) << 64).is_even());
|
||||||
assert!(((BigUint::from_uint(1) << 64) + BigUint::from_uint(1)).is_odd());
|
assert!(((BigUint::from_uint(1) << 64) + BigUint::from_uint(1)).is_odd());
|
||||||
}
|
}
|
||||||
|
@ -1595,7 +1595,7 @@ mod biguint_tests {
|
||||||
let &(ref n, ref rs) = num_pair;
|
let &(ref n, ref rs) = num_pair;
|
||||||
for str_pair in rs.iter() {
|
for str_pair in rs.iter() {
|
||||||
let &(ref radix, ref str) = str_pair;
|
let &(ref radix, ref str) = str_pair;
|
||||||
assert_eq!(n, &FromStrRadix::from_str_radix(*str, *radix).get());
|
assert_eq!(n, &FromStrRadix::from_str_radix(*str, *radix).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -437,12 +437,12 @@ mod tests {
|
||||||
assert_eq!(deq.len(), 3);
|
assert_eq!(deq.len(), 3);
|
||||||
deq.push_back(d.clone());
|
deq.push_back(d.clone());
|
||||||
assert_eq!(deq.len(), 4);
|
assert_eq!(deq.len(), 4);
|
||||||
assert_eq!((*deq.front().get()).clone(), b.clone());
|
assert_eq!((*deq.front().unwrap()).clone(), b.clone());
|
||||||
assert_eq!((*deq.back().get()).clone(), d.clone());
|
assert_eq!((*deq.back().unwrap()).clone(), d.clone());
|
||||||
assert_eq!(deq.pop_front().get(), b.clone());
|
assert_eq!(deq.pop_front().unwrap(), b.clone());
|
||||||
assert_eq!(deq.pop_back().get(), d.clone());
|
assert_eq!(deq.pop_back().unwrap(), d.clone());
|
||||||
assert_eq!(deq.pop_back().get(), c.clone());
|
assert_eq!(deq.pop_back().unwrap(), c.clone());
|
||||||
assert_eq!(deq.pop_back().get(), a.clone());
|
assert_eq!(deq.pop_back().unwrap(), a.clone());
|
||||||
assert_eq!(deq.len(), 0);
|
assert_eq!(deq.len(), 0);
|
||||||
deq.push_back(c.clone());
|
deq.push_back(c.clone());
|
||||||
assert_eq!(deq.len(), 1);
|
assert_eq!(deq.len(), 1);
|
||||||
|
|
|
@ -386,8 +386,8 @@ fn test_spec_order() {
|
||||||
"1.0.0"];
|
"1.0.0"];
|
||||||
let mut i = 1;
|
let mut i = 1;
|
||||||
while i < vs.len() {
|
while i < vs.len() {
|
||||||
let a = parse(vs[i-1]).get();
|
let a = parse(vs[i-1]).unwrap();
|
||||||
let b = parse(vs[i]).get();
|
let b = parse(vs[i]).unwrap();
|
||||||
assert!(a < b);
|
assert!(a < b);
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,9 +366,9 @@ mod test_map {
|
||||||
map.update_with_key(3, 2, addMoreToCount);
|
map.update_with_key(3, 2, addMoreToCount);
|
||||||
|
|
||||||
// check the total counts
|
// check the total counts
|
||||||
assert_eq!(map.find(&3).get(), &10);
|
assert_eq!(map.find(&3).unwrap(), &10);
|
||||||
assert_eq!(map.find(&5).get(), &3);
|
assert_eq!(map.find(&5).unwrap(), &3);
|
||||||
assert_eq!(map.find(&9).get(), &1);
|
assert_eq!(map.find(&9).unwrap(), &1);
|
||||||
|
|
||||||
// sadly, no sevens were counted
|
// sadly, no sevens were counted
|
||||||
assert!(map.find(&7).is_none());
|
assert!(map.find(&7).is_none());
|
||||||
|
|
|
@ -247,9 +247,8 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
|
||||||
let ratchet_metrics = getopts::opt_maybe_str(&matches, "ratchet-metrics");
|
let ratchet_metrics = getopts::opt_maybe_str(&matches, "ratchet-metrics");
|
||||||
let ratchet_metrics = ratchet_metrics.map(|s| Path(*s));
|
let ratchet_metrics = ratchet_metrics.map(|s| Path(*s));
|
||||||
|
|
||||||
let ratchet_noise_percent =
|
let ratchet_noise_percent = getopts::opt_maybe_str(&matches, "ratchet-noise-percent");
|
||||||
getopts::opt_maybe_str(&matches, "ratchet-noise-percent");
|
let ratchet_noise_percent = ratchet_noise_percent.map(|s| f64::from_str(*s).unwrap());
|
||||||
let ratchet_noise_percent = ratchet_noise_percent.map(|s| f64::from_str(*s).get());
|
|
||||||
|
|
||||||
let save_metrics = getopts::opt_maybe_str(&matches, "save-metrics");
|
let save_metrics = getopts::opt_maybe_str(&matches, "save-metrics");
|
||||||
let save_metrics = save_metrics.map(|s| Path(*s));
|
let save_metrics = save_metrics.map(|s| Path(*s));
|
||||||
|
@ -631,8 +630,8 @@ fn should_sort_failures_before_printing_them() {
|
||||||
st.write_failures();
|
st.write_failures();
|
||||||
};
|
};
|
||||||
|
|
||||||
let apos = s.find_str("a").get();
|
let apos = s.find_str("a").unwrap();
|
||||||
let bpos = s.find_str("b").get();
|
let bpos = s.find_str("b").unwrap();
|
||||||
assert!(apos < bpos);
|
assert!(apos < bpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,7 +867,7 @@ impl MetricMap {
|
||||||
pub fn load(p: &Path) -> MetricMap {
|
pub fn load(p: &Path) -> MetricMap {
|
||||||
assert!(os::path_exists(p));
|
assert!(os::path_exists(p));
|
||||||
let f = io::file_reader(p).unwrap();
|
let f = io::file_reader(p).unwrap();
|
||||||
let mut decoder = json::Decoder(json::from_reader(f).get());
|
let mut decoder = json::Decoder(json::from_reader(f).unwrap());
|
||||||
MetricMap(Decodable::decode(&mut decoder))
|
MetricMap(Decodable::decode(&mut decoder))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1207,7 +1206,7 @@ mod tests {
|
||||||
either::Left(o) => o,
|
either::Left(o) => o,
|
||||||
_ => fail!("Malformed arg in first_free_arg_should_be_a_filter")
|
_ => fail!("Malformed arg in first_free_arg_should_be_a_filter")
|
||||||
};
|
};
|
||||||
assert!("filter" == opts.filter.clone().get());
|
assert!("filter" == opts.filter.clone().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1346,28 +1345,28 @@ mod tests {
|
||||||
|
|
||||||
let diff1 = m2.compare_to_old(&m1, None);
|
let diff1 = m2.compare_to_old(&m1, None);
|
||||||
|
|
||||||
assert_eq!(*(diff1.find(&~"in-both-noise").get()), LikelyNoise);
|
assert_eq!(*(diff1.find(&~"in-both-noise").unwrap()), LikelyNoise);
|
||||||
assert_eq!(*(diff1.find(&~"in-first-noise").get()), MetricRemoved);
|
assert_eq!(*(diff1.find(&~"in-first-noise").unwrap()), MetricRemoved);
|
||||||
assert_eq!(*(diff1.find(&~"in-second-noise").get()), MetricAdded);
|
assert_eq!(*(diff1.find(&~"in-second-noise").unwrap()), MetricAdded);
|
||||||
assert_eq!(*(diff1.find(&~"in-both-want-downwards-but-regressed").get()),
|
assert_eq!(*(diff1.find(&~"in-both-want-downwards-but-regressed").unwrap()),
|
||||||
Regression(100.0));
|
Regression(100.0));
|
||||||
assert_eq!(*(diff1.find(&~"in-both-want-downwards-and-improved").get()),
|
assert_eq!(*(diff1.find(&~"in-both-want-downwards-and-improved").unwrap()),
|
||||||
Improvement(50.0));
|
Improvement(50.0));
|
||||||
assert_eq!(*(diff1.find(&~"in-both-want-upwards-but-regressed").get()),
|
assert_eq!(*(diff1.find(&~"in-both-want-upwards-but-regressed").unwrap()),
|
||||||
Regression(50.0));
|
Regression(50.0));
|
||||||
assert_eq!(*(diff1.find(&~"in-both-want-upwards-and-improved").get()),
|
assert_eq!(*(diff1.find(&~"in-both-want-upwards-and-improved").unwrap()),
|
||||||
Improvement(100.0));
|
Improvement(100.0));
|
||||||
assert_eq!(diff1.len(), 7);
|
assert_eq!(diff1.len(), 7);
|
||||||
|
|
||||||
let diff2 = m2.compare_to_old(&m1, Some(200.0));
|
let diff2 = m2.compare_to_old(&m1, Some(200.0));
|
||||||
|
|
||||||
assert_eq!(*(diff2.find(&~"in-both-noise").get()), LikelyNoise);
|
assert_eq!(*(diff2.find(&~"in-both-noise").unwrap()), LikelyNoise);
|
||||||
assert_eq!(*(diff2.find(&~"in-first-noise").get()), MetricRemoved);
|
assert_eq!(*(diff2.find(&~"in-first-noise").unwrap()), MetricRemoved);
|
||||||
assert_eq!(*(diff2.find(&~"in-second-noise").get()), MetricAdded);
|
assert_eq!(*(diff2.find(&~"in-second-noise").unwrap()), MetricAdded);
|
||||||
assert_eq!(*(diff2.find(&~"in-both-want-downwards-but-regressed").get()), LikelyNoise);
|
assert_eq!(*(diff2.find(&~"in-both-want-downwards-but-regressed").unwrap()), LikelyNoise);
|
||||||
assert_eq!(*(diff2.find(&~"in-both-want-downwards-and-improved").get()), LikelyNoise);
|
assert_eq!(*(diff2.find(&~"in-both-want-downwards-and-improved").unwrap()), LikelyNoise);
|
||||||
assert_eq!(*(diff2.find(&~"in-both-want-upwards-but-regressed").get()), LikelyNoise);
|
assert_eq!(*(diff2.find(&~"in-both-want-upwards-but-regressed").unwrap()), LikelyNoise);
|
||||||
assert_eq!(*(diff2.find(&~"in-both-want-upwards-and-improved").get()), LikelyNoise);
|
assert_eq!(*(diff2.find(&~"in-both-want-upwards-and-improved").unwrap()), LikelyNoise);
|
||||||
assert_eq!(diff2.len(), 7);
|
assert_eq!(diff2.len(), 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1391,28 +1390,28 @@ mod tests {
|
||||||
let (diff1, ok1) = m2.ratchet(&pth, None);
|
let (diff1, ok1) = m2.ratchet(&pth, None);
|
||||||
assert_eq!(ok1, false);
|
assert_eq!(ok1, false);
|
||||||
assert_eq!(diff1.len(), 2);
|
assert_eq!(diff1.len(), 2);
|
||||||
assert_eq!(*(diff1.find(&~"runtime").get()), Regression(10.0));
|
assert_eq!(*(diff1.find(&~"runtime").unwrap()), Regression(10.0));
|
||||||
assert_eq!(*(diff1.find(&~"throughput").get()), LikelyNoise);
|
assert_eq!(*(diff1.find(&~"throughput").unwrap()), LikelyNoise);
|
||||||
|
|
||||||
// Check that it was not rewritten.
|
// Check that it was not rewritten.
|
||||||
let m3 = MetricMap::load(&pth);
|
let m3 = MetricMap::load(&pth);
|
||||||
assert_eq!(m3.len(), 2);
|
assert_eq!(m3.len(), 2);
|
||||||
assert_eq!(*(m3.find(&~"runtime").get()), Metric { value: 1000.0, noise: 2.0 });
|
assert_eq!(*(m3.find(&~"runtime").unwrap()), Metric { value: 1000.0, noise: 2.0 });
|
||||||
assert_eq!(*(m3.find(&~"throughput").get()), Metric { value: 50.0, noise: 2.0 });
|
assert_eq!(*(m3.find(&~"throughput").unwrap()), Metric { value: 50.0, noise: 2.0 });
|
||||||
|
|
||||||
// Ask for a ratchet with an explicit noise-percentage override,
|
// Ask for a ratchet with an explicit noise-percentage override,
|
||||||
// that should advance.
|
// that should advance.
|
||||||
let (diff2, ok2) = m2.ratchet(&pth, Some(10.0));
|
let (diff2, ok2) = m2.ratchet(&pth, Some(10.0));
|
||||||
assert_eq!(ok2, true);
|
assert_eq!(ok2, true);
|
||||||
assert_eq!(diff2.len(), 2);
|
assert_eq!(diff2.len(), 2);
|
||||||
assert_eq!(*(diff2.find(&~"runtime").get()), LikelyNoise);
|
assert_eq!(*(diff2.find(&~"runtime").unwrap()), LikelyNoise);
|
||||||
assert_eq!(*(diff2.find(&~"throughput").get()), LikelyNoise);
|
assert_eq!(*(diff2.find(&~"throughput").unwrap()), LikelyNoise);
|
||||||
|
|
||||||
// Check that it was rewritten.
|
// Check that it was rewritten.
|
||||||
let m4 = MetricMap::load(&pth);
|
let m4 = MetricMap::load(&pth);
|
||||||
assert_eq!(m4.len(), 2);
|
assert_eq!(m4.len(), 2);
|
||||||
assert_eq!(*(m4.find(&~"runtime").get()), Metric { value: 1100.0, noise: 2.0 });
|
assert_eq!(*(m4.find(&~"runtime").unwrap()), Metric { value: 1100.0, noise: 2.0 });
|
||||||
assert_eq!(*(m4.find(&~"throughput").get()), Metric { value: 50.0, noise: 2.0 });
|
assert_eq!(*(m4.find(&~"throughput").unwrap()), Metric { value: 50.0, noise: 2.0 });
|
||||||
|
|
||||||
os::remove_dir_recursive(&dpth);
|
os::remove_dir_recursive(&dpth);
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ fn decode_inner(s: &str, full_url: bool) -> ~str {
|
||||||
match rdr.read_char() {
|
match rdr.read_char() {
|
||||||
'%' => {
|
'%' => {
|
||||||
let bytes = rdr.read_bytes(2u);
|
let bytes = rdr.read_bytes(2u);
|
||||||
let ch = uint::parse_bytes(bytes, 16u).get() as char;
|
let ch = uint::parse_bytes(bytes, 16u).unwrap() as char;
|
||||||
|
|
||||||
if full_url {
|
if full_url {
|
||||||
// Only decode some characters:
|
// Only decode some characters:
|
||||||
|
@ -257,7 +257,7 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> {
|
||||||
let ch = match ch {
|
let ch = match ch {
|
||||||
'%' => {
|
'%' => {
|
||||||
let bytes = rdr.read_bytes(2u);
|
let bytes = rdr.read_bytes(2u);
|
||||||
uint::parse_bytes(bytes, 16u).get() as char
|
uint::parse_bytes(bytes, 16u).unwrap() as char
|
||||||
}
|
}
|
||||||
'+' => ' ',
|
'+' => ' ',
|
||||||
ch => ch
|
ch => ch
|
||||||
|
|
|
@ -915,7 +915,7 @@ pub fn link_args(sess: Session,
|
||||||
}
|
}
|
||||||
let dir = cratepath.dirname();
|
let dir = cratepath.dirname();
|
||||||
if dir != ~"" { args.push(~"-L" + dir); }
|
if dir != ~"" { args.push(~"-L" + dir); }
|
||||||
let libarg = unlib(sess.targ_cfg, cratepath.filestem().get());
|
let libarg = unlib(sess.targ_cfg, cratepath.filestem().unwrap());
|
||||||
args.push(~"-l" + libarg);
|
args.push(~"-l" + libarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,7 +953,7 @@ pub fn link_args(sess: Session,
|
||||||
// be rpathed
|
// be rpathed
|
||||||
if sess.targ_cfg.os == session::os_macos {
|
if sess.targ_cfg.os == session::os_macos {
|
||||||
args.push(~"-Wl,-install_name,@rpath/"
|
args.push(~"-Wl,-install_name,@rpath/"
|
||||||
+ output.filename().get());
|
+ output.filename().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,7 @@ fn passes_exist() {
|
||||||
if !pass.is_some() {
|
if !pass.is_some() {
|
||||||
failed.push(name);
|
failed.push(name);
|
||||||
} else {
|
} else {
|
||||||
unsafe { llvm::LLVMDestroyPass(pass.get()) }
|
unsafe { llvm::LLVMDestroyPass(pass.unwrap()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for &(name,_) in transform_passes.iter() {
|
for &(name,_) in transform_passes.iter() {
|
||||||
|
@ -328,7 +328,7 @@ fn passes_exist() {
|
||||||
if !pass.is_some() {
|
if !pass.is_some() {
|
||||||
failed.push(name);
|
failed.push(name);
|
||||||
} else {
|
} else {
|
||||||
unsafe { llvm::LLVMDestroyPass(pass.get()) }
|
unsafe { llvm::LLVMDestroyPass(pass.unwrap()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for &(name,_) in utility_passes.iter() {
|
for &(name,_) in utility_passes.iter() {
|
||||||
|
@ -336,7 +336,7 @@ fn passes_exist() {
|
||||||
if !pass.is_some() {
|
if !pass.is_some() {
|
||||||
failed.push(name);
|
failed.push(name);
|
||||||
} else {
|
} else {
|
||||||
unsafe { llvm::LLVMDestroyPass(pass.get()) }
|
unsafe { llvm::LLVMDestroyPass(pass.unwrap()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -408,11 +408,10 @@ pub fn stop_after_phase_5(sess: Session) -> bool {
|
||||||
#[fixed_stack_segment]
|
#[fixed_stack_segment]
|
||||||
pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
|
pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
|
||||||
outdir: &Option<Path>, output: &Option<Path>) {
|
outdir: &Option<Path>, output: &Option<Path>) {
|
||||||
let outputs = build_output_filenames(input, outdir, output, [], sess);
|
|
||||||
// We need nested scopes here, because the intermediate results can keep
|
// We need nested scopes here, because the intermediate results can keep
|
||||||
// large chunks of memory alive and we want to free them as soon as
|
// large chunks of memory alive and we want to free them as soon as
|
||||||
// possible to keep the peak memory usage low
|
// possible to keep the peak memory usage low
|
||||||
let trans = {
|
let (outputs, trans) = {
|
||||||
let expanded_crate = {
|
let expanded_crate = {
|
||||||
let crate = phase_1_parse_input(sess, cfg.clone(), input);
|
let crate = phase_1_parse_input(sess, cfg.clone(), input);
|
||||||
if stop_after_phase_1(sess) { return; }
|
if stop_after_phase_1(sess) { return; }
|
||||||
|
@ -420,7 +419,10 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
|
||||||
};
|
};
|
||||||
let analysis = phase_3_run_analysis_passes(sess, expanded_crate);
|
let analysis = phase_3_run_analysis_passes(sess, expanded_crate);
|
||||||
if stop_after_phase_3(sess) { return; }
|
if stop_after_phase_3(sess) { return; }
|
||||||
phase_4_translate_to_llvm(sess, expanded_crate, &analysis, outputs)
|
let outputs = build_output_filenames(input, outdir, output, [], sess);
|
||||||
|
let trans = phase_4_translate_to_llvm(sess, expanded_crate,
|
||||||
|
&analysis, outputs);
|
||||||
|
(outputs, trans)
|
||||||
};
|
};
|
||||||
phase_5_run_llvm_passes(sess, &trans, outputs);
|
phase_5_run_llvm_passes(sess, &trans, outputs);
|
||||||
if stop_after_phase_5(sess) { return; }
|
if stop_after_phase_5(sess) { return; }
|
||||||
|
@ -922,7 +924,7 @@ pub fn build_output_filenames(input: &input,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut stem = match *input {
|
let mut stem = match *input {
|
||||||
file_input(ref ifile) => (*ifile).filestem().get().to_managed(),
|
file_input(ref ifile) => (*ifile).filestem().unwrap().to_managed(),
|
||||||
str_input(_) => @"rust_out"
|
str_input(_) => @"rust_out"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -957,10 +959,7 @@ pub fn build_output_filenames(input: &input,
|
||||||
};
|
};
|
||||||
|
|
||||||
if *sess.building_library {
|
if *sess.building_library {
|
||||||
// FIXME (#2401): We might want to warn here; we're actually not
|
sess.warn("ignoring specified output filename for library.");
|
||||||
// going to respect the user's choice of library name when it
|
|
||||||
// comes time to link, we'll be linking to
|
|
||||||
// lib<basename>-<hash>-<version>.so no matter what.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if *odir != None {
|
if *odir != None {
|
||||||
|
|
|
@ -308,7 +308,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item {
|
||||||
#[main];
|
#[main];
|
||||||
extra::test::test_main_static(::std::os::args(), TESTS);
|
extra::test::test_main_static(::std::os::args(), TESTS);
|
||||||
}
|
}
|
||||||
)).get();
|
)).unwrap();
|
||||||
|
|
||||||
let testmod = ast::_mod {
|
let testmod = ast::_mod {
|
||||||
view_items: view_items,
|
view_items: view_items,
|
||||||
|
@ -366,7 +366,7 @@ fn mk_tests(cx: &TestCtxt) -> @ast::item {
|
||||||
pub static TESTS : &'static [self::extra::test::TestDescAndFn] =
|
pub static TESTS : &'static [self::extra::test::TestDescAndFn] =
|
||||||
$test_descs
|
$test_descs
|
||||||
;
|
;
|
||||||
)).get()
|
)).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_extra(cx: &TestCtxt) -> bool {
|
fn is_extra(cx: &TestCtxt) -> bool {
|
||||||
|
|
|
@ -413,15 +413,14 @@ fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) {
|
fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) {
|
||||||
do bs.builtin_bounds.each |bound| {
|
for bound in bs.builtin_bounds.iter() {
|
||||||
match bound {
|
match bound {
|
||||||
ty::BoundSend => w.write_char('S'),
|
ty::BoundSend => w.write_char('S'),
|
||||||
ty::BoundFreeze => w.write_char('K'),
|
ty::BoundFreeze => w.write_char('K'),
|
||||||
ty::BoundStatic => w.write_char('O'),
|
ty::BoundStatic => w.write_char('O'),
|
||||||
ty::BoundSized => w.write_char('Z'),
|
ty::BoundSized => w.write_char('Z'),
|
||||||
}
|
}
|
||||||
true
|
}
|
||||||
};
|
|
||||||
|
|
||||||
for &tp in bs.trait_bounds.iter() {
|
for &tp in bs.trait_bounds.iter() {
|
||||||
w.write_char('I');
|
w.write_char('I');
|
||||||
|
|
|
@ -328,7 +328,7 @@ fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
|
||||||
|
|
||||||
match *ii {
|
match *ii {
|
||||||
//hack: we're not dropping items
|
//hack: we're not dropping items
|
||||||
ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()),
|
ast::ii_item(i) => ast::ii_item(fld.fold_item(i).unwrap()),
|
||||||
ast::ii_method(d, is_provided, m) =>
|
ast::ii_method(d, is_provided, m) =>
|
||||||
ast::ii_method(d, is_provided, fld.fold_method(m)),
|
ast::ii_method(d, is_provided, fld.fold_method(m)),
|
||||||
ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i))
|
ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i))
|
||||||
|
@ -350,7 +350,7 @@ fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item)
|
||||||
});
|
});
|
||||||
|
|
||||||
match ii {
|
match ii {
|
||||||
ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()),
|
ast::ii_item(i) => ast::ii_item(fld.fold_item(i).unwrap()),
|
||||||
ast::ii_method(d, is_provided, m) =>
|
ast::ii_method(d, is_provided, m) =>
|
||||||
ast::ii_method(xcx.tr_def_id(d), is_provided, fld.fold_method(m)),
|
ast::ii_method(xcx.tr_def_id(d), is_provided, fld.fold_method(m)),
|
||||||
ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)),
|
ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)),
|
||||||
|
@ -1275,7 +1275,7 @@ fn mk_ctxt() -> @fake_ext_ctxt {
|
||||||
fn roundtrip(in_item: Option<@ast::item>) {
|
fn roundtrip(in_item: Option<@ast::item>) {
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
let in_item = in_item.get();
|
let in_item = in_item.unwrap();
|
||||||
let bytes = do io::with_bytes_writer |wr| {
|
let bytes = do io::with_bytes_writer |wr| {
|
||||||
let mut ebml_w = writer::Encoder(wr);
|
let mut ebml_w = writer::Encoder(wr);
|
||||||
encode_item_ast(&mut ebml_w, in_item);
|
encode_item_ast(&mut ebml_w, in_item);
|
||||||
|
@ -1321,13 +1321,13 @@ fn test_simplification() {
|
||||||
fn eq_int(a: int, b: int) -> bool { a == b }
|
fn eq_int(a: int, b: int) -> bool { a == b }
|
||||||
return alist {eq_fn: eq_int, data: ~[]};
|
return alist {eq_fn: eq_int, data: ~[]};
|
||||||
}
|
}
|
||||||
).get());
|
).unwrap());
|
||||||
let item_out = simplify_ast(&item_in);
|
let item_out = simplify_ast(&item_in);
|
||||||
let item_exp = ast::ii_item(quote_item!(
|
let item_exp = ast::ii_item(quote_item!(
|
||||||
fn new_int_alist<B>() -> alist<int, B> {
|
fn new_int_alist<B>() -> alist<int, B> {
|
||||||
return alist {eq_fn: eq_int, data: ~[]};
|
return alist {eq_fn: eq_int, data: ~[]};
|
||||||
}
|
}
|
||||||
).get());
|
).unwrap());
|
||||||
match (item_out, item_exp) {
|
match (item_out, item_exp) {
|
||||||
(ast::ii_item(item_out), ast::ii_item(item_exp)) => {
|
(ast::ii_item(item_out), ast::ii_item(item_exp)) => {
|
||||||
assert!(pprust::item_to_str(item_out,
|
assert!(pprust::item_to_str(item_out,
|
||||||
|
|
|
@ -307,7 +307,7 @@ impl<'self> CheckLoanCtxt<'self> {
|
||||||
// if they cannot already have been assigned
|
// if they cannot already have been assigned
|
||||||
if self.is_local_variable(cmt) {
|
if self.is_local_variable(cmt) {
|
||||||
assert!(cmt.mutbl.is_immutable()); // no "const" locals
|
assert!(cmt.mutbl.is_immutable()); // no "const" locals
|
||||||
let lp = opt_loan_path(cmt).get();
|
let lp = opt_loan_path(cmt).unwrap();
|
||||||
do self.move_data.each_assignment_of(expr.id, lp) |assign| {
|
do self.move_data.each_assignment_of(expr.id, lp) |assign| {
|
||||||
self.bccx.report_reassigned_immutable_variable(
|
self.bccx.report_reassigned_immutable_variable(
|
||||||
expr.span,
|
expr.span,
|
||||||
|
|
|
@ -225,7 +225,7 @@ impl CFGBuilder {
|
||||||
// Note that `break` and `loop` statements
|
// Note that `break` and `loop` statements
|
||||||
// may cause additional edges.
|
// may cause additional edges.
|
||||||
|
|
||||||
// NOTE: Is the condition considered part of the loop?
|
// Is the condition considered part of the loop?
|
||||||
let loopback = self.add_dummy_node([pred]); // 1
|
let loopback = self.add_dummy_node([pred]); // 1
|
||||||
let cond_exit = self.expr(cond, loopback); // 2
|
let cond_exit = self.expr(cond, loopback); // 2
|
||||||
let expr_exit = self.add_node(expr.id, [cond_exit]); // 3
|
let expr_exit = self.add_node(expr.id, [cond_exit]); // 3
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: &Crate) {
|
||||||
}
|
}
|
||||||
expr_again(_) => {
|
expr_again(_) => {
|
||||||
if !cx.in_loop {
|
if !cx.in_loop {
|
||||||
tcx.sess.span_err(e.span, "`again` outside of loop");
|
tcx.sess.span_err(e.span, "`loop` outside of loop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr_ret(oe) => {
|
expr_ret(oe) => {
|
||||||
|
|
|
@ -109,7 +109,7 @@ pub fn check_arms(cx: &MatchCheckCtxt, arms: &[arm]) {
|
||||||
let pat_matches_nan: &fn(@pat) -> bool = |p| {
|
let pat_matches_nan: &fn(@pat) -> bool = |p| {
|
||||||
match cx.tcx.def_map.find(&p.id) {
|
match cx.tcx.def_map.find(&p.id) {
|
||||||
Some(&def_static(did, false)) => {
|
Some(&def_static(did, false)) => {
|
||||||
let const_expr = lookup_const_by_id(cx.tcx, did).get();
|
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
|
||||||
match eval_const_expr(cx.tcx, const_expr) {
|
match eval_const_expr(cx.tcx, const_expr) {
|
||||||
const_float(f) if f.is_NaN() => true,
|
const_float(f) if f.is_NaN() => true,
|
||||||
_ => false
|
_ => false
|
||||||
|
@ -304,7 +304,7 @@ pub fn is_useful_specialized(cx: &MatchCheckCtxt,
|
||||||
-> useful {
|
-> useful {
|
||||||
let ms = m.iter().filter_map(|r| specialize(cx, *r, &ctor, arity, lty)).collect::<matrix>();
|
let ms = m.iter().filter_map(|r| specialize(cx, *r, &ctor, arity, lty)).collect::<matrix>();
|
||||||
let could_be_useful = is_useful(
|
let could_be_useful = is_useful(
|
||||||
cx, &ms, specialize(cx, v, &ctor, arity, lty).get());
|
cx, &ms, specialize(cx, v, &ctor, arity, lty).unwrap());
|
||||||
match could_be_useful {
|
match could_be_useful {
|
||||||
useful_ => useful(lty, ctor),
|
useful_ => useful(lty, ctor),
|
||||||
ref u => *u,
|
ref u => *u,
|
||||||
|
@ -319,7 +319,7 @@ pub fn pat_ctor_id(cx: &MatchCheckCtxt, p: @pat) -> Option<ctor> {
|
||||||
match cx.tcx.def_map.find(&pat.id) {
|
match cx.tcx.def_map.find(&pat.id) {
|
||||||
Some(&def_variant(_, id)) => Some(variant(id)),
|
Some(&def_variant(_, id)) => Some(variant(id)),
|
||||||
Some(&def_static(did, false)) => {
|
Some(&def_static(did, false)) => {
|
||||||
let const_expr = lookup_const_by_id(cx.tcx, did).get();
|
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
|
||||||
Some(val(eval_const_expr(cx.tcx, const_expr)))
|
Some(val(eval_const_expr(cx.tcx, const_expr)))
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
|
@ -515,7 +515,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
|
||||||
}
|
}
|
||||||
Some(&def_static(did, _)) => {
|
Some(&def_static(did, _)) => {
|
||||||
let const_expr =
|
let const_expr =
|
||||||
lookup_const_by_id(cx.tcx, did).get();
|
lookup_const_by_id(cx.tcx, did).unwrap();
|
||||||
let e_v = eval_const_expr(cx.tcx, const_expr);
|
let e_v = eval_const_expr(cx.tcx, const_expr);
|
||||||
let match_ = match *ctor_id {
|
let match_ = match *ctor_id {
|
||||||
val(ref v) => {
|
val(ref v) => {
|
||||||
|
@ -565,7 +565,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
|
||||||
match cx.tcx.def_map.get_copy(&pat_id) {
|
match cx.tcx.def_map.get_copy(&pat_id) {
|
||||||
def_static(did, _) => {
|
def_static(did, _) => {
|
||||||
let const_expr =
|
let const_expr =
|
||||||
lookup_const_by_id(cx.tcx, did).get();
|
lookup_const_by_id(cx.tcx, did).unwrap();
|
||||||
let e_v = eval_const_expr(cx.tcx, const_expr);
|
let e_v = eval_const_expr(cx.tcx, const_expr);
|
||||||
let match_ = match *ctor_id {
|
let match_ = match *ctor_id {
|
||||||
val(ref v) =>
|
val(ref v) =>
|
||||||
|
@ -867,7 +867,7 @@ pub fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
|
||||||
"cannot bind by-move and by-ref \
|
"cannot bind by-move and by-ref \
|
||||||
in the same pattern");
|
in the same pattern");
|
||||||
tcx.sess.span_note(
|
tcx.sess.span_note(
|
||||||
by_ref_span.get(),
|
by_ref_span.unwrap(),
|
||||||
"by-ref binding occurs here");
|
"by-ref binding occurs here");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -466,9 +466,9 @@ pub fn lit_to_const(lit: &lit) -> const_val {
|
||||||
lit_int(n, _) => const_int(n),
|
lit_int(n, _) => const_int(n),
|
||||||
lit_uint(n, _) => const_uint(n),
|
lit_uint(n, _) => const_uint(n),
|
||||||
lit_int_unsuffixed(n) => const_int(n),
|
lit_int_unsuffixed(n) => const_int(n),
|
||||||
lit_float(n, _) => const_float(float::from_str(n).get() as f64),
|
lit_float(n, _) => const_float(float::from_str(n).unwrap() as f64),
|
||||||
lit_float_unsuffixed(n) =>
|
lit_float_unsuffixed(n) =>
|
||||||
const_float(float::from_str(n).get() as f64),
|
const_float(float::from_str(n).unwrap() as f64),
|
||||||
lit_nil => const_int(0i64),
|
lit_nil => const_int(0i64),
|
||||||
lit_bool(b) => const_bool(b)
|
lit_bool(b) => const_bool(b)
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,12 +338,11 @@ pub fn check_builtin_bounds(cx: Context, ty: ty::t, bounds: ty::BuiltinBounds,
|
||||||
{
|
{
|
||||||
let kind = ty::type_contents(cx.tcx, ty);
|
let kind = ty::type_contents(cx.tcx, ty);
|
||||||
let mut missing = ty::EmptyBuiltinBounds();
|
let mut missing = ty::EmptyBuiltinBounds();
|
||||||
do bounds.each |bound| {
|
for bound in bounds.iter() {
|
||||||
if !kind.meets_bound(cx.tcx, bound) {
|
if !kind.meets_bound(cx.tcx, bound) {
|
||||||
missing.add(bound);
|
missing.add(bound);
|
||||||
}
|
}
|
||||||
true
|
}
|
||||||
};
|
|
||||||
if !missing.is_empty() {
|
if !missing.is_empty() {
|
||||||
any_missing(missing);
|
any_missing(missing);
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
|
||||||
// the default implementation.
|
// the default implementation.
|
||||||
// Having to do this this is really unfortunate.
|
// Having to do this this is really unfortunate.
|
||||||
let method_id = ty::method(tcx, method_id).provided_source
|
let method_id = ty::method(tcx, method_id).provided_source
|
||||||
.get_or_default(method_id);
|
.unwrap_or_default(method_id);
|
||||||
|
|
||||||
if method_id.crate == LOCAL_CRATE {
|
if method_id.crate == LOCAL_CRATE {
|
||||||
let is_private = method_is_private(span, method_id.node);
|
let is_private = method_is_private(span, method_id.node);
|
||||||
|
|
|
@ -1726,7 +1726,7 @@ impl Resolver {
|
||||||
let mut modules = HashMap::new();
|
let mut modules = HashMap::new();
|
||||||
|
|
||||||
// Create all the items reachable by paths.
|
// Create all the items reachable by paths.
|
||||||
do each_path(self.session.cstore, root.def_id.get().crate)
|
do each_path(self.session.cstore, root.def_id.unwrap().crate)
|
||||||
|path_string, def_like, visibility| {
|
|path_string, def_like, visibility| {
|
||||||
|
|
||||||
debug!("(building reduced graph for external crate) found path \
|
debug!("(building reduced graph for external crate) found path \
|
||||||
|
@ -2350,7 +2350,7 @@ impl Resolver {
|
||||||
match type_result {
|
match type_result {
|
||||||
BoundResult(target_module, name_bindings) => {
|
BoundResult(target_module, name_bindings) => {
|
||||||
debug!("(resolving single import) found type target: %?",
|
debug!("(resolving single import) found type target: %?",
|
||||||
name_bindings.type_def.get().type_def);
|
name_bindings.type_def.unwrap().type_def);
|
||||||
import_resolution.type_target =
|
import_resolution.type_target =
|
||||||
Some(Target(target_module, name_bindings));
|
Some(Target(target_module, name_bindings));
|
||||||
import_resolution.type_id = directive.id;
|
import_resolution.type_id = directive.id;
|
||||||
|
@ -3097,7 +3097,7 @@ impl Resolver {
|
||||||
let imports: &mut ~[@ImportDirective] = &mut *module_.imports;
|
let imports: &mut ~[@ImportDirective] = &mut *module_.imports;
|
||||||
let import_count = imports.len();
|
let import_count = imports.len();
|
||||||
if index != import_count {
|
if index != import_count {
|
||||||
let sn = self.session.codemap.span_to_snippet(imports[index].span);
|
let sn = self.session.codemap.span_to_snippet(imports[index].span).unwrap();
|
||||||
if sn.contains("::") {
|
if sn.contains("::") {
|
||||||
self.session.span_err(imports[index].span, "unresolved import");
|
self.session.span_err(imports[index].span, "unresolved import");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -171,6 +171,7 @@ use middle::trans::tvec;
|
||||||
use middle::trans::type_of;
|
use middle::trans::type_of;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use util::common::indenter;
|
use util::common::indenter;
|
||||||
|
use util::ppaux::{Repr, vec_map_to_str};
|
||||||
|
|
||||||
use std::hashmap::HashMap;
|
use std::hashmap::HashMap;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
@ -179,7 +180,6 @@ use syntax::ast::ident;
|
||||||
use syntax::ast_util::path_to_ident;
|
use syntax::ast_util::path_to_ident;
|
||||||
use syntax::ast_util;
|
use syntax::ast_util;
|
||||||
use syntax::codemap::{span, dummy_sp};
|
use syntax::codemap::{span, dummy_sp};
|
||||||
use syntax::print::pprust::pat_to_str;
|
|
||||||
|
|
||||||
// An option identifying a literal: either a unit-like struct or an
|
// An option identifying a literal: either a unit-like struct or an
|
||||||
// expression.
|
// expression.
|
||||||
|
@ -210,7 +210,7 @@ pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
|
||||||
ExprLit(existing_a_expr) => a_expr = existing_a_expr,
|
ExprLit(existing_a_expr) => a_expr = existing_a_expr,
|
||||||
ConstLit(a_const) => {
|
ConstLit(a_const) => {
|
||||||
let e = const_eval::lookup_const_by_id(tcx, a_const);
|
let e = const_eval::lookup_const_by_id(tcx, a_const);
|
||||||
a_expr = e.get();
|
a_expr = e.unwrap();
|
||||||
}
|
}
|
||||||
UnitLikeStructLit(_) => {
|
UnitLikeStructLit(_) => {
|
||||||
fail!("UnitLikeStructLit should have been handled \
|
fail!("UnitLikeStructLit should have been handled \
|
||||||
|
@ -223,7 +223,7 @@ pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
|
||||||
ExprLit(existing_b_expr) => b_expr = existing_b_expr,
|
ExprLit(existing_b_expr) => b_expr = existing_b_expr,
|
||||||
ConstLit(b_const) => {
|
ConstLit(b_const) => {
|
||||||
let e = const_eval::lookup_const_by_id(tcx, b_const);
|
let e = const_eval::lookup_const_by_id(tcx, b_const);
|
||||||
b_expr = e.get();
|
b_expr = e.unwrap();
|
||||||
}
|
}
|
||||||
UnitLikeStructLit(_) => {
|
UnitLikeStructLit(_) => {
|
||||||
fail!("UnitLikeStructLit should have been handled \
|
fail!("UnitLikeStructLit should have been handled \
|
||||||
|
@ -353,17 +353,15 @@ pub struct Match<'self> {
|
||||||
data: ArmData<'self>
|
data: ArmData<'self>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match_to_str(bcx: @mut Block, m: &Match) -> ~str {
|
impl<'self> Repr for Match<'self> {
|
||||||
if bcx.sess().verbose() {
|
fn repr(&self, tcx: ty::ctxt) -> ~str {
|
||||||
|
if tcx.sess.verbose() {
|
||||||
// for many programs, this just take too long to serialize
|
// for many programs, this just take too long to serialize
|
||||||
fmt!("%?", m.pats.map(|p| pat_to_str(*p, bcx.sess().intr())))
|
self.pats.repr(tcx)
|
||||||
} else {
|
} else {
|
||||||
fmt!("%u pats", m.pats.len())
|
fmt!("%u pats", self.pats.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn matches_to_str(bcx: @mut Block, m: &[Match]) -> ~str {
|
|
||||||
fmt!("%?", m.map(|n| match_to_str(bcx, n)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_nested_bindings(m: &[Match], col: uint) -> bool {
|
pub fn has_nested_bindings(m: &[Match], col: uint) -> bool {
|
||||||
|
@ -381,9 +379,9 @@ pub fn expand_nested_bindings<'r>(bcx: @mut Block,
|
||||||
col: uint,
|
col: uint,
|
||||||
val: ValueRef)
|
val: ValueRef)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("expand_nested_bindings(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("expand_nested_bindings(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -416,7 +414,7 @@ pub fn assert_is_binding_or_wild(bcx: @mut Block, p: @ast::pat) {
|
||||||
bcx.sess().span_bug(
|
bcx.sess().span_bug(
|
||||||
p.span,
|
p.span,
|
||||||
fmt!("Expected an identifier pattern but found p: %s",
|
fmt!("Expected an identifier pattern but found p: %s",
|
||||||
pat_to_str(p, bcx.sess().intr())));
|
p.repr(bcx.tcx())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,9 +427,9 @@ pub fn enter_match<'r>(bcx: @mut Block,
|
||||||
val: ValueRef,
|
val: ValueRef,
|
||||||
e: enter_pat)
|
e: enter_pat)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_match(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_match(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -467,7 +465,7 @@ pub fn enter_match<'r>(bcx: @mut Block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("result=%s", matches_to_str(bcx, result));
|
debug!("result=%s", result.repr(bcx.tcx()));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -478,9 +476,9 @@ pub fn enter_default<'r>(bcx: @mut Block,
|
||||||
col: uint,
|
col: uint,
|
||||||
val: ValueRef)
|
val: ValueRef)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_default(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_default(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -525,9 +523,9 @@ pub fn enter_opt<'r>(bcx: @mut Block,
|
||||||
variant_size: uint,
|
variant_size: uint,
|
||||||
val: ValueRef)
|
val: ValueRef)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_opt(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_opt(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -637,9 +635,9 @@ pub fn enter_rec_or_struct<'r>(bcx: @mut Block,
|
||||||
fields: &[ast::ident],
|
fields: &[ast::ident],
|
||||||
val: ValueRef)
|
val: ValueRef)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_rec_or_struct(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_rec_or_struct(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -672,9 +670,9 @@ pub fn enter_tup<'r>(bcx: @mut Block,
|
||||||
val: ValueRef,
|
val: ValueRef,
|
||||||
n_elts: uint)
|
n_elts: uint)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_tup(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_tup(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -698,9 +696,9 @@ pub fn enter_tuple_struct<'r>(bcx: @mut Block,
|
||||||
val: ValueRef,
|
val: ValueRef,
|
||||||
n_elts: uint)
|
n_elts: uint)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_tuple_struct(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_tuple_struct(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -723,9 +721,9 @@ pub fn enter_box<'r>(bcx: @mut Block,
|
||||||
col: uint,
|
col: uint,
|
||||||
val: ValueRef)
|
val: ValueRef)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_box(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_box(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -750,9 +748,9 @@ pub fn enter_uniq<'r>(bcx: @mut Block,
|
||||||
col: uint,
|
col: uint,
|
||||||
val: ValueRef)
|
val: ValueRef)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_uniq(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_uniq(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -777,9 +775,9 @@ pub fn enter_region<'r>(bcx: @mut Block,
|
||||||
col: uint,
|
col: uint,
|
||||||
val: ValueRef)
|
val: ValueRef)
|
||||||
-> ~[Match<'r>] {
|
-> ~[Match<'r>] {
|
||||||
debug!("enter_region(bcx=%s, m=%s, col=%u, val=%?)",
|
debug!("enter_region(bcx=%s, m=%s, col=%u, val=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
col,
|
col,
|
||||||
bcx.val_to_str(val));
|
bcx.val_to_str(val));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
@ -922,7 +920,7 @@ pub fn extract_vec_elems(bcx: @mut Block,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if slice.is_some() {
|
if slice.is_some() {
|
||||||
let n = slice.get();
|
let n = slice.unwrap();
|
||||||
let slice_offset = Mul(bcx, vt.llunit_size,
|
let slice_offset = Mul(bcx, vt.llunit_size,
|
||||||
C_int(bcx.ccx(), n as int)
|
C_int(bcx.ccx(), n as int)
|
||||||
);
|
);
|
||||||
|
@ -1213,11 +1211,11 @@ pub fn compile_guard(bcx: @mut Block,
|
||||||
vals: &[ValueRef],
|
vals: &[ValueRef],
|
||||||
chk: Option<mk_fail>)
|
chk: Option<mk_fail>)
|
||||||
-> @mut Block {
|
-> @mut Block {
|
||||||
debug!("compile_guard(bcx=%s, guard_expr=%s, m=%s, vals=%?)",
|
debug!("compile_guard(bcx=%s, guard_expr=%s, m=%s, vals=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
bcx.expr_to_str(guard_expr),
|
bcx.expr_to_str(guard_expr),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
vals.map(|v| bcx.val_to_str(*v)));
|
vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
|
||||||
let mut bcx = bcx;
|
let mut bcx = bcx;
|
||||||
|
@ -1267,10 +1265,10 @@ pub fn compile_submatch(bcx: @mut Block,
|
||||||
m: &[Match],
|
m: &[Match],
|
||||||
vals: &[ValueRef],
|
vals: &[ValueRef],
|
||||||
chk: Option<mk_fail>) {
|
chk: Option<mk_fail>) {
|
||||||
debug!("compile_submatch(bcx=%s, m=%s, vals=%?)",
|
debug!("compile_submatch(bcx=%s, m=%s, vals=%s)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
matches_to_str(bcx, m),
|
m.repr(bcx.tcx()),
|
||||||
vals.map(|v| bcx.val_to_str(*v)));
|
vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1280,7 +1278,7 @@ pub fn compile_submatch(bcx: @mut Block,
|
||||||
let _icx = push_ctxt("match::compile_submatch");
|
let _icx = push_ctxt("match::compile_submatch");
|
||||||
let mut bcx = bcx;
|
let mut bcx = bcx;
|
||||||
if m.len() == 0u {
|
if m.len() == 0u {
|
||||||
Br(bcx, chk.get()());
|
Br(bcx, chk.unwrap()());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if m[0].pats.len() == 0u {
|
if m[0].pats.len() == 0u {
|
||||||
|
@ -1427,6 +1425,7 @@ fn compile_submatch_continue(mut bcx: @mut Block,
|
||||||
|
|
||||||
// Decide what kind of branch we need
|
// Decide what kind of branch we need
|
||||||
let opts = get_options(bcx, m, col);
|
let opts = get_options(bcx, m, col);
|
||||||
|
debug!("options=%?", opts);
|
||||||
let mut kind = no_branch;
|
let mut kind = no_branch;
|
||||||
let mut test_val = val;
|
let mut test_val = val;
|
||||||
if opts.len() > 0u {
|
if opts.len() > 0u {
|
||||||
|
@ -1914,12 +1913,12 @@ fn bind_irrefutable_pat(bcx: @mut Block,
|
||||||
|
|
||||||
debug!("bind_irrefutable_pat(bcx=%s, pat=%s, binding_mode=%?)",
|
debug!("bind_irrefutable_pat(bcx=%s, pat=%s, binding_mode=%?)",
|
||||||
bcx.to_str(),
|
bcx.to_str(),
|
||||||
pat_to_str(pat, bcx.sess().intr()),
|
pat.repr(bcx.tcx()),
|
||||||
binding_mode);
|
binding_mode);
|
||||||
|
|
||||||
if bcx.sess().asm_comments() {
|
if bcx.sess().asm_comments() {
|
||||||
add_comment(bcx, fmt!("bind_irrefutable_pat(pat=%s)",
|
add_comment(bcx, fmt!("bind_irrefutable_pat(pat=%s)",
|
||||||
pat_to_str(pat, bcx.sess().intr())));
|
pat.repr(bcx.tcx())));
|
||||||
}
|
}
|
||||||
|
|
||||||
let _indenter = indenter();
|
let _indenter = indenter();
|
||||||
|
|
|
@ -260,7 +260,7 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] {
|
||||||
most_aligned = Some(st);
|
most_aligned = Some(st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let most_aligned = most_aligned.get();
|
let most_aligned = most_aligned.unwrap();
|
||||||
let padding = largest_size - most_aligned.size;
|
let padding = largest_size - most_aligned.size;
|
||||||
|
|
||||||
struct_llfields(cx, most_aligned, sizing)
|
struct_llfields(cx, most_aligned, sizing)
|
||||||
|
|
|
@ -1322,7 +1322,7 @@ pub fn cleanup_and_leave(bcx: @mut Block,
|
||||||
}
|
}
|
||||||
match leave {
|
match leave {
|
||||||
Some(target) => Br(bcx, target),
|
Some(target) => Br(bcx, target),
|
||||||
None => { Resume(bcx, Load(bcx, bcx.fcx.personality.get())); }
|
None => { Resume(bcx, Load(bcx, bcx.fcx.personality.unwrap())); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1530,7 +1530,7 @@ pub fn alloca_maybe_zeroed(cx: @mut Block, ty: Type, name: &str, zero: bool) ->
|
||||||
let p = Alloca(cx, ty, name);
|
let p = Alloca(cx, ty, name);
|
||||||
if zero {
|
if zero {
|
||||||
let b = cx.fcx.ccx.builder();
|
let b = cx.fcx.ccx.builder();
|
||||||
b.position_before(cx.fcx.alloca_insert_pt.get());
|
b.position_before(cx.fcx.alloca_insert_pt.unwrap());
|
||||||
memzero(&b, p, ty);
|
memzero(&b, p, ty);
|
||||||
}
|
}
|
||||||
p
|
p
|
||||||
|
@ -1576,7 +1576,7 @@ pub fn make_return_pointer(fcx: @mut FunctionContext, output_type: ty::t) -> Val
|
||||||
llvm::LLVMGetParam(fcx.llfn, 0)
|
llvm::LLVMGetParam(fcx.llfn, 0)
|
||||||
} else {
|
} else {
|
||||||
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
|
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
Alloca(bcx, lloutputtype, "__make_return_pointer")
|
Alloca(bcx, lloutputtype, "__make_return_pointer")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1794,7 +1794,7 @@ pub fn finish_fn(fcx: @mut FunctionContext, last_bcx: @mut Block) {
|
||||||
pub fn build_return_block(fcx: &FunctionContext, ret_cx: @mut Block) {
|
pub fn build_return_block(fcx: &FunctionContext, ret_cx: @mut Block) {
|
||||||
// Return the value if this function immediate; otherwise, return void.
|
// Return the value if this function immediate; otherwise, return void.
|
||||||
if fcx.llretptr.is_some() && fcx.has_immediate_return_value {
|
if fcx.llretptr.is_some() && fcx.has_immediate_return_value {
|
||||||
Ret(ret_cx, Load(ret_cx, fcx.llretptr.get()))
|
Ret(ret_cx, Load(ret_cx, fcx.llretptr.unwrap()))
|
||||||
} else {
|
} else {
|
||||||
RetVoid(ret_cx)
|
RetVoid(ret_cx)
|
||||||
}
|
}
|
||||||
|
@ -1844,7 +1844,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
|
||||||
|
|
||||||
// Create the first basic block in the function and keep a handle on it to
|
// Create the first basic block in the function and keep a handle on it to
|
||||||
// pass to finish_fn later.
|
// pass to finish_fn later.
|
||||||
let bcx_top = fcx.entry_bcx.get();
|
let bcx_top = fcx.entry_bcx.unwrap();
|
||||||
let mut bcx = bcx_top;
|
let mut bcx = bcx_top;
|
||||||
let block_ty = node_id_type(bcx, body.id);
|
let block_ty = node_id_type(bcx, body.id);
|
||||||
|
|
||||||
|
@ -1862,7 +1862,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
|
||||||
{
|
{
|
||||||
bcx = controlflow::trans_block(bcx, body, expr::Ignore);
|
bcx = controlflow::trans_block(bcx, body, expr::Ignore);
|
||||||
} else {
|
} else {
|
||||||
let dest = expr::SaveIn(fcx.llretptr.get());
|
let dest = expr::SaveIn(fcx.llretptr.unwrap());
|
||||||
bcx = controlflow::trans_block(bcx, body, dest);
|
bcx = controlflow::trans_block(bcx, body, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2056,18 +2056,18 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
|
||||||
|
|
||||||
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
|
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
|
||||||
|
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
let arg_tys = ty::ty_fn_args(ctor_ty);
|
let arg_tys = ty::ty_fn_args(ctor_ty);
|
||||||
|
|
||||||
insert_synthetic_type_entries(bcx, fn_args, arg_tys);
|
insert_synthetic_type_entries(bcx, fn_args, arg_tys);
|
||||||
let bcx = copy_args_to_allocas(fcx, bcx, fn_args, raw_llargs, arg_tys);
|
let bcx = copy_args_to_allocas(fcx, bcx, fn_args, raw_llargs, arg_tys);
|
||||||
|
|
||||||
let repr = adt::represent_type(ccx, result_ty);
|
let repr = adt::represent_type(ccx, result_ty);
|
||||||
adt::trans_start_init(bcx, repr, fcx.llretptr.get(), disr);
|
adt::trans_start_init(bcx, repr, fcx.llretptr.unwrap(), disr);
|
||||||
for (i, fn_arg) in fn_args.iter().enumerate() {
|
for (i, fn_arg) in fn_args.iter().enumerate() {
|
||||||
let lldestptr = adt::trans_field_ptr(bcx,
|
let lldestptr = adt::trans_field_ptr(bcx,
|
||||||
repr,
|
repr,
|
||||||
fcx.llretptr.get(),
|
fcx.llretptr.unwrap(),
|
||||||
disr,
|
disr,
|
||||||
i);
|
i);
|
||||||
let llarg = fcx.llargs.get_copy(&fn_arg.pat.id);
|
let llarg = fcx.llargs.get_copy(&fn_arg.pat.id);
|
||||||
|
@ -2217,25 +2217,16 @@ pub fn trans_mod(ccx: @mut CrateContext, m: &ast::_mod) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_fn(ccx: @mut CrateContext,
|
pub fn register_fn(ccx: @mut CrateContext,
|
||||||
sp: span,
|
|
||||||
sym: ~str,
|
|
||||||
node_id: ast::NodeId)
|
|
||||||
-> ValueRef {
|
|
||||||
let t = ty::node_id_to_type(ccx.tcx, node_id);
|
|
||||||
register_fn_full(ccx, sp, sym, node_id, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_fn_full(ccx: @mut CrateContext,
|
|
||||||
sp: span,
|
sp: span,
|
||||||
sym: ~str,
|
sym: ~str,
|
||||||
node_id: ast::NodeId,
|
node_id: ast::NodeId,
|
||||||
node_type: ty::t)
|
node_type: ty::t)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
let llfty = type_of_fn_from_ty(ccx, node_type);
|
let llfty = type_of_fn_from_ty(ccx, node_type);
|
||||||
register_fn_fuller(ccx, sp, sym, node_id, lib::llvm::CCallConv, llfty)
|
register_fn_llvmty(ccx, sp, sym, node_id, lib::llvm::CCallConv, llfty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_fn_fuller(ccx: @mut CrateContext,
|
pub fn register_fn_llvmty(ccx: @mut CrateContext,
|
||||||
sp: span,
|
sp: span,
|
||||||
sym: ~str,
|
sym: ~str,
|
||||||
node_id: ast::NodeId,
|
node_id: ast::NodeId,
|
||||||
|
@ -2294,7 +2285,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
|
||||||
// be updated if this assertion starts to fail.
|
// be updated if this assertion starts to fail.
|
||||||
assert!(fcx.has_immediate_return_value);
|
assert!(fcx.has_immediate_return_value);
|
||||||
|
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
// Call main.
|
// Call main.
|
||||||
let llenvarg = unsafe {
|
let llenvarg = unsafe {
|
||||||
let env_arg = fcx.env_arg_pos();
|
let env_arg = fcx.env_arg_pos();
|
||||||
|
@ -2449,7 +2440,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
|
||||||
|
|
||||||
ast::item_fn(_, purity, _, _, _) => {
|
ast::item_fn(_, purity, _, _, _) => {
|
||||||
let llfn = if purity != ast::extern_fn {
|
let llfn = if purity != ast::extern_fn {
|
||||||
register_fn_full(ccx, i.span, sym, i.id, ty)
|
register_fn(ccx, i.span, sym, i.id, ty)
|
||||||
} else {
|
} else {
|
||||||
foreign::register_foreign_fn(ccx, i.span, sym, i.id)
|
foreign::register_foreign_fn(ccx, i.span, sym, i.id)
|
||||||
};
|
};
|
||||||
|
@ -2499,7 +2490,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
|
||||||
let path = vec::append((*pth).clone(), [path_name(ni.ident)]);
|
let path = vec::append((*pth).clone(), [path_name(ni.ident)]);
|
||||||
let sym = exported_name(ccx, path, ty, ni.attrs);
|
let sym = exported_name(ccx, path, ty, ni.attrs);
|
||||||
|
|
||||||
register_fn_full(ccx, ni.span, sym, ni.id, ty)
|
register_fn(ccx, ni.span, sym, ni.id, ty)
|
||||||
}
|
}
|
||||||
ast::foreign_item_static(*) => {
|
ast::foreign_item_static(*) => {
|
||||||
let ident = token::ident_to_str(&ni.ident);
|
let ident = token::ident_to_str(&ni.ident);
|
||||||
|
@ -2527,7 +2518,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
|
||||||
|
|
||||||
llfn = match enm.node {
|
llfn = match enm.node {
|
||||||
ast::item_enum(_, _) => {
|
ast::item_enum(_, _) => {
|
||||||
register_fn_full(ccx, (*v).span, sym, id, ty)
|
register_fn(ccx, (*v).span, sym, id, ty)
|
||||||
}
|
}
|
||||||
_ => fail!("node_variant, shouldn't happen")
|
_ => fail!("node_variant, shouldn't happen")
|
||||||
};
|
};
|
||||||
|
@ -2551,7 +2542,8 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
|
||||||
let ty = ty::node_id_to_type(ccx.tcx, ctor_id);
|
let ty = ty::node_id_to_type(ccx.tcx, ctor_id);
|
||||||
let sym = exported_name(ccx, (*struct_path).clone(), ty,
|
let sym = exported_name(ccx, (*struct_path).clone(), ty,
|
||||||
struct_item.attrs);
|
struct_item.attrs);
|
||||||
let llfn = register_fn_full(ccx, struct_item.span, sym, ctor_id, ty);
|
let llfn = register_fn(ccx, struct_item.span,
|
||||||
|
sym, ctor_id, ty);
|
||||||
set_inline_hint(llfn);
|
set_inline_hint(llfn);
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
|
@ -2586,7 +2578,7 @@ pub fn register_method(ccx: @mut CrateContext,
|
||||||
|
|
||||||
let sym = exported_name(ccx, path, mty, m.attrs);
|
let sym = exported_name(ccx, path, mty, m.attrs);
|
||||||
|
|
||||||
let llfn = register_fn_full(ccx, m.span, sym, id, mty);
|
let llfn = register_fn(ccx, m.span, sym, id, mty);
|
||||||
set_inline_hint_if_appr(m.attrs, llfn);
|
set_inline_hint_if_appr(m.attrs, llfn);
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
|
@ -2782,7 +2774,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
for key in keys.iter() {
|
for key in keys.iter() {
|
||||||
let val = *ccx.module_data.find_equiv(key).get();
|
let val = *ccx.module_data.find_equiv(key).unwrap();
|
||||||
let s_const = C_cstr(ccx, *key);
|
let s_const = C_cstr(ccx, *key);
|
||||||
let s_ptr = p2i(ccx, s_const);
|
let s_ptr = p2i(ccx, s_const);
|
||||||
let v_ptr = p2i(ccx, val);
|
let v_ptr = p2i(ccx, val);
|
||||||
|
|
|
@ -319,7 +319,7 @@ pub fn Alloca(cx: @mut Block, Ty: Type, name: &str) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
|
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
|
||||||
let b = cx.fcx.ccx.builder();
|
let b = cx.fcx.ccx.builder();
|
||||||
b.position_before(cx.fcx.alloca_insert_pt.get());
|
b.position_before(cx.fcx.alloca_insert_pt.unwrap());
|
||||||
b.alloca(Ty, name)
|
b.alloca(Ty, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +328,7 @@ pub fn ArrayAlloca(cx: @mut Block, Ty: Type, Val: ValueRef) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
|
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
|
||||||
let b = cx.fcx.ccx.builder();
|
let b = cx.fcx.ccx.builder();
|
||||||
b.position_before(cx.fcx.alloca_insert_pt.get());
|
b.position_before(cx.fcx.alloca_insert_pt.unwrap());
|
||||||
b.array_alloca(Ty, Val)
|
b.array_alloca(Ty, Val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,7 @@ impl FnType {
|
||||||
} else {
|
} else {
|
||||||
Load(bcx, llretval)
|
Load(bcx, llretval)
|
||||||
};
|
};
|
||||||
let llretptr = BitCast(bcx, bcx.fcx.llretptr.get(), self.ret_ty.ty.ptr_to());
|
let llretptr = BitCast(bcx, bcx.fcx.llretptr.unwrap(), self.ret_ty.ty.ptr_to());
|
||||||
Store(bcx, llretval, llretptr);
|
Store(bcx, llretval, llretptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,7 +330,7 @@ pub fn load_environment(fcx: @mut FunctionContext,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
|
|
||||||
// Load a pointer to the closure data, skipping over the box header:
|
// Load a pointer to the closure data, skipping over the box header:
|
||||||
let llcdata = opaque_box_body(bcx, cdata_ty, fcx.llenv);
|
let llcdata = opaque_box_body(bcx, cdata_ty, fcx.llenv);
|
||||||
|
@ -443,7 +443,7 @@ pub fn trans_expr_fn(bcx: @mut Block,
|
||||||
if is_loop_body.is_some() {
|
if is_loop_body.is_some() {
|
||||||
Store(bcx,
|
Store(bcx,
|
||||||
C_bool(true),
|
C_bool(true),
|
||||||
bcx.fcx.llretptr.get());
|
bcx.fcx.llretptr.unwrap());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
rslt(bcx, llbox)
|
rslt(bcx, llbox)
|
||||||
|
|
|
@ -252,7 +252,7 @@ impl FunctionContext {
|
||||||
|
|
||||||
pub fn cleanup(&mut self) {
|
pub fn cleanup(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt.get());
|
llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt.unwrap());
|
||||||
}
|
}
|
||||||
// Remove the cycle between fcx and bcx, so memory can be freed
|
// Remove the cycle between fcx and bcx, so memory can be freed
|
||||||
self.entry_bcx = None;
|
self.entry_bcx = None;
|
||||||
|
@ -263,7 +263,7 @@ impl FunctionContext {
|
||||||
self.llreturn = Some(base::mk_return_basic_block(self.llfn));
|
self.llreturn = Some(base::mk_return_basic_block(self.llfn));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.llreturn.get()
|
self.llreturn.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ pub fn trans_break_cont(bcx: @mut Block,
|
||||||
Some(bcx) => bcx,
|
Some(bcx) => bcx,
|
||||||
// This is a return from a loop body block
|
// This is a return from a loop body block
|
||||||
None => {
|
None => {
|
||||||
Store(bcx, C_bool(!to_end), bcx.fcx.llretptr.get());
|
Store(bcx, C_bool(!to_end), bcx.fcx.llretptr.unwrap());
|
||||||
cleanup_and_leave(bcx, None, Some(bcx.fcx.get_llreturn()));
|
cleanup_and_leave(bcx, None, Some(bcx.fcx.get_llreturn()));
|
||||||
Unreachable(bcx);
|
Unreachable(bcx);
|
||||||
return bcx;
|
return bcx;
|
||||||
|
@ -347,7 +347,7 @@ pub fn trans_ret(bcx: @mut Block, e: Option<@ast::expr>) -> @mut Block {
|
||||||
// to false, return flag to true, and then store the value in the
|
// to false, return flag to true, and then store the value in the
|
||||||
// parent's retptr.
|
// parent's retptr.
|
||||||
Store(bcx, C_bool(true), flagptr);
|
Store(bcx, C_bool(true), flagptr);
|
||||||
Store(bcx, C_bool(false), bcx.fcx.llretptr.get());
|
Store(bcx, C_bool(false), bcx.fcx.llretptr.unwrap());
|
||||||
expr::SaveIn(match e {
|
expr::SaveIn(match e {
|
||||||
Some(x) => PointerCast(bcx, retptr,
|
Some(x) => PointerCast(bcx, retptr,
|
||||||
type_of(bcx.ccx(), expr_ty(bcx, x)).ptr_to()),
|
type_of(bcx.ccx(), expr_ty(bcx, x)).ptr_to()),
|
||||||
|
|
|
@ -486,8 +486,8 @@ fn lexical_block_metadata(bcx: @mut Block) -> DILexicalBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = bcx.node_info.get().span;
|
let span = bcx.node_info.unwrap().span;
|
||||||
let id = bcx.node_info.get().id;
|
let id = bcx.node_info.unwrap().id;
|
||||||
|
|
||||||
// Check whether we already have a cache entry for this node id
|
// Check whether we already have a cache entry for this node id
|
||||||
match dbg_cx(cx).created_blocks.find(&id) {
|
match dbg_cx(cx).created_blocks.find(&id) {
|
||||||
|
|
|
@ -149,7 +149,7 @@ fn build_shim_fn_(ccx: @mut CrateContext,
|
||||||
|
|
||||||
// Declare the body of the shim function:
|
// Declare the body of the shim function:
|
||||||
let fcx = new_fn_ctxt(ccx, ~[], llshimfn, tys.fn_sig.output, None);
|
let fcx = new_fn_ctxt(ccx, ~[], llshimfn, tys.fn_sig.output, None);
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
|
|
||||||
let llargbundle = get_param(llshimfn, 0u);
|
let llargbundle = get_param(llshimfn, 0u);
|
||||||
let llargvals = arg_builder(bcx, tys, llargbundle);
|
let llargvals = arg_builder(bcx, tys, llargbundle);
|
||||||
|
@ -190,7 +190,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
|
||||||
ret_builder: wrap_ret_builder) {
|
ret_builder: wrap_ret_builder) {
|
||||||
let _icx = push_ctxt("foreign::build_wrap_fn_");
|
let _icx = push_ctxt("foreign::build_wrap_fn_");
|
||||||
let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None);
|
let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None);
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
|
|
||||||
// Patch up the return type if it's not immediate and we're returning via
|
// Patch up the return type if it's not immediate and we're returning via
|
||||||
// the C ABI.
|
// the C ABI.
|
||||||
|
@ -226,7 +226,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
|
||||||
} else {
|
} else {
|
||||||
// Cast if we have to...
|
// Cast if we have to...
|
||||||
// XXX: This is ugly.
|
// XXX: This is ugly.
|
||||||
let llretptr = BitCast(return_context, fcx.llretptr.get(), return_type.ptr_to());
|
let llretptr = BitCast(return_context, fcx.llretptr.unwrap(), return_type.ptr_to());
|
||||||
Ret(return_context, Load(return_context, llretptr));
|
Ret(return_context, Load(return_context, llretptr));
|
||||||
}
|
}
|
||||||
fcx.cleanup();
|
fcx.cleanup();
|
||||||
|
@ -421,7 +421,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
|
||||||
debug!("build_direct_fn(%s)", link_name(ccx, item));
|
debug!("build_direct_fn(%s)", link_name(ccx, item));
|
||||||
|
|
||||||
let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
|
let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc);
|
let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc);
|
||||||
let ty = ty::lookup_item_type(ccx.tcx,
|
let ty = ty::lookup_item_type(ccx.tcx,
|
||||||
ast_util::local_def(item.id)).ty;
|
ast_util::local_def(item.id)).ty;
|
||||||
|
@ -431,7 +431,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
|
||||||
});
|
});
|
||||||
let retval = Call(bcx, llbasefn, args);
|
let retval = Call(bcx, llbasefn, args);
|
||||||
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
|
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
|
||||||
Store(bcx, retval, fcx.llretptr.get());
|
Store(bcx, retval, fcx.llretptr.unwrap());
|
||||||
}
|
}
|
||||||
finish_fn(fcx, bcx);
|
finish_fn(fcx, bcx);
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
|
||||||
debug!("build_fast_ffi_fn(%s)", link_name(ccx, item));
|
debug!("build_fast_ffi_fn(%s)", link_name(ccx, item));
|
||||||
|
|
||||||
let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
|
let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc);
|
let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc);
|
||||||
set_no_inline(fcx.llfn);
|
set_no_inline(fcx.llfn);
|
||||||
set_fixed_stack_segment(fcx.llfn);
|
set_fixed_stack_segment(fcx.llfn);
|
||||||
|
@ -458,7 +458,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
|
||||||
});
|
});
|
||||||
let retval = Call(bcx, llbasefn, args);
|
let retval = Call(bcx, llbasefn, args);
|
||||||
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
|
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
|
||||||
Store(bcx, retval, fcx.llretptr.get());
|
Store(bcx, retval, fcx.llretptr.unwrap());
|
||||||
}
|
}
|
||||||
finish_fn(fcx, bcx);
|
finish_fn(fcx, bcx);
|
||||||
}
|
}
|
||||||
|
@ -618,7 +618,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
|
||||||
set_fixed_stack_segment(fcx.llfn);
|
set_fixed_stack_segment(fcx.llfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut bcx = fcx.entry_bcx.get();
|
let mut bcx = fcx.entry_bcx.unwrap();
|
||||||
let first_real_arg = fcx.arg_pos(0u);
|
let first_real_arg = fcx.arg_pos(0u);
|
||||||
|
|
||||||
let nm = ccx.sess.str_of(item.ident);
|
let nm = ccx.sess.str_of(item.ident);
|
||||||
|
@ -775,7 +775,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
|
||||||
let in_type_size = machine::llbitsize_of_real(ccx, llintype);
|
let in_type_size = machine::llbitsize_of_real(ccx, llintype);
|
||||||
let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
|
let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
|
||||||
if in_type_size != out_type_size {
|
if in_type_size != out_type_size {
|
||||||
let sp = match ccx.tcx.items.get_copy(&ref_id.get()) {
|
let sp = match ccx.tcx.items.get_copy(&ref_id.unwrap()) {
|
||||||
ast_map::node_expr(e) => e.span,
|
ast_map::node_expr(e) => e.span,
|
||||||
_ => fail!("transmute has non-expr arg"),
|
_ => fail!("transmute has non-expr arg"),
|
||||||
};
|
};
|
||||||
|
@ -816,7 +816,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
|
||||||
// NB: Do not use a Load and Store here. This causes massive
|
// NB: Do not use a Load and Store here. This causes massive
|
||||||
// code bloat when `transmute` is used on large structural
|
// code bloat when `transmute` is used on large structural
|
||||||
// types.
|
// types.
|
||||||
let lldestptr = fcx.llretptr.get();
|
let lldestptr = fcx.llretptr.unwrap();
|
||||||
let lldestptr = PointerCast(bcx, lldestptr, Type::i8p());
|
let lldestptr = PointerCast(bcx, lldestptr, Type::i8p());
|
||||||
let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p());
|
let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p());
|
||||||
|
|
||||||
|
@ -1157,6 +1157,6 @@ pub fn register_foreign_fn(ccx: @mut CrateContext,
|
||||||
|
|
||||||
let tys = shim_types(ccx, node_id);
|
let tys = shim_types(ccx, node_id);
|
||||||
do tys.fn_ty.decl_fn |fnty| {
|
do tys.fn_ty.decl_fn |fnty| {
|
||||||
register_fn_fuller(ccx, sp, sym.take(), node_id, lib::llvm::CCallConv, fnty)
|
register_fn_llvmty(ccx, sp, sym.take(), node_id, lib::llvm::CCallConv, fnty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,7 @@ pub fn call_tydesc_glue_full(bcx: @mut Block,
|
||||||
let llrawptr = if static_ti.is_none() || static_glue_fn.is_none() {
|
let llrawptr = if static_ti.is_none() || static_glue_fn.is_none() {
|
||||||
PointerCast(bcx, v, Type::i8p())
|
PointerCast(bcx, v, Type::i8p())
|
||||||
} else {
|
} else {
|
||||||
let ty = static_ti.get().ty;
|
let ty = static_ti.unwrap().ty;
|
||||||
let simpl = simplified_glue_type(ccx.tcx, field, ty);
|
let simpl = simplified_glue_type(ccx.tcx, field, ty);
|
||||||
if simpl != ty {
|
if simpl != ty {
|
||||||
PointerCast(bcx, v, type_of(ccx, simpl).ptr_to())
|
PointerCast(bcx, v, type_of(ccx, simpl).ptr_to())
|
||||||
|
@ -709,7 +709,7 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext,
|
||||||
// llfn is expected be declared to take a parameter of the appropriate
|
// llfn is expected be declared to take a parameter of the appropriate
|
||||||
// type, so we don't need to explicitly cast the function parameter.
|
// type, so we don't need to explicitly cast the function parameter.
|
||||||
|
|
||||||
let bcx = fcx.entry_bcx.get();
|
let bcx = fcx.entry_bcx.unwrap();
|
||||||
let rawptr0_arg = fcx.arg_pos(0u);
|
let rawptr0_arg = fcx.arg_pos(0u);
|
||||||
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
|
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
|
||||||
let bcx = helper(bcx, llrawptr0, t);
|
let bcx = helper(bcx, llrawptr0, t);
|
||||||
|
|
|
@ -180,7 +180,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||||
let idx = psubsts.tys.len() - num_method_ty_params;
|
let idx = psubsts.tys.len() - num_method_ty_params;
|
||||||
let substs =
|
let substs =
|
||||||
(psubsts.tys.slice(0, idx) +
|
(psubsts.tys.slice(0, idx) +
|
||||||
&[psubsts.self_ty.get()] +
|
&[psubsts.self_ty.unwrap()] +
|
||||||
psubsts.tys.tailn(idx));
|
psubsts.tys.tailn(idx));
|
||||||
debug!("static default: changed substitution to %s",
|
debug!("static default: changed substitution to %s",
|
||||||
substs.repr(ccx.tcx));
|
substs.repr(ccx.tcx));
|
||||||
|
@ -245,7 +245,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||||
}
|
}
|
||||||
ast_map::node_variant(ref v, enum_item, _) => {
|
ast_map::node_variant(ref v, enum_item, _) => {
|
||||||
let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id));
|
let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id));
|
||||||
let this_tv = *tvs.iter().find_(|tv| { tv.id.node == fn_id.node}).get();
|
let this_tv = *tvs.iter().find_(|tv| { tv.id.node == fn_id.node}).unwrap();
|
||||||
let d = mk_lldecl();
|
let d = mk_lldecl();
|
||||||
set_inline_hint(d);
|
set_inline_hint(d);
|
||||||
match v.node.kind {
|
match v.node.kind {
|
||||||
|
|
|
@ -303,10 +303,10 @@ impl Reflector {
|
||||||
//
|
//
|
||||||
llvm::LLVMGetParam(llfdecl, fcx.arg_pos(0u) as c_uint)
|
llvm::LLVMGetParam(llfdecl, fcx.arg_pos(0u) as c_uint)
|
||||||
};
|
};
|
||||||
let mut bcx = fcx.entry_bcx.get();
|
let mut bcx = fcx.entry_bcx.unwrap();
|
||||||
let arg = BitCast(bcx, arg, llptrty);
|
let arg = BitCast(bcx, arg, llptrty);
|
||||||
let ret = adt::trans_get_discr(bcx, repr, arg);
|
let ret = adt::trans_get_discr(bcx, repr, arg);
|
||||||
Store(bcx, ret, fcx.llretptr.get());
|
Store(bcx, ret, fcx.llretptr.unwrap());
|
||||||
match fcx.llreturn {
|
match fcx.llreturn {
|
||||||
Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn),
|
Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn),
|
||||||
None => bcx = cleanup_block(bcx, Some(bcx.llbb))
|
None => bcx = cleanup_block(bcx, Some(bcx.llbb))
|
||||||
|
|
|
@ -239,7 +239,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
|
||||||
|
|
||||||
ty::ty_estr(ty::vstore_slice(_)) => {
|
ty::ty_estr(ty::vstore_slice(_)) => {
|
||||||
// This means we get a nicer name in the output
|
// This means we get a nicer name in the output
|
||||||
cx.tn.find_type("str_slice").get()
|
cx.tn.find_type("str_slice").unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ty_estr(ty::vstore_fixed(n)) => {
|
ty::ty_estr(ty::vstore_fixed(n)) => {
|
||||||
|
|
|
@ -25,7 +25,6 @@ use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str};
|
||||||
use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str};
|
use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str};
|
||||||
use util::ppaux::{Repr, UserString};
|
use util::ppaux::{Repr, UserString};
|
||||||
use util::common::{indenter};
|
use util::common::{indenter};
|
||||||
use util::enum_set::{EnumSet, CLike};
|
|
||||||
|
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
@ -33,6 +32,7 @@ use std::hashmap::{HashMap, HashSet};
|
||||||
use std::ops;
|
use std::ops;
|
||||||
use std::ptr::to_unsafe_ptr;
|
use std::ptr::to_unsafe_ptr;
|
||||||
use std::to_bytes;
|
use std::to_bytes;
|
||||||
|
use std::to_str::ToStr;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
|
@ -47,6 +47,7 @@ use syntax::opt_vec::OptVec;
|
||||||
use syntax::opt_vec;
|
use syntax::opt_vec;
|
||||||
use syntax::abi::AbiSet;
|
use syntax::abi::AbiSet;
|
||||||
use syntax;
|
use syntax;
|
||||||
|
use extra::enum_set::{EnumSet, CLike};
|
||||||
|
|
||||||
pub static INITIAL_DISCRIMINANT_VALUE: uint = 0;
|
pub static INITIAL_DISCRIMINANT_VALUE: uint = 0;
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ pub struct mt {
|
||||||
mutbl: ast::mutability,
|
mutbl: ast::mutability,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes, ToStr)]
|
||||||
pub enum vstore {
|
pub enum vstore {
|
||||||
vstore_fixed(uint),
|
vstore_fixed(uint),
|
||||||
vstore_uniq,
|
vstore_uniq,
|
||||||
|
@ -124,7 +125,7 @@ pub enum vstore {
|
||||||
vstore_slice(Region)
|
vstore_slice(Region)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
|
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr)]
|
||||||
pub enum TraitStore {
|
pub enum TraitStore {
|
||||||
BoxTraitStore, // @Trait
|
BoxTraitStore, // @Trait
|
||||||
UniqTraitStore, // ~Trait
|
UniqTraitStore, // ~Trait
|
||||||
|
@ -350,6 +351,12 @@ pub struct t_box_ {
|
||||||
enum t_opaque {}
|
enum t_opaque {}
|
||||||
pub type t = *t_opaque;
|
pub type t = *t_opaque;
|
||||||
|
|
||||||
|
impl ToStr for t {
|
||||||
|
fn to_str(&self) -> ~str {
|
||||||
|
~"*t_opaque"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(t: t) -> t_box {
|
pub fn get(t: t) -> t_box {
|
||||||
unsafe {
|
unsafe {
|
||||||
let t2: t_box = cast::transmute(t);
|
let t2: t_box = cast::transmute(t);
|
||||||
|
@ -410,7 +417,7 @@ pub struct param_ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Representation of regions:
|
/// Representation of regions:
|
||||||
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
|
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr)]
|
||||||
pub enum Region {
|
pub enum Region {
|
||||||
/// Bound regions are found (primarily) in function types. They indicate
|
/// Bound regions are found (primarily) in function types. They indicate
|
||||||
/// region parameters that have yet to be replaced with actual regions
|
/// region parameters that have yet to be replaced with actual regions
|
||||||
|
@ -456,13 +463,13 @@ impl Region {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
|
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr)]
|
||||||
pub struct FreeRegion {
|
pub struct FreeRegion {
|
||||||
scope_id: NodeId,
|
scope_id: NodeId,
|
||||||
bound_region: bound_region
|
bound_region: bound_region
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
|
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr)]
|
||||||
pub enum bound_region {
|
pub enum bound_region {
|
||||||
/// The self region for structs, impls (&T in a type defn or &'self T)
|
/// The self region for structs, impls (&T in a type defn or &'self T)
|
||||||
br_self,
|
br_self,
|
||||||
|
@ -620,19 +627,22 @@ pub enum IntVarValue {
|
||||||
UintType(ast::uint_ty),
|
UintType(ast::uint_ty),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone, ToStr)]
|
||||||
pub enum terr_vstore_kind {
|
pub enum terr_vstore_kind {
|
||||||
terr_vec, terr_str, terr_fn, terr_trait
|
terr_vec,
|
||||||
|
terr_str,
|
||||||
|
terr_fn,
|
||||||
|
terr_trait
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone, ToStr)]
|
||||||
pub struct expected_found<T> {
|
pub struct expected_found<T> {
|
||||||
expected: T,
|
expected: T,
|
||||||
found: T
|
found: T
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data structures used in type unification
|
// Data structures used in type unification
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone, ToStr)]
|
||||||
pub enum type_err {
|
pub enum type_err {
|
||||||
terr_mismatch,
|
terr_mismatch,
|
||||||
terr_purity_mismatch(expected_found<purity>),
|
terr_purity_mismatch(expected_found<purity>),
|
||||||
|
@ -674,7 +684,7 @@ pub struct ParamBounds {
|
||||||
|
|
||||||
pub type BuiltinBounds = EnumSet<BuiltinBound>;
|
pub type BuiltinBounds = EnumSet<BuiltinBound>;
|
||||||
|
|
||||||
#[deriving(Clone, Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes, ToStr)]
|
||||||
pub enum BuiltinBound {
|
pub enum BuiltinBound {
|
||||||
BoundStatic,
|
BoundStatic,
|
||||||
BoundSend,
|
BoundSend,
|
||||||
|
@ -725,7 +735,7 @@ pub enum InferTy {
|
||||||
FloatVar(FloatVid)
|
FloatVar(FloatVid)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Encodable, Decodable, IterBytes, ToStr)]
|
||||||
pub enum InferRegion {
|
pub enum InferRegion {
|
||||||
ReVar(RegionVid),
|
ReVar(RegionVid),
|
||||||
ReSkolemized(uint, bound_region)
|
ReSkolemized(uint, bound_region)
|
||||||
|
@ -2277,7 +2287,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||||
// This is like with typarams below, but less "pessimistic" and also
|
// This is like with typarams below, but less "pessimistic" and also
|
||||||
// dependent on the trait store.
|
// dependent on the trait store.
|
||||||
let mut bt = TC_NONE;
|
let mut bt = TC_NONE;
|
||||||
do (AllBuiltinBounds() - bounds).each |bound| {
|
for bound in (AllBuiltinBounds() - bounds).iter() {
|
||||||
bt = bt + match bound {
|
bt = bt + match bound {
|
||||||
BoundStatic if bounds.contains_elem(BoundSend)
|
BoundStatic if bounds.contains_elem(BoundSend)
|
||||||
=> TC_NONE, // Send bound implies static bound.
|
=> TC_NONE, // Send bound implies static bound.
|
||||||
|
@ -2286,8 +2296,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||||
BoundFreeze => TC_MUTABLE,
|
BoundFreeze => TC_MUTABLE,
|
||||||
BoundSized => TC_NONE, // don't care if interior is sized
|
BoundSized => TC_NONE, // don't care if interior is sized
|
||||||
};
|
};
|
||||||
true
|
}
|
||||||
};
|
|
||||||
st + mt + bt
|
st + mt + bt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2298,7 +2307,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||||
let _i = indenter();
|
let _i = indenter();
|
||||||
|
|
||||||
let mut tc = TC_ALL;
|
let mut tc = TC_ALL;
|
||||||
do type_param_def.bounds.builtin_bounds.each |bound| {
|
for bound in type_param_def.bounds.builtin_bounds.iter() {
|
||||||
debug!("tc = %s, bound = %?", tc.to_str(), bound);
|
debug!("tc = %s, bound = %?", tc.to_str(), bound);
|
||||||
tc = tc - match bound {
|
tc = tc - match bound {
|
||||||
BoundStatic => TypeContents::nonstatic(cx),
|
BoundStatic => TypeContents::nonstatic(cx),
|
||||||
|
@ -2307,8 +2316,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||||
// The dynamic-size bit can be removed at pointer-level, etc.
|
// The dynamic-size bit can be removed at pointer-level, etc.
|
||||||
BoundSized => TypeContents::dynamically_sized(cx),
|
BoundSized => TypeContents::dynamically_sized(cx),
|
||||||
};
|
};
|
||||||
true
|
}
|
||||||
};
|
|
||||||
|
|
||||||
debug!("result = %s", tc.to_str());
|
debug!("result = %s", tc.to_str());
|
||||||
return tc;
|
return tc;
|
||||||
|
|
|
@ -531,7 +531,7 @@ pub fn ty_of_arg<AC:AstConv,
|
||||||
expected_ty: Option<ty::t>)
|
expected_ty: Option<ty::t>)
|
||||||
-> ty::t {
|
-> ty::t {
|
||||||
match a.ty.node {
|
match a.ty.node {
|
||||||
ast::ty_infer if expected_ty.is_some() => expected_ty.get(),
|
ast::ty_infer if expected_ty.is_some() => expected_ty.unwrap(),
|
||||||
ast::ty_infer => this.ty_infer(a.ty.span),
|
ast::ty_infer => this.ty_infer(a.ty.span),
|
||||||
_ => ast_ty_to_ty(this, rscope, &a.ty),
|
_ => ast_ty_to_ty(this, rscope, &a.ty),
|
||||||
}
|
}
|
||||||
|
@ -587,7 +587,7 @@ pub fn ty_of_method<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
};
|
};
|
||||||
let (a, b) = ty_of_method_or_bare_fn(
|
let (a, b) = ty_of_method_or_bare_fn(
|
||||||
this, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
|
this, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
|
||||||
(a.get(), b)
|
(a.unwrap(), b)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Clone + 'static>(
|
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
|
@ -735,7 +735,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
|
|
||||||
let expected_ret_ty = expected_sig.map(|e| e.output);
|
let expected_ret_ty = expected_sig.map(|e| e.output);
|
||||||
let output_ty = match decl.output.node {
|
let output_ty = match decl.output.node {
|
||||||
ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(),
|
ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.unwrap(),
|
||||||
ast::ty_infer => this.ty_infer(decl.output.span),
|
ast::ty_infer => this.ty_infer(decl.output.span),
|
||||||
_ => ast_ty_to_ty(this, &rb, &decl.output)
|
_ => ast_ty_to_ty(this, &rb, &decl.output)
|
||||||
};
|
};
|
||||||
|
|
|
@ -166,7 +166,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
|
||||||
fcx.write_error(pat.id);
|
fcx.write_error(pat.id);
|
||||||
kind_name = "[error]";
|
kind_name = "[error]";
|
||||||
arg_types = (*subpats).clone()
|
arg_types = (*subpats).clone()
|
||||||
.get_or_default(~[])
|
.unwrap_or_default(~[])
|
||||||
.map(|_| ty::mk_err());
|
.map(|_| ty::mk_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
|
||||||
fcx.write_error(pat.id);
|
fcx.write_error(pat.id);
|
||||||
kind_name = "[error]";
|
kind_name = "[error]";
|
||||||
arg_types = (*subpats).clone()
|
arg_types = (*subpats).clone()
|
||||||
.get_or_default(~[])
|
.unwrap_or_default(~[])
|
||||||
.map(|_| ty::mk_err());
|
.map(|_| ty::mk_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -854,7 +854,7 @@ impl<'self> LookupContext<'self> {
|
||||||
// like &'a Self. We then perform a
|
// like &'a Self. We then perform a
|
||||||
// substitution which will replace Self with
|
// substitution which will replace Self with
|
||||||
// @Trait.
|
// @Trait.
|
||||||
let t = candidate.method_ty.transformed_self_ty.get();
|
let t = candidate.method_ty.transformed_self_ty.unwrap();
|
||||||
ty::subst(tcx, &candidate.rcvr_substs, t)
|
ty::subst(tcx, &candidate.rcvr_substs, t)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -863,7 +863,7 @@ impl<'self> LookupContext<'self> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let t = candidate.method_ty.transformed_self_ty.get();
|
let t = candidate.method_ty.transformed_self_ty.unwrap();
|
||||||
ty::subst(tcx, &candidate.rcvr_substs, t)
|
ty::subst(tcx, &candidate.rcvr_substs, t)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -922,7 +922,7 @@ impl<'self> LookupContext<'self> {
|
||||||
tcx, @Nil, Some(transformed_self_ty), &bare_fn_ty.sig,
|
tcx, @Nil, Some(transformed_self_ty), &bare_fn_ty.sig,
|
||||||
|br| self.fcx.infcx().next_region_var(
|
|br| self.fcx.infcx().next_region_var(
|
||||||
infer::BoundRegionInFnCall(self.expr.span, br)));
|
infer::BoundRegionInFnCall(self.expr.span, br)));
|
||||||
let transformed_self_ty = opt_transformed_self_ty.get();
|
let transformed_self_ty = opt_transformed_self_ty.unwrap();
|
||||||
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||||
sig: fn_sig,
|
sig: fn_sig,
|
||||||
purity: bare_fn_ty.purity,
|
purity: bare_fn_ty.purity,
|
||||||
|
|
|
@ -365,7 +365,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
|
||||||
bound_region: br}));
|
bound_region: br}));
|
||||||
let opt_self_info =
|
let opt_self_info =
|
||||||
opt_self_info.map(
|
opt_self_info.map(
|
||||||
|si| SelfInfo {self_ty: opt_self_ty.get(), ..*si});
|
|si| SelfInfo {self_ty: opt_self_ty.unwrap(), ..*si});
|
||||||
(isr, opt_self_info, fn_sig)
|
(isr, opt_self_info, fn_sig)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2449,7 +2449,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
expected,
|
expected,
|
||||||
|x| Some((*x).clone()));
|
|x| Some((*x).clone()));
|
||||||
let inner_ty = match expected_sty {
|
let inner_ty = match expected_sty {
|
||||||
Some(ty::ty_closure(_)) => expected.get(),
|
Some(ty::ty_closure(_)) => expected.unwrap(),
|
||||||
_ => match expected {
|
_ => match expected {
|
||||||
Some(expected_t) => {
|
Some(expected_t) => {
|
||||||
fcx.type_error_message(expr.span, |actual| {
|
fcx.type_error_message(expr.span, |actual| {
|
||||||
|
|
|
@ -253,7 +253,7 @@ impl Combine for Glb {
|
||||||
|
|
||||||
if a_r.is_some() && b_r.is_some() && only_new_vars {
|
if a_r.is_some() && b_r.is_some() && only_new_vars {
|
||||||
// Related to exactly one bound variable from each fn:
|
// Related to exactly one bound variable from each fn:
|
||||||
return rev_lookup(this, a_isr, a_r.get());
|
return rev_lookup(this, a_isr, a_r.unwrap());
|
||||||
} else if a_r.is_none() && b_r.is_none() {
|
} else if a_r.is_none() && b_r.is_none() {
|
||||||
// Not related to bound variables from either fn:
|
// Not related to bound variables from either fn:
|
||||||
return r0;
|
return r0;
|
||||||
|
|
|
@ -295,7 +295,7 @@ trait get_and_find_region {
|
||||||
|
|
||||||
impl get_and_find_region for isr_alist {
|
impl get_and_find_region for isr_alist {
|
||||||
pub fn get(&self, br: ty::bound_region) -> ty::Region {
|
pub fn get(&self, br: ty::bound_region) -> ty::Region {
|
||||||
self.find(br).get()
|
self.find(br).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find(&self, br: ty::bound_region) -> Option<ty::Region> {
|
pub fn find(&self, br: ty::bound_region) -> Option<ty::Region> {
|
||||||
|
|
|
@ -18,6 +18,7 @@ use syntax::opt_vec::OptVec;
|
||||||
use syntax::opt_vec;
|
use syntax::opt_vec;
|
||||||
use syntax::parse::token::special_idents;
|
use syntax::parse::token::special_idents;
|
||||||
|
|
||||||
|
#[deriving(ToStr)]
|
||||||
pub struct RegionError {
|
pub struct RegionError {
|
||||||
msg: ~str,
|
msg: ~str,
|
||||||
replacement: ty::Region
|
replacement: ty::Region
|
||||||
|
|
|
@ -96,7 +96,6 @@ pub mod driver;
|
||||||
pub mod util {
|
pub mod util {
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod ppaux;
|
pub mod ppaux;
|
||||||
pub mod enum_set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod lib {
|
pub mod lib {
|
||||||
|
|
|
@ -280,9 +280,13 @@ pub fn vstore_ty_to_str(cx: ctxt, mt: &mt, vs: ty::vstore) -> ~str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn vec_map_to_str<T>(ts: &[T], f: &fn(t: &T) -> ~str) -> ~str {
|
||||||
|
let tstrs = ts.map(f);
|
||||||
|
fmt!("[%s]", tstrs.connect(", "))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tys_to_str(cx: ctxt, ts: &[t]) -> ~str {
|
pub fn tys_to_str(cx: ctxt, ts: &[t]) -> ~str {
|
||||||
let tstrs = ts.map(|t| ty_to_str(cx, *t));
|
vec_map_to_str(ts, |t| ty_to_str(cx, *t))
|
||||||
fmt!("(%s)", tstrs.connect(", "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fn_sig_to_str(cx: ctxt, typ: &ty::FnSig) -> ~str {
|
pub fn fn_sig_to_str(cx: ctxt, typ: &ty::FnSig) -> ~str {
|
||||||
|
@ -529,7 +533,7 @@ impl<T:Repr> Repr for ~T {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn repr_vec<T:Repr>(tcx: ctxt, v: &[T]) -> ~str {
|
fn repr_vec<T:Repr>(tcx: ctxt, v: &[T]) -> ~str {
|
||||||
fmt!("[%s]", v.map(|t| t.repr(tcx)).connect(","))
|
vec_map_to_str(v, |t| t.repr(tcx))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self, T:Repr> Repr for &'self [T] {
|
impl<'self, T:Repr> Repr for &'self [T] {
|
||||||
|
@ -589,15 +593,14 @@ impl Repr for ty::RegionSubsts {
|
||||||
impl Repr for ty::ParamBounds {
|
impl Repr for ty::ParamBounds {
|
||||||
fn repr(&self, tcx: ctxt) -> ~str {
|
fn repr(&self, tcx: ctxt) -> ~str {
|
||||||
let mut res = ~[];
|
let mut res = ~[];
|
||||||
do self.builtin_bounds.each |b| {
|
for b in self.builtin_bounds.iter() {
|
||||||
res.push(match b {
|
res.push(match b {
|
||||||
ty::BoundStatic => ~"'static",
|
ty::BoundStatic => ~"'static",
|
||||||
ty::BoundSend => ~"Send",
|
ty::BoundSend => ~"Send",
|
||||||
ty::BoundFreeze => ~"Freeze",
|
ty::BoundFreeze => ~"Freeze",
|
||||||
ty::BoundSized => ~"Sized",
|
ty::BoundSized => ~"Sized",
|
||||||
});
|
});
|
||||||
true
|
}
|
||||||
};
|
|
||||||
for t in self.trait_bounds.iter() {
|
for t in self.trait_bounds.iter() {
|
||||||
res.push(t.repr(tcx));
|
res.push(t.repr(tcx));
|
||||||
}
|
}
|
||||||
|
@ -833,10 +836,9 @@ impl UserString for ty::BuiltinBounds {
|
||||||
fn user_string(&self, tcx: ctxt) -> ~str {
|
fn user_string(&self, tcx: ctxt) -> ~str {
|
||||||
if self.is_empty() { ~"<no-bounds>" } else {
|
if self.is_empty() { ~"<no-bounds>" } else {
|
||||||
let mut result = ~[];
|
let mut result = ~[];
|
||||||
do self.each |bb| {
|
for bb in self.iter() {
|
||||||
result.push(bb.user_string(tcx));
|
result.push(bb.user_string(tcx));
|
||||||
true
|
}
|
||||||
};
|
|
||||||
result.connect("+")
|
result.connect("+")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ fn fold_crate(
|
||||||
doc::CrateDoc {
|
doc::CrateDoc {
|
||||||
topmod: doc::ModDoc {
|
topmod: doc::ModDoc {
|
||||||
item: doc::ItemDoc {
|
item: doc::ItemDoc {
|
||||||
name: attrs.name.clone().get_or_default(doc.topmod.name_()),
|
name: attrs.name.clone().unwrap_or_default(doc.topmod.name_()),
|
||||||
.. doc.topmod.item.clone()
|
.. doc.topmod.item.clone()
|
||||||
},
|
},
|
||||||
.. doc.topmod.clone()
|
.. doc.topmod.clone()
|
||||||
|
@ -135,7 +135,7 @@ fn fold_enum(
|
||||||
let ast_variant =
|
let ast_variant =
|
||||||
(*enum_definition.variants.iter().find_(|v| {
|
(*enum_definition.variants.iter().find_(|v| {
|
||||||
to_str(v.node.name) == variant.name
|
to_str(v.node.name) == variant.name
|
||||||
}).get()).clone();
|
}).unwrap()).clone();
|
||||||
|
|
||||||
attr_parser::parse_desc(
|
attr_parser::parse_desc(
|
||||||
ast_variant.node.attrs.clone())
|
ast_variant.node.attrs.clone())
|
||||||
|
|
|
@ -142,7 +142,7 @@ fn config_from_opts(
|
||||||
let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
|
let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
|
||||||
let output_dir = output_dir.map(|s| Path(*s));
|
let output_dir = output_dir.map(|s| Path(*s));
|
||||||
result::Ok(Config {
|
result::Ok(Config {
|
||||||
output_dir: output_dir.get_or_default(config.output_dir.clone()),
|
output_dir: output_dir.unwrap_or_default(config.output_dir.clone()),
|
||||||
.. config
|
.. config
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -273,20 +273,20 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn should_error_with_no_crates() {
|
fn should_error_with_no_crates() {
|
||||||
let config = parse_config([~"rustdoc"]);
|
let config = parse_config([~"rustdoc"]);
|
||||||
assert!(config.get_err() == ~"no crates specified");
|
assert!(config.unwrap_err() == ~"no crates specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_error_with_multiple_crates() {
|
fn should_error_with_multiple_crates() {
|
||||||
let config =
|
let config =
|
||||||
parse_config([~"rustdoc", ~"crate1.rc", ~"crate2.rc"]);
|
parse_config([~"rustdoc", ~"crate1.rc", ~"crate2.rc"]);
|
||||||
assert!(config.get_err() == ~"multiple crates specified");
|
assert!(config.unwrap_err() == ~"multiple crates specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_set_output_dir_to_cwd_if_not_provided() {
|
fn should_set_output_dir_to_cwd_if_not_provided() {
|
||||||
let config = parse_config([~"rustdoc", ~"crate.rc"]);
|
let config = parse_config([~"rustdoc", ~"crate.rc"]);
|
||||||
assert!(config.get().output_dir == Path("."));
|
assert!(config.unwrap().output_dir == Path("."));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -294,13 +294,13 @@ mod test {
|
||||||
let config = parse_config([
|
let config = parse_config([
|
||||||
~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles"
|
~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles"
|
||||||
]);
|
]);
|
||||||
assert!(config.get().output_dir == Path("snuggles"));
|
assert!(config.unwrap().output_dir == Path("snuggles"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_set_output_format_to_pandoc_html_if_not_provided() {
|
fn should_set_output_format_to_pandoc_html_if_not_provided() {
|
||||||
let config = parse_config([~"rustdoc", ~"crate.rc"]);
|
let config = parse_config([~"rustdoc", ~"crate.rc"]);
|
||||||
assert!(config.get().output_format == PandocHtml);
|
assert!(config.unwrap().output_format == PandocHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -308,7 +308,7 @@ mod test {
|
||||||
let config = parse_config([
|
let config = parse_config([
|
||||||
~"rustdoc", ~"crate.rc", ~"--output-format", ~"markdown"
|
~"rustdoc", ~"crate.rc", ~"--output-format", ~"markdown"
|
||||||
]);
|
]);
|
||||||
assert!(config.get().output_format == Markdown);
|
assert!(config.unwrap().output_format == Markdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -316,7 +316,7 @@ mod test {
|
||||||
let config = parse_config([
|
let config = parse_config([
|
||||||
~"rustdoc", ~"crate.rc", ~"--output-format", ~"html"
|
~"rustdoc", ~"crate.rc", ~"--output-format", ~"html"
|
||||||
]);
|
]);
|
||||||
assert!(config.get().output_format == PandocHtml);
|
assert!(config.unwrap().output_format == PandocHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -324,13 +324,13 @@ mod test {
|
||||||
let config = parse_config([
|
let config = parse_config([
|
||||||
~"rustdoc", ~"crate.rc", ~"--output-format", ~"bogus"
|
~"rustdoc", ~"crate.rc", ~"--output-format", ~"bogus"
|
||||||
]);
|
]);
|
||||||
assert!(config.get_err() == ~"unknown output format 'bogus'");
|
assert!(config.unwrap_err() == ~"unknown output format 'bogus'");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_set_output_style_to_doc_per_mod_by_default() {
|
fn should_set_output_style_to_doc_per_mod_by_default() {
|
||||||
let config = parse_config([~"rustdoc", ~"crate.rc"]);
|
let config = parse_config([~"rustdoc", ~"crate.rc"]);
|
||||||
assert!(config.get().output_style == DocPerMod);
|
assert!(config.unwrap().output_style == DocPerMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -338,7 +338,7 @@ mod test {
|
||||||
let config = parse_config([
|
let config = parse_config([
|
||||||
~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-crate"
|
~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-crate"
|
||||||
]);
|
]);
|
||||||
assert!(config.get().output_style == DocPerCrate);
|
assert!(config.unwrap().output_style == DocPerCrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -346,7 +346,7 @@ mod test {
|
||||||
let config = parse_config([
|
let config = parse_config([
|
||||||
~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-mod"
|
~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-mod"
|
||||||
]);
|
]);
|
||||||
assert!(config.get().output_style == DocPerMod);
|
assert!(config.unwrap().output_style == DocPerMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -354,7 +354,7 @@ mod test {
|
||||||
let config = parse_config([
|
let config = parse_config([
|
||||||
~"rustdoc", ~"crate.rc", ~"--output-style", ~"bogus"
|
~"rustdoc", ~"crate.rc", ~"--output-style", ~"bogus"
|
||||||
]);
|
]);
|
||||||
assert!(config.get_err() == ~"unknown output style 'bogus'");
|
assert!(config.unwrap_err() == ~"unknown output style 'bogus'");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -362,12 +362,12 @@ mod test {
|
||||||
let config = parse_config([
|
let config = parse_config([
|
||||||
~"rustdoc", ~"crate.rc", ~"--pandoc-cmd", ~"panda-bear-doc"
|
~"rustdoc", ~"crate.rc", ~"--pandoc-cmd", ~"panda-bear-doc"
|
||||||
]);
|
]);
|
||||||
assert!(config.get().pandoc_cmd == Some(~"panda-bear-doc"));
|
assert!(config.unwrap().pandoc_cmd == Some(~"panda-bear-doc"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_set_pandoc_command_when_using_pandoc() {
|
fn should_set_pandoc_command_when_using_pandoc() {
|
||||||
let config = parse_config([~"rustdoc", ~"crate.rc"]);
|
let config = parse_config([~"rustdoc", ~"crate.rc"]);
|
||||||
assert!(config.get().pandoc_cmd == Some(~"pandoc"));
|
assert!(config.unwrap().pandoc_cmd == Some(~"pandoc"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ pub fn extract(desc: Option<~str>) -> Option<~str> {
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_desc(desc.clone().get())
|
parse_desc(desc.clone().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_desc(desc: ~str) -> Option<~str> {
|
fn parse_desc(desc: ~str) -> Option<~str> {
|
||||||
|
|
|
@ -176,7 +176,7 @@ impl Doc {
|
||||||
doc::CratePage(doc) => Some(doc),
|
doc::CratePage(doc) => Some(doc),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}).get()
|
}).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cratemod(&self) -> ModDoc {
|
pub fn cratemod(&self) -> ModDoc {
|
||||||
|
|
|
@ -223,13 +223,13 @@ mod test {
|
||||||
config::DocPerCrate,
|
config::DocPerCrate,
|
||||||
~"mod a { } fn b() { }"
|
~"mod a { } fn b() { }"
|
||||||
);
|
);
|
||||||
assert!(doc.cratemod().index.get().entries[0] == doc::IndexEntry {
|
assert!(doc.cratemod().index.unwrap().entries[0] == doc::IndexEntry {
|
||||||
kind: ~"Module",
|
kind: ~"Module",
|
||||||
name: ~"a",
|
name: ~"a",
|
||||||
brief: None,
|
brief: None,
|
||||||
link: ~"#module-a"
|
link: ~"#module-a"
|
||||||
});
|
});
|
||||||
assert!(doc.cratemod().index.get().entries[1] == doc::IndexEntry {
|
assert!(doc.cratemod().index.unwrap().entries[1] == doc::IndexEntry {
|
||||||
kind: ~"Function",
|
kind: ~"Function",
|
||||||
name: ~"b",
|
name: ~"b",
|
||||||
brief: None,
|
brief: None,
|
||||||
|
@ -243,13 +243,13 @@ mod test {
|
||||||
config::DocPerMod,
|
config::DocPerMod,
|
||||||
~"mod a { } fn b() { }"
|
~"mod a { } fn b() { }"
|
||||||
);
|
);
|
||||||
assert_eq!(doc.cratemod().index.get().entries[0], doc::IndexEntry {
|
assert_eq!(doc.cratemod().index.unwrap().entries[0], doc::IndexEntry {
|
||||||
kind: ~"Module",
|
kind: ~"Module",
|
||||||
name: ~"a",
|
name: ~"a",
|
||||||
brief: None,
|
brief: None,
|
||||||
link: ~"a.html"
|
link: ~"a.html"
|
||||||
});
|
});
|
||||||
assert_eq!(doc.cratemod().index.get().entries[1], doc::IndexEntry {
|
assert_eq!(doc.cratemod().index.unwrap().entries[1], doc::IndexEntry {
|
||||||
kind: ~"Function",
|
kind: ~"Function",
|
||||||
name: ~"b",
|
name: ~"b",
|
||||||
brief: None,
|
brief: None,
|
||||||
|
@ -263,7 +263,7 @@ mod test {
|
||||||
config::DocPerMod,
|
config::DocPerMod,
|
||||||
~"#[doc = \"test\"] mod a { }"
|
~"#[doc = \"test\"] mod a { }"
|
||||||
);
|
);
|
||||||
assert_eq!(doc.cratemod().index.get().entries[0].brief, Some(~"test"));
|
assert_eq!(doc.cratemod().index.unwrap().entries[0].brief, Some(~"test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -273,7 +273,7 @@ mod test {
|
||||||
~"extern { fn b(); }"
|
~"extern { fn b(); }"
|
||||||
);
|
);
|
||||||
// hidden __std_macros module at the start.
|
// hidden __std_macros module at the start.
|
||||||
assert_eq!(doc.cratemod().nmods()[0].index.get().entries[0],
|
assert_eq!(doc.cratemod().nmods()[0].index.unwrap().entries[0],
|
||||||
doc::IndexEntry {
|
doc::IndexEntry {
|
||||||
kind: ~"Function",
|
kind: ~"Function",
|
||||||
name: ~"b",
|
name: ~"b",
|
||||||
|
|
|
@ -617,10 +617,10 @@ mod test {
|
||||||
fn d() { }"
|
fn d() { }"
|
||||||
);
|
);
|
||||||
|
|
||||||
let idx_a = markdown.find_str("# Module `a`").get();
|
let idx_a = markdown.find_str("# Module `a`").unwrap();
|
||||||
let idx_b = markdown.find_str("## Function `b`").get();
|
let idx_b = markdown.find_str("## Function `b`").unwrap();
|
||||||
let idx_c = markdown.find_str("# Module `c`").get();
|
let idx_c = markdown.find_str("# Module `c`").unwrap();
|
||||||
let idx_d = markdown.find_str("## Function `d`").get();
|
let idx_d = markdown.find_str("## Function `d`").unwrap();
|
||||||
|
|
||||||
assert!(idx_b < idx_d);
|
assert!(idx_b < idx_d);
|
||||||
assert!(idx_d < idx_a);
|
assert!(idx_d < idx_a);
|
||||||
|
|
|
@ -218,8 +218,8 @@ mod test {
|
||||||
Body\"]\
|
Body\"]\
|
||||||
mod a {
|
mod a {
|
||||||
}");
|
}");
|
||||||
assert!(!doc.cratemod().mods()[0].desc().get().contains("Header"));
|
assert!(!doc.cratemod().mods()[0].desc().unwrap().contains("Header"));
|
||||||
assert!(!doc.cratemod().mods()[0].desc().get().contains("Body"));
|
assert!(!doc.cratemod().mods()[0].desc().unwrap().contains("Body"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -135,7 +135,7 @@ fn fold_enum(
|
||||||
let ast_variant =
|
let ast_variant =
|
||||||
(*do enum_definition.variants.iter().find_ |v| {
|
(*do enum_definition.variants.iter().find_ |v| {
|
||||||
to_str(v.node.name) == variant.name
|
to_str(v.node.name) == variant.name
|
||||||
}.get()).clone();
|
}.unwrap()).clone();
|
||||||
|
|
||||||
pprust::variant_to_str(
|
pprust::variant_to_str(
|
||||||
&ast_variant, extract::interner())
|
&ast_variant, extract::interner())
|
||||||
|
@ -443,7 +443,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn should_add_struct_defs() {
|
fn should_add_struct_defs() {
|
||||||
let doc = mk_doc(~"struct S { field: () }");
|
let doc = mk_doc(~"struct S { field: () }");
|
||||||
assert!(doc.cratemod().structs()[0].sig.get().contains(
|
assert!(doc.cratemod().structs()[0].sig.unwrap().contains(
|
||||||
"struct S {"));
|
"struct S {"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +451,6 @@ mod test {
|
||||||
fn should_not_serialize_struct_attrs() {
|
fn should_not_serialize_struct_attrs() {
|
||||||
// All we care about are the fields
|
// All we care about are the fields
|
||||||
let doc = mk_doc(~"#[wut] struct S { field: () }");
|
let doc = mk_doc(~"#[wut] struct S { field: () }");
|
||||||
assert!(!doc.cratemod().structs()[0].sig.get().contains("wut"));
|
assert!(!doc.cratemod().structs()[0].sig.unwrap().contains("wut"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -322,14 +322,14 @@ fn compile_crate(src_filename: ~str, binary: ~str) -> Option<bool> {
|
||||||
// instead we guess which file is the library by matching
|
// instead we guess which file is the library by matching
|
||||||
// the prefix and suffix of out_filename to files in the
|
// the prefix and suffix of out_filename to files in the
|
||||||
// directory.
|
// directory.
|
||||||
let file_str = file.filename().get();
|
let file_str = file.filename().unwrap();
|
||||||
file_str.starts_with(outputs.out_filename.filestem().get())
|
file_str.starts_with(outputs.out_filename.filestem().unwrap())
|
||||||
&& file_str.ends_with(outputs.out_filename.filetype().get())
|
&& file_str.ends_with(outputs.out_filename.filetype().unwrap())
|
||||||
};
|
};
|
||||||
match maybe_lib_path {
|
match maybe_lib_path {
|
||||||
Some(lib_path) => {
|
Some(lib_path) => {
|
||||||
let (src_mtime, _) = src_path.get_mtime().get();
|
let (src_mtime, _) = src_path.get_mtime().unwrap();
|
||||||
let (lib_mtime, _) = lib_path.get_mtime().get();
|
let (lib_mtime, _) = lib_path.get_mtime().unwrap();
|
||||||
if lib_mtime >= src_mtime {
|
if lib_mtime >= src_mtime {
|
||||||
should_compile = false;
|
should_compile = false;
|
||||||
}
|
}
|
||||||
|
@ -565,10 +565,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: #7220 rusti on 32bit mac doesn't work.
|
#[cfg(not(target_word_size = "32"))]
|
||||||
// FIXME: #7641 rusti on 32bit linux cross compile doesn't work
|
|
||||||
// FIXME: #7115 re-enable once LLVM has been upgraded
|
|
||||||
#[cfg(thiswillneverbeacfgflag)]
|
|
||||||
fn run_program(prog: &str) {
|
fn run_program(prog: &str) {
|
||||||
let mut r = repl();
|
let mut r = repl();
|
||||||
for cmd in prog.split_iter('\n') {
|
for cmd in prog.split_iter('\n') {
|
||||||
|
@ -577,6 +574,9 @@ mod tests {
|
||||||
"the command '%s' failed", cmd);
|
"the command '%s' failed", cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// FIXME: #7220 rusti on 32bit mac doesn't work
|
||||||
|
// FIXME: #7641 rusti on 32bit linux cross compile doesn't work
|
||||||
|
#[cfg(target_word_size = "32")]
|
||||||
fn run_program(_: &str) {}
|
fn run_program(_: &str) {}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -594,13 +594,12 @@ mod tests {
|
||||||
run_program("let a = 3;");
|
run_program("let a = 3;");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] #[ignore]
|
#[test]
|
||||||
fn new_tasks() {
|
fn new_tasks() {
|
||||||
// XXX: can't spawn new tasks because the JIT code is cleaned up
|
|
||||||
// after the main function is done.
|
|
||||||
run_program("
|
run_program("
|
||||||
spawn( || println(\"Please don't segfault\") );
|
use std::task::try;
|
||||||
do spawn { println(\"Please?\"); }
|
try( || println(\"Please don't segfault\") );
|
||||||
|
do try { println(\"Please?\"); }
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ impl<'self> PkgScript<'self> {
|
||||||
debug!("pkgscript parse: %?", os::self_exe_path());
|
debug!("pkgscript parse: %?", os::self_exe_path());
|
||||||
let options = @session::options {
|
let options = @session::options {
|
||||||
binary: binary,
|
binary: binary,
|
||||||
maybe_sysroot: Some(@os::self_exe_path().get().pop()),
|
maybe_sysroot: Some(@os::self_exe_path().unwrap().pop()),
|
||||||
crate_type: session::bin_crate,
|
crate_type: session::bin_crate,
|
||||||
.. (*session::basic_options()).clone()
|
.. (*session::basic_options()).clone()
|
||||||
};
|
};
|
||||||
|
@ -535,7 +535,7 @@ pub fn main() {
|
||||||
* in is the working directory.
|
* in is the working directory.
|
||||||
*/
|
*/
|
||||||
pub fn work_dir() -> Path {
|
pub fn work_dir() -> Path {
|
||||||
os::self_exe_path().get()
|
os::self_exe_path().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -196,7 +196,7 @@ pub fn compile_input(ctxt: &Ctx,
|
||||||
}
|
}
|
||||||
+ flags
|
+ flags
|
||||||
+ cfgs.flat_map(|c| { ~[~"--cfg", (*c).clone()] }),
|
+ cfgs.flat_map(|c| { ~[~"--cfg", (*c).clone()] }),
|
||||||
driver::optgroups()).get();
|
driver::optgroups()).unwrap();
|
||||||
let options = @session::options {
|
let options = @session::options {
|
||||||
crate_type: crate_type,
|
crate_type: crate_type,
|
||||||
optimize: if opt { session::Aggressive } else { session::No },
|
optimize: if opt { session::Aggressive } else { session::No },
|
||||||
|
|
|
@ -78,10 +78,8 @@ pub fn build<A>(builder: &fn(push: &fn(v: A))) -> @[A] {
|
||||||
* onto the vector being constructed.
|
* onto the vector being constructed.
|
||||||
*/
|
*/
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn build_sized_opt<A>(size: Option<uint>,
|
pub fn build_sized_opt<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> @[A] {
|
||||||
builder: &fn(push: &fn(v: A)))
|
build_sized(size.unwrap_or_default(4), builder)
|
||||||
-> @[A] {
|
|
||||||
build_sized(size.get_or_default(4), builder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appending
|
// Appending
|
||||||
|
|
|
@ -23,29 +23,102 @@ use str::StrSlice;
|
||||||
use vec;
|
use vec;
|
||||||
use vec::{OwnedVector, ImmutableVector};
|
use vec::{OwnedVector, ImmutableVector};
|
||||||
|
|
||||||
/// The either type
|
/// `Either` is a type that represents one of two alternatives
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum Either<T, U> {
|
pub enum Either<L, R> {
|
||||||
Left(T),
|
Left(L),
|
||||||
Right(U)
|
Right(R)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<L, R> Either<L, R> {
|
||||||
/// Applies a function based on the given either value
|
/// Applies a function based on the given either value
|
||||||
///
|
///
|
||||||
/// If `value` is left(T) then `f_left` is applied to its contents, if
|
/// If `value` is `Left(L)` then `f_left` is applied to its contents, if
|
||||||
/// `value` is right(U) then `f_right` is applied to its contents, and the
|
/// `value` is `Right(R)` then `f_right` is applied to its contents, and the
|
||||||
/// result is returned.
|
/// result is returned.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn either<T, U, V>(f_left: &fn(&T) -> V,
|
pub fn either<T>(&self, f_left: &fn(&L) -> T, f_right: &fn(&R) -> T) -> T {
|
||||||
f_right: &fn(&U) -> V, value: &Either<T, U>) -> V {
|
match *self {
|
||||||
match *value {
|
|
||||||
Left(ref l) => f_left(l),
|
Left(ref l) => f_left(l),
|
||||||
Right(ref r) => f_right(r)
|
Right(ref r) => f_right(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flips between left and right of a given `Either`
|
||||||
|
#[inline]
|
||||||
|
pub fn flip(self) -> Either<R, L> {
|
||||||
|
match self {
|
||||||
|
Right(r) => Left(r),
|
||||||
|
Left(l) => Right(l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a `Either` to a `Result`
|
||||||
|
///
|
||||||
|
/// Converts an `Either` type to a `Result` type, making the "right" choice
|
||||||
|
/// an `Ok` result, and the "left" choice a `Err`
|
||||||
|
#[inline]
|
||||||
|
pub fn to_result(self) -> Result<R, L> {
|
||||||
|
match self {
|
||||||
|
Right(r) => result::Ok(r),
|
||||||
|
Left(l) => result::Err(l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks whether the given value is a `Left`
|
||||||
|
#[inline]
|
||||||
|
pub fn is_left(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Left(_) => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks whether the given value is a `Right`
|
||||||
|
#[inline]
|
||||||
|
pub fn is_right(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Right(_) => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the value from a `Left`.
|
||||||
|
/// Fails with a specified reason if the `Either` is `Right`.
|
||||||
|
#[inline]
|
||||||
|
pub fn expect_left(self, reason: &str) -> L {
|
||||||
|
match self {
|
||||||
|
Left(x) => x,
|
||||||
|
Right(_) => fail!(reason.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the value from a `Left`. Fails if the `Either` is `Right`.
|
||||||
|
#[inline]
|
||||||
|
pub fn unwrap_left(self) -> L {
|
||||||
|
self.expect_left("called Either::unwrap_left()` on `Right` value")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the value from a `Right`.
|
||||||
|
/// Fails with a specified reason if the `Either` is `Left`.
|
||||||
|
#[inline]
|
||||||
|
pub fn expect_right(self, reason: &str) -> R {
|
||||||
|
match self {
|
||||||
|
Right(x) => x,
|
||||||
|
Left(_) => fail!(reason.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the value from a `Right`. Fails if the `Either` is `Left`.
|
||||||
|
#[inline]
|
||||||
|
pub fn unwrap_right(self) -> R {
|
||||||
|
self.expect_right("called Either::unwrap_right()` on `Left` value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: #8228 Replaceable by an external iterator?
|
||||||
/// Extracts from a vector of either all the left values
|
/// Extracts from a vector of either all the left values
|
||||||
pub fn lefts<T:Clone,U>(eithers: &[Either<T, U>]) -> ~[T] {
|
pub fn lefts<L: Clone, R>(eithers: &[Either<L, R>]) -> ~[L] {
|
||||||
do vec::build_sized(eithers.len()) |push| {
|
do vec::build_sized(eithers.len()) |push| {
|
||||||
for elt in eithers.iter() {
|
for elt in eithers.iter() {
|
||||||
match *elt {
|
match *elt {
|
||||||
|
@ -56,8 +129,9 @@ pub fn lefts<T:Clone,U>(eithers: &[Either<T, U>]) -> ~[T] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: #8228 Replaceable by an external iterator?
|
||||||
/// Extracts from a vector of either all the right values
|
/// Extracts from a vector of either all the right values
|
||||||
pub fn rights<T, U: Clone>(eithers: &[Either<T, U>]) -> ~[U] {
|
pub fn rights<L, R: Clone>(eithers: &[Either<L, R>]) -> ~[R] {
|
||||||
do vec::build_sized(eithers.len()) |push| {
|
do vec::build_sized(eithers.len()) |push| {
|
||||||
for elt in eithers.iter() {
|
for elt in eithers.iter() {
|
||||||
match *elt {
|
match *elt {
|
||||||
|
@ -68,13 +142,14 @@ pub fn rights<T, U: Clone>(eithers: &[Either<T, U>]) -> ~[U] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: #8228 Replaceable by an external iterator?
|
||||||
/// Extracts from a vector of either all the left values and right values
|
/// Extracts from a vector of either all the left values and right values
|
||||||
///
|
///
|
||||||
/// Returns a structure containing a vector of left values and a vector of
|
/// Returns a structure containing a vector of left values and a vector of
|
||||||
/// right values.
|
/// right values.
|
||||||
pub fn partition<T, U>(eithers: ~[Either<T, U>]) -> (~[T], ~[U]) {
|
pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
|
||||||
let mut lefts: ~[T] = ~[];
|
let mut lefts: ~[L] = ~[];
|
||||||
let mut rights: ~[U] = ~[];
|
let mut rights: ~[R] = ~[];
|
||||||
for elt in eithers.consume_iter() {
|
for elt in eithers.consume_iter() {
|
||||||
match elt {
|
match elt {
|
||||||
Left(l) => lefts.push(l),
|
Left(l) => lefts.push(l),
|
||||||
|
@ -84,113 +159,16 @@ pub fn partition<T, U>(eithers: ~[Either<T, U>]) -> (~[T], ~[U]) {
|
||||||
return (lefts, rights);
|
return (lefts, rights);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flips between left and right of a given either
|
#[cfg(test)]
|
||||||
#[inline]
|
mod tests {
|
||||||
pub fn flip<T, U>(eith: Either<T, U>) -> Either<U, T> {
|
use super::*;
|
||||||
match eith {
|
|
||||||
Right(r) => Left(r),
|
|
||||||
Left(l) => Right(l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts either::t to a result::t
|
|
||||||
///
|
|
||||||
/// Converts an `either` type to a `result` type, making the "right" choice
|
|
||||||
/// an ok result, and the "left" choice a fail
|
|
||||||
#[inline]
|
|
||||||
pub fn to_result<T, U>(eith: Either<T, U>) -> Result<U, T> {
|
|
||||||
match eith {
|
|
||||||
Right(r) => result::Ok(r),
|
|
||||||
Left(l) => result::Err(l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks whether the given value is a left
|
|
||||||
#[inline]
|
|
||||||
pub fn is_left<T, U>(eith: &Either<T, U>) -> bool {
|
|
||||||
match *eith {
|
|
||||||
Left(_) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks whether the given value is a right
|
|
||||||
#[inline]
|
|
||||||
pub fn is_right<T, U>(eith: &Either<T, U>) -> bool {
|
|
||||||
match *eith {
|
|
||||||
Right(_) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the value in the left branch.
|
|
||||||
/// Fails with a specified reason if the either is Right.
|
|
||||||
#[inline]
|
|
||||||
pub fn expect_left<T,U>(eith: Either<T,U>, reason: &str) -> T {
|
|
||||||
match eith {
|
|
||||||
Left(x) => x,
|
|
||||||
Right(_) => fail!(reason.to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the value in the left branch. Fails if the either is Right.
|
|
||||||
#[inline]
|
|
||||||
pub fn unwrap_left<T,U>(eith: Either<T,U>) -> T {
|
|
||||||
expect_left(eith, "either::unwrap_left Right")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the value in the right branch.
|
|
||||||
/// Fails with a specified reason if the either is Left.
|
|
||||||
#[inline]
|
|
||||||
pub fn expect_right<T,U>(eith: Either<T,U>, reason: &str) -> U {
|
|
||||||
match eith {
|
|
||||||
Right(x) => x,
|
|
||||||
Left(_) => fail!(reason.to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the value in the right branch. Fails if the either is Left.
|
|
||||||
pub fn unwrap_right<T,U>(eith: Either<T,U>) -> U {
|
|
||||||
expect_right(eith, "either::unwrap_right Left")
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> Either<T, U> {
|
|
||||||
#[inline]
|
|
||||||
pub fn either<V>(&self, f_left: &fn(&T) -> V, f_right: &fn(&U) -> V) -> V {
|
|
||||||
either(f_left, f_right, self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn flip(self) -> Either<U, T> { flip(self) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn to_result(self) -> Result<U, T> { to_result(self) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_left(&self) -> bool { is_left(self) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_right(&self) -> bool { is_right(self) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn expect_left(self, reason: &str) -> T { expect_left(self, reason) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn unwrap_left(self) -> T { unwrap_left(self) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn expect_right(self, reason: &str) -> U { expect_right(self, reason) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn unwrap_right(self) -> U { unwrap_right(self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_either_left() {
|
fn test_either_left() {
|
||||||
let val = Left(10);
|
let val = Left(10);
|
||||||
fn f_left(x: &int) -> bool { *x == 10 }
|
fn f_left(x: &int) -> bool { *x == 10 }
|
||||||
fn f_right(_x: &uint) -> bool { false }
|
fn f_right(_x: &uint) -> bool { false }
|
||||||
assert!((either(f_left, f_right, &val)));
|
assert!(val.either(f_left, f_right));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -198,7 +176,7 @@ fn test_either_right() {
|
||||||
let val = Right(10u);
|
let val = Right(10u);
|
||||||
fn f_left(_x: &int) -> bool { false }
|
fn f_left(_x: &int) -> bool { false }
|
||||||
fn f_right(x: &uint) -> bool { *x == 10u }
|
fn f_right(x: &uint) -> bool { *x == 10u }
|
||||||
assert!((either(f_left, f_right, &val)));
|
assert!(val.either(f_left, f_right));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -277,3 +255,5 @@ fn test_partition_empty() {
|
||||||
assert_eq!(lefts.len(), 0u);
|
assert_eq!(lefts.len(), 0u);
|
||||||
assert_eq!(rights.len(), 0u);
|
assert_eq!(rights.len(), 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
|
||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use cmp::{Eq, Equiv};
|
use cmp::{Eq, Equiv};
|
||||||
use hash::Hash;
|
use hash::Hash;
|
||||||
use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, Chain, range};
|
use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, range};
|
||||||
|
use iterator::{FilterMap, Chain, Repeat, Zip};
|
||||||
use num;
|
use num;
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
use rand::RngUtil;
|
use rand::RngUtil;
|
||||||
|
@ -712,10 +713,12 @@ impl<T:Hash + Eq> HashSet<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visit the values representing the difference
|
/// Visit the values representing the difference
|
||||||
pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>)
|
pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraIter<'a, T> {
|
||||||
-> SetAlgebraIter<'a, T> {
|
Repeat::new(other)
|
||||||
EnvFilterIterator{iter: self.iter(), env: other,
|
.zip(self.iter())
|
||||||
filter: |elt, other| !other.contains(elt) }
|
.filter_map(|(other, elt)| {
|
||||||
|
if !other.contains(elt) { Some(elt) } else { None }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visit the values representing the symmetric difference
|
/// Visit the values representing the symmetric difference
|
||||||
|
@ -727,8 +730,11 @@ impl<T:Hash + Eq> HashSet<T> {
|
||||||
/// Visit the values representing the intersection
|
/// Visit the values representing the intersection
|
||||||
pub fn intersection_iter<'a>(&'a self, other: &'a HashSet<T>)
|
pub fn intersection_iter<'a>(&'a self, other: &'a HashSet<T>)
|
||||||
-> SetAlgebraIter<'a, T> {
|
-> SetAlgebraIter<'a, T> {
|
||||||
EnvFilterIterator{iter: self.iter(), env: other,
|
Repeat::new(other)
|
||||||
filter: |elt, other| other.contains(elt) }
|
.zip(self.iter())
|
||||||
|
.filter_map(|(other, elt)| {
|
||||||
|
if other.contains(elt) { Some(elt) } else { None }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visit the values representing the union
|
/// Visit the values representing the union
|
||||||
|
@ -756,38 +762,12 @@ impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME #7814: use std::iterator::FilterIterator
|
// `Repeat` is used to feed the filter closure an explicit capture
|
||||||
/// Building block for Set operation iterators
|
// of a reference to the other set
|
||||||
pub struct EnvFilterIterator<A, Env, I> {
|
|
||||||
priv env: Env,
|
|
||||||
priv filter: &'static fn(&A, Env) -> bool,
|
|
||||||
priv iter: I,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'self, A, Env: Clone, I: Iterator<&'self A>> Iterator<&'self A>
|
|
||||||
for EnvFilterIterator<A, Env, I> {
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<&'self A> {
|
|
||||||
loop {
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(elt) => if (self.filter)(elt, self.env.clone()) {
|
|
||||||
return Some(elt)
|
|
||||||
},
|
|
||||||
None => return None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
||||||
let (_, upper) = self.iter.size_hint();
|
|
||||||
(0, upper)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set operations iterator
|
/// Set operations iterator
|
||||||
pub type SetAlgebraIter<'self, T> =
|
pub type SetAlgebraIter<'self, T> =
|
||||||
EnvFilterIterator<T, &'self HashSet<T>, HashSetIterator<'self, T>>;
|
FilterMap<'static,(&'self HashSet<T>, &'self T), &'self T,
|
||||||
|
Zip<Repeat<&'self HashSet<T>>,HashSetIterator<'self,T>>>;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1042,7 +1042,7 @@ pub fn stdin() -> @Reader {
|
||||||
|
|
||||||
pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
|
pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
|
||||||
let f = do path.to_c_str().with_ref |pathbuf| {
|
let f = do path.to_c_str().with_ref |pathbuf| {
|
||||||
do "r".to_c_str().with_ref |modebuf| {
|
do "rb".to_c_str().with_ref |modebuf| {
|
||||||
unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
|
unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -82,6 +82,17 @@ pub trait DoubleEndedIteratorUtil {
|
||||||
/// In the future these will be default methods instead of a utility trait.
|
/// In the future these will be default methods instead of a utility trait.
|
||||||
impl<A, T: DoubleEndedIterator<A>> DoubleEndedIteratorUtil for T {
|
impl<A, T: DoubleEndedIterator<A>> DoubleEndedIteratorUtil for T {
|
||||||
/// Flip the direction of the iterator
|
/// Flip the direction of the iterator
|
||||||
|
///
|
||||||
|
/// The inverted iterator flips the ends on an iterator that can already
|
||||||
|
/// be iterated from the front and from the back.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// If the iterator also implements RandomAccessIterator, the inverted
|
||||||
|
/// iterator is also random access, with the indices starting at the back
|
||||||
|
/// of the original iterator.
|
||||||
|
///
|
||||||
|
/// Note: Random access with inverted indices still only applies to the first
|
||||||
|
/// `uint::max_value` elements of the original iterator.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn invert(self) -> Invert<T> {
|
fn invert(self) -> Invert<T> {
|
||||||
Invert{iter: self}
|
Invert{iter: self}
|
||||||
|
@ -106,6 +117,16 @@ impl<A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Invert<T> {
|
||||||
fn next_back(&mut self) -> Option<A> { self.iter.next() }
|
fn next_back(&mut self) -> Option<A> { self.iter.next() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterator<A>
|
||||||
|
for Invert<T> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint { self.iter.indexable() }
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<A> {
|
||||||
|
self.iter.idx(self.indexable() - index - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
|
/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
|
||||||
/// implementations of the `Iterator` trait.
|
/// implementations of the `Iterator` trait.
|
||||||
///
|
///
|
||||||
|
@ -1555,6 +1576,39 @@ impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator that repeats an element endlessly
|
||||||
|
#[deriving(Clone, DeepClone)]
|
||||||
|
pub struct Repeat<A> {
|
||||||
|
priv element: A
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Clone> Repeat<A> {
|
||||||
|
/// Create a new `Repeat` that enlessly repeats the element `elt`.
|
||||||
|
#[inline]
|
||||||
|
pub fn new(elt: A) -> Repeat<A> {
|
||||||
|
Repeat{element: elt}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Clone> Iterator<A> for Repeat<A> {
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<A> { self.idx(0) }
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (uint, Option<uint>) { (uint::max_value, None) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Clone> DoubleEndedIterator<A> for Repeat<A> {
|
||||||
|
#[inline]
|
||||||
|
fn next_back(&mut self) -> Option<A> { self.idx(0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint { uint::max_value }
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, _: uint) -> Option<A> { Some(self.element.clone()) }
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -2017,6 +2071,17 @@ mod tests {
|
||||||
check_randacc_iter(xs.iter().enumerate(), xs.len());
|
check_randacc_iter(xs.iter().enumerate(), xs.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_random_access_invert() {
|
||||||
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
check_randacc_iter(xs.iter().invert(), xs.len());
|
||||||
|
let mut it = xs.iter().invert();
|
||||||
|
it.next();
|
||||||
|
it.next_back();
|
||||||
|
it.next();
|
||||||
|
check_randacc_iter(it, xs.len() - 3);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_random_access_zip() {
|
fn test_random_access_zip() {
|
||||||
let xs = [1, 2, 3, 4, 5];
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
|
|
@ -112,14 +112,14 @@ fn test_tls_multitask() {
|
||||||
// TLS shouldn't carry over.
|
// TLS shouldn't carry over.
|
||||||
assert!(get(my_key, |k| k.map(|&k| *k)).is_none());
|
assert!(get(my_key, |k| k.map(|&k| *k)).is_none());
|
||||||
set(my_key, @~"child data");
|
set(my_key, @~"child data");
|
||||||
assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) ==
|
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) ==
|
||||||
~"child data");
|
~"child data");
|
||||||
// should be cleaned up for us
|
// should be cleaned up for us
|
||||||
}
|
}
|
||||||
// Must work multiple times
|
// Must work multiple times
|
||||||
assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) == ~"parent data");
|
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
|
||||||
assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) == ~"parent data");
|
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
|
||||||
assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) == ~"parent data");
|
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -127,14 +127,14 @@ fn test_tls_overwrite() {
|
||||||
static my_key: Key<@~str> = &Key;
|
static my_key: Key<@~str> = &Key;
|
||||||
set(my_key, @~"first data");
|
set(my_key, @~"first data");
|
||||||
set(my_key, @~"next data"); // Shouldn't leak.
|
set(my_key, @~"next data"); // Shouldn't leak.
|
||||||
assert!(*(get(my_key, |k| k.map(|&k| *k)).get()) == ~"next data");
|
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"next data");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tls_pop() {
|
fn test_tls_pop() {
|
||||||
static my_key: Key<@~str> = &Key;
|
static my_key: Key<@~str> = &Key;
|
||||||
set(my_key, @~"weasel");
|
set(my_key, @~"weasel");
|
||||||
assert!(*(pop(my_key).get()) == ~"weasel");
|
assert!(*(pop(my_key).unwrap()) == ~"weasel");
|
||||||
// Pop must remove the data from the map.
|
// Pop must remove the data from the map.
|
||||||
assert!(pop(my_key).is_none());
|
assert!(pop(my_key).is_none());
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ fn test_tls_modify() {
|
||||||
None => fail!("missing value")
|
None => fail!("missing value")
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
assert!(*(pop(my_key).get()) == ~"next data");
|
assert!(*(pop(my_key).unwrap()) == ~"next data");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -70,30 +70,6 @@ pub fn div_round(x: uint, y: uint) -> uint {
|
||||||
///
|
///
|
||||||
pub fn div_floor(x: uint, y: uint) -> uint { return x / y; }
|
pub 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 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl iter::Times for uint {
|
impl iter::Times for uint {
|
||||||
#[inline]
|
#[inline]
|
||||||
///
|
///
|
||||||
|
|
|
@ -47,7 +47,8 @@ use ops::Add;
|
||||||
use util;
|
use util;
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
use iterator::Iterator;
|
use iterator::Iterator;
|
||||||
use str::StrSlice;
|
use str::{StrSlice, OwnedStr};
|
||||||
|
use to_str::ToStr;
|
||||||
use clone::DeepClone;
|
use clone::DeepClone;
|
||||||
|
|
||||||
/// The option type
|
/// The option type
|
||||||
|
@ -85,22 +86,37 @@ impl<T:Ord> Ord for Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
|
impl<T: Add<T, T>> Add<Option<T>, Option<T>> for Option<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&self, other: &Option<T>) -> Option<T> {
|
fn add(&self, other: &Option<T>) -> Option<T> {
|
||||||
match (&*self, &*other) {
|
match (&*self, &*other) {
|
||||||
(&None, &None) => None,
|
(&None, &None) => None,
|
||||||
(_, &None) => (*self).clone(),
|
(_, &None) => None,
|
||||||
(&None, _) => (*other).clone(),
|
(&None, _) => None,
|
||||||
(&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
|
(&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: #8242 implementing manually because deriving doesn't work for some reason
|
||||||
|
impl<T: ToStr> ToStr for Option<T> {
|
||||||
|
fn to_str(&self) -> ~str {
|
||||||
|
match *self {
|
||||||
|
Some(ref x) => {
|
||||||
|
let mut s = ~"Some(";
|
||||||
|
s.push_str(x.to_str());
|
||||||
|
s.push_str(")");
|
||||||
|
s
|
||||||
|
}
|
||||||
|
None => ~"None"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Option<T> {
|
impl<T> Option<T> {
|
||||||
/// Return an iterator over the possibly contained value
|
/// Return an iterator over the possibly contained value
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter<'r>(&'r self) -> OptionIterator<'r, T> {
|
pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
|
||||||
match *self {
|
match *self {
|
||||||
Some(ref x) => OptionIterator{opt: Some(x)},
|
Some(ref x) => OptionIterator{opt: Some(x)},
|
||||||
None => OptionIterator{opt: None}
|
None => OptionIterator{opt: None}
|
||||||
|
@ -109,13 +125,19 @@ impl<T> Option<T> {
|
||||||
|
|
||||||
/// Return a mutable iterator over the possibly contained value
|
/// Return a mutable iterator over the possibly contained value
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mut_iter<'r>(&'r mut self) -> OptionMutIterator<'r, T> {
|
pub fn mut_iter<'r>(&'r mut self) -> OptionIterator<&'r mut T> {
|
||||||
match *self {
|
match *self {
|
||||||
Some(ref mut x) => OptionMutIterator{opt: Some(x)},
|
Some(ref mut x) => OptionIterator{opt: Some(x)},
|
||||||
None => OptionMutIterator{opt: None}
|
None => OptionIterator{opt: None}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a consuming iterator over the possibly contained value
|
||||||
|
#[inline]
|
||||||
|
pub fn consume(self) -> OptionIterator<T> {
|
||||||
|
OptionIterator{opt: self}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the option equals `None`
|
/// Returns true if the option equals `None`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_none(&self) -> bool {
|
pub fn is_none(&self) -> bool {
|
||||||
|
@ -148,8 +170,7 @@ impl<T> Option<T> {
|
||||||
/// Update an optional value by optionally running its content by reference
|
/// Update an optional value by optionally running its content by reference
|
||||||
/// through a function that returns an option.
|
/// through a function that returns an option.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>)
|
pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>) -> Option<U> {
|
||||||
-> Option<U> {
|
|
||||||
match *self {
|
match *self {
|
||||||
Some(ref x) => f(x),
|
Some(ref x) => f(x),
|
||||||
None => None
|
None => None
|
||||||
|
@ -159,8 +180,7 @@ impl<T> Option<T> {
|
||||||
/// Update an optional value by optionally running its content by mut reference
|
/// Update an optional value by optionally running its content by mut reference
|
||||||
/// through a function that returns an option.
|
/// through a function that returns an option.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn chain_mut_ref<'a, U>(&'a mut self, f: &fn(x: &'a mut T) -> Option<U>)
|
pub fn chain_mut_ref<'a, U>(&'a mut self, f: &fn(x: &'a mut T) -> Option<U>) -> Option<U> {
|
||||||
-> Option<U> {
|
|
||||||
match *self {
|
match *self {
|
||||||
Some(ref mut x) => f(x),
|
Some(ref mut x) => f(x),
|
||||||
None => None
|
None => None
|
||||||
|
@ -256,96 +276,88 @@ impl<T> Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Gets an immutable reference to the value inside an option.
|
||||||
Gets an immutable reference to the value inside an option.
|
///
|
||||||
|
/// # Failure
|
||||||
# Failure
|
///
|
||||||
|
/// Fails if the value equals `None`
|
||||||
Fails if the value equals `None`
|
///
|
||||||
|
/// # Safety note
|
||||||
# Safety note
|
///
|
||||||
|
/// In general, because this function may fail, its use is discouraged
|
||||||
In general, because this function may fail, its use is discouraged
|
/// (calling `get` on `None` is akin to dereferencing a null pointer).
|
||||||
(calling `get` on `None` is akin to dereferencing a null pointer).
|
/// Instead, prefer to use pattern matching and handle the `None`
|
||||||
Instead, prefer to use pattern matching and handle the `None`
|
/// case explicitly.
|
||||||
case explicitly.
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_ref<'a>(&'a self) -> &'a T {
|
pub fn get_ref<'a>(&'a self) -> &'a T {
|
||||||
match *self {
|
match *self {
|
||||||
Some(ref x) => x,
|
Some(ref x) => x,
|
||||||
None => fail!("option::get_ref `None`"),
|
None => fail!("called `Option::get_ref()` on a `None` value"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Gets a mutable reference to the value inside an option.
|
||||||
Gets a mutable reference to the value inside an option.
|
///
|
||||||
|
/// # Failure
|
||||||
# Failure
|
///
|
||||||
|
/// Fails if the value equals `None`
|
||||||
Fails if the value equals `None`
|
///
|
||||||
|
/// # Safety note
|
||||||
# Safety note
|
///
|
||||||
|
/// In general, because this function may fail, its use is discouraged
|
||||||
In general, because this function may fail, its use is discouraged
|
/// (calling `get` on `None` is akin to dereferencing a null pointer).
|
||||||
(calling `get` on `None` is akin to dereferencing a null pointer).
|
/// Instead, prefer to use pattern matching and handle the `None`
|
||||||
Instead, prefer to use pattern matching and handle the `None`
|
/// case explicitly.
|
||||||
case explicitly.
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
|
pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
|
||||||
match *self {
|
match *self {
|
||||||
Some(ref mut x) => x,
|
Some(ref mut x) => x,
|
||||||
None => fail!("option::get_mut_ref `None`"),
|
None => fail!("called `Option::get_mut_ref()` on a `None` value"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Moves a value out of an option type and returns it.
|
||||||
|
///
|
||||||
|
/// Useful primarily for getting strings, vectors and unique pointers out
|
||||||
|
/// of option types without copying them.
|
||||||
|
///
|
||||||
|
/// # Failure
|
||||||
|
///
|
||||||
|
/// Fails if the value equals `None`.
|
||||||
|
///
|
||||||
|
/// # Safety note
|
||||||
|
///
|
||||||
|
/// In general, because this function may fail, its use is discouraged.
|
||||||
|
/// Instead, prefer to use pattern matching and handle the `None`
|
||||||
|
/// case explicitly.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unwrap(self) -> T {
|
pub fn unwrap(self) -> T {
|
||||||
/*!
|
|
||||||
Moves a value out of an option type and returns it.
|
|
||||||
|
|
||||||
Useful primarily for getting strings, vectors and unique pointers out
|
|
||||||
of option types without copying them.
|
|
||||||
|
|
||||||
# Failure
|
|
||||||
|
|
||||||
Fails if the value equals `None`.
|
|
||||||
|
|
||||||
# Safety note
|
|
||||||
|
|
||||||
In general, because this function may fail, its use is discouraged.
|
|
||||||
Instead, prefer to use pattern matching and handle the `None`
|
|
||||||
case explicitly.
|
|
||||||
*/
|
|
||||||
match self {
|
match self {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => fail!("option::unwrap `None`"),
|
None => fail!("called `Option::unwrap()` on a `None` value"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// The option dance. Moves a value out of an option type and returns it,
|
||||||
* The option dance. Moves a value out of an option type and returns it,
|
/// replacing the original with `None`.
|
||||||
* replacing the original with `None`.
|
///
|
||||||
*
|
/// # Failure
|
||||||
* # Failure
|
///
|
||||||
*
|
/// Fails if the value equals `None`.
|
||||||
* Fails if the value equals `None`.
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn take_unwrap(&mut self) -> T {
|
pub fn take_unwrap(&mut self) -> T {
|
||||||
if self.is_none() { fail!("option::take_unwrap `None`") }
|
if self.is_none() {
|
||||||
|
fail!("called `Option::take_unwrap()` on a `None` value")
|
||||||
|
}
|
||||||
self.take().unwrap()
|
self.take().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Gets the value out of an option, printing a specified message on
|
||||||
* Gets the value out of an option, printing a specified message on
|
/// failure
|
||||||
* failure
|
///
|
||||||
*
|
/// # Failure
|
||||||
* # Failure
|
///
|
||||||
*
|
/// Fails if the value equals `None`
|
||||||
* Fails if the value equals `None`
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn expect(self, reason: &str) -> T {
|
pub fn expect(self, reason: &str) -> T {
|
||||||
match self {
|
match self {
|
||||||
|
@ -354,32 +366,13 @@ impl<T> Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Gets the value out of an option
|
|
||||||
|
|
||||||
# Failure
|
|
||||||
|
|
||||||
Fails if the value equals `None`
|
|
||||||
|
|
||||||
# Safety note
|
|
||||||
|
|
||||||
In general, because this function may fail, its use is discouraged
|
|
||||||
(calling `get` on `None` is akin to dereferencing a null pointer).
|
|
||||||
Instead, prefer to use pattern matching and handle the `None`
|
|
||||||
case explicitly.
|
|
||||||
*/
|
|
||||||
#[inline]
|
|
||||||
pub fn get(self) -> T {
|
|
||||||
match self {
|
|
||||||
Some(x) => return x,
|
|
||||||
None => fail!("option::get `None`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the contained value or a default
|
/// Returns the contained value or a default
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_or_default(self, def: T) -> T {
|
pub fn unwrap_or_default(self, def: T) -> T {
|
||||||
match self { Some(x) => x, None => def }
|
match self {
|
||||||
|
Some(x) => x,
|
||||||
|
None => def
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies a function zero or more times until the result is `None`.
|
/// Applies a function zero or more times until the result is `None`.
|
||||||
|
@ -395,12 +388,21 @@ impl<T> Option<T> {
|
||||||
impl<T:Zero> Option<T> {
|
impl<T:Zero> Option<T> {
|
||||||
/// Returns the contained value or zero (for this type)
|
/// Returns the contained value or zero (for this type)
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_or_zero(self) -> T {
|
pub fn unwrap_or_zero(self) -> T {
|
||||||
match self {
|
match self {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => Zero::zero()
|
None => Zero::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns self or `Some(zero)` (for this type)
|
||||||
|
#[inline]
|
||||||
|
pub fn or_zero(self) -> Option<T> {
|
||||||
|
match self {
|
||||||
|
None => Some(Zero::zero()),
|
||||||
|
x => x
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Zero for Option<T> {
|
impl<T> Zero for Option<T> {
|
||||||
|
@ -408,34 +410,18 @@ impl<T> Zero for Option<T> {
|
||||||
fn is_zero(&self) -> bool { self.is_none() }
|
fn is_zero(&self) -> bool { self.is_none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Immutable iterator over an `Option<A>`
|
/// An iterator that yields either one or zero elements
|
||||||
pub struct OptionIterator<'self, A> {
|
pub struct OptionIterator<A> {
|
||||||
priv opt: Option<&'self A>
|
priv opt: Option<A>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self, A> Iterator<&'self A> for OptionIterator<'self, A> {
|
impl<A> Iterator<A> for OptionIterator<A> {
|
||||||
fn next(&mut self) -> Option<&'self A> {
|
#[inline]
|
||||||
util::replace(&mut self.opt, None)
|
fn next(&mut self) -> Option<A> {
|
||||||
}
|
self.opt.take()
|
||||||
|
|
||||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
||||||
match self.opt {
|
|
||||||
Some(_) => (1, Some(1)),
|
|
||||||
None => (0, Some(0)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mutable iterator over an `Option<A>`
|
|
||||||
pub struct OptionMutIterator<'self, A> {
|
|
||||||
priv opt: Option<&'self mut A>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
|
|
||||||
fn next(&mut self) -> Option<&'self mut A> {
|
|
||||||
util::replace(&mut self.opt, None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||||
match self.opt {
|
match self.opt {
|
||||||
Some(_) => (1, Some(1)),
|
Some(_) => (1, Some(1)),
|
||||||
|
@ -450,7 +436,7 @@ mod tests {
|
||||||
use util;
|
use util;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unwrap_ptr() {
|
fn test_get_ptr() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let x = ~0;
|
let x = ~0;
|
||||||
let addr_x: *int = ::cast::transmute(&*x);
|
let addr_x: *int = ::cast::transmute(&*x);
|
||||||
|
@ -462,7 +448,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unwrap_str() {
|
fn test_get_str() {
|
||||||
let x = ~"test";
|
let x = ~"test";
|
||||||
let addr_x = x.as_imm_buf(|buf, _len| buf);
|
let addr_x = x.as_imm_buf(|buf, _len| buf);
|
||||||
let opt = Some(x);
|
let opt = Some(x);
|
||||||
|
@ -472,7 +458,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unwrap_resource() {
|
fn test_get_resource() {
|
||||||
struct R {
|
struct R {
|
||||||
i: @mut int,
|
i: @mut int,
|
||||||
}
|
}
|
||||||
|
@ -530,18 +516,18 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_or_zero() {
|
fn test_unwrap_or_zero() {
|
||||||
let some_stuff = Some(42);
|
let some_stuff = Some(42);
|
||||||
assert_eq!(some_stuff.get_or_zero(), 42);
|
assert_eq!(some_stuff.unwrap_or_zero(), 42);
|
||||||
let no_stuff: Option<int> = None;
|
let no_stuff: Option<int> = None;
|
||||||
assert_eq!(no_stuff.get_or_zero(), 0);
|
assert_eq!(no_stuff.unwrap_or_zero(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filtered() {
|
fn test_filtered() {
|
||||||
let some_stuff = Some(42);
|
let some_stuff = Some(42);
|
||||||
let modified_stuff = some_stuff.filtered(|&x| {x < 10});
|
let modified_stuff = some_stuff.filtered(|&x| {x < 10});
|
||||||
assert_eq!(some_stuff.get(), 42);
|
assert_eq!(some_stuff.unwrap(), 42);
|
||||||
assert!(modified_stuff.is_none());
|
assert!(modified_stuff.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -574,7 +574,7 @@ pub fn tmpdir() -> Path {
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn lookup() -> Path {
|
fn lookup() -> Path {
|
||||||
getenv_nonempty("TMPDIR").get_or_default(Path("/tmp"))
|
getenv_nonempty("TMPDIR").unwrap_or_default(Path("/tmp"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -582,7 +582,7 @@ pub fn tmpdir() -> Path {
|
||||||
getenv_nonempty("TMP").or(
|
getenv_nonempty("TMP").or(
|
||||||
getenv_nonempty("TEMP").or(
|
getenv_nonempty("TEMP").or(
|
||||||
getenv_nonempty("USERPROFILE").or(
|
getenv_nonempty("USERPROFILE").or(
|
||||||
getenv_nonempty("WINDIR")))).get_or_default(Path("C:\\Windows"))
|
getenv_nonempty("WINDIR")))).unwrap_or_default(Path("C:\\Windows"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1788,7 +1788,7 @@ mod tests {
|
||||||
fn test_self_exe_path() {
|
fn test_self_exe_path() {
|
||||||
let path = os::self_exe_path();
|
let path = os::self_exe_path();
|
||||||
assert!(path.is_some());
|
assert!(path.is_some());
|
||||||
let path = path.get();
|
let path = path.unwrap();
|
||||||
debug!(path.clone());
|
debug!(path.clone());
|
||||||
|
|
||||||
// Hard to test this function
|
// Hard to test this function
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
use cast;
|
use cast;
|
||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
|
use iterator::{range, Iterator};
|
||||||
use option::{Option, Some, None};
|
use option::{Option, Some, None};
|
||||||
use unstable::intrinsics;
|
use unstable::intrinsics;
|
||||||
use util::swap;
|
use util::swap;
|
||||||
|
@ -20,7 +21,6 @@ use util::swap;
|
||||||
#[cfg(not(test))] use num::Int;
|
#[cfg(not(test))] use num::Int;
|
||||||
|
|
||||||
#[cfg(not(test))] use cmp::{Eq, Ord};
|
#[cfg(not(test))] use cmp::{Eq, Ord};
|
||||||
use uint;
|
|
||||||
|
|
||||||
/// Calculate the offset from a pointer
|
/// Calculate the offset from a pointer
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -240,11 +240,10 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: &fn(*T)) {
|
||||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
||||||
}
|
}
|
||||||
//let start_ptr = *arr;
|
//let start_ptr = *arr;
|
||||||
uint::iterate(0, len, |e| {
|
for e in range(0, len) {
|
||||||
let n = offset(arr, e as int);
|
let n = offset(arr, e as int);
|
||||||
cb(*n);
|
cb(*n);
|
||||||
true
|
}
|
||||||
});
|
|
||||||
debug!("array_each_with_len: after iterate");
|
debug!("array_each_with_len: after iterate");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -533,7 +533,7 @@ impl<R: Rng> RngUtil for R {
|
||||||
|
|
||||||
/// Choose an item randomly, failing if values is empty
|
/// Choose an item randomly, failing if values is empty
|
||||||
fn choose<T:Clone>(&mut self, values: &[T]) -> T {
|
fn choose<T:Clone>(&mut self, values: &[T]) -> T {
|
||||||
self.choose_option(values).get()
|
self.choose_option(values).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Choose Some(item) randomly, returning None if values is empty
|
/// Choose Some(item) randomly, returning None if values is empty
|
||||||
|
@ -549,7 +549,7 @@ impl<R: Rng> RngUtil for R {
|
||||||
* the weights is 0
|
* the weights is 0
|
||||||
*/
|
*/
|
||||||
fn choose_weighted<T:Clone>(&mut self, v: &[Weighted<T>]) -> T {
|
fn choose_weighted<T:Clone>(&mut self, v: &[Weighted<T>]) -> T {
|
||||||
self.choose_weighted_option(v).get()
|
self.choose_weighted_option(v).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,27 +16,31 @@ use clone::Clone;
|
||||||
use cmp::Eq;
|
use cmp::Eq;
|
||||||
use either;
|
use either;
|
||||||
use iterator::Iterator;
|
use iterator::Iterator;
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some, OptionIterator};
|
||||||
use vec;
|
use vec;
|
||||||
use vec::{OwnedVector, ImmutableVector};
|
use vec::{OwnedVector, ImmutableVector};
|
||||||
use container::Container;
|
use container::Container;
|
||||||
|
use to_str::ToStr;
|
||||||
|
use str::StrSlice;
|
||||||
|
|
||||||
/// The result type
|
/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
|
||||||
|
///
|
||||||
|
/// In order to provide informative error messages, `E` is reqired to implement `ToStr`.
|
||||||
|
/// It is further recommended for `E` to be a descriptive error type, eg a `enum` for
|
||||||
|
/// all possible errors cases.
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum Result<T, U> {
|
pub enum Result<T, E> {
|
||||||
/// Contains the successful result value
|
/// Contains the successful result value
|
||||||
Ok(T),
|
Ok(T),
|
||||||
/// Contains the error value
|
/// Contains the error value
|
||||||
Err(U)
|
Err(E)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, E> Result<T, E> {
|
impl<T, E: ToStr> Result<T, E> {
|
||||||
/**
|
/// Convert to the `either` type
|
||||||
* Convert to the `either` type
|
///
|
||||||
*
|
/// `Ok` result variants are converted to `either::Right` variants, `Err`
|
||||||
* `Ok` result variants are converted to `either::Right` variants, `Err`
|
/// result variants are converted to `either::Left`.
|
||||||
* result variants are converted to `either::Left`.
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_either(self)-> either::Either<E, T>{
|
pub fn to_either(self)-> either::Either<E, T>{
|
||||||
match self {
|
match self {
|
||||||
|
@ -45,18 +49,16 @@ impl<T, E> Result<T, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Get a reference to the value out of a successful result
|
||||||
* Get a reference to the value out of a successful result
|
///
|
||||||
*
|
/// # Failure
|
||||||
* # Failure
|
///
|
||||||
*
|
/// If the result is an error
|
||||||
* If the result is an error
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_ref<'a>(&'a self) -> &'a T {
|
pub fn get_ref<'a>(&'a self) -> &'a T {
|
||||||
match *self {
|
match *self {
|
||||||
Ok(ref t) => t,
|
Ok(ref t) => t,
|
||||||
Err(ref e) => fail!("get_ref called on `Err` result: %?", *e),
|
Err(ref e) => fail!("called `Result::get_ref()` on `Err` value: %s", e.to_str()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,76 +77,90 @@ impl<T, E> Result<T, E> {
|
||||||
!self.is_ok()
|
!self.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Call a method based on a previous result
|
||||||
* Call a method based on a previous result
|
///
|
||||||
*
|
/// If `self` is `Ok` then the value is extracted and passed to `op`
|
||||||
* If `self` is `Ok` then the value is extracted and passed to `op`
|
/// whereupon `op`s result is returned. if `self` is `Err` then it is
|
||||||
* whereupon `op`s result is returned. if `self` is `Err` then it is
|
/// immediately returned. This function can be used to compose the results
|
||||||
* immediately returned. This function can be used to compose the results
|
/// of two functions.
|
||||||
* of two functions.
|
///
|
||||||
*
|
/// Example:
|
||||||
* Example:
|
///
|
||||||
*
|
/// for buf in read_file(file) {
|
||||||
* do read_file(file).iter |buf| {
|
/// print_buf(buf)
|
||||||
* print_buf(buf)
|
/// }
|
||||||
* }
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter(&self, f: &fn(&T)) {
|
pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
|
||||||
match *self {
|
match *self {
|
||||||
Ok(ref t) => f(t),
|
Ok(ref t) => Some(t),
|
||||||
Err(_) => (),
|
Err(*) => None,
|
||||||
}
|
}.consume()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Call a method based on a previous result
|
||||||
* Call a method based on a previous result
|
///
|
||||||
*
|
/// If `self` is `Err` then the value is extracted and passed to `op`
|
||||||
* If `self` is `Err` then the value is extracted and passed to `op`
|
/// whereupon `op`s result is returned. if `self` is `Ok` then it is
|
||||||
* whereupon `op`s result is returned. if `self` is `Ok` then it is
|
/// immediately returned. This function can be used to pass through a
|
||||||
* immediately returned. This function can be used to pass through a
|
/// successful result while handling an error.
|
||||||
* successful result while handling an error.
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter_err(&self, f: &fn(&E)) {
|
pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> {
|
||||||
match *self {
|
match *self {
|
||||||
Ok(_) => (),
|
Ok(*) => None,
|
||||||
Err(ref e) => f(e),
|
Err(ref t) => Some(t),
|
||||||
}
|
}.consume()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unwraps a result, assuming it is an `Ok(T)`
|
/// Unwraps a result, yielding the content of an `Ok`.
|
||||||
|
/// Fails if the value is a `Err` with an error message derived
|
||||||
|
/// from `E`'s `ToStr` implementation.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unwrap(self) -> T {
|
pub fn unwrap(self) -> T {
|
||||||
match self {
|
match self {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(_) => fail!("unwrap called on an `Err` result"),
|
Err(e) => fail!("called `Result::unwrap()` on `Err` value: %s", e.to_str()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unwraps a result, assuming it is an `Err(U)`
|
/// Unwraps a result, yielding the content of an `Err`.
|
||||||
|
/// Fails if the value is a `Ok`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unwrap_err(self) -> E {
|
pub fn unwrap_err(self) -> E {
|
||||||
|
self.expect_err("called `Result::unwrap_err()` on `Ok` value")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unwraps a result, yielding the content of an `Ok`.
|
||||||
|
/// Fails if the value is a `Err` with a custom failure message.
|
||||||
|
#[inline]
|
||||||
|
pub fn expect(self, reason: &str) -> T {
|
||||||
match self {
|
match self {
|
||||||
Err(e) => e,
|
Ok(t) => t,
|
||||||
Ok(_) => fail!("unwrap called on an `Ok` result"),
|
Err(_) => fail!(reason.to_owned()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Unwraps a result, yielding the content of an `Err`
|
||||||
* Call a method based on a previous result
|
/// Fails if the value is a `Ok` with a custom failure message.
|
||||||
*
|
#[inline]
|
||||||
* If `self` is `Ok` then the value is extracted and passed to `op`
|
pub fn expect_err(self, reason: &str) -> E {
|
||||||
* whereupon `op`s result is returned. if `self` is `Err` then it is
|
match self {
|
||||||
* immediately returned. This function can be used to compose the results
|
Err(e) => e,
|
||||||
* of two functions.
|
Ok(_) => fail!(reason.to_owned()),
|
||||||
*
|
}
|
||||||
* Example:
|
}
|
||||||
*
|
|
||||||
* let res = do read_file(file) |buf| {
|
/// Call a method based on a previous result
|
||||||
* Ok(parse_bytes(buf))
|
///
|
||||||
* };
|
/// If `self` is `Ok` then the value is extracted and passed to `op`
|
||||||
*/
|
/// whereupon `op`s result is returned. if `self` is `Err` then it is
|
||||||
|
/// immediately returned. This function can be used to compose the results
|
||||||
|
/// of two functions.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// let res = do read_file(file) |buf| {
|
||||||
|
/// Ok(parse_bytes(buf))
|
||||||
|
/// };
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn chain<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
|
pub fn chain<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -153,14 +169,12 @@ impl<T, E> Result<T, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Call a function based on a previous result
|
||||||
* Call a function based on a previous result
|
///
|
||||||
*
|
/// If `self` is `Err` then the value is extracted and passed to `op`
|
||||||
* If `self` is `Err` then the value is extracted and passed to `op`
|
/// whereupon `op`s result is returned. if `self` is `Ok` then it is
|
||||||
* whereupon `op`s result is returned. if `self` is `Ok` then it is
|
/// immediately returned. This function can be used to pass through a
|
||||||
* immediately returned. This function can be used to pass through a
|
/// successful result while handling an error.
|
||||||
* successful result while handling an error.
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn chain_err<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
|
pub fn chain_err<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -170,30 +184,13 @@ impl<T, E> Result<T, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone, E> Result<T, E> {
|
impl<T: Clone, E: ToStr> Result<T, E> {
|
||||||
/**
|
/// Call a method based on a previous result
|
||||||
* Get the value out of a successful result
|
///
|
||||||
*
|
/// If `self` is `Err` then the value is extracted and passed to `op`
|
||||||
* # Failure
|
/// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
|
||||||
*
|
/// `Ok` then it is immediately returned. This function can be used to pass
|
||||||
* If the result is an error
|
/// through a successful result while handling an error.
|
||||||
*/
|
|
||||||
#[inline]
|
|
||||||
pub fn get(&self) -> T {
|
|
||||||
match *self {
|
|
||||||
Ok(ref t) => t.clone(),
|
|
||||||
Err(ref e) => fail!("get called on `Err` result: %?", *e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call a method based on a previous result
|
|
||||||
*
|
|
||||||
* If `self` is `Err` then the value is extracted and passed to `op`
|
|
||||||
* whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
|
|
||||||
* `Ok` then it is immediately returned. This function can be used to pass
|
|
||||||
* through a successful result while handling an error.
|
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn map_err<F: Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
|
pub fn map_err<F: Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -203,38 +200,21 @@ impl<T: Clone, E> Result<T, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, E: Clone> Result<T, E> {
|
impl<T, E: Clone + ToStr> Result<T, E> {
|
||||||
/**
|
/// Call a method based on a previous result
|
||||||
* Get the value out of an error result
|
///
|
||||||
*
|
/// If `self` is `Ok` then the value is extracted and passed to `op`
|
||||||
* # Failure
|
/// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
|
||||||
*
|
/// `Err` then it is immediately returned. This function can be used to
|
||||||
* If the result is not an error
|
/// compose the results of two functions.
|
||||||
*/
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// let res = do read_file(file).map |buf| {
|
||||||
|
/// parse_bytes(buf)
|
||||||
|
/// };
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_err(&self) -> E {
|
pub fn map<U>(&self, op: &fn(&T) -> U) -> Result<U,E> {
|
||||||
match *self {
|
|
||||||
Err(ref e) => e.clone(),
|
|
||||||
Ok(_) => fail!("get_err called on `Ok` result")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call a method based on a previous result
|
|
||||||
*
|
|
||||||
* If `self` is `Ok` then the value is extracted and passed to `op`
|
|
||||||
* whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
|
|
||||||
* `Err` then it is immediately returned. This function can be used to
|
|
||||||
* compose the results of two functions.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* let res = do read_file(file).map |buf| {
|
|
||||||
* parse_bytes(buf)
|
|
||||||
* };
|
|
||||||
*/
|
|
||||||
#[inline]
|
|
||||||
pub fn map<U:Clone>(&self, op: &fn(&T) -> U) -> Result<U,E> {
|
|
||||||
match *self {
|
match *self {
|
||||||
Ok(ref t) => Ok(op(t)),
|
Ok(ref t) => Ok(op(t)),
|
||||||
Err(ref e) => Err(e.clone())
|
Err(ref e) => Err(e.clone())
|
||||||
|
@ -242,23 +222,35 @@ impl<T, E: Clone> Result<T, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[inline]
|
||||||
* Maps each element in the vector `ts` using the operation `op`. Should an
|
#[allow(missing_doc)]
|
||||||
* error occur, no further mappings are performed and the error is returned.
|
pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
|
||||||
* Should no error occur, a vector containing the result of each map is
|
op: &fn(&T) -> Result<V,U>) -> Result<Option<V>,U> {
|
||||||
* returned.
|
match *o_t {
|
||||||
*
|
None => Ok(None),
|
||||||
* Here is an example which increments every integer in a vector,
|
Some(ref t) => match op(t) {
|
||||||
* checking for overflow:
|
Ok(v) => Ok(Some(v)),
|
||||||
*
|
Err(e) => Err(e)
|
||||||
* fn inc_conditionally(x: uint) -> result<uint,str> {
|
}
|
||||||
* if x == uint::max_value { return Err("overflow"); }
|
}
|
||||||
* else { return Ok(x+1u); }
|
}
|
||||||
* }
|
|
||||||
* map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
|
// FIXME: #8228 Replaceable by an external iterator?
|
||||||
* assert!(incd == ~[2u, 3u, 4u]);
|
/// Maps each element in the vector `ts` using the operation `op`. Should an
|
||||||
* }
|
/// error occur, no further mappings are performed and the error is returned.
|
||||||
*/
|
/// Should no error occur, a vector containing the result of each map is
|
||||||
|
/// returned.
|
||||||
|
///
|
||||||
|
/// Here is an example which increments every integer in a vector,
|
||||||
|
/// checking for overflow:
|
||||||
|
///
|
||||||
|
/// fn inc_conditionally(x: uint) -> result<uint,str> {
|
||||||
|
/// if x == uint::max_value { return Err("overflow"); }
|
||||||
|
/// else { return Ok(x+1u); }
|
||||||
|
/// }
|
||||||
|
/// map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
|
||||||
|
/// assert!(incd == ~[2u, 3u, 4u]);
|
||||||
|
/// }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
|
pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
|
||||||
-> Result<~[V],U> {
|
-> Result<~[V],U> {
|
||||||
|
@ -272,36 +264,17 @@ pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
|
||||||
return Ok(vs);
|
return Ok(vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: #8228 Replaceable by an external iterator?
|
||||||
|
/// Same as map, but it operates over two parallel vectors.
|
||||||
|
///
|
||||||
|
/// A precondition is used here to ensure that the vectors are the same
|
||||||
|
/// length. While we do not often use preconditions in the standard
|
||||||
|
/// library, a precondition is used here because result::t is generally
|
||||||
|
/// used in 'careful' code contexts where it is both appropriate and easy
|
||||||
|
/// to accommodate an error like the vectors being of different lengths.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(missing_doc)]
|
pub fn map_vec2<S, T, U: ToStr, V>(ss: &[S], ts: &[T],
|
||||||
pub fn map_opt<T,
|
|
||||||
U,
|
|
||||||
V>(
|
|
||||||
o_t: &Option<T>,
|
|
||||||
op: &fn(&T) -> Result<V,U>)
|
|
||||||
-> Result<Option<V>,U> {
|
|
||||||
match *o_t {
|
|
||||||
None => Ok(None),
|
|
||||||
Some(ref t) => match op(t) {
|
|
||||||
Ok(v) => Ok(Some(v)),
|
|
||||||
Err(e) => Err(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as map, but it operates over two parallel vectors.
|
|
||||||
*
|
|
||||||
* A precondition is used here to ensure that the vectors are the same
|
|
||||||
* length. While we do not often use preconditions in the standard
|
|
||||||
* library, a precondition is used here because result::t is generally
|
|
||||||
* used in 'careful' code contexts where it is both appropriate and easy
|
|
||||||
* to accommodate an error like the vectors being of different lengths.
|
|
||||||
*/
|
|
||||||
#[inline]
|
|
||||||
pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
|
|
||||||
op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
|
op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
|
||||||
|
|
||||||
assert!(vec::same_length(ss, ts));
|
assert!(vec::same_length(ss, ts));
|
||||||
let n = ts.len();
|
let n = ts.len();
|
||||||
let mut vs = vec::with_capacity(n);
|
let mut vs = vec::with_capacity(n);
|
||||||
|
@ -316,15 +289,13 @@ pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
|
||||||
return Ok(vs);
|
return Ok(vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// FIXME: #8228 Replaceable by an external iterator?
|
||||||
* Applies op to the pairwise elements from `ss` and `ts`, aborting on
|
/// Applies op to the pairwise elements from `ss` and `ts`, aborting on
|
||||||
* error. This could be implemented using `map_zip()` but it is more efficient
|
/// error. This could be implemented using `map_zip()` but it is more efficient
|
||||||
* on its own as no result vector is built.
|
/// on its own as no result vector is built.
|
||||||
*/
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter_vec2<S,T,U>(ss: &[S], ts: &[T],
|
pub fn iter_vec2<S, T, U: ToStr>(ss: &[S], ts: &[T],
|
||||||
op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
|
op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
|
||||||
|
|
||||||
assert!(vec::same_length(ss, ts));
|
assert!(vec::same_length(ss, ts));
|
||||||
let n = ts.len();
|
let n = ts.len();
|
||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
|
@ -353,32 +324,36 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn chain_success() {
|
pub fn chain_success() {
|
||||||
assert_eq!(op1().chain(op2).get(), 667u);
|
assert_eq!(op1().chain(op2).unwrap(), 667u);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn chain_failure() {
|
pub fn chain_failure() {
|
||||||
assert_eq!(op3().chain( op2).get_err(), ~"sadface");
|
assert_eq!(op3().chain( op2).unwrap_err(), ~"sadface");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_impl_iter() {
|
pub fn test_impl_iter() {
|
||||||
let mut valid = false;
|
let mut valid = false;
|
||||||
Ok::<~str, ~str>(~"a").iter(|_x| valid = true);
|
let okval = Ok::<~str, ~str>(~"a");
|
||||||
|
do okval.iter().next().map |_| { valid = true; };
|
||||||
assert!(valid);
|
assert!(valid);
|
||||||
|
|
||||||
Err::<~str, ~str>(~"b").iter(|_x| valid = false);
|
let errval = Err::<~str, ~str>(~"b");
|
||||||
|
do errval.iter().next().map |_| { valid = false; };
|
||||||
assert!(valid);
|
assert!(valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_impl_iter_err() {
|
pub fn test_impl_iter_err() {
|
||||||
let mut valid = true;
|
let mut valid = true;
|
||||||
Ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
|
let okval = Ok::<~str, ~str>(~"a");
|
||||||
|
do okval.iter_err().next().map |_| { valid = false };
|
||||||
assert!(valid);
|
assert!(valid);
|
||||||
|
|
||||||
valid = false;
|
valid = false;
|
||||||
Err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
|
let errval = Err::<~str, ~str>(~"b");
|
||||||
|
do errval.iter_err().next().map |_| { valid = true };
|
||||||
assert!(valid);
|
assert!(valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
//! Some various other I/O types
|
//! Some various other I/O types
|
||||||
|
|
||||||
// NOTE: These ultimately belong somewhere else
|
// FIXME(#3660): should move to libextra
|
||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -115,7 +115,7 @@ mod test {
|
||||||
let mem_reader = MemReader::new(buf);
|
let mem_reader = MemReader::new(buf);
|
||||||
let mut inflate_reader = InflateReader::new(mem_reader);
|
let mut inflate_reader = InflateReader::new(mem_reader);
|
||||||
let mut out_bytes = [0, .. 100];
|
let mut out_bytes = [0, .. 100];
|
||||||
let bytes_read = inflate_reader.read(out_bytes).get();
|
let bytes_read = inflate_reader.read(out_bytes).unwrap();
|
||||||
assert_eq!(bytes_read, in_bytes.len());
|
assert_eq!(bytes_read, in_bytes.len());
|
||||||
let out_msg = str::from_bytes(out_bytes);
|
let out_msg = str::from_bytes(out_bytes);
|
||||||
assert!(in_msg == out_msg);
|
assert!(in_msg == out_msg);
|
||||||
|
|
|
@ -243,6 +243,8 @@ Out of scope
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
use to_str::ToStr;
|
||||||
|
use str::{StrSlice, OwnedStr};
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use self::stdio::stdin;
|
pub use self::stdio::stdin;
|
||||||
|
@ -334,6 +336,20 @@ pub struct IoError {
|
||||||
detail: Option<~str>
|
detail: Option<~str>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: #8242 implementing manually because deriving doesn't work for some reason
|
||||||
|
impl ToStr for IoError {
|
||||||
|
fn to_str(&self) -> ~str {
|
||||||
|
let mut s = ~"IoError { kind: ";
|
||||||
|
s.push_str(self.kind.to_str());
|
||||||
|
s.push_str(", desc: ");
|
||||||
|
s.push_str(self.desc);
|
||||||
|
s.push_str(", detail: ");
|
||||||
|
s.push_str(self.detail.to_str());
|
||||||
|
s.push_str(" }");
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
pub enum IoErrorKind {
|
pub enum IoErrorKind {
|
||||||
PreviousIoError,
|
PreviousIoError,
|
||||||
|
@ -348,6 +364,24 @@ pub enum IoErrorKind {
|
||||||
BrokenPipe
|
BrokenPipe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: #8242 implementing manually because deriving doesn't work for some reason
|
||||||
|
impl ToStr for IoErrorKind {
|
||||||
|
fn to_str(&self) -> ~str {
|
||||||
|
match *self {
|
||||||
|
PreviousIoError => ~"PreviousIoError",
|
||||||
|
OtherIoError => ~"OtherIoError",
|
||||||
|
EndOfFile => ~"EndOfFile",
|
||||||
|
FileNotFound => ~"FileNotFound",
|
||||||
|
PermissionDenied => ~"PermissionDenied",
|
||||||
|
ConnectionFailed => ~"ConnectionFailed",
|
||||||
|
Closed => ~"Closed",
|
||||||
|
ConnectionRefused => ~"ConnectionRefused",
|
||||||
|
ConnectionReset => ~"ConnectionReset",
|
||||||
|
BrokenPipe => ~"BrokenPipe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// XXX: Can't put doc comments on macros
|
// XXX: Can't put doc comments on macros
|
||||||
// Raised by `I/O` operations on error.
|
// Raised by `I/O` operations on error.
|
||||||
condition! {
|
condition! {
|
||||||
|
|
|
@ -193,6 +193,10 @@ impl BlockedTask {
|
||||||
|
|
||||||
/// Create a blocked task, unless the task was already killed.
|
/// Create a blocked task, unless the task was already killed.
|
||||||
pub fn try_block(mut task: ~Task) -> Either<~Task, BlockedTask> {
|
pub fn try_block(mut task: ~Task) -> Either<~Task, BlockedTask> {
|
||||||
|
// NB: As an optimization, we could give a free pass to being unkillable
|
||||||
|
// to tasks whose taskgroups haven't been initialized yet, but that
|
||||||
|
// introduces complications with select() and with the test cases below,
|
||||||
|
// and it's not clear the uncommon performance boost is worth it.
|
||||||
if task.death.unkillable > 0 {
|
if task.death.unkillable > 0 {
|
||||||
Right(Unkillable(task))
|
Right(Unkillable(task))
|
||||||
} else {
|
} else {
|
||||||
|
@ -205,11 +209,10 @@ impl BlockedTask {
|
||||||
let flag_arc = match task.death.spare_kill_flag.take() {
|
let flag_arc = match task.death.spare_kill_flag.take() {
|
||||||
Some(spare_flag) => spare_flag,
|
Some(spare_flag) => spare_flag,
|
||||||
None => {
|
None => {
|
||||||
// FIXME(#7544): Uncomment this when terminate_current_task
|
// A task that kills us won't have a spare kill flag to
|
||||||
// stops being *terrible*. That's the only place that violates
|
// give back to us, so we restore it ourselves here. This
|
||||||
// the assumption of "becoming unkillable will fail if the
|
// situation should only arise when we're already failing.
|
||||||
// task was killed".
|
rtassert!(task.unwinder.unwinding);
|
||||||
// rtassert!(task.unwinder.unwinding);
|
|
||||||
(*task.death.kill_handle.get_ref().get()).killed.clone()
|
(*task.death.kill_handle.get_ref().get()).killed.clone()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -365,7 +365,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
|
||||||
|
|
||||||
rtdebug!("about to create the main scheduler task");
|
rtdebug!("about to create the main scheduler task");
|
||||||
|
|
||||||
let mut main_sched = main_sched.get();
|
let mut main_sched = main_sched.unwrap();
|
||||||
|
|
||||||
let home = Sched(main_sched.make_handle());
|
let home = Sched(main_sched.make_handle());
|
||||||
let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool,
|
let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool,
|
||||||
|
|
|
@ -465,10 +465,10 @@ mod test {
|
||||||
do run_in_newsched_task() {
|
do run_in_newsched_task() {
|
||||||
static key: local_data::Key<@~str> = &local_data::Key;
|
static key: local_data::Key<@~str> = &local_data::Key;
|
||||||
local_data::set(key, @~"data");
|
local_data::set(key, @~"data");
|
||||||
assert!(*local_data::get(key, |k| k.map(|&k| *k)).get() == ~"data");
|
assert!(*local_data::get(key, |k| k.map(|&k| *k)).unwrap() == ~"data");
|
||||||
static key2: local_data::Key<@~str> = &local_data::Key;
|
static key2: local_data::Key<@~str> = &local_data::Key;
|
||||||
local_data::set(key2, @~"data");
|
local_data::set(key2, @~"data");
|
||||||
assert!(*local_data::get(key2, |k| k.map(|&k| *k)).get() == ~"data");
|
assert!(*local_data::get(key2, |k| k.map(|&k| *k)).unwrap() == ~"data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
|
||||||
|
|
||||||
do run_in_bare_thread {
|
do run_in_bare_thread {
|
||||||
let nthreads = match os::getenv("RUST_RT_TEST_THREADS") {
|
let nthreads = match os::getenv("RUST_RT_TEST_THREADS") {
|
||||||
Some(nstr) => FromStr::from_str(nstr).get(),
|
Some(nstr) => FromStr::from_str(nstr).unwrap(),
|
||||||
None => {
|
None => {
|
||||||
// Using more threads than cores in test code
|
// Using more threads than cores in test code
|
||||||
// to force the OS to preempt them frequently.
|
// to force the OS to preempt them frequently.
|
||||||
|
@ -362,7 +362,7 @@ pub fn stress_factor() -> uint {
|
||||||
use os::getenv;
|
use os::getenv;
|
||||||
|
|
||||||
match getenv("RUST_RT_STRESS") {
|
match getenv("RUST_RT_STRESS") {
|
||||||
Some(val) => uint::from_str(val).get(),
|
Some(val) => uint::from_str(val).unwrap(),
|
||||||
None => 1
|
None => 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub fn num_cpus() -> uint {
|
||||||
/// either `RUST_THREADS` or `num_cpus`.
|
/// either `RUST_THREADS` or `num_cpus`.
|
||||||
pub fn default_sched_threads() -> uint {
|
pub fn default_sched_threads() -> uint {
|
||||||
match os::getenv("RUST_THREADS") {
|
match os::getenv("RUST_THREADS") {
|
||||||
Some(nstr) => FromStr::from_str(nstr).get(),
|
Some(nstr) => FromStr::from_str(nstr).unwrap(),
|
||||||
None => num_cpus()
|
None => num_cpus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ fn uv_socket_addr_as_socket_addr<T>(addr: UvSocketAddr, f: &fn(SocketAddr) -> T)
|
||||||
"" => ~[],
|
"" => ~[],
|
||||||
// IPv4-Mapped/Compatible IPv6 Address?
|
// IPv4-Mapped/Compatible IPv6 Address?
|
||||||
s if s.find('.').is_some() => {
|
s if s.find('.').is_some() => {
|
||||||
let i = s.rfind(':').get_or_default(-1);
|
let i = s.rfind(':').unwrap_or_default(-1);
|
||||||
|
|
||||||
let b = s.slice(i + 1, s.len()); // the ipv4 part
|
let b = s.slice(i + 1, s.len()); // the ipv4 part
|
||||||
|
|
||||||
|
@ -614,7 +614,7 @@ mod test {
|
||||||
do tcp_watcher.connect(addr) |stream_watcher, status| {
|
do tcp_watcher.connect(addr) |stream_watcher, status| {
|
||||||
rtdebug!("tcp_watcher.connect!");
|
rtdebug!("tcp_watcher.connect!");
|
||||||
assert!(status.is_some());
|
assert!(status.is_some());
|
||||||
assert_eq!(status.get().name(), ~"ECONNREFUSED");
|
assert_eq!(status.unwrap().name(), ~"ECONNREFUSED");
|
||||||
stream_watcher.close(||());
|
stream_watcher.close(||());
|
||||||
}
|
}
|
||||||
loop_.run();
|
loop_.run();
|
||||||
|
@ -632,7 +632,7 @@ mod test {
|
||||||
do tcp_watcher.connect(addr) |stream_watcher, status| {
|
do tcp_watcher.connect(addr) |stream_watcher, status| {
|
||||||
rtdebug!("tcp_watcher.connect!");
|
rtdebug!("tcp_watcher.connect!");
|
||||||
assert!(status.is_some());
|
assert!(status.is_some());
|
||||||
assert_eq!(status.get().name(), ~"ECONNREFUSED");
|
assert_eq!(status.unwrap().name(), ~"ECONNREFUSED");
|
||||||
stream_watcher.close(||());
|
stream_watcher.close(||());
|
||||||
}
|
}
|
||||||
loop_.run();
|
loop_.run();
|
||||||
|
|
|
@ -278,7 +278,7 @@ impl IoFactory for UvIoFactory {
|
||||||
rtdebug!("status is some");
|
rtdebug!("status is some");
|
||||||
let task_cell = Cell::new(task_cell.take());
|
let task_cell = Cell::new(task_cell.take());
|
||||||
do stream_watcher.close {
|
do stream_watcher.close {
|
||||||
let res = Err(uv_error_to_io_error(status.get()));
|
let res = Err(uv_error_to_io_error(status.unwrap()));
|
||||||
unsafe { (*result_cell_ptr).put_back(res); }
|
unsafe { (*result_cell_ptr).put_back(res); }
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler = Local::take::<Scheduler>();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub fn from_bytes(vv: &[u8]) -> ~str {
|
||||||
use str::not_utf8::cond;
|
use str::not_utf8::cond;
|
||||||
|
|
||||||
if !is_utf8(vv) {
|
if !is_utf8(vv) {
|
||||||
let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get();
|
let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).unwrap();
|
||||||
cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
|
cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
|
||||||
first_bad_byte as uint))
|
first_bad_byte as uint))
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,7 +76,7 @@ pub fn from_bytes_owned(vv: ~[u8]) -> ~str {
|
||||||
use str::not_utf8::cond;
|
use str::not_utf8::cond;
|
||||||
|
|
||||||
if !is_utf8(vv) {
|
if !is_utf8(vv) {
|
||||||
let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get();
|
let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).unwrap();
|
||||||
cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
|
cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
|
||||||
first_bad_byte as uint))
|
first_bad_byte as uint))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1029,7 +1029,7 @@ pub mod raw {
|
||||||
/// If end is greater than the length of the string.
|
/// If end is greater than the length of the string.
|
||||||
#[cfg(stage0)]
|
#[cfg(stage0)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> &str {
|
pub unsafe fn slice_bytes<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
|
||||||
do s.as_imm_buf |sbuf, n| {
|
do s.as_imm_buf |sbuf, n| {
|
||||||
assert!((begin <= end));
|
assert!((begin <= end));
|
||||||
assert!((end <= n));
|
assert!((end <= n));
|
||||||
|
|
|
@ -926,7 +926,7 @@ fn test_named_task() {
|
||||||
t.name(~"ada lovelace");
|
t.name(~"ada lovelace");
|
||||||
do t.spawn {
|
do t.spawn {
|
||||||
do with_task_name |name| {
|
do with_task_name |name| {
|
||||||
assert!(name.get() == "ada lovelace");
|
assert!(name.unwrap() == "ada lovelace");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -568,7 +568,8 @@ impl RuntimeGlue {
|
||||||
let me = Local::unsafe_borrow::<Task>();
|
let me = Local::unsafe_borrow::<Task>();
|
||||||
blk(match (*me).taskgroup {
|
blk(match (*me).taskgroup {
|
||||||
None => {
|
None => {
|
||||||
// Main task, doing first spawn ever. Lazily initialize.
|
// First task in its (unlinked/unsupervised) taskgroup.
|
||||||
|
// Lazily initialize.
|
||||||
let mut members = TaskSet::new();
|
let mut members = TaskSet::new();
|
||||||
let my_handle = (*me).death.kill_handle.get_ref().clone();
|
let my_handle = (*me).death.kill_handle.get_ref().clone();
|
||||||
members.insert(NewTask(my_handle));
|
members.insert(NewTask(my_handle));
|
||||||
|
@ -591,15 +592,21 @@ impl RuntimeGlue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns 'None' in the case where the child's TG should be lazily initialized.
|
||||||
fn gen_child_taskgroup(linked: bool, supervised: bool)
|
fn gen_child_taskgroup(linked: bool, supervised: bool)
|
||||||
-> (TaskGroupArc, AncestorList, bool) {
|
-> Option<(TaskGroupArc, AncestorList, bool)> {
|
||||||
|
// FIXME(#7544): Not safe to lazily initialize in the old runtime. Remove
|
||||||
|
// this context check once 'spawn_raw_oldsched' is gone.
|
||||||
|
if context() == OldTaskContext || linked || supervised {
|
||||||
|
// with_my_taskgroup will lazily initialize the parent's taskgroup if
|
||||||
|
// it doesn't yet exist. We don't want to call it in the unlinked case.
|
||||||
do RuntimeGlue::with_my_taskgroup |spawner_group| {
|
do RuntimeGlue::with_my_taskgroup |spawner_group| {
|
||||||
let ancestors = AncestorList(spawner_group.ancestors.map(|x| x.clone()));
|
let ancestors = AncestorList(spawner_group.ancestors.map(|x| x.clone()));
|
||||||
if linked {
|
if linked {
|
||||||
// Child is in the same group as spawner.
|
// Child is in the same group as spawner.
|
||||||
// Child's ancestors are spawner's ancestors.
|
// Child's ancestors are spawner's ancestors.
|
||||||
// Propagate main-ness.
|
// Propagate main-ness.
|
||||||
(spawner_group.tasks.clone(), ancestors, spawner_group.is_main)
|
Some((spawner_group.tasks.clone(), ancestors, spawner_group.is_main))
|
||||||
} else {
|
} else {
|
||||||
// Child is in a separate group from spawner.
|
// Child is in a separate group from spawner.
|
||||||
let g = Exclusive::new(Some(TaskGroupData {
|
let g = Exclusive::new(Some(TaskGroupData {
|
||||||
|
@ -620,9 +627,12 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
|
||||||
// Child has no ancestors.
|
// Child has no ancestors.
|
||||||
AncestorList(None)
|
AncestorList(None)
|
||||||
};
|
};
|
||||||
(g, a, false)
|
Some((g, a, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up membership in taskgroup and descendantship in all ancestor
|
// Set up membership in taskgroup and descendantship in all ancestor
|
||||||
|
@ -670,8 +680,11 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
|
||||||
|
|
||||||
let child_wrapper: ~fn() = || {
|
let child_wrapper: ~fn() = || {
|
||||||
// Child task runs this code.
|
// Child task runs this code.
|
||||||
let child_data = Cell::new(child_data.take()); // :(
|
|
||||||
let enlist_success = do Local::borrow::<Task, bool> |me| {
|
// If child data is 'None', the enlist is vacuously successful.
|
||||||
|
let enlist_success = do child_data.take().map_consume_default(true) |child_data| {
|
||||||
|
let child_data = Cell::new(child_data); // :(
|
||||||
|
do Local::borrow::<Task, bool> |me| {
|
||||||
let (child_tg, ancestors, is_main) = child_data.take();
|
let (child_tg, ancestors, is_main) = child_data.take();
|
||||||
let mut ancestors = ancestors;
|
let mut ancestors = ancestors;
|
||||||
// FIXME(#7544): Optimize out the xadd in this clone, somehow.
|
// FIXME(#7544): Optimize out the xadd in this clone, somehow.
|
||||||
|
@ -685,6 +698,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Should be run after the local-borrowed task is returned.
|
// Should be run after the local-borrowed task is returned.
|
||||||
if enlist_success {
|
if enlist_success {
|
||||||
|
@ -749,7 +763,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
|
||||||
let join_task = join_task_cell.take();
|
let join_task = join_task_cell.take();
|
||||||
|
|
||||||
let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool) || {
|
let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool) || {
|
||||||
rtdebug!("boostraping a 1:1 scheduler");
|
rtdebug!("bootstrapping a 1:1 scheduler");
|
||||||
};
|
};
|
||||||
new_sched.bootstrap(bootstrap_task);
|
new_sched.bootstrap(bootstrap_task);
|
||||||
|
|
||||||
|
@ -793,7 +807,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
|
||||||
fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
|
fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
|
||||||
|
|
||||||
let (child_tg, ancestors, is_main) =
|
let (child_tg, ancestors, is_main) =
|
||||||
gen_child_taskgroup(opts.linked, opts.supervised);
|
gen_child_taskgroup(opts.linked, opts.supervised).expect("old runtime needs TG");
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let child_data = Cell::new((child_tg, ancestors, f));
|
let child_data = Cell::new((child_tg, ancestors, f));
|
||||||
|
|
|
@ -14,6 +14,7 @@ use prelude::*;
|
||||||
use iterator::{IteratorUtil, FromIterator, Extendable};
|
use iterator::{IteratorUtil, FromIterator, Extendable};
|
||||||
use uint;
|
use uint;
|
||||||
use util::{swap, replace};
|
use util::{swap, replace};
|
||||||
|
use vec;
|
||||||
|
|
||||||
// FIXME: #5244: need to manually update the TrieNode constructor
|
// FIXME: #5244: need to manually update the TrieNode constructor
|
||||||
static SHIFT: uint = 4;
|
static SHIFT: uint = 4;
|
||||||
|
@ -146,6 +147,15 @@ impl<T> TrieMap<T> {
|
||||||
pub fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool {
|
pub fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool {
|
||||||
self.each_reverse(|_, v| f(v))
|
self.each_reverse(|_, v| f(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get an iterator over the key-value pairs in the map
|
||||||
|
pub fn iter<'a>(&'a self) -> TrieMapIterator<'a, T> {
|
||||||
|
TrieMapIterator {
|
||||||
|
stack: ~[self.root.children.iter()],
|
||||||
|
remaining_min: self.length,
|
||||||
|
remaining_max: self.length
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
|
impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
|
||||||
|
@ -217,6 +227,12 @@ impl TrieSet {
|
||||||
pub fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool {
|
pub fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool {
|
||||||
self.map.each_key_reverse(f)
|
self.map.each_key_reverse(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get an iterator over the values in the set
|
||||||
|
#[inline]
|
||||||
|
pub fn iter<'a>(&'a self) -> TrieSetIterator<'a> {
|
||||||
|
TrieSetIterator{iter: self.map.iter()}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
|
impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
|
||||||
|
@ -366,6 +382,61 @@ fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Forward iterator over a map
|
||||||
|
pub struct TrieMapIterator<'self, T> {
|
||||||
|
priv stack: ~[vec::VecIterator<'self, Child<T>>],
|
||||||
|
priv remaining_min: uint,
|
||||||
|
priv remaining_max: uint
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self, T> Iterator<(uint, &'self T)> for TrieMapIterator<'self, T> {
|
||||||
|
fn next(&mut self) -> Option<(uint, &'self T)> {
|
||||||
|
while !self.stack.is_empty() {
|
||||||
|
match self.stack[self.stack.len() - 1].next() {
|
||||||
|
None => {
|
||||||
|
self.stack.pop();
|
||||||
|
}
|
||||||
|
Some(ref child) => {
|
||||||
|
match **child {
|
||||||
|
Internal(ref node) => {
|
||||||
|
self.stack.push(node.children.iter());
|
||||||
|
}
|
||||||
|
External(key, ref value) => {
|
||||||
|
self.remaining_max -= 1;
|
||||||
|
if self.remaining_min > 0 {
|
||||||
|
self.remaining_min -= 1;
|
||||||
|
}
|
||||||
|
return Some((key, value));
|
||||||
|
}
|
||||||
|
Nothing => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||||
|
(self.remaining_min, Some(self.remaining_max))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Forward iterator over a set
|
||||||
|
pub struct TrieSetIterator<'self> {
|
||||||
|
priv iter: TrieMapIterator<'self, ()>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self> Iterator<uint> for TrieSetIterator<'self> {
|
||||||
|
fn next(&mut self) -> Option<uint> {
|
||||||
|
do self.iter.next().map |&(key, _)| { key }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||||
|
self.iter.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn check_integrity<T>(trie: &TrieNode<T>) {
|
pub fn check_integrity<T>(trie: &TrieNode<T>) {
|
||||||
assert!(trie.count != 0);
|
assert!(trie.count != 0);
|
||||||
|
@ -553,6 +624,29 @@ mod test_map {
|
||||||
assert_eq!(map.find(&k), Some(&v));
|
assert_eq!(map.find(&k), Some(&v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_iteration() {
|
||||||
|
let empty_map : TrieMap<uint> = TrieMap::new();
|
||||||
|
assert_eq!(empty_map.iter().next(), None);
|
||||||
|
|
||||||
|
let first = uint::max_value - 10000;
|
||||||
|
let last = uint::max_value;
|
||||||
|
|
||||||
|
let mut map = TrieMap::new();
|
||||||
|
do uint::range_rev(last, first) |x| {
|
||||||
|
map.insert(x, x / 2);
|
||||||
|
true
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
for (k, &v) in map.iter() {
|
||||||
|
assert_eq!(k, first + i);
|
||||||
|
assert_eq!(v, k / 2);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
assert_eq!(i, last - first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -195,10 +195,8 @@ pub fn build<A>(builder: &fn(push: &fn(v: A))) -> ~[A] {
|
||||||
* onto the vector being constructed.
|
* onto the vector being constructed.
|
||||||
*/
|
*/
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn build_sized_opt<A>(size: Option<uint>,
|
pub fn build_sized_opt<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> ~[A] {
|
||||||
builder: &fn(push: &fn(v: A)))
|
build_sized(size.unwrap_or_default(4), builder)
|
||||||
-> ~[A] {
|
|
||||||
build_sized(size.get_or_default(4), builder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over the slices of a vector separated by elements that
|
/// An iterator over the slices of a vector separated by elements that
|
||||||
|
@ -481,6 +479,7 @@ pub fn each_permutation<T:Clone>(values: &[T], fun: &fn(perm : &[T]) -> bool) ->
|
||||||
|
|
||||||
/// An iterator over the (overlapping) slices of length `size` within
|
/// An iterator over the (overlapping) slices of length `size` within
|
||||||
/// a vector.
|
/// a vector.
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct WindowIter<'self, T> {
|
pub struct WindowIter<'self, T> {
|
||||||
priv v: &'self [T],
|
priv v: &'self [T],
|
||||||
priv size: uint
|
priv size: uint
|
||||||
|
@ -500,6 +499,10 @@ impl<'self, T> Iterator<&'self [T]> for WindowIter<'self, T> {
|
||||||
|
|
||||||
/// An iterator over a vector in (non-overlapping) chunks (`size`
|
/// An iterator over a vector in (non-overlapping) chunks (`size`
|
||||||
/// elements at a time).
|
/// elements at a time).
|
||||||
|
///
|
||||||
|
/// When the vector len is not evenly divided by the chunk size,
|
||||||
|
/// the last slice of the iteration will be the remainer.
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct ChunkIter<'self, T> {
|
pub struct ChunkIter<'self, T> {
|
||||||
priv v: &'self [T],
|
priv v: &'self [T],
|
||||||
priv size: uint
|
priv size: uint
|
||||||
|
@ -507,16 +510,49 @@ pub struct ChunkIter<'self, T> {
|
||||||
|
|
||||||
impl<'self, T> Iterator<&'self [T]> for ChunkIter<'self, T> {
|
impl<'self, T> Iterator<&'self [T]> for ChunkIter<'self, T> {
|
||||||
fn next(&mut self) -> Option<&'self [T]> {
|
fn next(&mut self) -> Option<&'self [T]> {
|
||||||
if self.size == 0 {
|
if self.v.len() == 0 {
|
||||||
None
|
None
|
||||||
} else if self.size >= self.v.len() {
|
|
||||||
// finished
|
|
||||||
self.size = 0;
|
|
||||||
Some(self.v)
|
|
||||||
} else {
|
} else {
|
||||||
let ret = Some(self.v.slice(0, self.size));
|
let chunksz = cmp::min(self.v.len(), self.size);
|
||||||
self.v = self.v.slice(self.size, self.v.len());
|
let (fst, snd) = (self.v.slice_to(chunksz),
|
||||||
ret
|
self.v.slice_from(chunksz));
|
||||||
|
self.v = snd;
|
||||||
|
Some(fst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self, T> DoubleEndedIterator<&'self [T]> for ChunkIter<'self, T> {
|
||||||
|
fn next_back(&mut self) -> Option<&'self [T]> {
|
||||||
|
if self.v.len() == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let remainder = self.v.len() % self.size;
|
||||||
|
let chunksz = if remainder != 0 { remainder } else { self.size };
|
||||||
|
let (fst, snd) = (self.v.slice_to(self.v.len() - chunksz),
|
||||||
|
self.v.slice_from(self.v.len() - chunksz));
|
||||||
|
self.v = fst;
|
||||||
|
Some(snd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self, T> RandomAccessIterator<&'self [T]> for ChunkIter<'self, T> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint {
|
||||||
|
self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<&'self [T]> {
|
||||||
|
if index < self.indexable() {
|
||||||
|
let lo = index * self.size;
|
||||||
|
let mut hi = lo + self.size;
|
||||||
|
if hi < lo || hi > self.v.len() { hi = self.v.len(); }
|
||||||
|
|
||||||
|
Some(self.v.slice(lo, hi))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3380,6 +3416,14 @@ mod tests {
|
||||||
assert_eq!(v.chunk_iter(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
|
assert_eq!(v.chunk_iter(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
|
||||||
assert_eq!(v.chunk_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
|
assert_eq!(v.chunk_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
|
||||||
assert_eq!(v.chunk_iter(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
|
assert_eq!(v.chunk_iter(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
|
||||||
|
|
||||||
|
assert_eq!(v.chunk_iter(2).invert().collect::<~[&[int]]>(), ~[&[5i], &[3,4], &[1,2]]);
|
||||||
|
let it = v.chunk_iter(2);
|
||||||
|
assert_eq!(it.indexable(), 3);
|
||||||
|
assert_eq!(it.idx(0).unwrap(), &[1,2]);
|
||||||
|
assert_eq!(it.idx(1).unwrap(), &[3,4]);
|
||||||
|
assert_eq!(it.idx(2).unwrap(), &[5]);
|
||||||
|
assert_eq!(it.idx(3), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -280,13 +280,13 @@ impl ToStr for AbiSet {
|
||||||
#[test]
|
#[test]
|
||||||
fn lookup_Rust() {
|
fn lookup_Rust() {
|
||||||
let abi = lookup("Rust");
|
let abi = lookup("Rust");
|
||||||
assert!(abi.is_some() && abi.get().data().name == "Rust");
|
assert!(abi.is_some() && abi.unwrap().data().name == "Rust");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lookup_cdecl() {
|
fn lookup_cdecl() {
|
||||||
let abi = lookup("cdecl");
|
let abi = lookup("cdecl");
|
||||||
assert!(abi.is_some() && abi.get().data().name == "cdecl");
|
assert!(abi.is_some() && abi.unwrap().data().name == "cdecl");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -24,7 +24,7 @@ use extra::serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||||
// table) and a SyntaxContext to track renaming and
|
// table) and a SyntaxContext to track renaming and
|
||||||
// macro expansion per Flatt et al., "Macros
|
// macro expansion per Flatt et al., "Macros
|
||||||
// That Work Together"
|
// That Work Together"
|
||||||
#[deriving(Clone, Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes, ToStr)]
|
||||||
pub struct ident { name: Name, ctxt: SyntaxContext }
|
pub struct ident { name: Name, ctxt: SyntaxContext }
|
||||||
|
|
||||||
/// Construct an identifier with the given name and an empty context:
|
/// Construct an identifier with the given name and an empty context:
|
||||||
|
@ -121,7 +121,7 @@ pub type CrateNum = int;
|
||||||
|
|
||||||
pub type NodeId = int;
|
pub type NodeId = int;
|
||||||
|
|
||||||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes, ToStr)]
|
||||||
pub struct def_id {
|
pub struct def_id {
|
||||||
crate: CrateNum,
|
crate: CrateNum,
|
||||||
node: NodeId,
|
node: NodeId,
|
||||||
|
|
|
@ -466,11 +466,11 @@ pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
|
||||||
Some(&node_local(ident)) => {
|
Some(&node_local(ident)) => {
|
||||||
fmt!("local (id=%?, name=%s)", id, itr.get(ident.name))
|
fmt!("local (id=%?, name=%s)", id, itr.get(ident.name))
|
||||||
}
|
}
|
||||||
Some(&node_block(_)) => {
|
Some(&node_block(ref block)) => {
|
||||||
fmt!("block")
|
fmt!("block %s (id=%?)", pprust::block_to_str(block, itr), id)
|
||||||
}
|
}
|
||||||
Some(&node_struct_ctor(*)) => {
|
Some(&node_struct_ctor(_, _, path)) => {
|
||||||
fmt!("struct_ctor")
|
fmt!("struct_ctor %s (id=%?)", path_to_str(*path, itr), id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,7 +410,7 @@ impl IdVisitor {
|
||||||
impl Visitor<()> for IdVisitor {
|
impl Visitor<()> for IdVisitor {
|
||||||
fn visit_mod(@mut self,
|
fn visit_mod(@mut self,
|
||||||
module: &_mod,
|
module: &_mod,
|
||||||
span: span,
|
_span: span,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
env: ()) {
|
env: ()) {
|
||||||
(self.visit_callback)(node_id);
|
(self.visit_callback)(node_id);
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl AttributeMethods for Attribute {
|
||||||
/// non-sugared doc attributes.)
|
/// non-sugared doc attributes.)
|
||||||
pub fn desugar_doc(&self) -> Attribute {
|
pub fn desugar_doc(&self) -> Attribute {
|
||||||
if self.node.is_sugared_doc {
|
if self.node.is_sugared_doc {
|
||||||
let comment = self.value_str().get();
|
let comment = self.value_str().unwrap();
|
||||||
let meta = mk_name_value_item_str(@"doc",
|
let meta = mk_name_value_item_str(@"doc",
|
||||||
strip_doc_comment_decoration(comment).to_managed());
|
strip_doc_comment_decoration(comment).to_managed());
|
||||||
mk_attr(meta)
|
mk_attr(meta)
|
||||||
|
|
|
@ -369,12 +369,19 @@ impl CodeMap {
|
||||||
return @FileLines {file: lo.file, lines: lines};
|
return @FileLines {file: lo.file, lines: lines};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span_to_snippet(&self, sp: span) -> ~str {
|
pub fn span_to_snippet(&self, sp: span) -> Option<~str> {
|
||||||
let begin = self.lookup_byte_offset(sp.lo);
|
let begin = self.lookup_byte_offset(sp.lo);
|
||||||
let end = self.lookup_byte_offset(sp.hi);
|
let end = self.lookup_byte_offset(sp.hi);
|
||||||
assert_eq!(begin.fm.start_pos, end.fm.start_pos);
|
|
||||||
return begin.fm.src.slice(
|
// FIXME #8256: this used to be an assert but whatever precondition
|
||||||
begin.pos.to_uint(), end.pos.to_uint()).to_owned();
|
// it's testing isn't true for all spans in the AST, so to allow the
|
||||||
|
// caller to not have to fail (and it can't catch it since the CodeMap
|
||||||
|
// isn't sendable), return None
|
||||||
|
if begin.fm.start_pos != end.fm.start_pos {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(begin.fm.src.slice( begin.pos.to_uint(), end.pos.to_uint()).to_owned())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_filemap(&self, filename: &str) -> @FileMap {
|
pub fn get_filemap(&self, filename: &str) -> @FileMap {
|
||||||
|
|
|
@ -538,20 +538,20 @@ mod test {
|
||||||
m.insert (@"def",@16);
|
m.insert (@"def",@16);
|
||||||
// FIXME: #4492 (ICE) assert_eq!(m.find(&@"abc"),Some(@15));
|
// FIXME: #4492 (ICE) assert_eq!(m.find(&@"abc"),Some(@15));
|
||||||
// .... assert_eq!(m.find(&@"def"),Some(@16));
|
// .... assert_eq!(m.find(&@"def"),Some(@16));
|
||||||
assert_eq!(*(m.find(&@"abc").get()),15);
|
assert_eq!(*(m.find(&@"abc").unwrap()),15);
|
||||||
assert_eq!(*(m.find(&@"def").get()),16);
|
assert_eq!(*(m.find(&@"def").unwrap()),16);
|
||||||
let n = m.push_frame();
|
let n = m.push_frame();
|
||||||
// old bindings are still present:
|
// old bindings are still present:
|
||||||
assert_eq!(*(n.find(&@"abc").get()),15);
|
assert_eq!(*(n.find(&@"abc").unwrap()),15);
|
||||||
assert_eq!(*(n.find(&@"def").get()),16);
|
assert_eq!(*(n.find(&@"def").unwrap()),16);
|
||||||
n.insert (@"def",@17);
|
n.insert (@"def",@17);
|
||||||
// n shows the new binding
|
// n shows the new binding
|
||||||
assert_eq!(*(n.find(&@"abc").get()),15);
|
assert_eq!(*(n.find(&@"abc").unwrap()),15);
|
||||||
assert_eq!(*(n.find(&@"def").get()),17);
|
assert_eq!(*(n.find(&@"def").unwrap()),17);
|
||||||
// ... but m still has the old ones
|
// ... but m still has the old ones
|
||||||
// FIXME: #4492: assert_eq!(m.find(&@"abc"),Some(@15));
|
// FIXME: #4492: assert_eq!(m.find(&@"abc"),Some(@15));
|
||||||
// FIXME: #4492: assert_eq!(m.find(&@"def"),Some(@16));
|
// FIXME: #4492: assert_eq!(m.find(&@"def"),Some(@16));
|
||||||
assert_eq!(*(m.find(&@"abc").get()),15);
|
assert_eq!(*(m.find(&@"abc").unwrap()),15);
|
||||||
assert_eq!(*(m.find(&@"def").get()),16);
|
assert_eq!(*(m.find(&@"def").unwrap()),16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -961,7 +961,7 @@ fn create_struct_pattern(cx: @ExtCtxt,
|
||||||
let field_pats = do vec::build |push| {
|
let field_pats = do vec::build |push| {
|
||||||
for (&pat, &(id, _)) in subpats.iter().zip(ident_expr.iter()) {
|
for (&pat, &(id, _)) in subpats.iter().zip(ident_expr.iter()) {
|
||||||
// id is guaranteed to be Some
|
// id is guaranteed to be Some
|
||||||
push(ast::field_pat { ident: id.get(), pat: pat })
|
push(ast::field_pat { ident: id.unwrap(), pat: pat })
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cx.pat_struct(span, matching_path, field_pats)
|
cx.pat_struct(span, matching_path, field_pats)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue