librustc: Remove all uses of "copy".
This commit is contained in:
parent
b4e674f6e6
commit
99b33f7219
278 changed files with 3196 additions and 2610 deletions
|
@ -117,9 +117,11 @@ pub fn parse_config(args: ~[~str]) -> config {
|
||||||
mode: str_mode(getopts::opt_str(matches, "mode")),
|
mode: str_mode(getopts::opt_str(matches, "mode")),
|
||||||
run_ignored: getopts::opt_present(matches, "ignored"),
|
run_ignored: getopts::opt_present(matches, "ignored"),
|
||||||
filter:
|
filter:
|
||||||
if !matches.free.is_empty() {
|
if !matches.free.is_empty() {
|
||||||
Some(copy matches.free[0])
|
Some(matches.free[0].clone())
|
||||||
} else { None },
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
logfile: getopts::opt_maybe_str(matches, "logfile").map(|s| Path(*s)),
|
logfile: getopts::opt_maybe_str(matches, "logfile").map(|s| Path(*s)),
|
||||||
save_metrics: getopts::opt_maybe_str(matches, "save-metrics").map(|s| Path(*s)),
|
save_metrics: getopts::opt_maybe_str(matches, "save-metrics").map(|s| Path(*s)),
|
||||||
ratchet_metrics:
|
ratchet_metrics:
|
||||||
|
@ -223,9 +225,9 @@ pub fn run_tests(config: &config) {
|
||||||
|
|
||||||
pub fn test_opts(config: &config) -> test::TestOpts {
|
pub fn test_opts(config: &config) -> test::TestOpts {
|
||||||
test::TestOpts {
|
test::TestOpts {
|
||||||
filter: copy config.filter,
|
filter: config.filter.clone(),
|
||||||
run_ignored: config.run_ignored,
|
run_ignored: config.run_ignored,
|
||||||
logfile: copy config.logfile,
|
logfile: config.logfile.clone(),
|
||||||
run_tests: true,
|
run_tests: true,
|
||||||
run_benchmarks: true,
|
run_benchmarks: true,
|
||||||
ratchet_metrics: copy config.ratchet_metrics,
|
ratchet_metrics: copy config.ratchet_metrics,
|
||||||
|
@ -240,7 +242,7 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] {
|
||||||
let mut tests = ~[];
|
let mut tests = ~[];
|
||||||
let dirs = os::list_dir_path(&config.src_base);
|
let dirs = os::list_dir_path(&config.src_base);
|
||||||
for dirs.iter().advance |file| {
|
for dirs.iter().advance |file| {
|
||||||
let file = copy *file;
|
let file = (*file).clone();
|
||||||
debug!("inspecting file %s", file.to_str());
|
debug!("inspecting file %s", file.to_str());
|
||||||
if is_test(config, file) {
|
if is_test(config, file) {
|
||||||
let t = do make_test(config, file) {
|
let t = do make_test(config, file) {
|
||||||
|
@ -306,7 +308,7 @@ pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName {
|
||||||
|
|
||||||
pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn {
|
pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn {
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
let config = Cell::new(copy *config);
|
let config = Cell::new((*config).clone());
|
||||||
let testfile = Cell::new(testfile.to_str());
|
let testfile = Cell::new(testfile.to_str());
|
||||||
test::DynTestFn(|| { runtest::run(config.take(), testfile.take()) })
|
test::DynTestFn(|| { runtest::run(config.take(), testfile.take()) })
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] {
|
||||||
let aux_path = prog.slice(0u, prog.len() - 4u).to_owned() + ".libaux";
|
let aux_path = prog.slice(0u, prog.len() - 4u).to_owned() + ".libaux";
|
||||||
|
|
||||||
env = do env.map() |pair| {
|
env = do env.map() |pair| {
|
||||||
let (k,v) = copy *pair;
|
let (k,v) = (*pair).clone();
|
||||||
if k == ~"PATH" { (~"PATH", v + ";" + lib_path + ";" + aux_path) }
|
if k == ~"PATH" { (~"PATH", v + ";" + lib_path + ";" + aux_path) }
|
||||||
else { (k,v) }
|
else { (k,v) }
|
||||||
};
|
};
|
||||||
|
|
|
@ -150,7 +150,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
|
||||||
let mut round = 0;
|
let mut round = 0;
|
||||||
while round < rounds {
|
while round < rounds {
|
||||||
logv(config, fmt!("pretty-printing round %d", round));
|
logv(config, fmt!("pretty-printing round %d", round));
|
||||||
let ProcRes = print_source(config, testfile, copy srcs[round]);
|
let ProcRes = print_source(config, testfile, srcs[round].clone());
|
||||||
|
|
||||||
if ProcRes.status != 0 {
|
if ProcRes.status != 0 {
|
||||||
fatal_ProcRes(fmt!("pretty-printing failed in round %d", round),
|
fatal_ProcRes(fmt!("pretty-printing failed in round %d", round),
|
||||||
|
@ -168,9 +168,9 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
|
||||||
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).get()
|
||||||
}
|
}
|
||||||
None => { copy srcs[srcs.len() - 2u] }
|
None => { srcs[srcs.len() - 2u].clone() }
|
||||||
};
|
};
|
||||||
let mut actual = copy srcs[srcs.len() - 1u];
|
let mut actual = srcs[srcs.len() - 1u].clone();
|
||||||
|
|
||||||
if props.pp_exact.is_some() {
|
if props.pp_exact.is_some() {
|
||||||
// Now we have to care about line endings
|
// Now we have to care about line endings
|
||||||
|
@ -243,13 +243,13 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
|
||||||
let mut config = match config.rustcflags {
|
let mut config = match config.rustcflags {
|
||||||
Some(ref flags) => config {
|
Some(ref flags) => config {
|
||||||
rustcflags: Some(flags.replace("-O", "")),
|
rustcflags: Some(flags.replace("-O", "")),
|
||||||
.. copy *config
|
.. (*config).clone()
|
||||||
},
|
},
|
||||||
None => copy *config
|
None => (*config).clone()
|
||||||
};
|
};
|
||||||
let config = &mut config;
|
let config = &mut config;
|
||||||
let cmds = props.debugger_cmds.connect("\n");
|
let cmds = props.debugger_cmds.connect("\n");
|
||||||
let check_lines = copy props.check_lines;
|
let check_lines = props.check_lines.clone();
|
||||||
|
|
||||||
// compile test file (it shoud have 'compile-flags:-g' in the header)
|
// compile test file (it shoud have 'compile-flags:-g' in the header)
|
||||||
let mut ProcRes = compile_test(config, props, testfile);
|
let mut ProcRes = compile_test(config, props, testfile);
|
||||||
|
@ -498,7 +498,7 @@ fn exec_compiled_test(config: &config, props: &TestProps,
|
||||||
testfile: &Path) -> ProcRes {
|
testfile: &Path) -> ProcRes {
|
||||||
|
|
||||||
// If testing the new runtime then set the RUST_NEWRT env var
|
// If testing the new runtime then set the RUST_NEWRT env var
|
||||||
let env = copy props.exec_env;
|
let env = props.exec_env.clone();
|
||||||
let env = if config.newrt { env + &[(~"RUST_NEWRT", ~"1")] } else { env };
|
let env = if config.newrt { env + &[(~"RUST_NEWRT", ~"1")] } else { env };
|
||||||
|
|
||||||
match config.target {
|
match config.target {
|
||||||
|
@ -742,7 +742,7 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps,
|
||||||
|
|
||||||
// copy to target
|
// copy to target
|
||||||
let copy_result = procsrv::run("", config.adb_path,
|
let copy_result = procsrv::run("", config.adb_path,
|
||||||
[~"push", copy args.prog, copy config.adb_test_dir],
|
[~"push", args.prog.clone(), config.adb_test_dir.clone()],
|
||||||
~[(~"",~"")], Some(~""));
|
~[(~"",~"")], Some(~""));
|
||||||
|
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
|
@ -832,7 +832,7 @@ fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
|
||||||
if (file.filetype() == Some(~".so")) {
|
if (file.filetype() == Some(~".so")) {
|
||||||
|
|
||||||
let copy_result = procsrv::run("", config.adb_path,
|
let copy_result = procsrv::run("", config.adb_path,
|
||||||
[~"push", file.to_str(), copy config.adb_test_dir],
|
[~"push", file.to_str(), config.adb_test_dir.clone()],
|
||||||
~[(~"",~"")], Some(~""));
|
~[(~"",~"")], Some(~""));
|
||||||
|
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
|
|
|
@ -534,7 +534,7 @@ mod tests {
|
||||||
|
|
||||||
let arc_v : ARC<~[int]> = p.recv();
|
let arc_v : ARC<~[int]> = p.recv();
|
||||||
|
|
||||||
let v = copy (*arc_v.get());
|
let v = (*arc_v.get()).clone();
|
||||||
assert_eq!(v[3], 4);
|
assert_eq!(v[3], 4);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -211,14 +211,14 @@ impl<'self> FromBase64 for &'self [u8] {
|
||||||
let val = byte as u32;
|
let val = byte as u32;
|
||||||
|
|
||||||
match ch {
|
match ch {
|
||||||
'A'..'Z' => buf |= val - 0x41,
|
'A'..'Z' => buf |= val - 0x41,
|
||||||
'a'..'z' => buf |= val - 0x47,
|
'a'..'z' => buf |= val - 0x47,
|
||||||
'0'..'9' => buf |= val + 0x04,
|
'0'..'9' => buf |= val + 0x04,
|
||||||
'+'|'-' => buf |= 0x3E,
|
'+'|'-' => buf |= 0x3E,
|
||||||
'/'|'_' => buf |= 0x3F,
|
'/'|'_' => buf |= 0x3F,
|
||||||
'\r'|'\n' => loop,
|
'\r'|'\n' => loop,
|
||||||
'=' => break,
|
'=' => break,
|
||||||
_ => return Err(~"Invalid Base64 character")
|
_ => return Err(~"Invalid Base64 character")
|
||||||
}
|
}
|
||||||
|
|
||||||
buf <<= 6;
|
buf <<= 6;
|
||||||
|
|
|
@ -266,7 +266,7 @@ impl Bitv {
|
||||||
else {
|
else {
|
||||||
let nelems = nbits/uint::bits +
|
let nelems = nbits/uint::bits +
|
||||||
if nbits % uint::bits == 0 {0} else {1};
|
if nbits % uint::bits == 0 {0} else {1};
|
||||||
let elem = if init {!0} else {0};
|
let elem = if init {!0u} else {0u};
|
||||||
let s = vec::from_elem(nelems, elem);
|
let s = vec::from_elem(nelems, elem);
|
||||||
Big(~BigBitv::new(s))
|
Big(~BigBitv::new(s))
|
||||||
};
|
};
|
||||||
|
@ -518,7 +518,7 @@ impl Clone for Bitv {
|
||||||
Bitv{nbits: self.nbits, rep: Small(~SmallBitv{bits: b.bits})}
|
Bitv{nbits: self.nbits, rep: Small(~SmallBitv{bits: b.bits})}
|
||||||
}
|
}
|
||||||
Big(ref b) => {
|
Big(ref b) => {
|
||||||
let mut st = vec::from_elem(self.nbits / uint::bits + 1, 0);
|
let mut st = vec::from_elem(self.nbits / uint::bits + 1, 0u);
|
||||||
let len = st.len();
|
let len = st.len();
|
||||||
for uint::range(0, len) |i| { st[i] = b.storage[i]; };
|
for uint::range(0, len) |i| { st[i] = b.storage[i]; };
|
||||||
Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: st})}
|
Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: st})}
|
||||||
|
|
|
@ -119,9 +119,11 @@ pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
|
||||||
*
|
*
|
||||||
* Fails if `ofs` is greater or equal to the length of the vector
|
* Fails if `ofs` is greater or equal to the length of the vector
|
||||||
*/
|
*/
|
||||||
pub fn get<T:Copy>(t: CVec<T>, ofs: uint) -> T {
|
pub fn get<T:Clone>(t: CVec<T>, ofs: uint) -> T {
|
||||||
assert!(ofs < len(t));
|
assert!(ofs < len(t));
|
||||||
return unsafe { copy *ptr::mut_offset(t.base, ofs) };
|
return unsafe {
|
||||||
|
(*ptr::mut_offset(t.base, ofs)).clone()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,7 +131,7 @@ pub fn get<T:Copy>(t: CVec<T>, ofs: uint) -> T {
|
||||||
*
|
*
|
||||||
* Fails if `ofs` is greater or equal to the length of the vector
|
* Fails if `ofs` is greater or equal to the length of the vector
|
||||||
*/
|
*/
|
||||||
pub fn set<T:Copy>(t: CVec<T>, ofs: uint, v: T) {
|
pub fn set<T>(t: CVec<T>, ofs: uint, v: T) {
|
||||||
assert!(ofs < len(t));
|
assert!(ofs < len(t));
|
||||||
unsafe { *ptr::mut_offset(t.base, ofs) = v };
|
unsafe { *ptr::mut_offset(t.base, ofs) = v };
|
||||||
}
|
}
|
||||||
|
|
|
@ -609,8 +609,8 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn list_from<T: Copy>(v: &[T]) -> DList<T> {
|
fn list_from<T: Clone>(v: &[T]) -> DList<T> {
|
||||||
v.iter().transform(|x| copy *x).collect()
|
v.iter().transform(|x| (*x).clone()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct EbmlState {
|
||||||
data_pos: uint,
|
data_pos: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct Doc {
|
pub struct Doc {
|
||||||
data: @~[u8],
|
data: @~[u8],
|
||||||
start: uint,
|
start: uint,
|
||||||
|
@ -615,6 +616,7 @@ pub mod writer {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::cast;
|
use std::cast;
|
||||||
|
use std::clone::Clone;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
// ebml writing
|
// ebml writing
|
||||||
|
@ -623,6 +625,15 @@ pub mod writer {
|
||||||
priv size_positions: ~[uint],
|
priv size_positions: ~[uint],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Clone for Encoder {
|
||||||
|
fn clone(&self) -> Encoder {
|
||||||
|
Encoder {
|
||||||
|
writer: self.writer,
|
||||||
|
size_positions: self.size_positions.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn write_sized_vuint(w: @io::Writer, n: uint, size: uint) {
|
fn write_sized_vuint(w: @io::Writer, n: uint, size: uint) {
|
||||||
match size {
|
match size {
|
||||||
1u => w.write(&[0x80u8 | (n as u8)]),
|
1u => w.write(&[0x80u8 | (n as u8)]),
|
||||||
|
|
|
@ -107,6 +107,7 @@ and `line_num_file` represent the number of lines read in total and in
|
||||||
the current file respectively. `current_path` is `None` if the current
|
the current file respectively. `current_path` is `None` if the current
|
||||||
file is `stdin`.
|
file is `stdin`.
|
||||||
*/
|
*/
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct FileInputState {
|
pub struct FileInputState {
|
||||||
current_path: Option<Path>,
|
current_path: Option<Path>,
|
||||||
line_num: uint,
|
line_num: uint,
|
||||||
|
@ -223,7 +224,7 @@ impl FileInput {
|
||||||
let path_option = self.fi.files.shift();
|
let path_option = self.fi.files.shift();
|
||||||
let file = match path_option {
|
let file = match path_option {
|
||||||
None => io::stdin(),
|
None => io::stdin(),
|
||||||
Some(ref path) => io::file_reader(path).get()
|
Some(ref path) => io::file_reader(path).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
self.fi.current_reader = Some(file);
|
self.fi.current_reader = Some(file);
|
||||||
|
@ -259,7 +260,7 @@ impl FileInput {
|
||||||
*/
|
*/
|
||||||
pub fn each_line_state(&self,
|
pub fn each_line_state(&self,
|
||||||
f: &fn(&str, FileInputState) -> bool) -> bool {
|
f: &fn(&str, FileInputState) -> bool) -> bool {
|
||||||
self.each_line(|line| f(line, copy self.fi.state))
|
self.each_line(|line| f(line, self.fi.state.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,7 +268,7 @@ impl FileInput {
|
||||||
Retrieve the current `FileInputState` information.
|
Retrieve the current `FileInputState` information.
|
||||||
*/
|
*/
|
||||||
pub fn state(&self) -> FileInputState {
|
pub fn state(&self) -> FileInputState {
|
||||||
copy self.fi.state
|
self.fi.state.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +432,7 @@ mod test {
|
||||||
let paths = ~[Some(Path("some/path")),
|
let paths = ~[Some(Path("some/path")),
|
||||||
Some(Path("some/other/path"))];
|
Some(Path("some/other/path"))];
|
||||||
|
|
||||||
assert_eq!(pathify(strs, true), copy paths);
|
assert_eq!(pathify(strs, true), paths.clone());
|
||||||
assert_eq!(pathify(strs, false), paths);
|
assert_eq!(pathify(strs, false), paths);
|
||||||
|
|
||||||
assert_eq!(pathify([~"-"], true), ~[None]);
|
assert_eq!(pathify([~"-"], true), ~[None]);
|
||||||
|
@ -449,7 +450,7 @@ mod test {
|
||||||
make_file(filename.get_ref(), [fmt!("%u", i)]);
|
make_file(filename.get_ref(), [fmt!("%u", i)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let fi = FileInput::from_vec(copy filenames);
|
let fi = FileInput::from_vec(filenames.clone());
|
||||||
|
|
||||||
for "012".iter().enumerate().advance |(line, c)| {
|
for "012".iter().enumerate().advance |(line, c)| {
|
||||||
assert_eq!(fi.read_byte(), c as int);
|
assert_eq!(fi.read_byte(), c as int);
|
||||||
|
@ -459,7 +460,7 @@ mod test {
|
||||||
assert_eq!(fi.state().line_num, line + 1);
|
assert_eq!(fi.state().line_num, line + 1);
|
||||||
assert_eq!(fi.state().line_num_file, 1);
|
assert_eq!(fi.state().line_num_file, 1);
|
||||||
|
|
||||||
assert_eq!(copy fi.state().current_path, copy filenames[line]);
|
assert_eq!(fi.state().current_path.clone(), filenames[line].clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(fi.read_byte(), -1);
|
assert_eq!(fi.read_byte(), -1);
|
||||||
|
@ -542,13 +543,13 @@ mod test {
|
||||||
make_file(filenames[2].get_ref(), [~"3", ~"4"]);
|
make_file(filenames[2].get_ref(), [~"3", ~"4"]);
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for input_vec_state(copy filenames) |line, state| {
|
for input_vec_state(filenames.clone()) |line, state| {
|
||||||
let expected_path = match line {
|
let expected_path = match line {
|
||||||
"1" | "2" => copy filenames[0],
|
"1" | "2" => filenames[0].clone(),
|
||||||
"3" | "4" => copy filenames[2],
|
"3" | "4" => filenames[2].clone(),
|
||||||
_ => fail!("unexpected line")
|
_ => fail!("unexpected line")
|
||||||
};
|
};
|
||||||
assert_eq!(copy state.current_path, expected_path);
|
assert_eq!(state.current_path.clone(), expected_path);
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
assert_eq!(count, 4);
|
assert_eq!(count, 4);
|
||||||
|
|
|
@ -164,8 +164,8 @@ Constructors for flat pipes that send POD types using memcpy.
|
||||||
|
|
||||||
# Safety Note
|
# Safety Note
|
||||||
|
|
||||||
This module is currently unsafe because it uses `Copy Send` as a type
|
This module is currently unsafe because it uses `Clone + Send` as a type
|
||||||
parameter bounds meaning POD (plain old data), but `Copy Send` and
|
parameter bounds meaning POD (plain old data), but `Clone + Send` and
|
||||||
POD are not equivelant.
|
POD are not equivelant.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -188,7 +188,7 @@ pub mod pod {
|
||||||
pub type PipeChan<T> = FlatChan<T, PodFlattener<T>, PipeByteChan>;
|
pub type PipeChan<T> = FlatChan<T, PodFlattener<T>, PipeByteChan>;
|
||||||
|
|
||||||
/// Create a `FlatPort` from a `Reader`
|
/// Create a `FlatPort` from a `Reader`
|
||||||
pub fn reader_port<T:Copy + Send,R:Reader>(
|
pub fn reader_port<T:Clone + Send,R:Reader>(
|
||||||
reader: R
|
reader: R
|
||||||
) -> ReaderPort<T, R> {
|
) -> ReaderPort<T, R> {
|
||||||
let unflat: PodUnflattener<T> = PodUnflattener::new();
|
let unflat: PodUnflattener<T> = PodUnflattener::new();
|
||||||
|
@ -197,7 +197,7 @@ pub mod pod {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a `FlatChan` from a `Writer`
|
/// Create a `FlatChan` from a `Writer`
|
||||||
pub fn writer_chan<T:Copy + Send,W:Writer>(
|
pub fn writer_chan<T:Clone + Send,W:Writer>(
|
||||||
writer: W
|
writer: W
|
||||||
) -> WriterChan<T, W> {
|
) -> WriterChan<T, W> {
|
||||||
let flat: PodFlattener<T> = PodFlattener::new();
|
let flat: PodFlattener<T> = PodFlattener::new();
|
||||||
|
@ -206,21 +206,21 @@ pub mod pod {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a `FlatPort` from a `Port<~[u8]>`
|
/// Create a `FlatPort` from a `Port<~[u8]>`
|
||||||
pub fn pipe_port<T:Copy + Send>(port: Port<~[u8]>) -> PipePort<T> {
|
pub fn pipe_port<T:Clone + Send>(port: Port<~[u8]>) -> PipePort<T> {
|
||||||
let unflat: PodUnflattener<T> = PodUnflattener::new();
|
let unflat: PodUnflattener<T> = PodUnflattener::new();
|
||||||
let byte_port = PipeBytePort::new(port);
|
let byte_port = PipeBytePort::new(port);
|
||||||
FlatPort::new(unflat, byte_port)
|
FlatPort::new(unflat, byte_port)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a `FlatChan` from a `Chan<~[u8]>`
|
/// Create a `FlatChan` from a `Chan<~[u8]>`
|
||||||
pub fn pipe_chan<T:Copy + Send>(chan: Chan<~[u8]>) -> PipeChan<T> {
|
pub fn pipe_chan<T:Clone + Send>(chan: Chan<~[u8]>) -> PipeChan<T> {
|
||||||
let flat: PodFlattener<T> = PodFlattener::new();
|
let flat: PodFlattener<T> = PodFlattener::new();
|
||||||
let byte_chan = PipeByteChan::new(chan);
|
let byte_chan = PipeByteChan::new(chan);
|
||||||
FlatChan::new(flat, byte_chan)
|
FlatChan::new(flat, byte_chan)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a pair of `FlatChan` and `FlatPort`, backed by pipes
|
/// Create a pair of `FlatChan` and `FlatPort`, backed by pipes
|
||||||
pub fn pipe_stream<T:Copy + Send>() -> (PipePort<T>, PipeChan<T>) {
|
pub fn pipe_stream<T:Clone + Send>() -> (PipePort<T>, PipeChan<T>) {
|
||||||
let (port, chan) = comm::stream();
|
let (port, chan) = comm::stream();
|
||||||
return (pipe_port(port), pipe_chan(chan));
|
return (pipe_port(port), pipe_chan(chan));
|
||||||
}
|
}
|
||||||
|
@ -348,7 +348,7 @@ pub mod flatteners {
|
||||||
use std::sys::size_of;
|
use std::sys::size_of;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
// FIXME #4074: Copy + Send != POD
|
// FIXME #4074: Clone + Send != POD
|
||||||
pub struct PodUnflattener<T> {
|
pub struct PodUnflattener<T> {
|
||||||
bogus: ()
|
bogus: ()
|
||||||
}
|
}
|
||||||
|
@ -357,17 +357,17 @@ pub mod flatteners {
|
||||||
bogus: ()
|
bogus: ()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Copy + Send> Unflattener<T> for PodUnflattener<T> {
|
impl<T:Clone + Send> Unflattener<T> for PodUnflattener<T> {
|
||||||
fn unflatten(&self, buf: ~[u8]) -> T {
|
fn unflatten(&self, buf: ~[u8]) -> T {
|
||||||
assert!(size_of::<T>() != 0);
|
assert!(size_of::<T>() != 0);
|
||||||
assert_eq!(size_of::<T>(), buf.len());
|
assert_eq!(size_of::<T>(), buf.len());
|
||||||
let addr_of_init: &u8 = unsafe { &*vec::raw::to_ptr(buf) };
|
let addr_of_init: &u8 = unsafe { &*vec::raw::to_ptr(buf) };
|
||||||
let addr_of_value: &T = unsafe { cast::transmute(addr_of_init) };
|
let addr_of_value: &T = unsafe { cast::transmute(addr_of_init) };
|
||||||
copy *addr_of_value
|
(*addr_of_value).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Copy + Send> Flattener<T> for PodFlattener<T> {
|
impl<T:Clone + Send> Flattener<T> for PodFlattener<T> {
|
||||||
fn flatten(&self, val: T) -> ~[u8] {
|
fn flatten(&self, val: T) -> ~[u8] {
|
||||||
assert!(size_of::<T>() != 0);
|
assert!(size_of::<T>() != 0);
|
||||||
let val: *T = ptr::to_unsafe_ptr(&val);
|
let val: *T = ptr::to_unsafe_ptr(&val);
|
||||||
|
@ -376,7 +376,7 @@ pub mod flatteners {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Copy + Send> PodUnflattener<T> {
|
impl<T:Clone + Send> PodUnflattener<T> {
|
||||||
pub fn new() -> PodUnflattener<T> {
|
pub fn new() -> PodUnflattener<T> {
|
||||||
PodUnflattener {
|
PodUnflattener {
|
||||||
bogus: ()
|
bogus: ()
|
||||||
|
@ -384,7 +384,7 @@ pub mod flatteners {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Copy + Send> PodFlattener<T> {
|
impl<T:Clone + Send> PodFlattener<T> {
|
||||||
pub fn new() -> PodFlattener<T> {
|
pub fn new() -> PodFlattener<T> {
|
||||||
PodFlattener {
|
PodFlattener {
|
||||||
bogus: ()
|
bogus: ()
|
||||||
|
@ -655,7 +655,7 @@ mod test {
|
||||||
|
|
||||||
chan.send(10);
|
chan.send(10);
|
||||||
|
|
||||||
let bytes = copy *chan.byte_chan.writer.bytes;
|
let bytes = (*chan.byte_chan.writer.bytes).clone();
|
||||||
|
|
||||||
let reader = BufReader::new(bytes);
|
let reader = BufReader::new(bytes);
|
||||||
let port = serial::reader_port(reader);
|
let port = serial::reader_port(reader);
|
||||||
|
@ -703,7 +703,7 @@ mod test {
|
||||||
|
|
||||||
chan.send(10);
|
chan.send(10);
|
||||||
|
|
||||||
let bytes = copy *chan.byte_chan.writer.bytes;
|
let bytes = (*chan.byte_chan.writer.bytes).clone();
|
||||||
|
|
||||||
let reader = BufReader::new(bytes);
|
let reader = BufReader::new(bytes);
|
||||||
let port = pod::reader_port(reader);
|
let port = pod::reader_port(reader);
|
||||||
|
@ -785,13 +785,13 @@ mod test {
|
||||||
let accept_chan = Cell::new(accept_chan);
|
let accept_chan = Cell::new(accept_chan);
|
||||||
|
|
||||||
// The server task
|
// The server task
|
||||||
let addr = copy addr0;
|
let addr = addr0.clone();
|
||||||
do task::spawn || {
|
do task::spawn || {
|
||||||
let iotask = &uv::global_loop::get();
|
let iotask = &uv::global_loop::get();
|
||||||
let begin_connect_chan = begin_connect_chan.take();
|
let begin_connect_chan = begin_connect_chan.take();
|
||||||
let accept_chan = accept_chan.take();
|
let accept_chan = accept_chan.take();
|
||||||
let listen_res = do tcp::listen(
|
let listen_res = do tcp::listen(
|
||||||
copy addr, port, 128, iotask, |_kill_ch| {
|
addr.clone(), port, 128, iotask, |_kill_ch| {
|
||||||
// Tell the sender to initiate the connection
|
// Tell the sender to initiate the connection
|
||||||
debug!("listening");
|
debug!("listening");
|
||||||
begin_connect_chan.send(())
|
begin_connect_chan.send(())
|
||||||
|
@ -811,14 +811,14 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client task
|
// Client task
|
||||||
let addr = copy addr0;
|
let addr = addr0.clone();
|
||||||
do task::spawn || {
|
do task::spawn || {
|
||||||
// Wait for the server to start listening
|
// Wait for the server to start listening
|
||||||
begin_connect_port.recv();
|
begin_connect_port.recv();
|
||||||
|
|
||||||
debug!("connecting");
|
debug!("connecting");
|
||||||
let iotask = &uv::global_loop::get();
|
let iotask = &uv::global_loop::get();
|
||||||
let connect_result = tcp::connect(copy addr, port, iotask);
|
let connect_result = tcp::connect(addr.clone(), port, iotask);
|
||||||
assert!(connect_result.is_ok());
|
assert!(connect_result.is_ok());
|
||||||
let sock = result::unwrap(connect_result);
|
let sock = result::unwrap(connect_result);
|
||||||
let socket_buf: tcp::TcpSocketBuf = tcp::socket_buf(sock);
|
let socket_buf: tcp::TcpSocketBuf = tcp::socket_buf(sock);
|
||||||
|
|
|
@ -46,11 +46,11 @@ pub fn insert<K:Eq + Ord,V>(m: Treemap<K, V>, k: K, v: V) -> Treemap<K, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a value based on the key
|
/// Find a value based on the key
|
||||||
pub fn find<K:Eq + Ord,V:Copy>(m: Treemap<K, V>, k: K) -> Option<V> {
|
pub fn find<K:Eq + Ord,V:Clone>(m: Treemap<K, V>, k: K) -> Option<V> {
|
||||||
match *m {
|
match *m {
|
||||||
Empty => None,
|
Empty => None,
|
||||||
Node(kk, v, left, right) => cond!(
|
Node(kk, v, left, right) => cond!(
|
||||||
(k == *kk) { Some(copy *v) }
|
(k == *kk) { Some((*v).clone()) }
|
||||||
(k < *kk) { find(left, k) }
|
(k < *kk) { find(left, k) }
|
||||||
_ { find(right, k) }
|
_ { find(right, k) }
|
||||||
)
|
)
|
||||||
|
@ -58,7 +58,7 @@ pub fn find<K:Eq + Ord,V:Copy>(m: Treemap<K, V>, k: K) -> Option<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visit all pairs in the map in order.
|
/// Visit all pairs in the map in order.
|
||||||
pub fn traverse<K, V: Copy>(m: Treemap<K, V>, f: &fn(&K, &V)) {
|
pub fn traverse<K, V>(m: Treemap<K, V>, f: &fn(&K, &V)) {
|
||||||
match *m {
|
match *m {
|
||||||
Empty => (),
|
Empty => (),
|
||||||
// Previously, this had what looked like redundant
|
// Previously, this had what looked like redundant
|
||||||
|
|
|
@ -53,10 +53,10 @@ priv enum FutureState<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Methods on the `future` type
|
/// Methods on the `future` type
|
||||||
impl<A:Copy> Future<A> {
|
impl<A:Clone> Future<A> {
|
||||||
pub fn get(&mut self) -> A {
|
pub fn get(&mut self) -> A {
|
||||||
//! Get the value of the future.
|
//! Get the value of the future.
|
||||||
copy *(self.get_ref())
|
(*(self.get_ref())).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
* fn main() {
|
* fn main() {
|
||||||
* let args = os::args();
|
* let args = os::args();
|
||||||
*
|
*
|
||||||
* let program = copy args[0];
|
* let program = args[0].clone();
|
||||||
*
|
*
|
||||||
* let opts = ~[
|
* let opts = ~[
|
||||||
* optopt("o"),
|
* optopt("o"),
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
* }
|
* }
|
||||||
* let output = opt_maybe_str(&matches, "o");
|
* let output = opt_maybe_str(&matches, "o");
|
||||||
* let input: &str = if !matches.free.is_empty() {
|
* let input: &str = if !matches.free.is_empty() {
|
||||||
* copy matches.free[0]
|
* matches.free[0].clone()
|
||||||
* } else {
|
* } else {
|
||||||
* print_usage(program, opts);
|
* print_usage(program, opts);
|
||||||
* return;
|
* return;
|
||||||
|
@ -89,20 +89,28 @@ use std::option::{Some, None};
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum Name {
|
pub enum Name {
|
||||||
Long(~str),
|
Long(~str),
|
||||||
Short(char),
|
Short(char),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum HasArg { Yes, No, Maybe, }
|
pub enum HasArg {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
Maybe,
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum Occur { Req, Optional, Multi, }
|
pub enum Occur {
|
||||||
|
Req,
|
||||||
|
Optional,
|
||||||
|
Multi,
|
||||||
|
}
|
||||||
|
|
||||||
/// A description of a possible option
|
/// A description of a possible option
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Opt {
|
pub struct Opt {
|
||||||
name: Name,
|
name: Name,
|
||||||
hasarg: HasArg,
|
hasarg: HasArg,
|
||||||
|
@ -150,14 +158,17 @@ pub fn optmulti(name: &str) -> Opt {
|
||||||
return Opt {name: mkname(name), hasarg: Yes, occur: Multi};
|
return Opt {name: mkname(name), hasarg: Yes, occur: Multi};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
enum Optval { Val(~str), Given, }
|
enum Optval {
|
||||||
|
Val(~str),
|
||||||
|
Given,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The result of checking command line arguments. Contains a vector
|
* The result of checking command line arguments. Contains a vector
|
||||||
* of matches and a vector of free strings.
|
* of matches and a vector of free strings.
|
||||||
*/
|
*/
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Matches {
|
pub struct Matches {
|
||||||
opts: ~[Opt],
|
opts: ~[Opt],
|
||||||
vals: ~[~[Optval]],
|
vals: ~[~[Optval]],
|
||||||
|
@ -171,7 +182,7 @@ fn is_arg(arg: &str) -> bool {
|
||||||
fn name_str(nm: &Name) -> ~str {
|
fn name_str(nm: &Name) -> ~str {
|
||||||
return match *nm {
|
return match *nm {
|
||||||
Short(ch) => str::from_char(ch),
|
Short(ch) => str::from_char(ch),
|
||||||
Long(ref s) => copy *s
|
Long(ref s) => (*s).clone()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +194,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(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum Fail_ {
|
pub enum Fail_ {
|
||||||
ArgumentMissing(~str),
|
ArgumentMissing(~str),
|
||||||
UnrecognizedOption(~str),
|
UnrecognizedOption(~str),
|
||||||
|
@ -234,13 +245,13 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
||||||
let l = args.len();
|
let l = args.len();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < l {
|
while i < l {
|
||||||
let cur = copy args[i];
|
let cur = args[i].clone();
|
||||||
let curlen = cur.len();
|
let curlen = cur.len();
|
||||||
if !is_arg(cur) {
|
if !is_arg(cur) {
|
||||||
free.push(cur);
|
free.push(cur);
|
||||||
} else if cur == ~"--" {
|
} else if cur == ~"--" {
|
||||||
let mut j = i + 1;
|
let mut j = i + 1;
|
||||||
while j < l { free.push(copy args[j]); j += 1; }
|
while j < l { free.push(args[j].clone()); j += 1; }
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
let mut names;
|
let mut names;
|
||||||
|
@ -270,7 +281,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
||||||
interpreted correctly
|
interpreted correctly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
match find_opt(opts, copy opt) {
|
match find_opt(opts, opt.clone()) {
|
||||||
Some(id) => last_valid_opt_id = Some(id),
|
Some(id) => last_valid_opt_id = Some(id),
|
||||||
None => {
|
None => {
|
||||||
let arg_follows =
|
let arg_follows =
|
||||||
|
@ -296,7 +307,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
||||||
let mut name_pos = 0;
|
let mut name_pos = 0;
|
||||||
for names.iter().advance() |nm| {
|
for names.iter().advance() |nm| {
|
||||||
name_pos += 1;
|
name_pos += 1;
|
||||||
let optid = match find_opt(opts, copy *nm) {
|
let optid = match find_opt(opts, (*nm).clone()) {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => return Err(UnrecognizedOption(name_str(nm)))
|
None => return Err(UnrecognizedOption(name_str(nm)))
|
||||||
};
|
};
|
||||||
|
@ -309,18 +320,18 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
||||||
}
|
}
|
||||||
Maybe => {
|
Maybe => {
|
||||||
if !i_arg.is_none() {
|
if !i_arg.is_none() {
|
||||||
vals[optid].push(Val((copy i_arg).get()));
|
vals[optid].push(Val((i_arg.clone()).get()));
|
||||||
} 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);
|
||||||
} else { i += 1; vals[optid].push(Val(copy args[i])); }
|
} else { i += 1; vals[optid].push(Val(args[i].clone())); }
|
||||||
}
|
}
|
||||||
Yes => {
|
Yes => {
|
||||||
if !i_arg.is_none() {
|
if !i_arg.is_none() {
|
||||||
vals[optid].push(Val((copy i_arg).get()));
|
vals[optid].push(Val(i_arg.clone().get()));
|
||||||
} 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(copy args[i])); }
|
} else { i += 1; vals[optid].push(Val(args[i].clone())); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,7 +361,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
|
||||||
|
|
||||||
fn opt_vals(mm: &Matches, nm: &str) -> ~[Optval] {
|
fn opt_vals(mm: &Matches, nm: &str) -> ~[Optval] {
|
||||||
return match find_opt(mm.opts, mkname(nm)) {
|
return match find_opt(mm.opts, mkname(nm)) {
|
||||||
Some(id) => copy mm.vals[id],
|
Some(id) => mm.vals[id].clone(),
|
||||||
None => {
|
None => {
|
||||||
error!("No option '%s' defined", nm);
|
error!("No option '%s' defined", nm);
|
||||||
fail!()
|
fail!()
|
||||||
|
@ -358,7 +369,7 @@ fn opt_vals(mm: &Matches, nm: &str) -> ~[Optval] {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opt_val(mm: &Matches, nm: &str) -> Optval { copy opt_vals(mm, nm)[0] }
|
fn opt_val(mm: &Matches, nm: &str) -> Optval { opt_vals(mm, nm)[0].clone() }
|
||||||
|
|
||||||
/// Returns true if an option was matched
|
/// Returns true if an option was matched
|
||||||
pub fn opt_present(mm: &Matches, nm: &str) -> bool {
|
pub fn opt_present(mm: &Matches, nm: &str) -> bool {
|
||||||
|
@ -401,7 +412,7 @@ pub fn opt_str(mm: &Matches, nm: &str) -> ~str {
|
||||||
pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str {
|
pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str {
|
||||||
for names.iter().advance |nm| {
|
for names.iter().advance |nm| {
|
||||||
match opt_val(mm, *nm) {
|
match opt_val(mm, *nm) {
|
||||||
Val(ref s) => return copy *s,
|
Val(ref s) => return (*s).clone(),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,7 +430,7 @@ pub fn opt_strs(mm: &Matches, nm: &str) -> ~[~str] {
|
||||||
let mut acc: ~[~str] = ~[];
|
let mut acc: ~[~str] = ~[];
|
||||||
let r = opt_vals(mm, nm);
|
let r = opt_vals(mm, nm);
|
||||||
for r.iter().advance |v| {
|
for r.iter().advance |v| {
|
||||||
match *v { Val(ref s) => acc.push(copy *s), _ => () }
|
match *v { Val(ref s) => acc.push((*s).clone()), _ => () }
|
||||||
}
|
}
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
|
@ -429,7 +440,7 @@ pub fn opt_maybe_str(mm: &Matches, nm: &str) -> Option<~str> {
|
||||||
let vals = opt_vals(mm, nm);
|
let vals = opt_vals(mm, nm);
|
||||||
if vals.is_empty() { return None::<~str>; }
|
if vals.is_empty() { return None::<~str>; }
|
||||||
return match vals[0] {
|
return match vals[0] {
|
||||||
Val(ref s) => Some(copy *s),
|
Val(ref s) => Some((*s).clone()),
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -445,7 +456,7 @@ pub fn opt_maybe_str(mm: &Matches, nm: &str) -> Option<~str> {
|
||||||
pub fn opt_default(mm: &Matches, nm: &str, def: &str) -> Option<~str> {
|
pub fn opt_default(mm: &Matches, nm: &str, def: &str) -> Option<~str> {
|
||||||
let vals = opt_vals(mm, nm);
|
let vals = opt_vals(mm, nm);
|
||||||
if vals.is_empty() { return None::<~str>; }
|
if vals.is_empty() { return None::<~str>; }
|
||||||
return match vals[0] { Val(ref s) => Some::<~str>(copy *s),
|
return match vals[0] { Val(ref s) => Some::<~str>((*s).clone()),
|
||||||
_ => Some::<~str>(str::to_owned(def)) }
|
_ => Some::<~str>(str::to_owned(def)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +482,7 @@ pub mod groups {
|
||||||
/** one group of options, e.g., both -h and --help, along with
|
/** one group of options, e.g., both -h and --help, along with
|
||||||
* their shared description and properties
|
* their shared description and properties
|
||||||
*/
|
*/
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct OptGroup {
|
pub struct OptGroup {
|
||||||
short_name: ~str,
|
short_name: ~str,
|
||||||
long_name: ~str,
|
long_name: ~str,
|
||||||
|
@ -556,7 +567,7 @@ pub mod groups {
|
||||||
long_name: long_name,
|
long_name: long_name,
|
||||||
hasarg: hasarg,
|
hasarg: hasarg,
|
||||||
occur: occur,
|
occur: occur,
|
||||||
_} = copy *lopt;
|
_} = (*lopt).clone();
|
||||||
|
|
||||||
match (short_name.len(), long_name.len()) {
|
match (short_name.len(), long_name.len()) {
|
||||||
(0,0) => fail!("this long-format option was given no name"),
|
(0,0) => fail!("this long-format option was given no name"),
|
||||||
|
@ -600,7 +611,7 @@ pub mod groups {
|
||||||
hint: hint,
|
hint: hint,
|
||||||
desc: desc,
|
desc: desc,
|
||||||
hasarg: hasarg,
|
hasarg: hasarg,
|
||||||
_} = copy *optref;
|
_} = (*optref).clone();
|
||||||
|
|
||||||
let mut row = " ".repeat(4);
|
let mut row = " ".repeat(4);
|
||||||
|
|
||||||
|
@ -916,7 +927,7 @@ mod tests {
|
||||||
let rs = getopts(args, opts);
|
let rs = getopts(args, opts);
|
||||||
match rs {
|
match rs {
|
||||||
Err(f) => {
|
Err(f) => {
|
||||||
error!(fail_str(copy f));
|
error!(fail_str(f.clone()));
|
||||||
check_fail_type(f, UnexpectedArgument_);
|
check_fail_type(f, UnexpectedArgument_);
|
||||||
}
|
}
|
||||||
_ => fail!()
|
_ => fail!()
|
||||||
|
|
|
@ -30,6 +30,7 @@ use sort::Sort;
|
||||||
use treemap::TreeMap;
|
use treemap::TreeMap;
|
||||||
|
|
||||||
/// Represents a json value
|
/// Represents a json value
|
||||||
|
#[deriving(Clone, Eq)]
|
||||||
pub enum Json {
|
pub enum Json {
|
||||||
Number(float),
|
Number(float),
|
||||||
String(~str),
|
String(~str),
|
||||||
|
@ -1113,43 +1114,6 @@ impl serialize::Decoder for Decoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for Json {
|
|
||||||
fn eq(&self, other: &Json) -> bool {
|
|
||||||
match (self) {
|
|
||||||
&Number(f0) =>
|
|
||||||
match other { &Number(f1) => f0 == f1, _ => false },
|
|
||||||
&String(ref s0) =>
|
|
||||||
match other { &String(ref s1) => s0 == s1, _ => false },
|
|
||||||
&Boolean(b0) =>
|
|
||||||
match other { &Boolean(b1) => b0 == b1, _ => false },
|
|
||||||
&Null =>
|
|
||||||
match other { &Null => true, _ => false },
|
|
||||||
&List(ref v0) =>
|
|
||||||
match other { &List(ref v1) => v0 == v1, _ => false },
|
|
||||||
&Object(ref d0) => {
|
|
||||||
match other {
|
|
||||||
&Object(ref d1) => {
|
|
||||||
if d0.len() == d1.len() {
|
|
||||||
let mut equal = true;
|
|
||||||
for d0.iter().advance |(k, v0)| {
|
|
||||||
match d1.find(k) {
|
|
||||||
Some(v1) if v0 == v1 => { },
|
|
||||||
_ => { equal = false; break }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
equal
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn ne(&self, other: &Json) -> bool { !self.eq(other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test if two json values are less than one another
|
/// Test if two json values are less than one another
|
||||||
impl Ord for Json {
|
impl Ord for Json {
|
||||||
fn lt(&self, other: &Json) -> bool {
|
fn lt(&self, other: &Json) -> bool {
|
||||||
|
@ -1195,12 +1159,12 @@ impl Ord for Json {
|
||||||
|
|
||||||
// FIXME #4430: this is horribly inefficient...
|
// FIXME #4430: this is horribly inefficient...
|
||||||
for d0.iter().advance |(k, v)| {
|
for d0.iter().advance |(k, v)| {
|
||||||
d0_flat.push((@copy *k, @copy *v));
|
d0_flat.push((@(*k).clone(), @(*v).clone()));
|
||||||
}
|
}
|
||||||
d0_flat.qsort();
|
d0_flat.qsort();
|
||||||
|
|
||||||
for d1.iter().advance |(k, v)| {
|
for d1.iter().advance |(k, v)| {
|
||||||
d1_flat.push((@copy *k, @copy *v));
|
d1_flat.push((@(*k).clone(), @(*v).clone()));
|
||||||
}
|
}
|
||||||
d1_flat.qsort();
|
d1_flat.qsort();
|
||||||
|
|
||||||
|
@ -1232,7 +1196,7 @@ pub trait ToJson {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJson for Json {
|
impl ToJson for Json {
|
||||||
fn to_json(&self) -> Json { copy *self }
|
fn to_json(&self) -> Json { (*self).clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJson for @Json {
|
impl ToJson for @Json {
|
||||||
|
@ -1300,11 +1264,11 @@ impl ToJson for bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJson for ~str {
|
impl ToJson for ~str {
|
||||||
fn to_json(&self) -> Json { String(copy *self) }
|
fn to_json(&self) -> Json { String((*self).clone()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJson for @~str {
|
impl ToJson for @~str {
|
||||||
fn to_json(&self) -> Json { String(copy **self) }
|
fn to_json(&self) -> Json { String((**self).clone()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A:ToJson,B:ToJson> ToJson for (A, B) {
|
impl<A:ToJson,B:ToJson> ToJson for (A, B) {
|
||||||
|
@ -1335,7 +1299,7 @@ impl<A:ToJson> ToJson for HashMap<~str, A> {
|
||||||
fn to_json(&self) -> Json {
|
fn to_json(&self) -> Json {
|
||||||
let mut d = HashMap::new();
|
let mut d = HashMap::new();
|
||||||
for self.iter().advance |(key, value)| {
|
for self.iter().advance |(key, value)| {
|
||||||
d.insert(copy *key, value.to_json());
|
d.insert((*key).clone(), value.to_json());
|
||||||
}
|
}
|
||||||
Object(~d)
|
Object(~d)
|
||||||
}
|
}
|
||||||
|
@ -1345,7 +1309,7 @@ impl<A:ToJson> ToJson for TreeMap<~str, A> {
|
||||||
fn to_json(&self) -> Json {
|
fn to_json(&self) -> Json {
|
||||||
let mut d = HashMap::new();
|
let mut d = HashMap::new();
|
||||||
for self.iter().advance |(key, value)| {
|
for self.iter().advance |(key, value)| {
|
||||||
d.insert(copy *key, value.to_json());
|
d.insert((*key).clone(), value.to_json());
|
||||||
}
|
}
|
||||||
Object(~d)
|
Object(~d)
|
||||||
}
|
}
|
||||||
|
@ -1404,7 +1368,7 @@ mod tests {
|
||||||
|
|
||||||
for items.iter().advance |item| {
|
for items.iter().advance |item| {
|
||||||
match *item {
|
match *item {
|
||||||
(ref key, ref value) => { d.insert(copy *key, copy *value); },
|
(ref key, ref value) => { d.insert((*key).clone(), (*value).clone()); },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1549,8 +1513,8 @@ mod tests {
|
||||||
|
|
||||||
// We can't compare the strings directly because the object fields be
|
// We can't compare the strings directly because the object fields be
|
||||||
// printed in a different order.
|
// printed in a different order.
|
||||||
assert_eq!(copy a, from_str(to_str(&a)).unwrap());
|
assert_eq!(a.clone(), from_str(to_str(&a)).unwrap());
|
||||||
assert_eq!(copy a, from_str(to_pretty_str(&a)).unwrap());
|
assert_eq!(a.clone(), from_str(to_pretty_str(&a)).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -25,8 +25,8 @@ pub enum MutList<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a list from a vector
|
/// Create a list from a vector
|
||||||
pub fn from_vec<T:Copy>(v: &[T]) -> @List<T> {
|
pub fn from_vec<T:Clone>(v: &[T]) -> @List<T> {
|
||||||
v.rev_iter().fold(@Nil::<T>, |t, h| @Cons(copy *h, t))
|
v.rev_iter().fold(@Nil::<T>, |t, h| @Cons((*h).clone(), t))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,7 +42,7 @@ pub fn from_vec<T:Copy>(v: &[T]) -> @List<T> {
|
||||||
* * z - The initial value
|
* * z - The initial value
|
||||||
* * f - The function to apply
|
* * f - The function to apply
|
||||||
*/
|
*/
|
||||||
pub fn foldl<T:Copy,U>(z: T, ls: @List<U>, f: &fn(&T, &U) -> T) -> T {
|
pub fn foldl<T:Clone,U>(z: T, ls: @List<U>, f: &fn(&T, &U) -> T) -> T {
|
||||||
let mut accum: T = z;
|
let mut accum: T = z;
|
||||||
do iter(ls) |elt| { accum = f(&accum, elt);}
|
do iter(ls) |elt| { accum = f(&accum, elt);}
|
||||||
accum
|
accum
|
||||||
|
@ -55,12 +55,12 @@ pub fn foldl<T:Copy,U>(z: T, ls: @List<U>, f: &fn(&T, &U) -> T) -> T {
|
||||||
* When function `f` returns true then an option containing the element
|
* When function `f` returns true then an option containing the element
|
||||||
* is returned. If `f` matches no elements then none is returned.
|
* is returned. If `f` matches no elements then none is returned.
|
||||||
*/
|
*/
|
||||||
pub fn find<T:Copy>(ls: @List<T>, f: &fn(&T) -> bool) -> Option<T> {
|
pub fn find<T:Clone>(ls: @List<T>, f: &fn(&T) -> bool) -> Option<T> {
|
||||||
let mut ls = ls;
|
let mut ls = ls;
|
||||||
loop {
|
loop {
|
||||||
ls = match *ls {
|
ls = match *ls {
|
||||||
Cons(ref hd, tl) => {
|
Cons(ref hd, tl) => {
|
||||||
if f(hd) { return Some(copy *hd); }
|
if f(hd) { return Some((*hd).clone()); }
|
||||||
tl
|
tl
|
||||||
}
|
}
|
||||||
Nil => return None
|
Nil => return None
|
||||||
|
@ -69,7 +69,7 @@ pub fn find<T:Copy>(ls: @List<T>, f: &fn(&T) -> bool) -> Option<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if a list contains an element with the given value
|
/// Returns true if a list contains an element with the given value
|
||||||
pub fn has<T:Copy + Eq>(ls: @List<T>, elt: T) -> bool {
|
pub fn has<T:Eq>(ls: @List<T>, elt: T) -> bool {
|
||||||
for each(ls) |e| {
|
for each(ls) |e| {
|
||||||
if *e == elt { return true; }
|
if *e == elt { return true; }
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ pub fn has<T:Copy + Eq>(ls: @List<T>, elt: T) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the list is empty
|
/// Returns true if the list is empty
|
||||||
pub fn is_empty<T:Copy>(ls: @List<T>) -> bool {
|
pub fn is_empty<T>(ls: @List<T>) -> bool {
|
||||||
match *ls {
|
match *ls {
|
||||||
Nil => true,
|
Nil => true,
|
||||||
_ => false
|
_ => false
|
||||||
|
@ -92,7 +92,7 @@ pub fn len<T>(ls: @List<T>) -> uint {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all but the first element of a list
|
/// Returns all but the first element of a list
|
||||||
pub fn tail<T:Copy>(ls: @List<T>) -> @List<T> {
|
pub fn tail<T>(ls: @List<T>) -> @List<T> {
|
||||||
match *ls {
|
match *ls {
|
||||||
Cons(_, tl) => return tl,
|
Cons(_, tl) => return tl,
|
||||||
Nil => fail!("list empty")
|
Nil => fail!("list empty")
|
||||||
|
@ -100,21 +100,21 @@ pub fn tail<T:Copy>(ls: @List<T>) -> @List<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first element of a list
|
/// Returns the first element of a list
|
||||||
pub fn head<T:Copy>(ls: @List<T>) -> T {
|
pub fn head<T:Clone>(ls: @List<T>) -> T {
|
||||||
match *ls {
|
match *ls {
|
||||||
Cons(ref hd, _) => copy *hd,
|
Cons(ref hd, _) => (*hd).clone(),
|
||||||
// makes me sad
|
// makes me sad
|
||||||
_ => fail!("head invoked on empty list")
|
_ => fail!("head invoked on empty list")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends one list to another
|
/// Appends one list to another
|
||||||
pub fn append<T:Copy>(l: @List<T>, m: @List<T>) -> @List<T> {
|
pub fn append<T:Clone>(l: @List<T>, m: @List<T>) -> @List<T> {
|
||||||
match *l {
|
match *l {
|
||||||
Nil => return m,
|
Nil => return m,
|
||||||
Cons(ref x, xs) => {
|
Cons(ref x, xs) => {
|
||||||
let rest = append(xs, m);
|
let rest = append(xs, m);
|
||||||
return @Cons(copy *x, rest);
|
return @Cons((*x).clone(), rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ pub fn append<T:Copy>(l: @List<T>, m: @List<T>) -> @List<T> {
|
||||||
/*
|
/*
|
||||||
/// Push one element into the front of a list, returning a new list
|
/// Push one element into the front of a list, returning a new list
|
||||||
/// THIS VERSION DOESN'T ACTUALLY WORK
|
/// THIS VERSION DOESN'T ACTUALLY WORK
|
||||||
fn push<T:Copy>(ll: &mut @list<T>, vv: T) {
|
fn push<T:Clone>(ll: &mut @list<T>, vv: T) {
|
||||||
ll = &mut @cons(vv, *ll)
|
ll = &mut @cons(vv, *ll)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -176,12 +176,19 @@ pub mod v4 {
|
||||||
pub fn parse_addr(ip: &str) -> IpAddr {
|
pub fn parse_addr(ip: &str) -> IpAddr {
|
||||||
match try_parse_addr(ip) {
|
match try_parse_addr(ip) {
|
||||||
result::Ok(addr) => addr,
|
result::Ok(addr) => addr,
|
||||||
result::Err(ref err_data) => fail!(copy err_data.err_msg)
|
result::Err(ref err_data) => fail!(err_data.err_msg.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the simple, old style numberic representation of
|
// the simple, old style numberic representation of
|
||||||
// ipv4
|
// ipv4
|
||||||
pub struct Ipv4Rep { a: u8, b: u8, c: u8, d: u8 }
|
#[deriving(Clone)]
|
||||||
|
pub struct Ipv4Rep {
|
||||||
|
a: u8,
|
||||||
|
b: u8,
|
||||||
|
c: u8,
|
||||||
|
d: u8,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait AsUnsafeU32 {
|
pub trait AsUnsafeU32 {
|
||||||
unsafe fn as_u32(&self) -> u32;
|
unsafe fn as_u32(&self) -> u32;
|
||||||
|
@ -271,7 +278,7 @@ pub mod v6 {
|
||||||
pub fn parse_addr(ip: &str) -> IpAddr {
|
pub fn parse_addr(ip: &str) -> IpAddr {
|
||||||
match try_parse_addr(ip) {
|
match try_parse_addr(ip) {
|
||||||
result::Ok(addr) => addr,
|
result::Ok(addr) => addr,
|
||||||
result::Err(err_data) => fail!(copy err_data.err_msg)
|
result::Err(err_data) => fail!(err_data.err_msg.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn try_parse_addr(ip: &str) -> result::Result<IpAddr,ParseAddrErr> {
|
pub fn try_parse_addr(ip: &str) -> result::Result<IpAddr,ParseAddrErr> {
|
||||||
|
|
|
@ -86,6 +86,7 @@ pub fn TcpSocketBuf(data: @mut TcpBufferedSocketData) -> TcpSocketBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains raw, string-based, error information returned from libuv
|
/// Contains raw, string-based, error information returned from libuv
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct TcpErrData {
|
pub struct TcpErrData {
|
||||||
err_name: ~str,
|
err_name: ~str,
|
||||||
err_msg: ~str,
|
err_msg: ~str,
|
||||||
|
@ -278,8 +279,8 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
|
||||||
as *libc::c_void);
|
as *libc::c_void);
|
||||||
let tcp_conn_err = match err_data.err_name {
|
let tcp_conn_err = match err_data.err_name {
|
||||||
~"ECONNREFUSED" => ConnectionRefused,
|
~"ECONNREFUSED" => ConnectionRefused,
|
||||||
_ => GenericConnectErr(copy err_data.err_name,
|
_ => GenericConnectErr(err_data.err_name.clone(),
|
||||||
copy err_data.err_msg)
|
err_data.err_msg.clone())
|
||||||
};
|
};
|
||||||
result::Err(tcp_conn_err)
|
result::Err(tcp_conn_err)
|
||||||
}
|
}
|
||||||
|
@ -343,7 +344,7 @@ pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8])
|
||||||
{
|
{
|
||||||
let socket_data_ptr: *TcpSocketData = &*sock.socket_data;
|
let socket_data_ptr: *TcpSocketData = &*sock.socket_data;
|
||||||
do future_spawn {
|
do future_spawn {
|
||||||
let data_copy = copy(raw_write_data);
|
let data_copy = raw_write_data.clone();
|
||||||
write_common_impl(socket_data_ptr, data_copy)
|
write_common_impl(socket_data_ptr, data_copy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -770,8 +771,8 @@ fn listen_common(host_ip: ip::IpAddr,
|
||||||
debug!("Got '%s' '%s' libuv error",
|
debug!("Got '%s' '%s' libuv error",
|
||||||
err_data.err_name, err_data.err_msg);
|
err_data.err_name, err_data.err_msg);
|
||||||
result::Err(
|
result::Err(
|
||||||
GenericListenErr(copy err_data.err_name,
|
GenericListenErr(err_data.err_name.clone(),
|
||||||
copy err_data.err_msg))
|
err_data.err_msg.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -791,8 +792,8 @@ fn listen_common(host_ip: ip::IpAddr,
|
||||||
match kill_result {
|
match kill_result {
|
||||||
// some failure post bind/listen
|
// some failure post bind/listen
|
||||||
Some(ref err_data) => result::Err(GenericListenErr(
|
Some(ref err_data) => result::Err(GenericListenErr(
|
||||||
copy err_data.err_name,
|
err_data.err_name.clone(),
|
||||||
copy err_data.err_msg)),
|
err_data.err_msg.clone())),
|
||||||
// clean exit
|
// clean exit
|
||||||
None => result::Ok(())
|
None => result::Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1263,7 +1264,10 @@ trait ToTcpErr {
|
||||||
|
|
||||||
impl ToTcpErr for uv::ll::uv_err_data {
|
impl ToTcpErr for uv::ll::uv_err_data {
|
||||||
fn to_tcp_err(&self) -> TcpErrData {
|
fn to_tcp_err(&self) -> TcpErrData {
|
||||||
TcpErrData { err_name: copy self.err_name, err_msg: copy self.err_msg }
|
TcpErrData {
|
||||||
|
err_name: self.err_name.clone(),
|
||||||
|
err_msg: self.err_msg.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,7 @@ impl Mul<BigUint, BigUint> for BigUint {
|
||||||
|
|
||||||
fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
|
fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
|
||||||
if n == 0 { return Zero::zero(); }
|
if n == 0 { return Zero::zero(); }
|
||||||
if n == 1 { return copy *a; }
|
if n == 1 { return (*a).clone(); }
|
||||||
|
|
||||||
let mut carry = 0;
|
let mut carry = 0;
|
||||||
let mut prod = do a.data.iter().transform |ai| {
|
let mut prod = do a.data.iter().transform |ai| {
|
||||||
|
@ -357,10 +357,10 @@ impl Integer for BigUint {
|
||||||
fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) {
|
fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) {
|
||||||
if other.is_zero() { fail!() }
|
if other.is_zero() { fail!() }
|
||||||
if self.is_zero() { return (Zero::zero(), Zero::zero()); }
|
if self.is_zero() { return (Zero::zero(), Zero::zero()); }
|
||||||
if *other == One::one() { return (copy *self, Zero::zero()); }
|
if *other == One::one() { return ((*self).clone(), Zero::zero()); }
|
||||||
|
|
||||||
match self.cmp(other) {
|
match self.cmp(other) {
|
||||||
Less => return (Zero::zero(), copy *self),
|
Less => return (Zero::zero(), (*self).clone()),
|
||||||
Equal => return (One::one(), Zero::zero()),
|
Equal => return (One::one(), Zero::zero()),
|
||||||
Greater => {} // Do nothing
|
Greater => {} // Do nothing
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ impl Integer for BigUint {
|
||||||
fn div_estimate(a: &BigUint, b: &BigUint, n: uint)
|
fn div_estimate(a: &BigUint, b: &BigUint, n: uint)
|
||||||
-> (BigUint, BigUint, BigUint) {
|
-> (BigUint, BigUint, BigUint) {
|
||||||
if a.data.len() < n {
|
if a.data.len() < n {
|
||||||
return (Zero::zero(), Zero::zero(), copy *a);
|
return (Zero::zero(), Zero::zero(), (*a).clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let an = a.data.slice(a.data.len() - n, a.data.len());
|
let an = a.data.slice(a.data.len() - n, a.data.len());
|
||||||
|
@ -428,7 +428,7 @@ impl Integer for BigUint {
|
||||||
|
|
||||||
let shift = (a.data.len() - an.len()) - (b.data.len() - 1);
|
let shift = (a.data.len() - an.len()) - (b.data.len() - 1);
|
||||||
if shift == 0 {
|
if shift == 0 {
|
||||||
return (BigUint::new(d), One::one(), copy *b);
|
return (BigUint::new(d), One::one(), (*b).clone());
|
||||||
}
|
}
|
||||||
return (BigUint::from_slice(d).shl_unit(shift),
|
return (BigUint::from_slice(d).shl_unit(shift),
|
||||||
One::one::<BigUint>().shl_unit(shift),
|
One::one::<BigUint>().shl_unit(shift),
|
||||||
|
@ -444,8 +444,8 @@ impl Integer for BigUint {
|
||||||
|
|
||||||
fn gcd(&self, other: &BigUint) -> BigUint {
|
fn gcd(&self, other: &BigUint) -> BigUint {
|
||||||
// Use Euclid's algorithm
|
// Use Euclid's algorithm
|
||||||
let mut m = copy *self;
|
let mut m = (*self).clone();
|
||||||
let mut n = copy *other;
|
let mut n = (*other).clone();
|
||||||
while !m.is_zero() {
|
while !m.is_zero() {
|
||||||
let temp = m;
|
let temp = m;
|
||||||
m = n % temp;
|
m = n % temp;
|
||||||
|
@ -500,7 +500,7 @@ impl ToStrRadix for BigUint {
|
||||||
if base == BigDigit::base {
|
if base == BigDigit::base {
|
||||||
return fill_concat(self.data, radix, max_len)
|
return fill_concat(self.data, radix, max_len)
|
||||||
}
|
}
|
||||||
return fill_concat(convert_base(copy *self, base), radix, max_len);
|
return fill_concat(convert_base((*self).clone(), base), radix, max_len);
|
||||||
|
|
||||||
|
|
||||||
fn convert_base(n: BigUint, base: uint) -> ~[BigDigit] {
|
fn convert_base(n: BigUint, base: uint) -> ~[BigDigit] {
|
||||||
|
@ -612,14 +612,14 @@ impl BigUint {
|
||||||
|
|
||||||
|
|
||||||
priv fn shl_unit(&self, n_unit: uint) -> BigUint {
|
priv fn shl_unit(&self, n_unit: uint) -> BigUint {
|
||||||
if n_unit == 0 || self.is_zero() { return copy *self; }
|
if n_unit == 0 || self.is_zero() { return (*self).clone(); }
|
||||||
|
|
||||||
return BigUint::new(vec::from_elem(n_unit, 0) + self.data);
|
return BigUint::new(vec::from_elem(n_unit, 0u32) + self.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
priv fn shl_bits(&self, n_bits: uint) -> BigUint {
|
priv fn shl_bits(&self, n_bits: uint) -> BigUint {
|
||||||
if n_bits == 0 || self.is_zero() { return copy *self; }
|
if n_bits == 0 || self.is_zero() { return (*self).clone(); }
|
||||||
|
|
||||||
let mut carry = 0;
|
let mut carry = 0;
|
||||||
let mut shifted = do self.data.iter().transform |elem| {
|
let mut shifted = do self.data.iter().transform |elem| {
|
||||||
|
@ -635,7 +635,7 @@ impl BigUint {
|
||||||
|
|
||||||
|
|
||||||
priv fn shr_unit(&self, n_unit: uint) -> BigUint {
|
priv fn shr_unit(&self, n_unit: uint) -> BigUint {
|
||||||
if n_unit == 0 { return copy *self; }
|
if n_unit == 0 { return (*self).clone(); }
|
||||||
if self.data.len() < n_unit { return Zero::zero(); }
|
if self.data.len() < n_unit { return Zero::zero(); }
|
||||||
return BigUint::from_slice(
|
return BigUint::from_slice(
|
||||||
self.data.slice(n_unit, self.data.len())
|
self.data.slice(n_unit, self.data.len())
|
||||||
|
@ -644,7 +644,7 @@ impl BigUint {
|
||||||
|
|
||||||
|
|
||||||
priv fn shr_bits(&self, n_bits: uint) -> BigUint {
|
priv fn shr_bits(&self, n_bits: uint) -> BigUint {
|
||||||
if n_bits == 0 || self.data.is_empty() { return copy *self; }
|
if n_bits == 0 || self.data.is_empty() { return (*self).clone(); }
|
||||||
|
|
||||||
let mut borrow = 0;
|
let mut borrow = 0;
|
||||||
let mut shifted = ~[];
|
let mut shifted = ~[];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
// Cloneright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
// file at the top-level directory of this distribution and at
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
//
|
//
|
||||||
|
@ -32,7 +32,7 @@ static MIN_GRANULARITY : uint = 1024u;
|
||||||
* This is used to build most of the other parallel vector functions,
|
* This is used to build most of the other parallel vector functions,
|
||||||
* like map or alli.
|
* like map or alli.
|
||||||
*/
|
*/
|
||||||
fn map_slices<A:Copy + Send,B:Copy + Send>(
|
fn map_slices<A:Clone + Send,B:Clone + Send>(
|
||||||
xs: &[A],
|
xs: &[A],
|
||||||
f: &fn() -> ~fn(uint, v: &[A]) -> B)
|
f: &fn() -> ~fn(uint, v: &[A]) -> B)
|
||||||
-> ~[B] {
|
-> ~[B] {
|
||||||
|
@ -42,8 +42,7 @@ fn map_slices<A:Copy + Send,B:Copy + Send>(
|
||||||
info!("small slice");
|
info!("small slice");
|
||||||
// This is a small vector, fall back on the normal map.
|
// This is a small vector, fall back on the normal map.
|
||||||
~[f()(0u, xs)]
|
~[f()(0u, xs)]
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
let num_tasks = num::min(MAX_TASKS, len / MIN_GRANULARITY);
|
let num_tasks = num::min(MAX_TASKS, len / MIN_GRANULARITY);
|
||||||
|
|
||||||
let items_per_task = len / num_tasks;
|
let items_per_task = len / num_tasks;
|
||||||
|
@ -86,7 +85,7 @@ fn map_slices<A:Copy + Send,B:Copy + Send>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A parallel version of map.
|
/// A parallel version of map.
|
||||||
pub fn map<A:Copy + Send,B:Copy + Send>(
|
pub fn map<A:Copy + Clone + Send,B:Copy + Clone + Send>(
|
||||||
xs: &[A], fn_factory: &fn() -> ~fn(&A) -> B) -> ~[B] {
|
xs: &[A], fn_factory: &fn() -> ~fn(&A) -> B) -> ~[B] {
|
||||||
vec::concat(map_slices(xs, || {
|
vec::concat(map_slices(xs, || {
|
||||||
let f = fn_factory();
|
let f = fn_factory();
|
||||||
|
@ -97,7 +96,7 @@ pub fn map<A:Copy + Send,B:Copy + Send>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A parallel version of mapi.
|
/// A parallel version of mapi.
|
||||||
pub fn mapi<A:Copy + Send,B:Copy + Send>(
|
pub fn mapi<A:Copy + Clone + Send,B:Copy + Clone + Send>(
|
||||||
xs: &[A],
|
xs: &[A],
|
||||||
fn_factory: &fn() -> ~fn(uint, &A) -> B) -> ~[B] {
|
fn_factory: &fn() -> ~fn(uint, &A) -> B) -> ~[B] {
|
||||||
let slices = map_slices(xs, || {
|
let slices = map_slices(xs, || {
|
||||||
|
@ -116,7 +115,7 @@ pub fn mapi<A:Copy + Send,B:Copy + Send>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the function holds for all elements in the vector.
|
/// Returns true if the function holds for all elements in the vector.
|
||||||
pub fn alli<A:Copy + Send>(
|
pub fn alli<A:Clone + Send>(
|
||||||
xs: &[A],
|
xs: &[A],
|
||||||
fn_factory: &fn() -> ~fn(uint, &A) -> bool) -> bool
|
fn_factory: &fn() -> ~fn(uint, &A) -> bool) -> bool
|
||||||
{
|
{
|
||||||
|
@ -131,7 +130,7 @@ pub fn alli<A:Copy + Send>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the function holds for any elements in the vector.
|
/// Returns true if the function holds for any elements in the vector.
|
||||||
pub fn any<A:Copy + Send>(
|
pub fn any<A:Clone + Send>(
|
||||||
xs: &[A],
|
xs: &[A],
|
||||||
fn_factory: &fn() -> ~fn(&A) -> bool) -> bool {
|
fn_factory: &fn() -> ~fn(&A) -> bool) -> bool {
|
||||||
let mapped = map_slices(xs, || {
|
let mapped = map_slices(xs, || {
|
||||||
|
|
|
@ -308,8 +308,8 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_to_vec(data: ~[int]) {
|
fn check_to_vec(data: ~[int]) {
|
||||||
let heap = PriorityQueue::from_vec(copy data);
|
let heap = PriorityQueue::from_vec(data.clone());
|
||||||
assert_eq!(merge_sort((copy heap).to_vec(), |x, y| x.le(y)),
|
assert_eq!(merge_sort(heap.clone().to_vec(), |x, y| x.le(y)),
|
||||||
merge_sort(data, |x, y| x.le(y)));
|
merge_sort(data, |x, y| x.le(y)));
|
||||||
assert_eq!(heap.to_sorted_vec(), merge_sort(data, |x, y| x.le(y)));
|
assert_eq!(heap.to_sorted_vec(), merge_sort(data, |x, y| x.le(y)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,8 +329,8 @@ impl<A, T: Iterator<A>> FromIterator<A, T> for RingBuf<A> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::clone::Clone;
|
||||||
use std::cmp::Eq;
|
use std::cmp::Eq;
|
||||||
use std::kinds::Copy;
|
|
||||||
use std::{int, uint};
|
use std::{int, uint};
|
||||||
use extra::test;
|
use extra::test;
|
||||||
|
|
||||||
|
@ -416,34 +416,34 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
|
fn test_parameterized<T:Clone + Eq>(a: T, b: T, c: T, d: T) {
|
||||||
let mut deq = RingBuf::new();
|
let mut deq = Deque::new();
|
||||||
assert_eq!(deq.len(), 0);
|
assert_eq!(deq.len(), 0);
|
||||||
deq.push_front(copy a);
|
deq.add_front(a.clone());
|
||||||
deq.push_front(copy b);
|
deq.add_front(b.clone());
|
||||||
deq.push_back(copy c);
|
deq.add_back(c.clone());
|
||||||
assert_eq!(deq.len(), 3);
|
assert_eq!(deq.len(), 3);
|
||||||
deq.push_back(copy d);
|
deq.add_back(d.clone());
|
||||||
assert_eq!(deq.len(), 4);
|
assert_eq!(deq.len(), 4);
|
||||||
assert_eq!(deq.front(), Some(&b));
|
assert_eq!((*deq.peek_front()).clone(), b.clone());
|
||||||
assert_eq!(deq.back(), Some(&d));
|
assert_eq!((*deq.peek_back()).clone(), d.clone());
|
||||||
assert_eq!(deq.pop_front(), Some(copy b));
|
assert_eq!(deq.pop_front(), b.clone());
|
||||||
assert_eq!(deq.pop_back(), Some(copy d));
|
assert_eq!(deq.pop_back(), d.clone());
|
||||||
assert_eq!(deq.pop_back(), Some(copy c));
|
assert_eq!(deq.pop_back(), c.clone());
|
||||||
assert_eq!(deq.pop_back(), Some(copy a));
|
assert_eq!(deq.pop_back(), a.clone());
|
||||||
assert_eq!(deq.len(), 0);
|
assert_eq!(deq.len(), 0);
|
||||||
deq.push_back(copy c);
|
deq.add_back(c.clone());
|
||||||
assert_eq!(deq.len(), 1);
|
assert_eq!(deq.len(), 1);
|
||||||
deq.push_front(copy b);
|
deq.add_front(b.clone());
|
||||||
assert_eq!(deq.len(), 2);
|
assert_eq!(deq.len(), 2);
|
||||||
deq.push_back(copy d);
|
deq.add_back(d.clone());
|
||||||
assert_eq!(deq.len(), 3);
|
assert_eq!(deq.len(), 3);
|
||||||
deq.push_front(copy a);
|
deq.add_front(a.clone());
|
||||||
assert_eq!(deq.len(), 4);
|
assert_eq!(deq.len(), 4);
|
||||||
assert_eq!(copy *deq.get(0), copy a);
|
assert_eq!((*deq.get(0)).clone(), a.clone());
|
||||||
assert_eq!(copy *deq.get(1), copy b);
|
assert_eq!((*deq.get(1)).clone(), b.clone());
|
||||||
assert_eq!(copy *deq.get(2), copy c);
|
assert_eq!((*deq.get(2)).clone(), c.clone());
|
||||||
assert_eq!(copy *deq.get(3), copy d);
|
assert_eq!((*deq.get(3)).clone(), d.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -501,15 +501,21 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
enum Taggy { One(int), Two(int, int), Three(int, int, int), }
|
enum Taggy {
|
||||||
|
One(int),
|
||||||
#[deriving(Eq)]
|
Two(int, int),
|
||||||
enum Taggypar<T> {
|
Three(int, int, int),
|
||||||
Onepar(int), Twopar(int, int), Threepar(int, int, int),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
|
enum Taggypar<T> {
|
||||||
|
Onepar(int),
|
||||||
|
Twopar(int, int),
|
||||||
|
Threepar(int, int, int),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone, Eq)]
|
||||||
struct RecCy {
|
struct RecCy {
|
||||||
x: int,
|
x: int,
|
||||||
y: int,
|
y: int,
|
||||||
|
|
|
@ -21,7 +21,7 @@ use std::option::{Option, Some, None};
|
||||||
use std::to_str::ToStr;
|
use std::to_str::ToStr;
|
||||||
use std::uint;
|
use std::uint;
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum Identifier {
|
pub enum Identifier {
|
||||||
Numeric(uint),
|
Numeric(uint),
|
||||||
AlphaNumeric(~str)
|
AlphaNumeric(~str)
|
||||||
|
@ -62,7 +62,7 @@ impl ToStr for Identifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Version {
|
pub struct Version {
|
||||||
major: uint,
|
major: uint,
|
||||||
minor: uint,
|
minor: uint,
|
||||||
|
|
|
@ -219,12 +219,12 @@ impl<V> SmallIntMap<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V:Copy> SmallIntMap<V> {
|
impl<V:Clone> SmallIntMap<V> {
|
||||||
pub fn update_with_key(&mut self, key: uint, val: V,
|
pub fn update_with_key(&mut self, key: uint, val: V,
|
||||||
ff: &fn(uint, V, V) -> V) -> bool {
|
ff: &fn(uint, V, V) -> V) -> bool {
|
||||||
let new_val = match self.find(&key) {
|
let new_val = match self.find(&key) {
|
||||||
None => val,
|
None => val,
|
||||||
Some(orig) => ff(key, copy *orig, val)
|
Some(orig) => ff(key, (*orig).clone(), val)
|
||||||
};
|
};
|
||||||
self.insert(key, new_val)
|
self.insert(key, new_val)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,19 +24,18 @@ type Le<'self, T> = &'self fn(v1: &T, v2: &T) -> bool;
|
||||||
* Has worst case O(n log n) performance, best case O(n), but
|
* Has worst case O(n log n) performance, best case O(n), but
|
||||||
* is not space efficient. This is a stable sort.
|
* is not space efficient. This is a stable sort.
|
||||||
*/
|
*/
|
||||||
pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
|
pub fn merge_sort<T:Copy + Clone>(v: &[T], le: Le<T>) -> ~[T] {
|
||||||
type Slice = (uint, uint);
|
type Slice = (uint, uint);
|
||||||
|
|
||||||
return merge_sort_(v, (0u, v.len()), le);
|
return merge_sort_(v, (0u, v.len()), le);
|
||||||
|
|
||||||
fn merge_sort_<T:Copy>(v: &[T], slice: Slice, le: Le<T>)
|
fn merge_sort_<T:Copy + Clone>(v: &[T], slice: Slice, le: Le<T>) -> ~[T] {
|
||||||
-> ~[T] {
|
|
||||||
let begin = slice.first();
|
let begin = slice.first();
|
||||||
let end = slice.second();
|
let end = slice.second();
|
||||||
|
|
||||||
let v_len = end - begin;
|
let v_len = end - begin;
|
||||||
if v_len == 0 { return ~[]; }
|
if v_len == 0 { return ~[]; }
|
||||||
if v_len == 1 { return ~[copy v[begin]]; }
|
if v_len == 1 { return ~[v[begin].clone()]; }
|
||||||
|
|
||||||
let mid = v_len / 2 + begin;
|
let mid = v_len / 2 + begin;
|
||||||
let a = (begin, mid);
|
let a = (begin, mid);
|
||||||
|
@ -45,7 +44,7 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
|
||||||
merge_sort_(v, b, |x,y| le(x,y)));
|
merge_sort_(v, b, |x,y| le(x,y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge<T:Copy>(le: Le<T>, a: &[T], b: &[T]) -> ~[T] {
|
fn merge<T:Copy + Clone>(le: Le<T>, a: &[T], b: &[T]) -> ~[T] {
|
||||||
let mut rs = vec::with_capacity(a.len() + b.len());
|
let mut rs = vec::with_capacity(a.len() + b.len());
|
||||||
let a_len = a.len();
|
let a_len = a.len();
|
||||||
let mut a_ix = 0;
|
let mut a_ix = 0;
|
||||||
|
@ -53,9 +52,12 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
|
||||||
let mut b_ix = 0;
|
let mut b_ix = 0;
|
||||||
while a_ix < a_len && b_ix < b_len {
|
while a_ix < a_len && b_ix < b_len {
|
||||||
if le(&a[a_ix], &b[b_ix]) {
|
if le(&a[a_ix], &b[b_ix]) {
|
||||||
rs.push(copy a[a_ix]);
|
rs.push(a[a_ix].clone());
|
||||||
a_ix += 1;
|
a_ix += 1;
|
||||||
} else { rs.push(copy b[b_ix]); b_ix += 1; }
|
} else {
|
||||||
|
rs.push(b[b_ix].clone());
|
||||||
|
b_ix += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rs.push_all(a.slice(a_ix, a_len));
|
rs.push_all(a.slice(a_ix, a_len));
|
||||||
rs.push_all(b.slice(b_ix, b_len));
|
rs.push_all(b.slice(b_ix, b_len));
|
||||||
|
@ -104,9 +106,9 @@ pub fn quick_sort<T>(arr: &mut [T], compare_func: Le<T>) {
|
||||||
qsort::<T>(arr, 0u, len - 1u, compare_func);
|
qsort::<T>(arr, 0u, len - 1u, compare_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qsort3<T:Copy + Ord + Eq>(arr: &mut [T], left: int, right: int) {
|
fn qsort3<T:Clone + Ord + Eq>(arr: &mut [T], left: int, right: int) {
|
||||||
if right <= left { return; }
|
if right <= left { return; }
|
||||||
let v: T = copy arr[right];
|
let v: T = arr[right].clone();
|
||||||
let mut i: int = left - 1;
|
let mut i: int = left - 1;
|
||||||
let mut j: int = right;
|
let mut j: int = right;
|
||||||
let mut p: int = i;
|
let mut p: int = i;
|
||||||
|
@ -161,7 +163,7 @@ fn qsort3<T:Copy + Ord + Eq>(arr: &mut [T], left: int, right: int) {
|
||||||
*
|
*
|
||||||
* This is an unstable sort.
|
* This is an unstable sort.
|
||||||
*/
|
*/
|
||||||
pub fn quick_sort3<T:Copy + Ord + Eq>(arr: &mut [T]) {
|
pub fn quick_sort3<T:Clone + Ord + Eq>(arr: &mut [T]) {
|
||||||
if arr.len() <= 1 { return; }
|
if arr.len() <= 1 { return; }
|
||||||
let len = arr.len(); // FIXME(#5074) nested calls
|
let len = arr.len(); // FIXME(#5074) nested calls
|
||||||
qsort3(arr, 0, (len - 1) as int);
|
qsort3(arr, 0, (len - 1) as int);
|
||||||
|
@ -172,7 +174,7 @@ pub trait Sort {
|
||||||
fn qsort(self);
|
fn qsort(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self, T:Copy + Ord + Eq> Sort for &'self mut [T] {
|
impl<'self, T:Clone + Ord + Eq> Sort for &'self mut [T] {
|
||||||
fn qsort(self) { quick_sort3(self); }
|
fn qsort(self) { quick_sort3(self); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +183,7 @@ static MIN_GALLOP: uint = 7;
|
||||||
static INITIAL_TMP_STORAGE: uint = 128;
|
static INITIAL_TMP_STORAGE: uint = 128;
|
||||||
|
|
||||||
#[allow(missing_doc)]
|
#[allow(missing_doc)]
|
||||||
pub fn tim_sort<T:Copy + Ord>(array: &mut [T]) {
|
pub fn tim_sort<T:Copy + Clone + Ord>(array: &mut [T]) {
|
||||||
let size = array.len();
|
let size = array.len();
|
||||||
if size < 2 {
|
if size < 2 {
|
||||||
return;
|
return;
|
||||||
|
@ -225,7 +227,7 @@ pub fn tim_sort<T:Copy + Ord>(array: &mut [T]) {
|
||||||
ms.merge_force_collapse(array);
|
ms.merge_force_collapse(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
|
fn binarysort<T:Copy + Clone + Ord>(array: &mut [T], start: uint) {
|
||||||
let size = array.len();
|
let size = array.len();
|
||||||
let mut start = start;
|
let mut start = start;
|
||||||
assert!(start <= size);
|
assert!(start <= size);
|
||||||
|
@ -233,7 +235,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
|
||||||
if start == 0 { start += 1; }
|
if start == 0 { start += 1; }
|
||||||
|
|
||||||
while start < size {
|
while start < size {
|
||||||
let pivot = copy array[start];
|
let pivot = array[start].clone();
|
||||||
let mut left = 0;
|
let mut left = 0;
|
||||||
let mut right = start;
|
let mut right = start;
|
||||||
assert!(left <= right);
|
assert!(left <= right);
|
||||||
|
@ -275,7 +277,7 @@ fn min_run_length(n: uint) -> uint {
|
||||||
return n + r;
|
return n + r;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count_run_ascending<T:Copy + Ord>(array: &mut [T]) -> uint {
|
fn count_run_ascending<T:Clone + Ord>(array: &mut [T]) -> uint {
|
||||||
let size = array.len();
|
let size = array.len();
|
||||||
assert!(size > 0);
|
assert!(size > 0);
|
||||||
if size == 1 { return 1; }
|
if size == 1 { return 1; }
|
||||||
|
@ -295,7 +297,7 @@ fn count_run_ascending<T:Copy + Ord>(array: &mut [T]) -> uint {
|
||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gallop_left<T:Copy + Ord>(key: &T,
|
fn gallop_left<T:Clone + Ord>(key: &T,
|
||||||
array: &[T],
|
array: &[T],
|
||||||
hint: uint)
|
hint: uint)
|
||||||
-> uint {
|
-> uint {
|
||||||
|
@ -346,7 +348,7 @@ fn gallop_left<T:Copy + Ord>(key: &T,
|
||||||
return ofs;
|
return ofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gallop_right<T:Copy + Ord>(key: &T,
|
fn gallop_right<T:Clone + Ord>(key: &T,
|
||||||
array: &[T],
|
array: &[T],
|
||||||
hint: uint)
|
hint: uint)
|
||||||
-> uint {
|
-> uint {
|
||||||
|
@ -417,7 +419,7 @@ fn MergeState<T>() -> MergeState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Copy + Ord> MergeState<T> {
|
impl<T:Copy + Clone + Ord> MergeState<T> {
|
||||||
fn push_run(&mut self, run_base: uint, run_len: uint) {
|
fn push_run(&mut self, run_base: uint, run_len: uint) {
|
||||||
let tmp = RunState{base: run_base, len: run_len};
|
let tmp = RunState{base: run_base, len: run_len};
|
||||||
self.runs.push(tmp);
|
self.runs.push(tmp);
|
||||||
|
@ -470,7 +472,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
||||||
|
|
||||||
let mut tmp = ~[];
|
let mut tmp = ~[];
|
||||||
for uint::range(base1, base1+len1) |i| {
|
for uint::range(base1, base1+len1) |i| {
|
||||||
tmp.push(copy array[i]);
|
tmp.push(array[i].clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut c1 = 0;
|
let mut c1 = 0;
|
||||||
|
@ -580,7 +582,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
||||||
|
|
||||||
let mut tmp = ~[];
|
let mut tmp = ~[];
|
||||||
for uint::range(base2, base2+len2) |i| {
|
for uint::range(base2, base2+len2) |i| {
|
||||||
tmp.push(copy array[i]);
|
tmp.push(array[i].clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut c1 = base1 + len1 - 1;
|
let mut c1 = base1 + len1 - 1;
|
||||||
|
@ -726,21 +728,21 @@ impl<T:Copy + Ord> MergeState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_vec<T:Copy>(dest: &mut [T],
|
fn copy_vec<T:Clone>(dest: &mut [T],
|
||||||
s1: uint,
|
s1: uint,
|
||||||
from: &[T]) {
|
from: &[T]) {
|
||||||
assert!(s1+from.len() <= dest.len());
|
assert!(s1+from.len() <= dest.len());
|
||||||
|
|
||||||
for from.iter().enumerate().advance |(i, v)| {
|
for from.iter().enumerate().advance |(i, v)| {
|
||||||
dest[s1+i] = copy *v;
|
dest[s1+i] = (*v).clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn shift_vec<T:Copy>(dest: &mut [T],
|
fn shift_vec<T:Copy + Clone>(dest: &mut [T],
|
||||||
s1: uint,
|
s1: uint,
|
||||||
s2: uint,
|
s2: uint,
|
||||||
len: uint) {
|
len: uint) {
|
||||||
assert!(s1+len <= dest.len());
|
assert!(s1+len <= dest.len());
|
||||||
|
|
||||||
let tmp = dest.slice(s2, s2+len).to_owned();
|
let tmp = dest.slice(s2, s2+len).to_owned();
|
||||||
|
@ -902,7 +904,7 @@ mod tests {
|
||||||
fn ile(x: &(&'static str), y: &(&'static str)) -> bool
|
fn ile(x: &(&'static str), y: &(&'static str)) -> bool
|
||||||
{
|
{
|
||||||
// FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
|
// FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
|
||||||
// to_ascii_consume and to_str_consume to not do a unnecessary copy.
|
// to_ascii_consume and to_str_consume to not do a unnecessary clone.
|
||||||
// (Actually, could just remove the to_str_* call, but needs an deriving(Ord) on
|
// (Actually, could just remove the to_str_* call, but needs an deriving(Ord) on
|
||||||
// Ascii)
|
// Ascii)
|
||||||
let x = x.to_ascii().to_lower().to_str_ascii();
|
let x = x.to_ascii().to_lower().to_str_ascii();
|
||||||
|
@ -1038,17 +1040,17 @@ mod big_tests {
|
||||||
tabulate_managed(low, high);
|
tabulate_managed(low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn multiplyVec<T:Copy>(arr: &[T], num: uint) -> ~[T] {
|
fn multiplyVec<T:Clone>(arr: &[T], num: uint) -> ~[T] {
|
||||||
let size = arr.len();
|
let size = arr.len();
|
||||||
let res = do vec::from_fn(num) |i| {
|
let res = do vec::from_fn(num) |i| {
|
||||||
copy arr[i % size]
|
arr[i % size].clone()
|
||||||
};
|
};
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn makeRange(n: uint) -> ~[uint] {
|
fn makeRange(n: uint) -> ~[uint] {
|
||||||
let one = do vec::from_fn(n) |i| { i };
|
let one = do vec::from_fn(n) |i| { i };
|
||||||
let mut two = copy one;
|
let mut two = one.clone();
|
||||||
two.reverse();
|
two.reverse();
|
||||||
vec::append(two, one)
|
vec::append(two, one)
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ pub trait Stats {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracted collection of all the summary statistics of a sample set.
|
/// Extracted collection of all the summary statistics of a sample set.
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
struct Summary {
|
struct Summary {
|
||||||
sum: f64,
|
sum: f64,
|
||||||
min: f64,
|
min: f64,
|
||||||
|
|
|
@ -39,6 +39,7 @@ enum FormatState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Types of parameters a capability can use
|
/// Types of parameters a capability can use
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum Param {
|
pub enum Param {
|
||||||
String(~str),
|
String(~str),
|
||||||
Number(int)
|
Number(int)
|
||||||
|
@ -82,7 +83,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
||||||
// Copy parameters into a local vector for mutability
|
// Copy parameters into a local vector for mutability
|
||||||
let mut mparams = [Number(0), ..9];
|
let mut mparams = [Number(0), ..9];
|
||||||
for mparams.mut_iter().zip(params.iter()).advance |(dst, src)| {
|
for mparams.mut_iter().zip(params.iter()).advance |(dst, src)| {
|
||||||
*dst = copy *src;
|
*dst = (*src).clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
for cap.iter().transform(|&x| x).advance |c| {
|
for cap.iter().transform(|&x| x).advance |c| {
|
||||||
|
@ -214,7 +215,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
||||||
_ => return Err(~"non-number on stack with %~")
|
_ => return Err(~"non-number on stack with %~")
|
||||||
}
|
}
|
||||||
} else { return Err(~"stack is empty") },
|
} else { return Err(~"stack is empty") },
|
||||||
'i' => match (copy mparams[0], copy mparams[1]) {
|
'i' => match (mparams[0].clone(), mparams[1].clone()) {
|
||||||
(Number(x), Number(y)) => {
|
(Number(x), Number(y)) => {
|
||||||
mparams[0] = Number(x+1);
|
mparams[0] = Number(x+1);
|
||||||
mparams[1] = Number(y+1);
|
mparams[1] = Number(y+1);
|
||||||
|
@ -263,10 +264,10 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
||||||
},
|
},
|
||||||
PushParam => {
|
PushParam => {
|
||||||
// params are 1-indexed
|
// params are 1-indexed
|
||||||
stack.push(copy mparams[match char::to_digit(cur, 10) {
|
stack.push(mparams[match char::to_digit(cur, 10) {
|
||||||
Some(d) => d - 1,
|
Some(d) => d - 1,
|
||||||
None => return Err(~"bad param number")
|
None => return Err(~"bad param number")
|
||||||
}]);
|
}].clone());
|
||||||
},
|
},
|
||||||
SetVar => {
|
SetVar => {
|
||||||
if cur >= 'A' && cur <= 'Z' {
|
if cur >= 'A' && cur <= 'Z' {
|
||||||
|
@ -286,10 +287,10 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
|
||||||
GetVar => {
|
GetVar => {
|
||||||
if cur >= 'A' && cur <= 'Z' {
|
if cur >= 'A' && cur <= 'Z' {
|
||||||
let idx = (cur as u8) - ('A' as u8);
|
let idx = (cur as u8) - ('A' as u8);
|
||||||
stack.push(copy vars.sta[idx]);
|
stack.push(vars.sta[idx].clone());
|
||||||
} else if cur >= 'a' && cur <= 'z' {
|
} else if cur >= 'a' && cur <= 'z' {
|
||||||
let idx = (cur as u8) - ('a' as u8);
|
let idx = (cur as u8) - ('a' as u8);
|
||||||
stack.push(copy vars.dyn[idx]);
|
stack.push(vars.dyn[idx].clone());
|
||||||
} else {
|
} else {
|
||||||
return Err(~"bad variable name in %g");
|
return Err(~"bad variable name in %g");
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,13 +44,14 @@ use std::os;
|
||||||
// colons. This way if some test runner wants to arrange the tests
|
// colons. This way if some test runner wants to arrange the tests
|
||||||
// hierarchically it may.
|
// hierarchically it may.
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum TestName {
|
pub enum TestName {
|
||||||
StaticTestName(&'static str),
|
StaticTestName(&'static str),
|
||||||
DynTestName(~str)
|
DynTestName(~str)
|
||||||
}
|
}
|
||||||
impl ToStr for TestName {
|
impl ToStr for TestName {
|
||||||
fn to_str(&self) -> ~str {
|
fn to_str(&self) -> ~str {
|
||||||
match copy *self {
|
match (*self).clone() {
|
||||||
StaticTestName(s) => s.to_str(),
|
StaticTestName(s) => s.to_str(),
|
||||||
DynTestName(s) => s.to_str()
|
DynTestName(s) => s.to_str()
|
||||||
}
|
}
|
||||||
|
@ -80,6 +81,7 @@ pub struct BenchHarness {
|
||||||
|
|
||||||
// The definition of a single test. A test runner will run a list of
|
// The definition of a single test. A test runner will run a list of
|
||||||
// these.
|
// these.
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct TestDesc {
|
pub struct TestDesc {
|
||||||
name: TestName,
|
name: TestName,
|
||||||
ignore: bool,
|
ignore: bool,
|
||||||
|
@ -134,10 +136,10 @@ pub fn test_main_static(args: &[~str], tests: &[TestDescAndFn]) {
|
||||||
let owned_tests = do tests.map |t| {
|
let owned_tests = do tests.map |t| {
|
||||||
match t.testfn {
|
match t.testfn {
|
||||||
StaticTestFn(f) =>
|
StaticTestFn(f) =>
|
||||||
TestDescAndFn { testfn: StaticTestFn(f), desc: copy t.desc },
|
TestDescAndFn { testfn: StaticTestFn(f), desc: t.desc.clone() },
|
||||||
|
|
||||||
StaticBenchFn(f) =>
|
StaticBenchFn(f) =>
|
||||||
TestDescAndFn { testfn: StaticBenchFn(f), desc: copy t.desc },
|
TestDescAndFn { testfn: StaticBenchFn(f), desc: t.desc.clone() },
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
fail!("non-static tests passed to test::test_main_static");
|
fail!("non-static tests passed to test::test_main_static");
|
||||||
|
@ -178,8 +180,10 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
|
||||||
|
|
||||||
let filter =
|
let filter =
|
||||||
if matches.free.len() > 0 {
|
if matches.free.len() > 0 {
|
||||||
Some(copy (matches).free[0])
|
Some((matches).free[0].clone())
|
||||||
} else { None };
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let run_ignored = getopts::opt_present(&matches, "ignored");
|
let run_ignored = getopts::opt_present(&matches, "ignored");
|
||||||
|
|
||||||
|
@ -214,19 +218,19 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
|
||||||
either::Left(test_opts)
|
either::Left(test_opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct BenchSamples {
|
pub struct BenchSamples {
|
||||||
ns_iter_summ: stats::Summary,
|
ns_iter_summ: stats::Summary,
|
||||||
mb_s: uint
|
mb_s: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum TestResult {
|
pub enum TestResult {
|
||||||
TrOk,
|
TrOk,
|
||||||
TrFailed,
|
TrFailed,
|
||||||
TrIgnored,
|
TrIgnored,
|
||||||
TrMetrics(MetricMap),
|
TrMetrics(MetricMap),
|
||||||
TrBench(BenchSamples)
|
TrBench(BenchSamples),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConsoleTestState {
|
struct ConsoleTestState {
|
||||||
|
@ -500,7 +504,7 @@ pub fn run_tests_console(opts: &TestOpts,
|
||||||
tests: ~[TestDescAndFn]) -> bool {
|
tests: ~[TestDescAndFn]) -> bool {
|
||||||
fn callback(event: &TestEvent, st: &mut ConsoleTestState) {
|
fn callback(event: &TestEvent, st: &mut ConsoleTestState) {
|
||||||
debug!("callback(event=%?)", event);
|
debug!("callback(event=%?)", event);
|
||||||
match copy *event {
|
match (*event).clone() {
|
||||||
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
|
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
|
||||||
TeWait(ref test) => st.write_test_start(test),
|
TeWait(ref test) => st.write_test_start(test),
|
||||||
TeResult(test, result) => {
|
TeResult(test, result) => {
|
||||||
|
@ -584,6 +588,7 @@ fn should_sort_failures_before_printing_them() {
|
||||||
|
|
||||||
fn use_color() -> bool { return get_concurrency() == 1; }
|
fn use_color() -> bool { return get_concurrency() == 1; }
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
enum TestEvent {
|
enum TestEvent {
|
||||||
TeFiltered(~[TestDesc]),
|
TeFiltered(~[TestDesc]),
|
||||||
TeWait(TestDesc),
|
TeWait(TestDesc),
|
||||||
|
@ -597,7 +602,7 @@ fn run_tests(opts: &TestOpts,
|
||||||
callback: &fn(e: TestEvent)) {
|
callback: &fn(e: TestEvent)) {
|
||||||
|
|
||||||
let filtered_tests = filter_tests(opts, tests);
|
let filtered_tests = filter_tests(opts, tests);
|
||||||
let filtered_descs = filtered_tests.map(|t| copy t.desc);
|
let filtered_descs = filtered_tests.map(|t| t.desc.clone());
|
||||||
|
|
||||||
callback(TeFiltered(filtered_descs));
|
callback(TeFiltered(filtered_descs));
|
||||||
|
|
||||||
|
@ -628,7 +633,7 @@ fn run_tests(opts: &TestOpts,
|
||||||
// We are doing one test at a time so we can print the name
|
// We are doing one test at a time so we can print the name
|
||||||
// of the test before we run it. Useful for debugging tests
|
// of the test before we run it. Useful for debugging tests
|
||||||
// that hang forever.
|
// that hang forever.
|
||||||
callback(TeWait(copy test.desc));
|
callback(TeWait(test.desc.clone()));
|
||||||
}
|
}
|
||||||
run_test(!opts.run_tests, test, ch.clone());
|
run_test(!opts.run_tests, test, ch.clone());
|
||||||
pending += 1;
|
pending += 1;
|
||||||
|
@ -636,7 +641,7 @@ fn run_tests(opts: &TestOpts,
|
||||||
|
|
||||||
let (desc, result) = p.recv();
|
let (desc, result) = p.recv();
|
||||||
if concurrency != 1 {
|
if concurrency != 1 {
|
||||||
callback(TeWait(copy desc));
|
callback(TeWait(desc.clone()));
|
||||||
}
|
}
|
||||||
callback(TeResult(desc, result));
|
callback(TeResult(desc, result));
|
||||||
pending -= 1;
|
pending -= 1;
|
||||||
|
@ -645,7 +650,7 @@ fn run_tests(opts: &TestOpts,
|
||||||
// All benchmarks run at the end, in serial.
|
// All benchmarks run at the end, in serial.
|
||||||
// (this includes metric fns)
|
// (this includes metric fns)
|
||||||
for filtered_benchs_and_metrics.consume_iter().advance |b| {
|
for filtered_benchs_and_metrics.consume_iter().advance |b| {
|
||||||
callback(TeWait(copy b.desc));
|
callback(TeWait(b.desc.clone()));
|
||||||
run_test(!opts.run_benchmarks, b, ch.clone());
|
run_test(!opts.run_benchmarks, b, ch.clone());
|
||||||
let (test, result) = p.recv();
|
let (test, result) = p.recv();
|
||||||
callback(TeResult(test, result));
|
callback(TeResult(test, result));
|
||||||
|
@ -678,7 +683,7 @@ pub fn filter_tests(
|
||||||
filtered
|
filtered
|
||||||
} else {
|
} else {
|
||||||
let filter_str = match opts.filter {
|
let filter_str = match opts.filter {
|
||||||
Some(ref f) => copy *f,
|
Some(ref f) => (*f).clone(),
|
||||||
None => ~""
|
None => ~""
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -752,7 +757,7 @@ pub fn run_test(force_ignore: bool,
|
||||||
let task_result = result_future.unwrap().recv();
|
let task_result = result_future.unwrap().recv();
|
||||||
let test_result = calc_result(&desc,
|
let test_result = calc_result(&desc,
|
||||||
task_result == task::Success);
|
task_result == task::Success);
|
||||||
monitor_ch.send((copy desc, test_result));
|
monitor_ch.send((desc.clone(), test_result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,14 +818,14 @@ impl MetricMap {
|
||||||
/// Load MetricDiff from a file.
|
/// Load MetricDiff from a file.
|
||||||
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).get();
|
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).get());
|
||||||
MetricMap(Decodable::decode(&mut decoder))
|
MetricMap(Decodable::decode(&mut decoder))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write MetricDiff to a file.
|
/// Write MetricDiff to a file.
|
||||||
pub fn save(&self, p: &Path) {
|
pub fn save(&self, p: &Path) {
|
||||||
let f = io::file_writer(p, [io::Create, io::Truncate]).get();
|
let f = io::file_writer(p, [io::Create, io::Truncate]).unwrap();
|
||||||
json::to_pretty_writer(f, &self.to_json());
|
json::to_pretty_writer(f, &self.to_json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,11 +873,11 @@ impl MetricMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
diff.insert(copy *k, r);
|
diff.insert((*k).clone(), r);
|
||||||
}
|
}
|
||||||
for self.iter().advance |(k, _)| {
|
for self.iter().advance |(k, _)| {
|
||||||
if !diff.contains_key(k) {
|
if !diff.contains_key(k) {
|
||||||
diff.insert(copy *k, MetricAdded);
|
diff.insert((*k).clone(), MetricAdded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff
|
diff
|
||||||
|
@ -1153,7 +1158,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" == (copy opts.filter).get());
|
assert!("filter" == opts.filter.clone().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1236,11 +1241,11 @@ mod tests {
|
||||||
for names.iter().advance |name| {
|
for names.iter().advance |name| {
|
||||||
let test = TestDescAndFn {
|
let test = TestDescAndFn {
|
||||||
desc: TestDesc {
|
desc: TestDesc {
|
||||||
name: DynTestName(copy *name),
|
name: DynTestName((*name).clone()),
|
||||||
ignore: false,
|
ignore: false,
|
||||||
should_fail: false
|
should_fail: false
|
||||||
},
|
},
|
||||||
testfn: DynTestFn(copy testfn),
|
testfn: DynTestFn(testfn.clone()),
|
||||||
};
|
};
|
||||||
tests.push(test);
|
tests.push(test);
|
||||||
}
|
}
|
||||||
|
|
|
@ -683,7 +683,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
tm_yday: tm.tm_yday,
|
tm_yday: tm.tm_yday,
|
||||||
tm_isdst: tm.tm_isdst,
|
tm_isdst: tm.tm_isdst,
|
||||||
tm_gmtoff: tm.tm_gmtoff,
|
tm_gmtoff: tm.tm_gmtoff,
|
||||||
tm_zone: copy tm.tm_zone,
|
tm_zone: tm.tm_zone.clone(),
|
||||||
tm_nsec: tm.tm_nsec,
|
tm_nsec: tm.tm_nsec,
|
||||||
})
|
})
|
||||||
} else { result }
|
} else { result }
|
||||||
|
@ -829,7 +829,7 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str {
|
||||||
//'x' {}
|
//'x' {}
|
||||||
'Y' => int::to_str(tm.tm_year as int + 1900),
|
'Y' => int::to_str(tm.tm_year as int + 1900),
|
||||||
'y' => fmt!("%02d", (tm.tm_year as int + 1900) % 100),
|
'y' => fmt!("%02d", (tm.tm_year as int + 1900) % 100),
|
||||||
'Z' => copy tm.tm_zone,
|
'Z' => tm.tm_zone.clone(),
|
||||||
'z' => {
|
'z' => {
|
||||||
let sign = if tm.tm_gmtoff > 0_i32 { '+' } else { '-' };
|
let sign = if tm.tm_gmtoff > 0_i32 { '+' } else { '-' };
|
||||||
let mut m = num::abs(tm.tm_gmtoff) / 60_i32;
|
let mut m = num::abs(tm.tm_gmtoff) / 60_i32;
|
||||||
|
|
|
@ -791,8 +791,8 @@ mod test_treemap {
|
||||||
let v1 = "baz".as_bytes();
|
let v1 = "baz".as_bytes();
|
||||||
let v2 = "foobar".as_bytes();
|
let v2 = "foobar".as_bytes();
|
||||||
|
|
||||||
m.insert(copy k1, copy v1);
|
m.insert(k1.clone(), v1.clone());
|
||||||
m.insert(copy k2, copy v2);
|
m.insert(k2.clone(), v2.clone());
|
||||||
|
|
||||||
assert_eq!(m.find(&k2), Some(&v2));
|
assert_eq!(m.find(&k2), Some(&v2));
|
||||||
assert_eq!(m.find(&k1), Some(&v1));
|
assert_eq!(m.find(&k1), Some(&v1));
|
||||||
|
|
|
@ -1476,7 +1476,7 @@ mod test {
|
||||||
let client_data = get_data_for_uv_handle(
|
let client_data = get_data_for_uv_handle(
|
||||||
client_stream_ptr as *libc::c_void) as *tcp_server_data;
|
client_stream_ptr as *libc::c_void) as *tcp_server_data;
|
||||||
|
|
||||||
let server_kill_msg = copy (*client_data).server_kill_msg;
|
let server_kill_msg = (*client_data).server_kill_msg.clone();
|
||||||
let write_req = (*client_data).server_write_req;
|
let write_req = (*client_data).server_write_req;
|
||||||
if request_str.contains(server_kill_msg) {
|
if request_str.contains(server_kill_msg) {
|
||||||
debug!(~"SERVER: client req contains kill_msg!");
|
debug!(~"SERVER: client req contains kill_msg!");
|
||||||
|
@ -1726,12 +1726,12 @@ mod test {
|
||||||
let (continue_port, continue_chan) = stream::<bool>();
|
let (continue_port, continue_chan) = stream::<bool>();
|
||||||
let continue_chan = SharedChan::new(continue_chan);
|
let continue_chan = SharedChan::new(continue_chan);
|
||||||
|
|
||||||
let kill_server_msg_copy = copy kill_server_msg;
|
let kill_server_msg_copy = kill_server_msg.clone();
|
||||||
let server_resp_msg_copy = copy server_resp_msg;
|
let server_resp_msg_copy = server_resp_msg.clone();
|
||||||
do task::spawn_sched(task::ManualThreads(1)) {
|
do task::spawn_sched(task::ManualThreads(1)) {
|
||||||
impl_uv_tcp_server(bind_ip, port,
|
impl_uv_tcp_server(bind_ip, port,
|
||||||
copy kill_server_msg_copy,
|
kill_server_msg_copy.clone(),
|
||||||
copy server_resp_msg_copy,
|
server_resp_msg_copy.clone(),
|
||||||
server_chan.clone(),
|
server_chan.clone(),
|
||||||
continue_chan.clone());
|
continue_chan.clone());
|
||||||
};
|
};
|
||||||
|
@ -1741,7 +1741,7 @@ mod test {
|
||||||
continue_port.recv();
|
continue_port.recv();
|
||||||
debug!(~"received on continue port, set up tcp client");
|
debug!(~"received on continue port, set up tcp client");
|
||||||
|
|
||||||
let kill_server_msg_copy = copy kill_server_msg;
|
let kill_server_msg_copy = kill_server_msg.clone();
|
||||||
do task::spawn_sched(task::ManualThreads(1u)) {
|
do task::spawn_sched(task::ManualThreads(1u)) {
|
||||||
impl_uv_tcp_request(request_ip, port,
|
impl_uv_tcp_request(request_ip, port,
|
||||||
kill_server_msg_copy,
|
kill_server_msg_copy,
|
||||||
|
|
|
@ -97,7 +97,7 @@ use std::util::replace;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[deriving(Eq, Encodable, Decodable)]
|
#[deriving(Clone, Eq, Encodable, Decodable)]
|
||||||
struct WorkKey {
|
struct WorkKey {
|
||||||
kind: ~str,
|
kind: ~str,
|
||||||
name: ~str
|
name: ~str
|
||||||
|
@ -138,6 +138,12 @@ impl WorkKey {
|
||||||
|
|
||||||
struct WorkMap(HashMap<WorkKey, ~str>);
|
struct WorkMap(HashMap<WorkKey, ~str>);
|
||||||
|
|
||||||
|
impl Clone for WorkMap {
|
||||||
|
fn clone(&self) -> WorkMap {
|
||||||
|
WorkMap((**self).clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl WorkMap {
|
impl WorkMap {
|
||||||
fn new() -> WorkMap { WorkMap(HashMap::new()) }
|
fn new() -> WorkMap { WorkMap(HashMap::new()) }
|
||||||
}
|
}
|
||||||
|
@ -146,7 +152,7 @@ impl<S:Encoder> Encodable<S> for WorkMap {
|
||||||
fn encode(&self, s: &mut S) {
|
fn encode(&self, s: &mut S) {
|
||||||
let mut d = ~[];
|
let mut d = ~[];
|
||||||
for self.iter().advance |(k, v)| {
|
for self.iter().advance |(k, v)| {
|
||||||
d.push((copy *k, copy *v))
|
d.push(((*k).clone(), (*v).clone()))
|
||||||
}
|
}
|
||||||
sort::tim_sort(d);
|
sort::tim_sort(d);
|
||||||
d.encode(s)
|
d.encode(s)
|
||||||
|
@ -215,6 +221,7 @@ struct Context {
|
||||||
freshness: HashMap<~str,@fn(&str,&str)->bool>
|
freshness: HashMap<~str,@fn(&str,&str)->bool>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
struct Prep {
|
struct Prep {
|
||||||
ctxt: @Context,
|
ctxt: @Context,
|
||||||
fn_name: ~str,
|
fn_name: ~str,
|
||||||
|
@ -341,7 +348,7 @@ impl TPrep for Prep {
|
||||||
&self.declared_inputs) &&
|
&self.declared_inputs) &&
|
||||||
self.all_fresh("discovered input", disc_in) &&
|
self.all_fresh("discovered input", disc_in) &&
|
||||||
self.all_fresh("discovered output", disc_out) => {
|
self.all_fresh("discovered output", disc_out) => {
|
||||||
Work::new(@mut copy *self, Left(json_decode(*res)))
|
Work::new(@mut (*self).clone(), Left(json_decode(*res)))
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -358,7 +365,7 @@ impl TPrep for Prep {
|
||||||
let v = blk(&exe);
|
let v = blk(&exe);
|
||||||
send_one(chan, (exe, v));
|
send_one(chan, (exe, v));
|
||||||
}
|
}
|
||||||
Work::new(@mut copy *self, Right(port))
|
Work::new(@mut (*self).clone(), Right(port))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,7 +420,7 @@ fn test() {
|
||||||
let w:Work<~str> = do cx.prep("test1") |prep| {
|
let w:Work<~str> = do cx.prep("test1") |prep| {
|
||||||
let pth = Path("foo.c");
|
let pth = Path("foo.c");
|
||||||
{
|
{
|
||||||
let file = io::file_writer(&pth, [io::Create]).get();
|
let file = io::file_writer(&pth, [io::Create]).unwrap();
|
||||||
file.write_str("int main() { return 0; }");
|
file.write_str("int main() { return 0; }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ static COMMANDS: &'static [Command<'static>] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
fn rustc_help() {
|
fn rustc_help() {
|
||||||
rustc::usage(copy os::args()[0])
|
rustc::usage(os::args()[0].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_cmd(command_string: &str) -> Option<Command> {
|
fn find_cmd(command_string: &str) -> Option<Command> {
|
||||||
|
@ -148,7 +148,7 @@ fn cmd_help(args: &[~str]) -> ValidUsage {
|
||||||
}
|
}
|
||||||
|
|
||||||
match args {
|
match args {
|
||||||
[ref command_string] => print_usage(copy *command_string),
|
[ref command_string] => print_usage((*command_string).clone()),
|
||||||
_ => Invalid
|
_ => Invalid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ use syntax::attr;
|
||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum output_type {
|
pub enum output_type {
|
||||||
output_type_none,
|
output_type_none,
|
||||||
output_type_bitcode,
|
output_type_bitcode,
|
||||||
|
@ -291,7 +291,7 @@ pub mod write {
|
||||||
}
|
}
|
||||||
|
|
||||||
let passes = if sess.opts.custom_passes.len() > 0 {
|
let passes = if sess.opts.custom_passes.len() > 0 {
|
||||||
copy sess.opts.custom_passes
|
sess.opts.custom_passes.clone()
|
||||||
} else {
|
} else {
|
||||||
if sess.lint_llvm() {
|
if sess.lint_llvm() {
|
||||||
mpm.add_pass_from_name("lint");
|
mpm.add_pass_from_name("lint");
|
||||||
|
@ -817,7 +817,7 @@ pub fn link_binary(sess: Session,
|
||||||
// For win32, there is no cc command,
|
// For win32, there is no cc command,
|
||||||
// so we add a condition to make it use gcc.
|
// so we add a condition to make it use gcc.
|
||||||
let cc_prog: ~str = match sess.opts.linker {
|
let cc_prog: ~str = match sess.opts.linker {
|
||||||
Some(ref linker) => copy *linker,
|
Some(ref linker) => linker.to_str(),
|
||||||
None => match sess.targ_cfg.os {
|
None => match sess.targ_cfg.os {
|
||||||
session::os_android =>
|
session::os_android =>
|
||||||
match &sess.opts.android_cross_path {
|
match &sess.opts.android_cross_path {
|
||||||
|
@ -845,7 +845,7 @@ pub fn link_binary(sess: Session,
|
||||||
|
|
||||||
out_filename.dir_path().push(long_libname)
|
out_filename.dir_path().push(long_libname)
|
||||||
} else {
|
} else {
|
||||||
/*bad*/copy *out_filename
|
out_filename.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("output: %s", output.to_str());
|
debug!("output: %s", output.to_str());
|
||||||
|
@ -896,7 +896,7 @@ pub fn link_args(sess: Session,
|
||||||
let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
|
let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
|
||||||
out_filename.dir_path().push(long_libname)
|
out_filename.dir_path().push(long_libname)
|
||||||
} else {
|
} else {
|
||||||
/*bad*/copy *out_filename
|
out_filename.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
// The default library location, we need this to find the runtime.
|
// The default library location, we need this to find the runtime.
|
||||||
|
|
|
@ -185,7 +185,7 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
|
||||||
let mut minimized = ~[];
|
let mut minimized = ~[];
|
||||||
for rpaths.iter().advance |rpath| {
|
for rpaths.iter().advance |rpath| {
|
||||||
if set.insert(rpath.to_str()) {
|
if set.insert(rpath.to_str()) {
|
||||||
minimized.push(copy *rpath);
|
minimized.push(rpath.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
minimized
|
minimized
|
||||||
|
|
|
@ -109,10 +109,14 @@ pub fn build_configuration(sess: Session, argv0: @str, input: &input) ->
|
||||||
// Combine the configuration requested by the session (command line) with
|
// Combine the configuration requested by the session (command line) with
|
||||||
// some default and generated configuration items
|
// some default and generated configuration items
|
||||||
let default_cfg = default_configuration(sess, argv0, input);
|
let default_cfg = default_configuration(sess, argv0, input);
|
||||||
let user_cfg = /*bad*/copy sess.opts.cfg;
|
let user_cfg = sess.opts.cfg.clone();
|
||||||
// If the user wants a test runner, then add the test cfg
|
// If the user wants a test runner, then add the test cfg
|
||||||
let user_cfg = if sess.opts.test { append_configuration(user_cfg, @"test") }
|
let user_cfg = if sess.opts.test {
|
||||||
else { user_cfg };
|
append_configuration(user_cfg, @"test")
|
||||||
|
} else {
|
||||||
|
user_cfg
|
||||||
|
};
|
||||||
|
|
||||||
// If the user requested GC, then add the GC cfg
|
// If the user requested GC, then add the GC cfg
|
||||||
let user_cfg = append_configuration(
|
let user_cfg = append_configuration(
|
||||||
user_cfg,
|
user_cfg,
|
||||||
|
@ -202,7 +206,8 @@ pub fn compile_rest(sess: Session,
|
||||||
front::config::strip_unconfigured_items(crate));
|
front::config::strip_unconfigured_items(crate));
|
||||||
|
|
||||||
crate = time(time_passes, ~"expansion", ||
|
crate = time(time_passes, ~"expansion", ||
|
||||||
syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg,
|
syntax::ext::expand::expand_crate(sess.parse_sess,
|
||||||
|
cfg.clone(),
|
||||||
crate));
|
crate));
|
||||||
|
|
||||||
// strip again, in case expansion added anything with a #[cfg].
|
// strip again, in case expansion added anything with a #[cfg].
|
||||||
|
@ -213,7 +218,9 @@ pub fn compile_rest(sess: Session,
|
||||||
front::test::modify_for_testing(sess, crate));
|
front::test::modify_for_testing(sess, crate));
|
||||||
}
|
}
|
||||||
|
|
||||||
if phases.to == cu_expand { return (Some(crate), None); }
|
if phases.to == cu_expand {
|
||||||
|
return (Some(crate), None);
|
||||||
|
}
|
||||||
|
|
||||||
assert!(phases.from != cu_no_trans);
|
assert!(phases.from != cu_no_trans);
|
||||||
|
|
||||||
|
@ -371,17 +378,28 @@ pub fn compile_rest(sess: Session,
|
||||||
return (None, None);
|
return (None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_upto(sess: Session, cfg: ast::crate_cfg,
|
pub fn compile_upto(sess: Session,
|
||||||
input: &input, upto: compile_phase,
|
cfg: ast::crate_cfg,
|
||||||
outputs: Option<@OutputFilenames>)
|
input: &input,
|
||||||
-> (Option<@ast::crate>, Option<ty::ctxt>) {
|
upto: compile_phase,
|
||||||
|
outputs: Option<@OutputFilenames>)
|
||||||
|
-> (Option<@ast::crate>, Option<ty::ctxt>) {
|
||||||
let time_passes = sess.time_passes();
|
let time_passes = sess.time_passes();
|
||||||
let crate = time(time_passes, ~"parsing",
|
let crate = time(time_passes,
|
||||||
|| parse_input(sess, copy cfg, input) );
|
~"parsing",
|
||||||
if upto == cu_parse { return (Some(crate), None); }
|
|| parse_input(sess, cfg.clone(), input) );
|
||||||
|
if upto == cu_parse {
|
||||||
|
return (Some(crate), None);
|
||||||
|
}
|
||||||
|
|
||||||
compile_rest(sess, cfg, compile_upto { from: cu_parse, to: upto },
|
compile_rest(sess,
|
||||||
outputs, Some(crate))
|
cfg,
|
||||||
|
compile_upto {
|
||||||
|
from: cu_parse,
|
||||||
|
to: upto
|
||||||
|
},
|
||||||
|
outputs,
|
||||||
|
Some(crate))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_input(sess: Session, cfg: ast::crate_cfg, input: &input,
|
pub fn compile_input(sess: Session, cfg: ast::crate_cfg, input: &input,
|
||||||
|
@ -877,7 +895,7 @@ pub fn build_output_filenames(input: &input,
|
||||||
// have to make up a name
|
// have to make up a name
|
||||||
// We want to toss everything after the final '.'
|
// We want to toss everything after the final '.'
|
||||||
let dirpath = match *odir {
|
let dirpath = match *odir {
|
||||||
Some(ref d) => (/*bad*/copy *d),
|
Some(ref d) => (*d).clone(),
|
||||||
None => match *input {
|
None => match *input {
|
||||||
str_input(_) => os::getcwd(),
|
str_input(_) => os::getcwd(),
|
||||||
file_input(ref ifile) => (*ifile).dir_path()
|
file_input(ref ifile) => (*ifile).dir_path()
|
||||||
|
@ -914,9 +932,9 @@ pub fn build_output_filenames(input: &input,
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ref out_file) => {
|
Some(ref out_file) => {
|
||||||
out_path = (/*bad*/copy *out_file);
|
out_path = (*out_file).clone();
|
||||||
obj_path = if stop_after_codegen {
|
obj_path = if stop_after_codegen {
|
||||||
(/*bad*/copy *out_file)
|
(*out_file).clone()
|
||||||
} else {
|
} else {
|
||||||
(*out_file).with_filetype(obj_suffix)
|
(*out_file).with_filetype(obj_suffix)
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,7 +33,12 @@ use std::hashmap::HashMap;
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
pub enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, }
|
pub enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, }
|
||||||
|
|
||||||
pub enum crate_type { bin_crate, lib_crate, unknown_crate, }
|
#[deriving(Clone)]
|
||||||
|
pub enum crate_type {
|
||||||
|
bin_crate,
|
||||||
|
lib_crate,
|
||||||
|
unknown_crate,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct config {
|
pub struct config {
|
||||||
os: os,
|
os: os,
|
||||||
|
@ -118,7 +123,7 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum OptLevel {
|
pub enum OptLevel {
|
||||||
No, // -O0
|
No, // -O0
|
||||||
Less, // -O1
|
Less, // -O1
|
||||||
|
@ -126,6 +131,7 @@ pub enum OptLevel {
|
||||||
Aggressive // -O3
|
Aggressive // -O3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct options {
|
pub struct options {
|
||||||
// The crate config requested for the session, which may be combined
|
// The crate config requested for the session, which may be combined
|
||||||
// with additional crate configurations during the compile process
|
// with additional crate configurations during the compile process
|
||||||
|
@ -345,10 +351,8 @@ pub fn basic_options() -> @options {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seems out of place, but it uses session, so I'm putting it here
|
// Seems out of place, but it uses session, so I'm putting it here
|
||||||
pub fn expect<T:Copy>(sess: Session,
|
pub fn expect<T:Clone>(sess: Session, opt: Option<T>, msg: &fn() -> ~str)
|
||||||
opt: Option<T>,
|
-> T {
|
||||||
msg: &fn() -> ~str)
|
|
||||||
-> T {
|
|
||||||
diagnostic::expect(sess.diagnostic(), opt, msg)
|
diagnostic::expect(sess.diagnostic(), opt, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,14 +99,14 @@ fn fold_item_underscore(cx: @Context, item: &ast::item_,
|
||||||
ast::item_impl(ref a, ref b, ref c, ref methods) => {
|
ast::item_impl(ref a, ref b, ref c, ref methods) => {
|
||||||
let methods = methods.iter().filter(|m| method_in_cfg(cx, **m))
|
let methods = methods.iter().filter(|m| method_in_cfg(cx, **m))
|
||||||
.transform(|x| *x).collect();
|
.transform(|x| *x).collect();
|
||||||
ast::item_impl(/*bad*/ copy *a, /*bad*/ copy *b, /*bad*/ copy *c, methods)
|
ast::item_impl((*a).clone(), (*b).clone(), (*c).clone(), methods)
|
||||||
}
|
}
|
||||||
ast::item_trait(ref a, ref b, ref methods) => {
|
ast::item_trait(ref a, ref b, ref methods) => {
|
||||||
let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) )
|
let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) )
|
||||||
.transform(|x| /* bad */copy *x).collect();
|
.transform(|x| (*x).clone()).collect();
|
||||||
ast::item_trait(/*bad*/copy *a, /*bad*/copy *b, methods)
|
ast::item_trait((*a).clone(), (*b).clone(), methods)
|
||||||
}
|
}
|
||||||
ref item => /*bad*/ copy *item
|
ref item => (*item).clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
fold::noop_fold_item_underscore(&item, fld)
|
fold::noop_fold_item_underscore(&item, fld)
|
||||||
|
@ -151,11 +151,11 @@ fn fold_block(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_in_cfg(cx: @Context, item: @ast::item) -> bool {
|
fn item_in_cfg(cx: @Context, item: @ast::item) -> bool {
|
||||||
return (cx.in_cfg)(/*bad*/copy item.attrs);
|
return (cx.in_cfg)(item.attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foreign_item_in_cfg(cx: @Context, item: @ast::foreign_item) -> bool {
|
fn foreign_item_in_cfg(cx: @Context, item: @ast::foreign_item) -> bool {
|
||||||
return (cx.in_cfg)(/*bad*/copy item.attrs);
|
return (cx.in_cfg)(item.attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_item_in_cfg(cx: @Context, item: &ast::view_item) -> bool {
|
fn view_item_in_cfg(cx: @Context, item: &ast::view_item) -> bool {
|
||||||
|
@ -163,13 +163,13 @@ fn view_item_in_cfg(cx: @Context, item: &ast::view_item) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn method_in_cfg(cx: @Context, meth: @ast::method) -> bool {
|
fn method_in_cfg(cx: @Context, meth: @ast::method) -> bool {
|
||||||
return (cx.in_cfg)(/*bad*/copy meth.attrs);
|
return (cx.in_cfg)(meth.attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool {
|
fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool {
|
||||||
match *meth {
|
match *meth {
|
||||||
ast::required(ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs),
|
ast::required(ref meth) => (cx.in_cfg)(meth.attrs),
|
||||||
ast::provided(@ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs)
|
ast::provided(@ref meth) => (cx.in_cfg)(meth.attrs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
|
||||||
let vis = vec::append(~[vi1], crate.module.view_items);
|
let vis = vec::append(~[vi1], crate.module.view_items);
|
||||||
let mut new_module = ast::_mod {
|
let mut new_module = ast::_mod {
|
||||||
view_items: vis,
|
view_items: vis,
|
||||||
../*bad*/copy crate.module
|
..crate.module.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
if !no_prelude(crate.attrs) {
|
if !no_prelude(crate.attrs) {
|
||||||
|
@ -76,7 +76,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
|
||||||
// FIXME #2543: Bad copy.
|
// FIXME #2543: Bad copy.
|
||||||
let new_crate = ast::crate_ {
|
let new_crate = ast::crate_ {
|
||||||
module: new_module,
|
module: new_module,
|
||||||
..copy *crate
|
..(*crate).clone()
|
||||||
};
|
};
|
||||||
(new_crate, span)
|
(new_crate, span)
|
||||||
},
|
},
|
||||||
|
@ -115,7 +115,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
|
||||||
// FIXME #2543: Bad copy.
|
// FIXME #2543: Bad copy.
|
||||||
let new_module = ast::_mod {
|
let new_module = ast::_mod {
|
||||||
view_items: vis,
|
view_items: vis,
|
||||||
..copy *module
|
..(*module).clone()
|
||||||
};
|
};
|
||||||
fold::noop_fold_mod(&new_module, fld)
|
fold::noop_fold_mod(&new_module, fld)
|
||||||
},
|
},
|
||||||
|
|
|
@ -66,7 +66,7 @@ fn generate_test_harness(sess: session::Session,
|
||||||
let cx: @mut TestCtxt = @mut TestCtxt {
|
let cx: @mut TestCtxt = @mut TestCtxt {
|
||||||
sess: sess,
|
sess: sess,
|
||||||
crate: crate,
|
crate: crate,
|
||||||
ext_cx: ExtCtxt::new(sess.parse_sess, copy sess.opts.cfg),
|
ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone()),
|
||||||
path: ~[],
|
path: ~[],
|
||||||
testfns: ~[]
|
testfns: ~[]
|
||||||
};
|
};
|
||||||
|
@ -109,26 +109,31 @@ fn fold_mod(cx: @mut TestCtxt,
|
||||||
|
|
||||||
fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item {
|
fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item {
|
||||||
if !*cx.sess.building_library {
|
if !*cx.sess.building_library {
|
||||||
@ast::item{
|
@ast::item {
|
||||||
attrs: do item.attrs.iter().filter_map |attr| {
|
attrs: do item.attrs.iter().filter_map |attr| {
|
||||||
if "main" != attr::get_attr_name(attr) {Some(*attr)} else {None}
|
if "main" != attr::get_attr_name(attr) {
|
||||||
|
Some(*attr)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}.collect(),
|
}.collect(),
|
||||||
.. copy *item}
|
.. (*item).clone()
|
||||||
} else { item }
|
}
|
||||||
|
} else {
|
||||||
|
item
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mod_nomain = ast::_mod {
|
let mod_nomain = ast::_mod {
|
||||||
view_items: /*bad*/copy m.view_items,
|
view_items: m.view_items.clone(),
|
||||||
items: m.items.iter().transform(|i| nomain(cx, *i)).collect(),
|
items: m.items.iter().transform(|i| nomain(cx, *i)).collect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
fold::noop_fold_mod(&mod_nomain, fld)
|
fold::noop_fold_mod(&mod_nomain, fld)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_crate(cx: @mut TestCtxt,
|
fn fold_crate(cx: @mut TestCtxt, c: &ast::crate_, fld: @fold::ast_fold)
|
||||||
c: &ast::crate_,
|
-> ast::crate_ {
|
||||||
fld: @fold::ast_fold)
|
|
||||||
-> ast::crate_ {
|
|
||||||
let folded = fold::noop_fold_crate(c, fld);
|
let folded = fold::noop_fold_crate(c, fld);
|
||||||
|
|
||||||
// Add a special __test module to the crate that will contain code
|
// Add a special __test module to the crate that will contain code
|
||||||
|
@ -144,7 +149,7 @@ fn fold_item(cx: @mut TestCtxt, i: @ast::item, fld: @fold::ast_fold)
|
||||||
-> Option<@ast::item> {
|
-> Option<@ast::item> {
|
||||||
cx.path.push(i.ident);
|
cx.path.push(i.ident);
|
||||||
debug!("current path: %s",
|
debug!("current path: %s",
|
||||||
ast_util::path_name_i(copy cx.path));
|
ast_util::path_name_i(cx.path.clone()));
|
||||||
|
|
||||||
if is_test_fn(cx, i) || is_bench_fn(i) {
|
if is_test_fn(cx, i) || is_bench_fn(i) {
|
||||||
match i.node {
|
match i.node {
|
||||||
|
@ -158,7 +163,7 @@ fn fold_item(cx: @mut TestCtxt, i: @ast::item, fld: @fold::ast_fold)
|
||||||
debug!("this is a test function");
|
debug!("this is a test function");
|
||||||
let test = Test {
|
let test = Test {
|
||||||
span: i.span,
|
span: i.span,
|
||||||
path: /*bad*/copy cx.path,
|
path: cx.path.clone(),
|
||||||
bench: is_bench_fn(i),
|
bench: is_bench_fn(i),
|
||||||
ignore: is_ignored(cx, i),
|
ignore: is_ignored(cx, i),
|
||||||
should_fail: should_fail(i)
|
should_fail: should_fail(i)
|
||||||
|
@ -235,7 +240,7 @@ fn is_ignored(cx: @mut TestCtxt, i: @ast::item) -> bool {
|
||||||
.filter_map(|i| attr::get_meta_item_list(i))
|
.filter_map(|i| attr::get_meta_item_list(i))
|
||||||
.collect::<~[~[@ast::meta_item]]>()
|
.collect::<~[~[@ast::meta_item]]>()
|
||||||
.concat_vec();
|
.concat_vec();
|
||||||
config::metas_in_cfg(/*bad*/copy cx.crate.node.config, cfg_metas)
|
config::metas_in_cfg(cx.crate.node.config.clone(), cfg_metas)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -248,8 +253,8 @@ fn should_fail(i: @ast::item) -> bool {
|
||||||
fn add_test_module(cx: &TestCtxt, m: &ast::_mod) -> ast::_mod {
|
fn add_test_module(cx: &TestCtxt, m: &ast::_mod) -> ast::_mod {
|
||||||
let testmod = mk_test_module(cx);
|
let testmod = mk_test_module(cx);
|
||||||
ast::_mod {
|
ast::_mod {
|
||||||
items: vec::append_one(/*bad*/copy m.items, testmod),
|
items: vec::append_one(m.items.clone(), testmod),
|
||||||
.. /*bad*/ copy *m
|
..(*m).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +338,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item {
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Synthetic test module:\n%s\n",
|
debug!("Synthetic test module:\n%s\n",
|
||||||
pprust::item_to_str(@copy item, cx.sess.intr()));
|
pprust::item_to_str(@item.clone(), cx.sess.intr()));
|
||||||
|
|
||||||
return @item;
|
return @item;
|
||||||
}
|
}
|
||||||
|
@ -406,7 +411,7 @@ fn mk_test_descs(cx: &TestCtxt) -> @ast::expr {
|
||||||
|
|
||||||
fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::expr {
|
fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::expr {
|
||||||
let span = test.span;
|
let span = test.span;
|
||||||
let path = /*bad*/copy test.path;
|
let path = test.path.clone();
|
||||||
|
|
||||||
let ext_cx = cx.ext_cx;
|
let ext_cx = cx.ext_cx;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ pub enum Linkage {
|
||||||
LinkerPrivateWeakLinkage = 16,
|
LinkerPrivateWeakLinkage = 16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum Attribute {
|
pub enum Attribute {
|
||||||
ZExtAttribute = 1,
|
ZExtAttribute = 1,
|
||||||
SExtAttribute = 2,
|
SExtAttribute = 2,
|
||||||
|
|
|
@ -82,8 +82,7 @@ fn warn_if_multiple_versions(e: @mut Env,
|
||||||
);
|
);
|
||||||
|
|
||||||
let vec: ~[Either<cache_entry, cache_entry>] = crate_cache.iter().transform(|&entry| {
|
let vec: ~[Either<cache_entry, cache_entry>] = crate_cache.iter().transform(|&entry| {
|
||||||
let othername = loader::crate_name_from_metas(
|
let othername = loader::crate_name_from_metas(*entry.metas);
|
||||||
copy *entry.metas);
|
|
||||||
if name == othername {
|
if name == othername {
|
||||||
Left(entry)
|
Left(entry)
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,8 +99,8 @@ fn warn_if_multiple_versions(e: @mut Env,
|
||||||
for matches.iter().advance |match_| {
|
for matches.iter().advance |match_| {
|
||||||
diag.span_note(match_.span, "used here");
|
diag.span_note(match_.span, "used here");
|
||||||
let attrs = ~[
|
let attrs = ~[
|
||||||
attr::mk_attr(attr::mk_list_item(
|
attr::mk_attr(attr::mk_list_item(@"link",
|
||||||
@"link", /*bad*/copy *match_.metas))
|
(*match_.metas).clone()))
|
||||||
];
|
];
|
||||||
loader::note_linkage_attrs(e.intr, diag, attrs);
|
loader::note_linkage_attrs(e.intr, diag, attrs);
|
||||||
}
|
}
|
||||||
|
@ -141,7 +140,11 @@ fn visit_view_item(e: @mut Env, i: &ast::view_item) {
|
||||||
ast::view_item_extern_mod(ident, ref meta_items, id) => {
|
ast::view_item_extern_mod(ident, ref meta_items, id) => {
|
||||||
debug!("resolving extern mod stmt. ident: %?, meta: %?",
|
debug!("resolving extern mod stmt. ident: %?, meta: %?",
|
||||||
ident, *meta_items);
|
ident, *meta_items);
|
||||||
let cnum = resolve_crate(e, ident, copy *meta_items, @"", i.span);
|
let cnum = resolve_crate(e,
|
||||||
|
ident,
|
||||||
|
(*meta_items).clone(),
|
||||||
|
@"",
|
||||||
|
i.span);
|
||||||
cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum);
|
cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum);
|
||||||
}
|
}
|
||||||
_ => ()
|
_ => ()
|
||||||
|
@ -306,8 +309,8 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map {
|
||||||
let cmetas = metas_with(dep.vers, @"vers", ~[]);
|
let cmetas = metas_with(dep.vers, @"vers", ~[]);
|
||||||
debug!("resolving dep crate %s ver: %s hash: %s",
|
debug!("resolving dep crate %s ver: %s hash: %s",
|
||||||
cname_str, dep.vers, dep.hash);
|
cname_str, dep.vers, dep.hash);
|
||||||
match existing_match(e, metas_with_ident(cname_str,
|
match existing_match(e,
|
||||||
copy cmetas),
|
metas_with_ident(cname_str, cmetas.clone()),
|
||||||
dep.hash) {
|
dep.hash) {
|
||||||
Some(local_cnum) => {
|
Some(local_cnum) => {
|
||||||
debug!("already have it");
|
debug!("already have it");
|
||||||
|
|
|
@ -91,12 +91,13 @@ pub fn iter_crate_data(cstore: &CStore,
|
||||||
|
|
||||||
pub fn add_used_crate_file(cstore: &mut CStore, lib: &Path) {
|
pub fn add_used_crate_file(cstore: &mut CStore, lib: &Path) {
|
||||||
if !cstore.used_crate_files.contains(lib) {
|
if !cstore.used_crate_files.contains(lib) {
|
||||||
cstore.used_crate_files.push(copy *lib);
|
cstore.used_crate_files.push((*lib).clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_used_crate_files(cstore: &CStore) -> ~[Path] {
|
pub fn get_used_crate_files(cstore: &CStore) -> ~[Path] {
|
||||||
return /*bad*/copy cstore.used_crate_files;
|
// XXX(pcwalton): Bad copy.
|
||||||
|
return cstore.used_crate_files.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_used_library(cstore: &mut CStore, lib: @str) -> bool {
|
pub fn add_used_library(cstore: &mut CStore, lib: @str) -> bool {
|
||||||
|
@ -135,10 +136,16 @@ pub fn find_extern_mod_stmt_cnum(cstore: &CStore,
|
||||||
cstore.extern_mod_crate_map.find(&emod_id).map_consume(|x| *x)
|
cstore.extern_mod_crate_map.find(&emod_id).map_consume(|x| *x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
|
struct crate_hash {
|
||||||
|
name: @str,
|
||||||
|
vers: @str,
|
||||||
|
hash: @str,
|
||||||
|
}
|
||||||
|
|
||||||
// returns hashes of crates directly used by this crate. Hashes are sorted by
|
// returns hashes of crates directly used by this crate. Hashes are sorted by
|
||||||
// (crate name, crate version, crate hash) in lexicographic order (not semver)
|
// (crate name, crate version, crate hash) in lexicographic order (not semver)
|
||||||
pub fn get_dep_hashes(cstore: &CStore) -> ~[@str] {
|
pub fn get_dep_hashes(cstore: &CStore) -> ~[@str] {
|
||||||
struct crate_hash { name: @str, vers: @str, hash: @str }
|
|
||||||
let mut result = ~[];
|
let mut result = ~[];
|
||||||
|
|
||||||
for cstore.extern_mod_crate_map.each_value |&cnum| {
|
for cstore.extern_mod_crate_map.each_value |&cnum| {
|
||||||
|
|
|
@ -714,7 +714,7 @@ pub fn maybe_get_item_ast(cdata: cmd, tcx: ty::ctxt,
|
||||||
let item_path = item_path(item_doc);
|
let item_path = item_path(item_doc);
|
||||||
item_path.init().to_owned()
|
item_path.init().to_owned()
|
||||||
};
|
};
|
||||||
match decode_inlined_item(cdata, tcx, copy path, item_doc) {
|
match decode_inlined_item(cdata, tcx, /*bad*/path.clone(), item_doc) {
|
||||||
Some(ref ii) => csearch::found(*ii),
|
Some(ref ii) => csearch::found(*ii),
|
||||||
None => {
|
None => {
|
||||||
match item_parent_item(item_doc) {
|
match item_parent_item(item_doc) {
|
||||||
|
@ -746,7 +746,7 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
||||||
item, tcx, cdata);
|
item, tcx, cdata);
|
||||||
let name = item_name(intr, item);
|
let name = item_name(intr, item);
|
||||||
let arg_tys = match ty::get(ctor_ty).sty {
|
let arg_tys = match ty::get(ctor_ty).sty {
|
||||||
ty::ty_bare_fn(ref f) => copy f.sig.inputs,
|
ty::ty_bare_fn(ref f) => f.sig.inputs.clone(),
|
||||||
_ => ~[], // Nullary enum variant.
|
_ => ~[], // Nullary enum variant.
|
||||||
};
|
};
|
||||||
match variant_disr_val(item) {
|
match variant_disr_val(item) {
|
||||||
|
@ -1149,6 +1149,7 @@ pub fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] {
|
||||||
return get_attributes(reader::Doc(data));
|
return get_attributes(reader::Doc(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct crate_dep {
|
pub struct crate_dep {
|
||||||
cnum: ast::crate_num,
|
cnum: ast::crate_num,
|
||||||
name: ast::ident,
|
name: ast::ident,
|
||||||
|
|
|
@ -128,6 +128,7 @@ fn encode_region_param(ecx: &EncodeContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
struct entry<T> {
|
struct entry<T> {
|
||||||
val: T,
|
val: T,
|
||||||
pos: uint
|
pos: uint
|
||||||
|
@ -662,7 +663,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
|
||||||
-> ~[entry<int>] {
|
-> ~[entry<int>] {
|
||||||
/* Each class has its own index, since different classes
|
/* Each class has its own index, since different classes
|
||||||
may have fields with the same name */
|
may have fields with the same name */
|
||||||
let index = @mut ~[];
|
let mut index = ~[];
|
||||||
let tcx = ecx.tcx;
|
let tcx = ecx.tcx;
|
||||||
/* We encode both private and public fields -- need to include
|
/* We encode both private and public fields -- need to include
|
||||||
private fields to get the offsets right */
|
private fields to get the offsets right */
|
||||||
|
@ -685,7 +686,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
|
||||||
encode_def_id(ebml_w, local_def(id));
|
encode_def_id(ebml_w, local_def(id));
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
/*bad*/copy *index
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is for encoding info for ctors and dtors
|
// This is for encoding info for ctors and dtors
|
||||||
|
@ -781,10 +782,10 @@ fn encode_info_for_method(ecx: &EncodeContext,
|
||||||
|
|
||||||
let mut combined_ty_params = opt_vec::Empty;
|
let mut combined_ty_params = opt_vec::Empty;
|
||||||
for owner_generics.ty_params.iter().advance |x| {
|
for owner_generics.ty_params.iter().advance |x| {
|
||||||
combined_ty_params.push(copy *x)
|
combined_ty_params.push((*x).clone())
|
||||||
}
|
}
|
||||||
for method_generics.ty_params.iter().advance |x| {
|
for method_generics.ty_params.iter().advance |x| {
|
||||||
combined_ty_params.push(copy *x)
|
combined_ty_params.push((*x).clone())
|
||||||
}
|
}
|
||||||
let len = combined_ty_params.len();
|
let len = combined_ty_params.len();
|
||||||
encode_type_param_bounds(ebml_w, ecx, &combined_ty_params);
|
encode_type_param_bounds(ebml_w, ecx, &combined_ty_params);
|
||||||
|
@ -1151,7 +1152,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
|
||||||
ebml_w: &mut writer::Encoder,
|
ebml_w: &mut writer::Encoder,
|
||||||
nitem: @foreign_item,
|
nitem: @foreign_item,
|
||||||
index: @mut ~[entry<int>],
|
index: @mut ~[entry<int>],
|
||||||
path: ast_map::path,
|
path: &ast_map::path,
|
||||||
abi: AbiSet) {
|
abi: AbiSet) {
|
||||||
index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() });
|
index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() });
|
||||||
|
|
||||||
|
@ -1164,11 +1165,11 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
|
||||||
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
||||||
encode_name(ecx, ebml_w, nitem.ident);
|
encode_name(ecx, ebml_w, nitem.ident);
|
||||||
if abi.is_intrinsic() {
|
if abi.is_intrinsic() {
|
||||||
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem));
|
(ecx.encode_inlined_item)(ecx, ebml_w, *path, ii_foreign(nitem));
|
||||||
} else {
|
} else {
|
||||||
encode_symbol(ecx, ebml_w, nitem.id);
|
encode_symbol(ecx, ebml_w, nitem.id);
|
||||||
}
|
}
|
||||||
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
|
encode_path(ecx, ebml_w, *path, ast_map::path_name(nitem.ident));
|
||||||
}
|
}
|
||||||
foreign_item_static(_, mutbl) => {
|
foreign_item_static(_, mutbl) => {
|
||||||
encode_def_id(ebml_w, local_def(nitem.id));
|
encode_def_id(ebml_w, local_def(nitem.id));
|
||||||
|
@ -1180,7 +1181,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
|
||||||
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
|
||||||
encode_symbol(ecx, ebml_w, nitem.id);
|
encode_symbol(ecx, ebml_w, nitem.id);
|
||||||
encode_name(ecx, ebml_w, nitem.ident);
|
encode_name(ecx, ebml_w, nitem.ident);
|
||||||
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
|
encode_path(ecx, ebml_w, *path, ast_map::path_name(nitem.ident));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
|
@ -1208,12 +1209,12 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
||||||
visit::visit_crate(crate, ((), visit::mk_vt(@visit::Visitor {
|
visit::visit_crate(crate, ((), visit::mk_vt(@visit::Visitor {
|
||||||
visit_expr: |_e, (_cx, _v)| { },
|
visit_expr: |_e, (_cx, _v)| { },
|
||||||
visit_item: {
|
visit_item: {
|
||||||
let ebml_w = copy *ebml_w;
|
let ebml_w = (*ebml_w).clone();
|
||||||
|i, (cx, v)| {
|
|i, (cx, v)| {
|
||||||
visit::visit_item(i, (cx, v));
|
visit::visit_item(i, (cx, v));
|
||||||
match items.get_copy(&i.id) {
|
match items.get_copy(&i.id) {
|
||||||
ast_map::node_item(_, pt) => {
|
ast_map::node_item(_, pt) => {
|
||||||
let mut ebml_w = copy ebml_w;
|
let mut ebml_w = ebml_w.clone();
|
||||||
// See above
|
// See above
|
||||||
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
||||||
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
|
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
|
||||||
|
@ -1223,7 +1224,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
visit_foreign_item: {
|
visit_foreign_item: {
|
||||||
let ebml_w = copy *ebml_w;
|
let ebml_w = (*ebml_w).clone();
|
||||||
|ni, (cx, v)| {
|
|ni, (cx, v)| {
|
||||||
visit::visit_foreign_item(ni, (cx, v));
|
visit::visit_foreign_item(ni, (cx, v));
|
||||||
match items.get_copy(&ni.id) {
|
match items.get_copy(&ni.id) {
|
||||||
|
@ -1234,14 +1235,14 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
||||||
token::get_ident_interner()),
|
token::get_ident_interner()),
|
||||||
token::ident_to_str(&ni.ident));
|
token::ident_to_str(&ni.ident));
|
||||||
|
|
||||||
let mut ebml_w = copy ebml_w;
|
let mut ebml_w = ebml_w.clone();
|
||||||
// See above
|
// See above
|
||||||
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
||||||
encode_info_for_foreign_item(ecx,
|
encode_info_for_foreign_item(ecx,
|
||||||
&mut ebml_w,
|
&mut ebml_w,
|
||||||
ni,
|
ni,
|
||||||
index,
|
index,
|
||||||
/*bad*/copy *pt,
|
pt,
|
||||||
abi);
|
abi);
|
||||||
}
|
}
|
||||||
// case for separate item and foreign-item tables
|
// case for separate item and foreign-item tables
|
||||||
|
@ -1252,24 +1253,24 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
||||||
..*visit::default_visitor()
|
..*visit::default_visitor()
|
||||||
})));
|
})));
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
return /*bad*/copy *index;
|
return /*bad*/(*index).clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Path and definition ID indexing
|
// Path and definition ID indexing
|
||||||
|
|
||||||
fn create_index<T:Copy + Hash + IterBytes>(index: ~[entry<T>]) ->
|
fn create_index<T:Clone + Hash + IterBytes>(index: ~[entry<T>])
|
||||||
~[@~[entry<T>]] {
|
-> ~[@~[entry<T>]] {
|
||||||
let mut buckets: ~[@mut ~[entry<T>]] = ~[];
|
let mut buckets: ~[@mut ~[entry<T>]] = ~[];
|
||||||
for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
|
for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
|
||||||
for index.iter().advance |elt| {
|
for index.iter().advance |elt| {
|
||||||
let h = elt.val.hash() as uint;
|
let h = elt.val.hash() as uint;
|
||||||
buckets[h % 256].push(copy *elt);
|
buckets[h % 256].push((*elt).clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut buckets_frozen = ~[];
|
let mut buckets_frozen = ~[];
|
||||||
for buckets.iter().advance |bucket| {
|
for buckets.iter().advance |bucket| {
|
||||||
buckets_frozen.push(@/*bad*/copy **bucket);
|
buckets_frozen.push(@/*bad*/(**bucket).clone());
|
||||||
}
|
}
|
||||||
return buckets_frozen;
|
return buckets_frozen;
|
||||||
}
|
}
|
||||||
|
@ -1401,7 +1402,7 @@ fn synthesize_crate_attrs(ecx: &EncodeContext,
|
||||||
match attr.node.value.node {
|
match attr.node.value.node {
|
||||||
meta_list(_, ref l) => {
|
meta_list(_, ref l) => {
|
||||||
found_link_attr = true;;
|
found_link_attr = true;;
|
||||||
synthesize_link_attr(ecx, /*bad*/copy *l)
|
synthesize_link_attr(ecx, (*l).clone())
|
||||||
}
|
}
|
||||||
_ => *attr
|
_ => *attr
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,11 @@ use std::str;
|
||||||
pub type pick<'self, T> = &'self fn(path: &Path) -> Option<T>;
|
pub type pick<'self, T> = &'self fn(path: &Path) -> Option<T>;
|
||||||
|
|
||||||
pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
|
pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
|
||||||
if path.file_path() == file { option::Some(copy *path) }
|
if path.file_path() == file {
|
||||||
else { option::None }
|
option::Some((*path).clone())
|
||||||
|
} else {
|
||||||
|
option::None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FileSearch {
|
pub trait FileSearch {
|
||||||
|
|
|
@ -55,11 +55,11 @@ pub struct Context {
|
||||||
|
|
||||||
pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) {
|
pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) {
|
||||||
match find_library_crate(cx) {
|
match find_library_crate(cx) {
|
||||||
Some(ref t) => return (/*bad*/copy *t),
|
Some(ref t) => return (/*bad*/(*t).clone()),
|
||||||
None => {
|
None => {
|
||||||
cx.diag.span_fatal(
|
cx.diag.span_fatal(cx.span,
|
||||||
cx.span, fmt!("can't find crate for `%s`",
|
fmt!("can't find crate for `%s`",
|
||||||
token::ident_to_str(&cx.ident)));
|
token::ident_to_str(&cx.ident)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub fn enc_ty(w: @io::Writer, cx: @ctxt, t: ty::t) {
|
||||||
Some(&s) => s,
|
Some(&s) => s,
|
||||||
None => {
|
None => {
|
||||||
let s = do io::with_str_writer |wr| {
|
let s = do io::with_str_writer |wr| {
|
||||||
enc_sty(wr, cx, /*bad*/copy ty::get(t).sty);
|
enc_sty(wr, cx, &ty::get(t).sty);
|
||||||
}.to_managed();
|
}.to_managed();
|
||||||
cx.tcx.short_names_cache.insert(t, s);
|
cx.tcx.short_names_cache.insert(t, s);
|
||||||
s
|
s
|
||||||
|
@ -75,7 +75,7 @@ pub fn enc_ty(w: @io::Writer, cx: @ctxt, t: ty::t) {
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
let pos = w.tell();
|
let pos = w.tell();
|
||||||
enc_sty(w, cx, /*bad*/copy ty::get(t).sty);
|
enc_sty(w, cx, &ty::get(t).sty);
|
||||||
let end = w.tell();
|
let end = w.tell();
|
||||||
let len = end - pos;
|
let len = end - pos;
|
||||||
fn estimate_sz(u: uint) -> uint {
|
fn estimate_sz(u: uint) -> uint {
|
||||||
|
@ -221,8 +221,8 @@ pub fn enc_trait_store(w: @io::Writer, cx: @ctxt, s: ty::TraitStore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enc_sty(w: @io::Writer, cx: @ctxt, st: ty::sty) {
|
fn enc_sty(w: @io::Writer, cx: @ctxt, st: &ty::sty) {
|
||||||
match st {
|
match *st {
|
||||||
ty::ty_nil => w.write_char('n'),
|
ty::ty_nil => w.write_char('n'),
|
||||||
ty::ty_bot => w.write_char('z'),
|
ty::ty_bot => w.write_char('z'),
|
||||||
ty::ty_bool => w.write_char('b'),
|
ty::ty_bool => w.write_char('b'),
|
||||||
|
@ -271,7 +271,7 @@ fn enc_sty(w: @io::Writer, cx: @ctxt, st: ty::sty) {
|
||||||
enc_bounds(w, cx, &bounds);
|
enc_bounds(w, cx, &bounds);
|
||||||
w.write_char(']');
|
w.write_char(']');
|
||||||
}
|
}
|
||||||
ty::ty_tup(ts) => {
|
ty::ty_tup(ref ts) => {
|
||||||
w.write_str(&"T[");
|
w.write_str(&"T[");
|
||||||
for ts.iter().advance |t| { enc_ty(w, cx, *t); }
|
for ts.iter().advance |t| { enc_ty(w, cx, *t); }
|
||||||
w.write_char(']');
|
w.write_char(']');
|
||||||
|
|
|
@ -106,7 +106,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
|
||||||
pub fn decode_inlined_item(cdata: @cstore::crate_metadata,
|
pub fn decode_inlined_item(cdata: @cstore::crate_metadata,
|
||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
maps: Maps,
|
maps: Maps,
|
||||||
path: ast_map::path,
|
path: &[ast_map::path_elt],
|
||||||
par_doc: ebml::Doc)
|
par_doc: ebml::Doc)
|
||||||
-> Option<ast::inlined_item> {
|
-> Option<ast::inlined_item> {
|
||||||
let dcx = @DecodeContext {
|
let dcx = @DecodeContext {
|
||||||
|
@ -134,7 +134,9 @@ pub fn decode_inlined_item(cdata: @cstore::crate_metadata,
|
||||||
ast_map::path_to_str(path, token::get_ident_interner()),
|
ast_map::path_to_str(path, token::get_ident_interner()),
|
||||||
tcx.sess.str_of(ii.ident()));
|
tcx.sess.str_of(ii.ident()));
|
||||||
ast_map::map_decoded_item(tcx.sess.diagnostic(),
|
ast_map::map_decoded_item(tcx.sess.diagnostic(),
|
||||||
dcx.tcx.items, path, &ii);
|
dcx.tcx.items,
|
||||||
|
path.to_owned(),
|
||||||
|
&ii);
|
||||||
decode_side_tables(xcx, ast_doc);
|
decode_side_tables(xcx, ast_doc);
|
||||||
match ii {
|
match ii {
|
||||||
ast::ii_item(i) => {
|
ast::ii_item(i) => {
|
||||||
|
@ -618,7 +620,7 @@ fn encode_vtable_origin(ecx: &e::EncodeContext,
|
||||||
ebml_w.emit_def_id(def_id)
|
ebml_w.emit_def_id(def_id)
|
||||||
}
|
}
|
||||||
do ebml_w.emit_enum_variant_arg(1u) |ebml_w| {
|
do ebml_w.emit_enum_variant_arg(1u) |ebml_w| {
|
||||||
ebml_w.emit_tys(ecx, /*bad*/copy *tys);
|
ebml_w.emit_tys(ecx, *tys);
|
||||||
}
|
}
|
||||||
do ebml_w.emit_enum_variant_arg(2u) |ebml_w| {
|
do ebml_w.emit_enum_variant_arg(2u) |ebml_w| {
|
||||||
encode_vtable_res(ecx, ebml_w, vtable_res);
|
encode_vtable_res(ecx, ebml_w, vtable_res);
|
||||||
|
@ -814,7 +816,7 @@ fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
|
||||||
ebml_w: &mut writer::Encoder,
|
ebml_w: &mut writer::Encoder,
|
||||||
ii: &ast::inlined_item) {
|
ii: &ast::inlined_item) {
|
||||||
ebml_w.start_tag(c::tag_table as uint);
|
ebml_w.start_tag(c::tag_table as uint);
|
||||||
let new_ebml_w = copy *ebml_w;
|
let new_ebml_w = (*ebml_w).clone();
|
||||||
|
|
||||||
// Because the ast visitor uses @fn, I can't pass in
|
// Because the ast visitor uses @fn, I can't pass in
|
||||||
// ecx directly, but /I/ know that it'll be fine since
|
// ecx directly, but /I/ know that it'll be fine since
|
||||||
|
@ -827,7 +829,7 @@ fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
|
||||||
// Note: this will cause a copy of ebml_w, which is bad as
|
// Note: this will cause a copy of ebml_w, which is bad as
|
||||||
// it is mutable. But I believe it's harmless since we generate
|
// it is mutable. But I believe it's harmless since we generate
|
||||||
// balanced EBML.
|
// balanced EBML.
|
||||||
let mut new_ebml_w = copy new_ebml_w;
|
let mut new_ebml_w = new_ebml_w.clone();
|
||||||
// See above
|
// See above
|
||||||
let ecx : &e::EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
let ecx : &e::EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
||||||
encode_side_tables_for_id(ecx, maps, &mut new_ebml_w, id)
|
encode_side_tables_for_id(ecx, maps, &mut new_ebml_w, id)
|
||||||
|
|
|
@ -49,6 +49,15 @@ pub mod gather_loans;
|
||||||
pub mod move_data;
|
pub mod move_data;
|
||||||
|
|
||||||
pub struct LoanDataFlowOperator;
|
pub struct LoanDataFlowOperator;
|
||||||
|
|
||||||
|
/// XXX(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
|
||||||
|
/// yet on unit structs.
|
||||||
|
impl Clone for LoanDataFlowOperator {
|
||||||
|
fn clone(&self) -> LoanDataFlowOperator {
|
||||||
|
LoanDataFlowOperator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type LoanDataFlow = DataFlowContext<LoanDataFlowOperator>;
|
pub type LoanDataFlow = DataFlowContext<LoanDataFlowOperator>;
|
||||||
|
|
||||||
pub fn check_crate(
|
pub fn check_crate(
|
||||||
|
|
|
@ -71,6 +71,12 @@ pub struct FlowedMoveData {
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
pub struct MovePathIndex(uint);
|
pub struct MovePathIndex(uint);
|
||||||
|
|
||||||
|
impl Clone for MovePathIndex {
|
||||||
|
fn clone(&self) -> MovePathIndex {
|
||||||
|
MovePathIndex(**self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static InvalidMovePathIndex: MovePathIndex =
|
static InvalidMovePathIndex: MovePathIndex =
|
||||||
MovePathIndex(uint::max_value);
|
MovePathIndex(uint::max_value);
|
||||||
|
|
||||||
|
@ -133,9 +139,27 @@ pub struct Assignment {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MoveDataFlowOperator;
|
pub struct MoveDataFlowOperator;
|
||||||
|
|
||||||
|
/// XXX(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
|
||||||
|
/// yet on unit structs.
|
||||||
|
impl Clone for MoveDataFlowOperator {
|
||||||
|
fn clone(&self) -> MoveDataFlowOperator {
|
||||||
|
MoveDataFlowOperator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type MoveDataFlow = DataFlowContext<MoveDataFlowOperator>;
|
pub type MoveDataFlow = DataFlowContext<MoveDataFlowOperator>;
|
||||||
|
|
||||||
pub struct AssignDataFlowOperator;
|
pub struct AssignDataFlowOperator;
|
||||||
|
|
||||||
|
/// XXX(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
|
||||||
|
/// yet on unit structs.
|
||||||
|
impl Clone for AssignDataFlowOperator {
|
||||||
|
fn clone(&self) -> AssignDataFlowOperator {
|
||||||
|
AssignDataFlowOperator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type AssignDataFlow = DataFlowContext<AssignDataFlowOperator>;
|
pub type AssignDataFlow = DataFlowContext<AssignDataFlowOperator>;
|
||||||
|
|
||||||
impl MoveData {
|
impl MoveData {
|
||||||
|
|
|
@ -194,20 +194,21 @@ pub fn check_expr(sess: Session,
|
||||||
visit::visit_expr(e, (is_const, v));
|
visit::visit_expr(e, (is_const, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
|
struct env {
|
||||||
|
root_it: @item,
|
||||||
|
sess: Session,
|
||||||
|
ast_map: ast_map::map,
|
||||||
|
def_map: resolve::DefMap,
|
||||||
|
idstack: @mut ~[node_id]
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure a const item doesn't recursively refer to itself
|
// Make sure a const item doesn't recursively refer to itself
|
||||||
// FIXME: Should use the dependency graph when it's available (#1356)
|
// FIXME: Should use the dependency graph when it's available (#1356)
|
||||||
pub fn check_item_recursion(sess: Session,
|
pub fn check_item_recursion(sess: Session,
|
||||||
ast_map: ast_map::map,
|
ast_map: ast_map::map,
|
||||||
def_map: resolve::DefMap,
|
def_map: resolve::DefMap,
|
||||||
it: @item) {
|
it: @item) {
|
||||||
struct env {
|
|
||||||
root_it: @item,
|
|
||||||
sess: Session,
|
|
||||||
ast_map: ast_map::map,
|
|
||||||
def_map: resolve::DefMap,
|
|
||||||
idstack: @mut ~[node_id]
|
|
||||||
}
|
|
||||||
|
|
||||||
let env = env {
|
let env = env {
|
||||||
root_it: it,
|
root_it: it,
|
||||||
sess: sess,
|
sess: sess,
|
||||||
|
|
|
@ -14,6 +14,7 @@ use middle::ty;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::visit;
|
use syntax::visit;
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
in_loop: bool,
|
in_loop: bool,
|
||||||
can_ret: bool
|
can_ret: bool
|
||||||
|
|
|
@ -473,7 +473,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
|
||||||
left_ty: ty::t)
|
left_ty: ty::t)
|
||||||
-> Option<~[@pat]> {
|
-> Option<~[@pat]> {
|
||||||
// Sad, but I can't get rid of this easily
|
// Sad, but I can't get rid of this easily
|
||||||
let r0 = copy *raw_pat(r[0]);
|
let r0 = (*raw_pat(r[0])).clone();
|
||||||
match r0 {
|
match r0 {
|
||||||
pat{id: pat_id, node: n, span: pat_span} =>
|
pat{id: pat_id, node: n, span: pat_span} =>
|
||||||
match n {
|
match n {
|
||||||
|
|
|
@ -238,7 +238,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
|
||||||
capture_map: @mut HashMap::new()
|
capture_map: @mut HashMap::new()
|
||||||
};
|
};
|
||||||
match csearch::maybe_get_item_ast(tcx, def_id,
|
match csearch::maybe_get_item_ast(tcx, def_id,
|
||||||
|a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) {
|
|a, b, c, d| astencode::decode_inlined_item(a, b, maps, c, d)) {
|
||||||
csearch::found(ast::ii_item(item)) => match item.node {
|
csearch::found(ast::ii_item(item)) => match item.node {
|
||||||
item_static(_, ast::m_imm, const_expr) => Some(const_expr),
|
item_static(_, ast::m_imm, const_expr) => Some(const_expr),
|
||||||
_ => None
|
_ => None
|
||||||
|
@ -275,7 +275,7 @@ pub fn process_crate(crate: &ast::crate,
|
||||||
|
|
||||||
// FIXME (#33): this doesn't handle big integer/float literals correctly
|
// FIXME (#33): this doesn't handle big integer/float literals correctly
|
||||||
// (nor does the rest of our literal handling).
|
// (nor does the rest of our literal handling).
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum const_val {
|
pub enum const_val {
|
||||||
const_float(f64),
|
const_float(f64),
|
||||||
const_int(i64),
|
const_int(i64),
|
||||||
|
@ -303,7 +303,7 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &expr)
|
||||||
Ok(const_uint(i)) => Ok(const_uint(-i)),
|
Ok(const_uint(i)) => Ok(const_uint(-i)),
|
||||||
Ok(const_str(_)) => Err(~"Negate on string"),
|
Ok(const_str(_)) => Err(~"Negate on string"),
|
||||||
Ok(const_bool(_)) => Err(~"Negate on boolean"),
|
Ok(const_bool(_)) => Err(~"Negate on boolean"),
|
||||||
ref err => (/*bad*/copy *err)
|
ref err => ((*err).clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr_unary(_, not, inner) => {
|
expr_unary(_, not, inner) => {
|
||||||
|
@ -410,28 +410,34 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &expr)
|
||||||
expr_cast(base, _) => {
|
expr_cast(base, _) => {
|
||||||
let ety = tcx.expr_ty(e);
|
let ety = tcx.expr_ty(e);
|
||||||
let base = eval_const_expr_partial(tcx, base);
|
let base = eval_const_expr_partial(tcx, base);
|
||||||
match /*bad*/copy base {
|
match base {
|
||||||
Err(_) => base,
|
Err(_) => base,
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
match ty::get(ety).sty {
|
match ty::get(ety).sty {
|
||||||
ty::ty_float(_) => match val {
|
ty::ty_float(_) => {
|
||||||
const_uint(u) => Ok(const_float(u as f64)),
|
match val {
|
||||||
const_int(i) => Ok(const_float(i as f64)),
|
const_uint(u) => Ok(const_float(u as f64)),
|
||||||
const_float(_) => base,
|
const_int(i) => Ok(const_float(i as f64)),
|
||||||
_ => Err(~"Can't cast float to str"),
|
const_float(f) => Ok(const_float(f)),
|
||||||
},
|
_ => Err(~"Can't cast float to str"),
|
||||||
ty::ty_uint(_) => match val {
|
}
|
||||||
const_uint(_) => base,
|
}
|
||||||
const_int(i) => Ok(const_uint(i as u64)),
|
ty::ty_uint(_) => {
|
||||||
const_float(f) => Ok(const_uint(f as u64)),
|
match val {
|
||||||
_ => Err(~"Can't cast str to uint"),
|
const_uint(u) => Ok(const_uint(u)),
|
||||||
},
|
const_int(i) => Ok(const_uint(i as u64)),
|
||||||
ty::ty_int(_) | ty::ty_bool => match val {
|
const_float(f) => Ok(const_uint(f as u64)),
|
||||||
const_uint(u) => Ok(const_int(u as i64)),
|
_ => Err(~"Can't cast str to uint"),
|
||||||
const_int(_) => base,
|
}
|
||||||
const_float(f) => Ok(const_int(f as i64)),
|
}
|
||||||
_ => Err(~"Can't cast str to int"),
|
ty::ty_int(_) | ty::ty_bool => {
|
||||||
},
|
match val {
|
||||||
|
const_uint(u) => Ok(const_int(u as i64)),
|
||||||
|
const_int(i) => Ok(const_int(i)),
|
||||||
|
const_float(f) => Ok(const_int(f as i64)),
|
||||||
|
_ => Err(~"Can't cast str to int"),
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => Err(~"Can't cast this type")
|
_ => Err(~"Can't cast this type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ use middle::ty;
|
||||||
use middle::typeck;
|
use middle::typeck;
|
||||||
use util::ppaux::Repr;
|
use util::ppaux::Repr;
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct DataFlowContext<O> {
|
pub struct DataFlowContext<O> {
|
||||||
priv tcx: ty::ctxt,
|
priv tcx: ty::ctxt,
|
||||||
priv method_map: typeck::method_map,
|
priv method_map: typeck::method_map,
|
||||||
|
@ -294,8 +295,8 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O:DataFlowOperator+Copy+'static> DataFlowContext<O> {
|
impl<O:DataFlowOperator+Clone+'static> DataFlowContext<O> {
|
||||||
// ^^^^^^^^^^^^ only needed for pretty printing
|
// ^^^^^^^^^^^^^ only needed for pretty printing
|
||||||
pub fn propagate(&mut self, blk: &ast::blk) {
|
pub fn propagate(&mut self, blk: &ast::blk) {
|
||||||
//! Performs the data flow analysis.
|
//! Performs the data flow analysis.
|
||||||
|
|
||||||
|
@ -304,23 +305,25 @@ impl<O:DataFlowOperator+Copy+'static> DataFlowContext<O> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut propcx = PropagationContext {
|
{
|
||||||
dfcx: self,
|
let mut propcx = PropagationContext {
|
||||||
changed: true
|
dfcx: self,
|
||||||
};
|
changed: true
|
||||||
|
};
|
||||||
|
|
||||||
let mut temp = vec::from_elem(self.words_per_id, 0);
|
let mut temp = vec::from_elem(self.words_per_id, 0u);
|
||||||
let mut loop_scopes = ~[];
|
let mut loop_scopes = ~[];
|
||||||
|
|
||||||
while propcx.changed {
|
while propcx.changed {
|
||||||
propcx.changed = false;
|
propcx.changed = false;
|
||||||
propcx.reset(temp);
|
propcx.reset(temp);
|
||||||
propcx.walk_block(blk, temp, &mut loop_scopes);
|
propcx.walk_block(blk, temp, &mut loop_scopes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Dataflow result:");
|
debug!("Dataflow result:");
|
||||||
debug!("%s", {
|
debug!("%s", {
|
||||||
let this = @copy *self;
|
let this = @(*self).clone();
|
||||||
this.pretty_print_to(io::stderr(), blk);
|
this.pretty_print_to(io::stderr(), blk);
|
||||||
""
|
""
|
||||||
});
|
});
|
||||||
|
@ -897,7 +900,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
|
||||||
// statement.
|
// statement.
|
||||||
let initial_state = reslice(in_out).to_owned();
|
let initial_state = reslice(in_out).to_owned();
|
||||||
for pats.iter().advance |&pat| {
|
for pats.iter().advance |&pat| {
|
||||||
let mut temp = copy initial_state;
|
let mut temp = initial_state.clone();
|
||||||
self.walk_pat(pat, temp, loop_scopes);
|
self.walk_pat(pat, temp, loop_scopes);
|
||||||
join_bits(&self.dfcx.oper, temp, in_out);
|
join_bits(&self.dfcx.oper, temp, in_out);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ fn collect_freevars(def_map: resolve::DefMap, blk: &ast::blk)
|
||||||
visit_expr: walk_expr,
|
visit_expr: walk_expr,
|
||||||
.. *visit::default_visitor()});
|
.. *visit::default_visitor()});
|
||||||
(v.visit_block)(blk, (1, v));
|
(v.visit_block)(blk, (1, v));
|
||||||
return @/*bad*/copy *refs;
|
return @(*refs).clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a map from every function and for-each body to a set of the
|
// Build a map from every function and for-each body to a set of the
|
||||||
|
|
|
@ -53,6 +53,7 @@ use syntax::{visit, ast_util};
|
||||||
|
|
||||||
pub static try_adding: &'static str = "Try adding a move";
|
pub static try_adding: &'static str = "Try adding a move";
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
method_map: typeck::method_map,
|
method_map: typeck::method_map,
|
||||||
|
|
|
@ -67,7 +67,7 @@ use syntax::{ast, visit, ast_util};
|
||||||
* item that's being warned about.
|
* item that's being warned about.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum lint {
|
pub enum lint {
|
||||||
ctypes,
|
ctypes,
|
||||||
unused_imports,
|
unused_imports,
|
||||||
|
@ -109,7 +109,7 @@ pub fn level_to_str(lv: level) -> &'static str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, Ord)]
|
#[deriving(Clone, Eq, Ord)]
|
||||||
pub enum level {
|
pub enum level {
|
||||||
allow, warn, deny, forbid
|
allow, warn, deny, forbid
|
||||||
}
|
}
|
||||||
|
@ -652,8 +652,11 @@ fn lint_type_limits() -> visit::vt<@mut Context> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_limits(cx: &Context, binop: ast::binop, l: &ast::expr,
|
fn check_limits(cx: &Context,
|
||||||
r: &ast::expr) -> bool {
|
binop: ast::binop,
|
||||||
|
l: @ast::expr,
|
||||||
|
r: @ast::expr)
|
||||||
|
-> bool {
|
||||||
let (lit, expr, swap) = match (&l.node, &r.node) {
|
let (lit, expr, swap) = match (&l.node, &r.node) {
|
||||||
(&ast::expr_lit(_), _) => (l, r, true),
|
(&ast::expr_lit(_), _) => (l, r, true),
|
||||||
(_, &ast::expr_lit(_)) => (r, l, false),
|
(_, &ast::expr_lit(_)) => (r, l, false),
|
||||||
|
@ -666,7 +669,7 @@ fn lint_type_limits() -> visit::vt<@mut Context> {
|
||||||
} else {
|
} else {
|
||||||
binop
|
binop
|
||||||
};
|
};
|
||||||
match ty::get(ty::expr_ty(cx.tcx, @/*bad*/copy *expr)).sty {
|
match ty::get(ty::expr_ty(cx.tcx, expr)).sty {
|
||||||
ty::ty_int(int_ty) => {
|
ty::ty_int(int_ty) => {
|
||||||
let (min, max) = int_ty_range(int_ty);
|
let (min, max) = int_ty_range(int_ty);
|
||||||
let lit_val: i64 = match lit.node {
|
let lit_val: i64 = match lit.node {
|
||||||
|
@ -708,7 +711,7 @@ fn lint_type_limits() -> visit::vt<@mut Context> {
|
||||||
visit::mk_vt(@visit::Visitor {
|
visit::mk_vt(@visit::Visitor {
|
||||||
visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| {
|
visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| {
|
||||||
match e.node {
|
match e.node {
|
||||||
ast::expr_binary(_, ref binop, @ref l, @ref r) => {
|
ast::expr_binary(_, ref binop, l, r) => {
|
||||||
if is_comparison(*binop)
|
if is_comparison(*binop)
|
||||||
&& !check_limits(cx, *binop, l, r) {
|
&& !check_limits(cx, *binop, l, r) {
|
||||||
cx.span_lint(type_limits, e.span,
|
cx.span_lint(type_limits, e.span,
|
||||||
|
|
|
@ -128,6 +128,12 @@ struct Variable(uint);
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
struct LiveNode(uint);
|
struct LiveNode(uint);
|
||||||
|
|
||||||
|
impl Clone for LiveNode {
|
||||||
|
fn clone(&self) -> LiveNode {
|
||||||
|
LiveNode(**self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
enum LiveNodeKind {
|
enum LiveNodeKind {
|
||||||
FreeVarNode(span),
|
FreeVarNode(span),
|
||||||
|
@ -522,6 +528,7 @@ fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
|
||||||
// Actually we compute just a bit more than just liveness, but we use
|
// Actually we compute just a bit more than just liveness, but we use
|
||||||
// the same basic propagation framework in all cases.
|
// the same basic propagation framework in all cases.
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
struct Users {
|
struct Users {
|
||||||
reader: LiveNode,
|
reader: LiveNode,
|
||||||
writer: LiveNode,
|
writer: LiveNode,
|
||||||
|
|
|
@ -170,12 +170,14 @@ pub type MovesMap = @mut HashSet<node_id>;
|
||||||
pub type MovedVariablesSet = @mut HashSet<node_id>;
|
pub type MovedVariablesSet = @mut HashSet<node_id>;
|
||||||
|
|
||||||
/** See the section Output on the module comment for explanation. */
|
/** See the section Output on the module comment for explanation. */
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct MoveMaps {
|
pub struct MoveMaps {
|
||||||
moves_map: MovesMap,
|
moves_map: MovesMap,
|
||||||
moved_variables_set: MovedVariablesSet,
|
moved_variables_set: MovedVariablesSet,
|
||||||
capture_map: CaptureMap
|
capture_map: CaptureMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
struct VisitContext {
|
struct VisitContext {
|
||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
method_map: method_map,
|
method_map: method_map,
|
||||||
|
|
|
@ -376,7 +376,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
|
||||||
visit_item: |item, (method_map, visitor)| {
|
visit_item: |item, (method_map, visitor)| {
|
||||||
// Do not check privacy inside items with the resolve_unexported
|
// Do not check privacy inside items with the resolve_unexported
|
||||||
// attribute. This is used for the test runner.
|
// attribute. This is used for the test runner.
|
||||||
if !attr::contains_name(attr::attr_metas(/*bad*/copy item.attrs),
|
if !attr::contains_name(attr::attr_metas(item.attrs),
|
||||||
"!resolve_unexported") {
|
"!resolve_unexported") {
|
||||||
visit::visit_item(item, (method_map, visitor));
|
visit::visit_item(item, (method_map, visitor));
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ fn trait_method_might_be_inlined(trait_method: &trait_method) -> bool {
|
||||||
// The context we're in. If we're in a public context, then public symbols are
|
// The context we're in. If we're in a public context, then public symbols are
|
||||||
// marked reachable. If we're in a private context, then only trait
|
// marked reachable. If we're in a private context, then only trait
|
||||||
// implementations are marked reachable.
|
// implementations are marked reachable.
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
enum PrivacyContext {
|
enum PrivacyContext {
|
||||||
PublicContext,
|
PublicContext,
|
||||||
PrivateContext,
|
PrivateContext,
|
||||||
|
|
|
@ -60,6 +60,7 @@ pub struct RegionMaps {
|
||||||
priv cleanup_scopes: HashSet<ast::node_id>
|
priv cleanup_scopes: HashSet<ast::node_id>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
sess: Session,
|
sess: Session,
|
||||||
def_map: resolve::DefMap,
|
def_map: resolve::DefMap,
|
||||||
|
|
|
@ -158,6 +158,7 @@ pub enum ImportDirectiveSubclass {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The context that we thread through while building the reduced graph.
|
/// The context that we thread through while building the reduced graph.
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum ReducedGraphParent {
|
pub enum ReducedGraphParent {
|
||||||
ModuleReducedGraphParent(@mut Module)
|
ModuleReducedGraphParent(@mut Module)
|
||||||
}
|
}
|
||||||
|
@ -1483,12 +1484,13 @@ impl Resolver {
|
||||||
for source_idents.iter().advance |source_ident| {
|
for source_idents.iter().advance |source_ident| {
|
||||||
let name = source_ident.node.name;
|
let name = source_ident.node.name;
|
||||||
let subclass = @SingleImport(name, name);
|
let subclass = @SingleImport(name, name);
|
||||||
self.build_import_directive(privacy,
|
self.build_import_directive(
|
||||||
module_,
|
privacy,
|
||||||
copy module_path,
|
module_,
|
||||||
subclass,
|
module_path.clone(),
|
||||||
source_ident.span,
|
subclass,
|
||||||
source_ident.node.id);
|
source_ident.span,
|
||||||
|
source_ident.node.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view_path_glob(_, id) => {
|
view_path_glob(_, id) => {
|
||||||
|
@ -5165,13 +5167,13 @@ impl Resolver {
|
||||||
match self.method_map.find(&name) {
|
match self.method_map.find(&name) {
|
||||||
Some(candidate_traits) => loop {
|
Some(candidate_traits) => loop {
|
||||||
// Look for the current trait.
|
// Look for the current trait.
|
||||||
match /*bad*/copy self.current_trait_refs {
|
match self.current_trait_refs {
|
||||||
Some(trait_def_ids) => {
|
Some(ref trait_def_ids) => {
|
||||||
for trait_def_ids.iter().advance |trait_def_id| {
|
for trait_def_ids.iter().advance |trait_def_id| {
|
||||||
if candidate_traits.contains(trait_def_id) {
|
if candidate_traits.contains(trait_def_id) {
|
||||||
self.add_trait_info(
|
self.add_trait_info(&mut found_traits,
|
||||||
&mut found_traits,
|
*trait_def_id,
|
||||||
*trait_def_id, name);
|
name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5428,10 +5430,9 @@ pub fn resolve_crate(session: Session,
|
||||||
-> CrateMap {
|
-> CrateMap {
|
||||||
let resolver = @mut Resolver(session, lang_items, crate);
|
let resolver = @mut Resolver(session, lang_items, crate);
|
||||||
resolver.resolve();
|
resolver.resolve();
|
||||||
let Resolver { def_map, export_map2, trait_map, _ } = copy *resolver;
|
|
||||||
CrateMap {
|
CrateMap {
|
||||||
def_map: def_map,
|
def_map: resolver.def_map,
|
||||||
exp_map2: export_map2,
|
exp_map2: resolver.export_map2,
|
||||||
trait_map: trait_map
|
trait_map: resolver.trait_map.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
*
|
*
|
||||||
* let a: A = ...;
|
* let a: A = ...;
|
||||||
* let b: B = ...;
|
* let b: B = ...;
|
||||||
* match (a, b) { (ref c, copy d) => { ... } }
|
* match (a, b) { (ref c, d) => { ... } }
|
||||||
*
|
*
|
||||||
* For `c` and `d`, we would generate allocas of type `C*` and `D*`
|
* For `c` and `d`, we would generate allocas of type `C*` and `D*`
|
||||||
* respectively. These are called the `llmatch`. As we match, when we come
|
* respectively. These are called the `llmatch`. As we match, when we come
|
||||||
|
@ -540,9 +540,10 @@ pub fn enter_opt<'r>(bcx: block,
|
||||||
}
|
}
|
||||||
ast::pat_enum(_, ref subpats) => {
|
ast::pat_enum(_, ref subpats) => {
|
||||||
if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
|
if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
|
||||||
|
// XXX: Must we clone?
|
||||||
match *subpats {
|
match *subpats {
|
||||||
None => Some(vec::from_elem(variant_size, dummy)),
|
None => Some(vec::from_elem(variant_size, dummy)),
|
||||||
_ => copy *subpats
|
_ => (*subpats).clone(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -597,7 +598,7 @@ pub fn enter_opt<'r>(bcx: block,
|
||||||
let n = before.len() + after.len();
|
let n = before.len() + after.len();
|
||||||
let i = before.len();
|
let i = before.len();
|
||||||
if opt_eq(tcx, &vec_len_ge(n, i), opt) {
|
if opt_eq(tcx, &vec_len_ge(n, i), opt) {
|
||||||
Some(vec::append_one(copy *before, slice) +
|
Some(vec::append_one((*before).clone(), slice) +
|
||||||
*after)
|
*after)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -606,7 +607,7 @@ pub fn enter_opt<'r>(bcx: block,
|
||||||
None => {
|
None => {
|
||||||
let n = before.len();
|
let n = before.len();
|
||||||
if opt_eq(tcx, &vec_len_eq(n), opt) {
|
if opt_eq(tcx, &vec_len_eq(n), opt) {
|
||||||
Some(copy *before)
|
Some((*before).clone())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -673,9 +674,7 @@ pub fn enter_tup<'r>(bcx: block,
|
||||||
let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()};
|
let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()};
|
||||||
do enter_match(bcx, dm, m, col, val) |p| {
|
do enter_match(bcx, dm, m, col, val) |p| {
|
||||||
match p.node {
|
match p.node {
|
||||||
ast::pat_tup(ref elts) => {
|
ast::pat_tup(ref elts) => Some((*elts).clone()),
|
||||||
Some(copy *elts)
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
assert_is_binding_or_wild(bcx, p);
|
assert_is_binding_or_wild(bcx, p);
|
||||||
Some(vec::from_elem(n_elts, dummy))
|
Some(vec::from_elem(n_elts, dummy))
|
||||||
|
@ -701,7 +700,7 @@ pub fn enter_tuple_struct<'r>(bcx: block,
|
||||||
let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()};
|
let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()};
|
||||||
do enter_match(bcx, dm, m, col, val) |p| {
|
do enter_match(bcx, dm, m, col, val) |p| {
|
||||||
match p.node {
|
match p.node {
|
||||||
ast::pat_enum(_, Some(ref elts)) => Some(copy *elts),
|
ast::pat_enum(_, Some(ref elts)) => Some((*elts).clone()),
|
||||||
_ => {
|
_ => {
|
||||||
assert_is_binding_or_wild(bcx, p);
|
assert_is_binding_or_wild(bcx, p);
|
||||||
Some(vec::from_elem(n_elts, dummy))
|
Some(vec::from_elem(n_elts, dummy))
|
||||||
|
@ -1582,7 +1581,7 @@ pub fn compile_submatch(bcx: block,
|
||||||
let args = extract_vec_elems(opt_cx, pat_span, pat_id, n, slice,
|
let args = extract_vec_elems(opt_cx, pat_span, pat_id, n, slice,
|
||||||
val, test_val);
|
val, test_val);
|
||||||
size = args.vals.len();
|
size = args.vals.len();
|
||||||
unpacked = /*bad*/copy args.vals;
|
unpacked = args.vals.clone();
|
||||||
opt_cx = args.bcx;
|
opt_cx = args.bcx;
|
||||||
}
|
}
|
||||||
lit(_) | range(_, _) => ()
|
lit(_) | range(_, _) => ()
|
||||||
|
@ -1606,7 +1605,7 @@ pub fn compile_submatch(bcx: block,
|
||||||
pub fn trans_match(bcx: block,
|
pub fn trans_match(bcx: block,
|
||||||
match_expr: &ast::expr,
|
match_expr: &ast::expr,
|
||||||
discr_expr: @ast::expr,
|
discr_expr: @ast::expr,
|
||||||
arms: ~[ast::arm],
|
arms: &[ast::arm],
|
||||||
dest: Dest) -> block {
|
dest: Dest) -> block {
|
||||||
let _icx = push_ctxt("match::trans_match");
|
let _icx = push_ctxt("match::trans_match");
|
||||||
do with_scope(bcx, match_expr.info(), "match") |bcx| {
|
do with_scope(bcx, match_expr.info(), "match") |bcx| {
|
||||||
|
|
|
@ -191,9 +191,11 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
|
||||||
Some(ptrfield) => {
|
Some(ptrfield) => {
|
||||||
return NullablePointer {
|
return NullablePointer {
|
||||||
nndiscr: discr,
|
nndiscr: discr,
|
||||||
nonnull: mk_struct(cx, cases[discr].tys, false),
|
nonnull: mk_struct(cx,
|
||||||
|
cases[discr].tys,
|
||||||
|
false),
|
||||||
ptrfield: ptrfield,
|
ptrfield: ptrfield,
|
||||||
nullfields: copy cases[1 - discr].tys
|
nullfields: cases[1 - discr].tys.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => { }
|
None => { }
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl Drop for _InsnCtxt {
|
||||||
fn drop(&self) {
|
fn drop(&self) {
|
||||||
do local_data::modify(task_local_insn_key) |c| {
|
do local_data::modify(task_local_insn_key) |c| {
|
||||||
do c.map_consume |ctx| {
|
do c.map_consume |ctx| {
|
||||||
let mut ctx = copy *ctx;
|
let mut ctx = (*ctx).clone();
|
||||||
ctx.pop();
|
ctx.pop();
|
||||||
@ctx
|
@ctx
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
|
||||||
debug!("new InsnCtxt: %s", s);
|
debug!("new InsnCtxt: %s", s);
|
||||||
do local_data::modify(task_local_insn_key) |c| {
|
do local_data::modify(task_local_insn_key) |c| {
|
||||||
do c.map_consume |ctx| {
|
do c.map_consume |ctx| {
|
||||||
let mut ctx = copy *ctx;
|
let mut ctx = (*ctx).clone();
|
||||||
ctx.push(s);
|
ctx.push(s);
|
||||||
@ctx
|
@ctx
|
||||||
}
|
}
|
||||||
|
@ -1413,7 +1413,7 @@ pub fn with_scope(bcx: block,
|
||||||
let scope = simple_block_scope(bcx.scope, opt_node_info);
|
let scope = simple_block_scope(bcx.scope, opt_node_info);
|
||||||
bcx.scope = Some(scope);
|
bcx.scope = Some(scope);
|
||||||
let ret = f(bcx);
|
let ret = f(bcx);
|
||||||
let ret = trans_block_cleanups_(ret, /*bad*/copy scope.cleanups, false);
|
let ret = trans_block_cleanups_(ret, (scope.cleanups).clone(), false);
|
||||||
bcx.scope = scope.parent;
|
bcx.scope = scope.parent;
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
@ -1427,7 +1427,9 @@ pub fn with_scope_result(bcx: block,
|
||||||
let scope = simple_block_scope(bcx.scope, opt_node_info);
|
let scope = simple_block_scope(bcx.scope, opt_node_info);
|
||||||
bcx.scope = Some(scope);
|
bcx.scope = Some(scope);
|
||||||
let Result { bcx: out_bcx, val } = f(bcx);
|
let Result { bcx: out_bcx, val } = f(bcx);
|
||||||
let out_bcx = trans_block_cleanups_(out_bcx, /*bad*/copy scope.cleanups, false);
|
let out_bcx = trans_block_cleanups_(out_bcx,
|
||||||
|
(scope.cleanups).clone(),
|
||||||
|
false);
|
||||||
bcx.scope = scope.parent;
|
bcx.scope = scope.parent;
|
||||||
|
|
||||||
rslt(out_bcx, val)
|
rslt(out_bcx, val)
|
||||||
|
@ -1932,7 +1934,7 @@ pub fn trans_fn(ccx: @mut CrateContext,
|
||||||
let _icx = push_ctxt("trans_fn");
|
let _icx = push_ctxt("trans_fn");
|
||||||
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
|
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
|
||||||
trans_closure(ccx,
|
trans_closure(ccx,
|
||||||
copy path,
|
path.clone(),
|
||||||
decl,
|
decl,
|
||||||
body,
|
body,
|
||||||
llfndecl,
|
llfndecl,
|
||||||
|
@ -2038,7 +2040,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
|
||||||
let fn_args = do args.map |varg| {
|
let fn_args = do args.map |varg| {
|
||||||
ast::arg {
|
ast::arg {
|
||||||
is_mutbl: false,
|
is_mutbl: false,
|
||||||
ty: copy *varg.ty(),
|
ty: (*varg.ty()).clone(),
|
||||||
pat: ast_util::ident_to_pat(
|
pat: ast_util::ident_to_pat(
|
||||||
ccx.tcx.sess.next_node_id(),
|
ccx.tcx.sess.next_node_id(),
|
||||||
codemap::dummy_sp(),
|
codemap::dummy_sp(),
|
||||||
|
@ -2047,12 +2049,21 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let no_substs: &[ty::t] = [];
|
||||||
let ty_param_substs = match param_substs {
|
let ty_param_substs = match param_substs {
|
||||||
Some(ref substs) => { copy substs.tys }
|
Some(ref substs) => {
|
||||||
None => ~[]
|
let v: &[ty::t] = substs.tys;
|
||||||
|
v
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let v: &[ty::t] = no_substs;
|
||||||
|
v
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let ctor_ty = ty::subst_tps(ccx.tcx, ty_param_substs, None,
|
let ctor_ty = ty::subst_tps(ccx.tcx,
|
||||||
|
ty_param_substs,
|
||||||
|
None,
|
||||||
ty::node_id_to_type(ccx.tcx, ctor_id));
|
ty::node_id_to_type(ccx.tcx, ctor_id));
|
||||||
|
|
||||||
let result_ty = match ty::get(ctor_ty).sty {
|
let result_ty = match ty::get(ctor_ty).sty {
|
||||||
|
@ -2130,7 +2141,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
|
||||||
if purity == ast::extern_fn {
|
if purity == ast::extern_fn {
|
||||||
let llfndecl = get_item_val(ccx, item.id);
|
let llfndecl = get_item_val(ccx, item.id);
|
||||||
foreign::trans_foreign_fn(ccx,
|
foreign::trans_foreign_fn(ccx,
|
||||||
vec::append(/*bad*/copy *path,
|
vec::append((*path).clone(),
|
||||||
[path_name(item.ident)]),
|
[path_name(item.ident)]),
|
||||||
decl,
|
decl,
|
||||||
body,
|
body,
|
||||||
|
@ -2139,7 +2150,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
|
||||||
} else if !generics.is_type_parameterized() {
|
} else if !generics.is_type_parameterized() {
|
||||||
let llfndecl = get_item_val(ccx, item.id);
|
let llfndecl = get_item_val(ccx, item.id);
|
||||||
trans_fn(ccx,
|
trans_fn(ccx,
|
||||||
vec::append(/*bad*/copy *path, [path_name(item.ident)]),
|
vec::append((*path).clone(), [path_name(item.ident)]),
|
||||||
decl,
|
decl,
|
||||||
body,
|
body,
|
||||||
llfndecl,
|
llfndecl,
|
||||||
|
@ -2160,8 +2171,12 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::item_impl(ref generics, _, _, ref ms) => {
|
ast::item_impl(ref generics, _, _, ref ms) => {
|
||||||
meth::trans_impl(ccx, /*bad*/copy *path, item.ident, *ms,
|
meth::trans_impl(ccx,
|
||||||
generics, item.id);
|
(*path).clone(),
|
||||||
|
item.ident,
|
||||||
|
*ms,
|
||||||
|
generics,
|
||||||
|
item.id);
|
||||||
}
|
}
|
||||||
ast::item_mod(ref m) => {
|
ast::item_mod(ref m) => {
|
||||||
trans_mod(ccx, m);
|
trans_mod(ccx, m);
|
||||||
|
@ -2274,7 +2289,7 @@ pub fn register_fn_fuller(ccx: @mut CrateContext,
|
||||||
let ps = if attr::attrs_contains_name(attrs, "no_mangle") {
|
let ps = if attr::attrs_contains_name(attrs, "no_mangle") {
|
||||||
path_elt_to_str(*path.last(), token::get_ident_interner())
|
path_elt_to_str(*path.last(), token::get_ident_interner())
|
||||||
} else {
|
} else {
|
||||||
mangle_exported_name(ccx, /*bad*/copy path, node_type)
|
mangle_exported_name(ccx, path, node_type)
|
||||||
};
|
};
|
||||||
|
|
||||||
let llfn = decl_fn(ccx.llmod, ps, cc, fn_ty);
|
let llfn = decl_fn(ccx.llmod, ps, cc, fn_ty);
|
||||||
|
@ -2432,7 +2447,7 @@ pub fn item_path(ccx: &CrateContext, i: &ast::item) -> path {
|
||||||
// separate map for paths?
|
// separate map for paths?
|
||||||
_ => fail!("item_path")
|
_ => fail!("item_path")
|
||||||
};
|
};
|
||||||
vec::append(/*bad*/copy *base, [path_name(i.ident)])
|
vec::append((*base).clone(), [path_name(i.ident)])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
||||||
|
@ -2445,8 +2460,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
||||||
let item = ccx.tcx.items.get_copy(&id);
|
let item = ccx.tcx.items.get_copy(&id);
|
||||||
let val = match item {
|
let val = match item {
|
||||||
ast_map::node_item(i, pth) => {
|
ast_map::node_item(i, pth) => {
|
||||||
let my_path = vec::append(/*bad*/copy *pth,
|
let my_path = vec::append((*pth).clone(), [path_name(i.ident)]);
|
||||||
[path_name(i.ident)]);
|
|
||||||
match i.node {
|
match i.node {
|
||||||
ast::item_static(_, m, expr) => {
|
ast::item_static(_, m, expr) => {
|
||||||
let typ = ty::node_id_to_type(ccx.tcx, i.id);
|
let typ = ty::node_id_to_type(ccx.tcx, i.id);
|
||||||
|
@ -2502,7 +2516,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
||||||
match ni.node {
|
match ni.node {
|
||||||
ast::foreign_item_fn(*) => {
|
ast::foreign_item_fn(*) => {
|
||||||
register_fn(ccx, ni.span,
|
register_fn(ccx, ni.span,
|
||||||
vec::append(/*bad*/copy *pth,
|
vec::append((*pth).clone(),
|
||||||
[path_name(ni.ident)]),
|
[path_name(ni.ident)]),
|
||||||
ni.id,
|
ni.id,
|
||||||
ni.attrs)
|
ni.attrs)
|
||||||
|
@ -2526,7 +2540,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
||||||
match v.node.kind {
|
match v.node.kind {
|
||||||
ast::tuple_variant_kind(ref args) => {
|
ast::tuple_variant_kind(ref args) => {
|
||||||
assert!(args.len() != 0u);
|
assert!(args.len() != 0u);
|
||||||
let pth = vec::append(/*bad*/copy *pth,
|
let pth = vec::append((*pth).clone(),
|
||||||
[path_name(enm.ident),
|
[path_name(enm.ident),
|
||||||
path_name((*v).node.name)]);
|
path_name((*v).node.name)]);
|
||||||
llfn = match enm.node {
|
llfn = match enm.node {
|
||||||
|
@ -2554,7 +2568,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
|
||||||
Some(ctor_id) => {
|
Some(ctor_id) => {
|
||||||
let llfn = register_fn(ccx,
|
let llfn = register_fn(ccx,
|
||||||
struct_item.span,
|
struct_item.span,
|
||||||
/*bad*/copy *struct_path,
|
(*struct_path).clone(),
|
||||||
ctor_id,
|
ctor_id,
|
||||||
struct_item.attrs);
|
struct_item.attrs);
|
||||||
set_inline_hint(llfn);
|
set_inline_hint(llfn);
|
||||||
|
@ -2583,7 +2597,7 @@ pub fn register_method(ccx: @mut CrateContext,
|
||||||
m: @ast::method) -> ValueRef {
|
m: @ast::method) -> ValueRef {
|
||||||
let mty = ty::node_id_to_type(ccx.tcx, id);
|
let mty = ty::node_id_to_type(ccx.tcx, id);
|
||||||
|
|
||||||
let mut path = /*bad*/ copy *path;
|
let mut path = (*path).clone();
|
||||||
path.push(path_name(gensym_name("meth")));
|
path.push(path_name(gensym_name("meth")));
|
||||||
path.push(path_name(m.ident));
|
path.push(path_name(m.ident));
|
||||||
|
|
||||||
|
@ -2603,7 +2617,7 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let path = item_path(ccx, it);
|
let path = item_path(ccx, it);
|
||||||
for (*enum_definition).variants.iter().advance |variant| {
|
for (*enum_definition).variants.iter().advance |variant| {
|
||||||
let p = vec::append(/*bad*/copy path, [
|
let p = vec::append(path.clone(), [
|
||||||
path_name(variant.node.name),
|
path_name(variant.node.name),
|
||||||
path_name(special_idents::descrim)
|
path_name(special_idents::descrim)
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -897,7 +897,7 @@ pub fn add_span_comment(bcx: block, sp: span, text: &str) {
|
||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
if ccx.sess.asm_comments() {
|
if ccx.sess.asm_comments() {
|
||||||
let s = fmt!("%s (%s)", text, ccx.sess.codemap.span_to_str(sp));
|
let s = fmt!("%s (%s)", text, ccx.sess.codemap.span_to_str(sp));
|
||||||
debug!("%s", copy s);
|
debug!("%s", s);
|
||||||
add_comment(bcx, s);
|
add_comment(bcx, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub trait ABIInfo {
|
||||||
fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType;
|
fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct LLVMType {
|
pub struct LLVMType {
|
||||||
cast: bool,
|
cast: bool,
|
||||||
ty: Type
|
ty: Type
|
||||||
|
|
|
@ -24,7 +24,7 @@ use std::option::Option;
|
||||||
use std::uint;
|
use std::uint;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
enum RegClass {
|
enum RegClass {
|
||||||
NoClass,
|
NoClass,
|
||||||
Int,
|
Int,
|
||||||
|
|
|
@ -221,7 +221,7 @@ fn resolve_default_method_vtables(bcx: block,
|
||||||
// Build up a param_substs that we are going to resolve the
|
// Build up a param_substs that we are going to resolve the
|
||||||
// trait_vtables under.
|
// trait_vtables under.
|
||||||
let param_substs = Some(@param_substs {
|
let param_substs = Some(@param_substs {
|
||||||
tys: copy substs.tps,
|
tys: substs.tps.clone(),
|
||||||
self_ty: substs.self_ty,
|
self_ty: substs.self_ty,
|
||||||
vtables: impl_vtables,
|
vtables: impl_vtables,
|
||||||
self_vtable: None
|
self_vtable: None
|
||||||
|
|
|
@ -423,11 +423,11 @@ pub fn trans_expr_fn(bcx: block,
|
||||||
|
|
||||||
let llfnty = type_of_fn_from_ty(ccx, fty);
|
let llfnty = type_of_fn_from_ty(ccx, fty);
|
||||||
|
|
||||||
let sub_path = vec::append_one(/*bad*/copy bcx.fcx.path,
|
let sub_path = vec::append_one(bcx.fcx.path.clone(),
|
||||||
path_name(special_idents::anon));
|
path_name(special_idents::anon));
|
||||||
// XXX: Bad copy.
|
// XXX: Bad copy.
|
||||||
let s = mangle_internal_name_by_path_and_seq(ccx,
|
let s = mangle_internal_name_by_path_and_seq(ccx,
|
||||||
copy sub_path,
|
sub_path.clone(),
|
||||||
"expr_fn");
|
"expr_fn");
|
||||||
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
|
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
|
||||||
|
|
||||||
|
|
|
@ -287,7 +287,7 @@ pub enum heap {
|
||||||
heap_exchange_closure
|
heap_exchange_closure
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum cleantype {
|
pub enum cleantype {
|
||||||
normal_exit_only,
|
normal_exit_only,
|
||||||
normal_exit_and_unwind
|
normal_exit_and_unwind
|
||||||
|
@ -298,8 +298,19 @@ pub enum cleanup {
|
||||||
clean_temp(ValueRef, @fn(block) -> block, cleantype),
|
clean_temp(ValueRef, @fn(block) -> block, cleantype),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Can't use deriving(Clone) because of the managed closure.
|
||||||
|
impl Clone for cleanup {
|
||||||
|
fn clone(&self) -> cleanup {
|
||||||
|
match *self {
|
||||||
|
clean(f, ct) => clean(f, ct),
|
||||||
|
clean_temp(v, f, ct) => clean_temp(v, f, ct),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Used to remember and reuse existing cleanup paths
|
// Used to remember and reuse existing cleanup paths
|
||||||
// target: none means the path ends in an resume instruction
|
// target: none means the path ends in an resume instruction
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct cleanup_path {
|
pub struct cleanup_path {
|
||||||
target: Option<BasicBlockRef>,
|
target: Option<BasicBlockRef>,
|
||||||
size: uint,
|
size: uint,
|
||||||
|
@ -441,7 +452,7 @@ pub fn revoke_clean(cx: block, val: ValueRef) {
|
||||||
pub fn block_cleanups(bcx: block) -> ~[cleanup] {
|
pub fn block_cleanups(bcx: block) -> ~[cleanup] {
|
||||||
match bcx.scope {
|
match bcx.scope {
|
||||||
None => ~[],
|
None => ~[],
|
||||||
Some(inf) => /*bad*/copy inf.cleanups
|
Some(inf) => inf.cleanups.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,7 +1047,9 @@ pub fn resolve_vtables_under_param_substs(tcx: ty::ctxt,
|
||||||
-> typeck::vtable_res {
|
-> typeck::vtable_res {
|
||||||
@vts.iter().transform(|ds|
|
@vts.iter().transform(|ds|
|
||||||
@ds.iter().transform(
|
@ds.iter().transform(
|
||||||
|d| resolve_vtable_under_param_substs(tcx, param_substs, copy *d))
|
|d| resolve_vtable_under_param_substs(tcx,
|
||||||
|
param_substs,
|
||||||
|
d))
|
||||||
.collect::<~[typeck::vtable_origin]>())
|
.collect::<~[typeck::vtable_origin]>())
|
||||||
.collect::<~[typeck::vtable_param_res]>()
|
.collect::<~[typeck::vtable_param_res]>()
|
||||||
}
|
}
|
||||||
|
@ -1044,7 +1057,7 @@ pub fn resolve_vtables_under_param_substs(tcx: ty::ctxt,
|
||||||
|
|
||||||
// Apply the typaram substitutions in the fn_ctxt to a vtable. This should
|
// Apply the typaram substitutions in the fn_ctxt to a vtable. This should
|
||||||
// eliminate any vtable_params.
|
// eliminate any vtable_params.
|
||||||
pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin)
|
pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: &typeck::vtable_origin)
|
||||||
-> typeck::vtable_origin {
|
-> typeck::vtable_origin {
|
||||||
resolve_vtable_under_param_substs(fcx.ccx.tcx,
|
resolve_vtable_under_param_substs(fcx.ccx.tcx,
|
||||||
fcx.param_substs,
|
fcx.param_substs,
|
||||||
|
@ -1053,17 +1066,17 @@ pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin)
|
||||||
|
|
||||||
pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
|
pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
|
||||||
param_substs: Option<@param_substs>,
|
param_substs: Option<@param_substs>,
|
||||||
vt: typeck::vtable_origin)
|
vt: &typeck::vtable_origin)
|
||||||
-> typeck::vtable_origin {
|
-> typeck::vtable_origin {
|
||||||
match vt {
|
match *vt {
|
||||||
typeck::vtable_static(trait_id, tys, sub) => {
|
typeck::vtable_static(trait_id, ref tys, sub) => {
|
||||||
let tys = match param_substs {
|
let tys = match param_substs {
|
||||||
Some(substs) => {
|
Some(substs) => {
|
||||||
do tys.iter().transform |t| {
|
do tys.iter().transform |t| {
|
||||||
ty::subst_tps(tcx, substs.tys, substs.self_ty, *t)
|
ty::subst_tps(tcx, substs.tys, substs.self_ty, *t)
|
||||||
}.collect()
|
}.collect()
|
||||||
}
|
}
|
||||||
_ => tys
|
_ => tys.to_owned()
|
||||||
};
|
};
|
||||||
typeck::vtable_static(
|
typeck::vtable_static(
|
||||||
trait_id, tys,
|
trait_id, tys,
|
||||||
|
@ -1085,7 +1098,7 @@ pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
|
||||||
match param_substs {
|
match param_substs {
|
||||||
Some(@param_substs
|
Some(@param_substs
|
||||||
{self_vtable: Some(ref self_vtable), _}) => {
|
{self_vtable: Some(ref self_vtable), _}) => {
|
||||||
copy *self_vtable
|
(*self_vtable).clone()
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
tcx.sess.bug(fmt!(
|
tcx.sess.bug(fmt!(
|
||||||
|
@ -1097,13 +1110,15 @@ pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_vtable(tcx: ty::ctxt, ps: ¶m_substs,
|
pub fn find_vtable(tcx: ty::ctxt,
|
||||||
n_param: uint, n_bound: uint)
|
ps: ¶m_substs,
|
||||||
-> typeck::vtable_origin {
|
n_param: uint,
|
||||||
|
n_bound: uint)
|
||||||
|
-> typeck::vtable_origin {
|
||||||
debug!("find_vtable(n_param=%u, n_bound=%u, ps=%s)",
|
debug!("find_vtable(n_param=%u, n_bound=%u, ps=%s)",
|
||||||
n_param, n_bound, ps.repr(tcx));
|
n_param, n_bound, ps.repr(tcx));
|
||||||
|
|
||||||
/*bad*/ copy ps.vtables.get()[n_param][n_bound]
|
ps.vtables.get()[n_param][n_bound].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dummy_substs(tps: ~[ty::t]) -> ty::substs {
|
pub fn dummy_substs(tps: ~[ty::t]) -> ty::substs {
|
||||||
|
|
|
@ -816,8 +816,8 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
|
||||||
|
|
||||||
debug!("create_ty: %?", ty::get(t));
|
debug!("create_ty: %?", ty::get(t));
|
||||||
|
|
||||||
let sty = copy ty::get(t).sty;
|
let sty = &ty::get(t).sty;
|
||||||
let ty_md = match sty {
|
let ty_md = match *sty {
|
||||||
ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_int(_) | ty::ty_uint(_)
|
ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_int(_) | ty::ty_uint(_)
|
||||||
| ty::ty_float(_) => create_basic_type(cx, t, span),
|
| ty::ty_float(_) => create_basic_type(cx, t, span),
|
||||||
ty::ty_estr(ref vstore) => {
|
ty::ty_estr(ref vstore) => {
|
||||||
|
|
|
@ -570,8 +570,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
|
||||||
return controlflow::trans_if(bcx, cond, thn, els, dest);
|
return controlflow::trans_if(bcx, cond, thn, els, dest);
|
||||||
}
|
}
|
||||||
ast::expr_match(discr, ref arms) => {
|
ast::expr_match(discr, ref arms) => {
|
||||||
return _match::trans_match(bcx, expr, discr, /*bad*/copy *arms,
|
return _match::trans_match(bcx, expr, discr, *arms, dest);
|
||||||
dest);
|
|
||||||
}
|
}
|
||||||
ast::expr_block(ref blk) => {
|
ast::expr_block(ref blk) => {
|
||||||
return do base::with_scope(bcx, blk.info(),
|
return do base::with_scope(bcx, blk.info(),
|
||||||
|
|
|
@ -109,7 +109,7 @@ fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig)
|
||||||
|
|
||||||
fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes {
|
fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes {
|
||||||
let fn_sig = match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty {
|
let fn_sig = match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty {
|
||||||
ty::ty_bare_fn(ref fn_ty) => copy fn_ty.sig,
|
ty::ty_bare_fn(ref fn_ty) => fn_ty.sig.clone(),
|
||||||
_ => ccx.sess.bug("c_arg_and_ret_lltys called on non-function type")
|
_ => ccx.sess.bug("c_arg_and_ret_lltys called on non-function type")
|
||||||
};
|
};
|
||||||
let llsig = foreign_signature(ccx, &fn_sig);
|
let llsig = foreign_signature(ccx, &fn_sig);
|
||||||
|
@ -1163,7 +1163,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
|
||||||
let _icx = push_ctxt("foreign::build_foreign_fn");
|
let _icx = push_ctxt("foreign::build_foreign_fn");
|
||||||
|
|
||||||
fn build_rust_fn(ccx: @mut CrateContext,
|
fn build_rust_fn(ccx: @mut CrateContext,
|
||||||
path: ast_map::path,
|
path: &ast_map::path,
|
||||||
decl: &ast::fn_decl,
|
decl: &ast::fn_decl,
|
||||||
body: &ast::blk,
|
body: &ast::blk,
|
||||||
id: ast::node_id)
|
id: ast::node_id)
|
||||||
|
@ -1172,13 +1172,14 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
|
||||||
let t = ty::node_id_to_type(ccx.tcx, id);
|
let t = ty::node_id_to_type(ccx.tcx, id);
|
||||||
// XXX: Bad copy.
|
// XXX: Bad copy.
|
||||||
let ps = link::mangle_internal_name_by_path(
|
let ps = link::mangle_internal_name_by_path(
|
||||||
ccx, vec::append_one(copy path, ast_map::path_name(
|
ccx,
|
||||||
special_idents::clownshoe_abi
|
vec::append_one((*path).clone(),
|
||||||
)));
|
ast_map::path_name(
|
||||||
|
special_idents::clownshoe_abi)));
|
||||||
let llty = type_of_fn_from_ty(ccx, t);
|
let llty = type_of_fn_from_ty(ccx, t);
|
||||||
let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty);
|
let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty);
|
||||||
trans_fn(ccx,
|
trans_fn(ccx,
|
||||||
path,
|
(*path).clone(),
|
||||||
decl,
|
decl,
|
||||||
body,
|
body,
|
||||||
llfndecl,
|
llfndecl,
|
||||||
|
@ -1318,7 +1319,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
|
||||||
let tys = shim_types(ccx, id);
|
let tys = shim_types(ccx, id);
|
||||||
// The internal Rust ABI function - runs on the Rust stack
|
// The internal Rust ABI function - runs on the Rust stack
|
||||||
// XXX: Bad copy.
|
// XXX: Bad copy.
|
||||||
let llrustfn = build_rust_fn(ccx, copy path, decl, body, id);
|
let llrustfn = build_rust_fn(ccx, &path, decl, body, id);
|
||||||
// The internal shim function - runs on the Rust stack
|
// The internal shim function - runs on the Rust stack
|
||||||
let llshimfn = build_shim_fn(ccx, path, llrustfn, &tys);
|
let llshimfn = build_shim_fn(ccx, path, llrustfn, &tys);
|
||||||
// The foreign C function - runs on the C stack
|
// The foreign C function - runs on the C stack
|
||||||
|
@ -1337,9 +1338,10 @@ 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| {
|
||||||
|
// XXX(pcwalton): We should not copy the path.
|
||||||
register_fn_fuller(ccx,
|
register_fn_fuller(ccx,
|
||||||
sp,
|
sp,
|
||||||
/*bad*/copy path,
|
path.clone(),
|
||||||
node_id,
|
node_id,
|
||||||
attrs,
|
attrs,
|
||||||
t,
|
t,
|
||||||
|
|
|
@ -426,7 +426,7 @@ pub fn trans_struct_drop_flag(bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast:
|
||||||
|
|
||||||
// Find and call the actual destructor
|
// Find and call the actual destructor
|
||||||
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did,
|
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did,
|
||||||
class_did, /*bad*/copy substs.tps);
|
class_did, substs.tps.clone());
|
||||||
|
|
||||||
// The second argument is the "self" argument for drop
|
// The second argument is the "self" argument for drop
|
||||||
let params = unsafe {
|
let params = unsafe {
|
||||||
|
@ -461,7 +461,7 @@ pub fn trans_struct_drop(mut bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast::
|
||||||
|
|
||||||
// Find and call the actual destructor
|
// Find and call the actual destructor
|
||||||
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did,
|
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did,
|
||||||
class_did, /*bad*/copy substs.tps);
|
class_did, substs.tps.clone());
|
||||||
|
|
||||||
// The second argument is the "self" argument for drop
|
// The second argument is the "self" argument for drop
|
||||||
let params = unsafe {
|
let params = unsafe {
|
||||||
|
|
|
@ -44,8 +44,7 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id)
|
||||||
csearch::maybe_get_item_ast(
|
csearch::maybe_get_item_ast(
|
||||||
ccx.tcx, fn_id,
|
ccx.tcx, fn_id,
|
||||||
|a,b,c,d| {
|
|a,b,c,d| {
|
||||||
astencode::decode_inlined_item(a, b, ccx.maps,
|
astencode::decode_inlined_item(a, b, ccx.maps, c.clone(), d)
|
||||||
/*bad*/ copy c, d)
|
|
||||||
});
|
});
|
||||||
return match csearch_result {
|
return match csearch_result {
|
||||||
csearch::not_found => {
|
csearch::not_found => {
|
||||||
|
|
|
@ -60,7 +60,7 @@ pub fn trans_impl(ccx: @mut CrateContext,
|
||||||
for methods.iter().advance |method| {
|
for methods.iter().advance |method| {
|
||||||
if method.generics.ty_params.len() == 0u {
|
if method.generics.ty_params.len() == 0u {
|
||||||
let llfn = get_item_val(ccx, method.id);
|
let llfn = get_item_val(ccx, method.id);
|
||||||
let path = vec::append_one(/*bad*/copy sub_path,
|
let path = vec::append_one(sub_path.clone(),
|
||||||
path_name(method.ident));
|
path_name(method.ident));
|
||||||
|
|
||||||
trans_method(ccx,
|
trans_method(ccx,
|
||||||
|
@ -72,18 +72,17 @@ pub fn trans_impl(ccx: @mut CrateContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Translates a (possibly monomorphized) method body.
|
||||||
Translates a (possibly monomorphized) method body.
|
///
|
||||||
|
/// Parameters:
|
||||||
# Parameters
|
/// * `path`: the path to the method
|
||||||
|
/// * `method`: the AST node for the method
|
||||||
- `path`: the path to the method
|
/// * `param_substs`: if this is a generic method, the current values for
|
||||||
- `method`: the AST node for the method
|
/// type parameters and so forth, else none
|
||||||
- `param_substs`: if this is a generic method, the current values for
|
/// * `llfn`: the LLVM ValueRef for the method
|
||||||
type parameters and so forth, else none
|
/// * `impl_id`: the node ID of the impl this method is inside
|
||||||
- `llfn`: the LLVM ValueRef for the method
|
///
|
||||||
- `impl_id`: the node ID of the impl this method is inside
|
/// XXX(pcwalton) Can we take `path` by reference?
|
||||||
*/
|
|
||||||
pub fn trans_method(ccx: @mut CrateContext,
|
pub fn trans_method(ccx: @mut CrateContext,
|
||||||
path: path,
|
path: path,
|
||||||
method: &ast::method,
|
method: &ast::method,
|
||||||
|
@ -226,9 +225,13 @@ pub fn trans_method_callee(bcx: block,
|
||||||
match bcx.fcx.param_substs {
|
match bcx.fcx.param_substs {
|
||||||
Some(@param_substs
|
Some(@param_substs
|
||||||
{self_vtable: Some(ref vtbl), _}) => {
|
{self_vtable: Some(ref vtbl), _}) => {
|
||||||
trans_monomorphized_callee(bcx, callee_id, this, mentry,
|
trans_monomorphized_callee(bcx,
|
||||||
trait_id, method_index,
|
callee_id,
|
||||||
copy *vtbl)
|
this,
|
||||||
|
mentry,
|
||||||
|
trait_id,
|
||||||
|
method_index,
|
||||||
|
(*vtbl).clone())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
fail!("trans_method_callee: missing self_vtable")
|
fail!("trans_method_callee: missing self_vtable")
|
||||||
|
@ -503,7 +506,7 @@ pub fn trans_trait_callee(bcx: block,
|
||||||
self_expr: @ast::expr,
|
self_expr: @ast::expr,
|
||||||
store: ty::TraitStore,
|
store: ty::TraitStore,
|
||||||
explicit_self: ast::explicit_self_)
|
explicit_self: ast::explicit_self_)
|
||||||
-> Callee {
|
-> Callee {
|
||||||
//!
|
//!
|
||||||
//
|
//
|
||||||
// Create a method callee where the method is coming from a trait
|
// Create a method callee where the method is coming from a trait
|
||||||
|
@ -646,7 +649,7 @@ pub fn vtable_id(ccx: @mut CrateContext,
|
||||||
match origin {
|
match origin {
|
||||||
&typeck::vtable_static(impl_id, ref substs, sub_vtables) => {
|
&typeck::vtable_static(impl_id, ref substs, sub_vtables) => {
|
||||||
let psubsts = param_substs {
|
let psubsts = param_substs {
|
||||||
tys: copy *substs,
|
tys: (*substs).clone(),
|
||||||
vtables: Some(sub_vtables),
|
vtables: Some(sub_vtables),
|
||||||
self_ty: None,
|
self_ty: None,
|
||||||
self_vtable: None
|
self_vtable: None
|
||||||
|
@ -733,7 +736,7 @@ pub fn make_impl_vtable(bcx: block,
|
||||||
let fty = ty::subst_tps(tcx,
|
let fty = ty::subst_tps(tcx,
|
||||||
substs,
|
substs,
|
||||||
None,
|
None,
|
||||||
ty::mk_bare_fn(tcx, copy im.fty));
|
ty::mk_bare_fn(tcx, im.fty.clone()));
|
||||||
if im.generics.has_type_params() || ty::type_has_self(fty) {
|
if im.generics.has_type_params() || ty::type_has_self(fty) {
|
||||||
debug!("(making impl vtable) method has self or type params: %s",
|
debug!("(making impl vtable) method has self or type params: %s",
|
||||||
tcx.sess.str_of(im.ident));
|
tcx.sess.str_of(im.ident));
|
||||||
|
@ -784,8 +787,8 @@ pub fn trans_trait_cast(bcx: block,
|
||||||
bcx = expr::trans_into(bcx, val, SaveIn(llboxdest));
|
bcx = expr::trans_into(bcx, val, SaveIn(llboxdest));
|
||||||
|
|
||||||
// Store the vtable into the pair or triple.
|
// Store the vtable into the pair or triple.
|
||||||
let orig = /*bad*/copy ccx.maps.vtable_map.get(&id)[0][0];
|
let orig = ccx.maps.vtable_map.get(&id)[0][0].clone();
|
||||||
let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig);
|
let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, &orig);
|
||||||
let vtable = get_vtable(bcx, v_ty, orig);
|
let vtable = get_vtable(bcx, v_ty, orig);
|
||||||
Store(bcx, vtable, PointerCast(bcx,
|
Store(bcx, vtable, PointerCast(bcx,
|
||||||
GEPi(bcx, lldest, [0u, abi::trt_field_vtable]),
|
GEPi(bcx, lldest, [0u, abi::trt_field_vtable]),
|
||||||
|
|
|
@ -210,13 +210,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||||
ccx.monomorphizing.insert(fn_id, depth + 1);
|
ccx.monomorphizing.insert(fn_id, depth + 1);
|
||||||
|
|
||||||
let elt = path_name(gensym_name(ccx.sess.str_of(name)));
|
let elt = path_name(gensym_name(ccx.sess.str_of(name)));
|
||||||
let mut pt = /* bad */copy (*pt);
|
let mut pt = (*pt).clone();
|
||||||
pt.push(elt);
|
pt.push(elt);
|
||||||
let s = mangle_exported_name(ccx, /*bad*/copy pt, mono_ty);
|
let s = mangle_exported_name(ccx, pt.clone(), mono_ty);
|
||||||
debug!("monomorphize_fn mangled to %s", s);
|
debug!("monomorphize_fn mangled to %s", s);
|
||||||
|
|
||||||
let mk_lldecl = || {
|
let mk_lldecl = || {
|
||||||
let lldecl = decl_internal_cdecl_fn(ccx.llmod, /*bad*/copy s, llfty);
|
let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, llfty);
|
||||||
ccx.monomorphized.insert(hash_id, lldecl);
|
ccx.monomorphized.insert(hash_id, lldecl);
|
||||||
lldecl
|
lldecl
|
||||||
};
|
};
|
||||||
|
@ -227,7 +227,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||||
_
|
_
|
||||||
}, _) => {
|
}, _) => {
|
||||||
let d = mk_lldecl();
|
let d = mk_lldecl();
|
||||||
set_inline_hint_if_appr(/*bad*/copy i.attrs, d);
|
set_inline_hint_if_appr(i.attrs, d);
|
||||||
trans_fn(ccx,
|
trans_fn(ccx,
|
||||||
pt,
|
pt,
|
||||||
decl,
|
decl,
|
||||||
|
@ -255,8 +255,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||||
set_inline_hint(d);
|
set_inline_hint(d);
|
||||||
match v.node.kind {
|
match v.node.kind {
|
||||||
ast::tuple_variant_kind(ref args) => {
|
ast::tuple_variant_kind(ref args) => {
|
||||||
trans_enum_variant(ccx, enum_item.id, v, /*bad*/copy *args,
|
trans_enum_variant(ccx,
|
||||||
this_tv.disr_val, Some(psubsts), d);
|
enum_item.id,
|
||||||
|
v,
|
||||||
|
(*args).clone(),
|
||||||
|
this_tv.disr_val,
|
||||||
|
Some(psubsts),
|
||||||
|
d);
|
||||||
}
|
}
|
||||||
ast::struct_variant_kind(_) =>
|
ast::struct_variant_kind(_) =>
|
||||||
ccx.tcx.sess.bug("can't monomorphize struct variants"),
|
ccx.tcx.sess.bug("can't monomorphize struct variants"),
|
||||||
|
@ -266,21 +271,21 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||||
ast_map::node_method(mth, _, _) => {
|
ast_map::node_method(mth, _, _) => {
|
||||||
// XXX: What should the self type be here?
|
// XXX: What should the self type be here?
|
||||||
let d = mk_lldecl();
|
let d = mk_lldecl();
|
||||||
set_inline_hint_if_appr(/*bad*/copy mth.attrs, d);
|
set_inline_hint_if_appr(mth.attrs.clone(), d);
|
||||||
meth::trans_method(ccx, pt, mth, Some(psubsts), d);
|
meth::trans_method(ccx, pt, mth, Some(psubsts), d);
|
||||||
d
|
d
|
||||||
}
|
}
|
||||||
ast_map::node_trait_method(@ast::provided(mth), _, pt) => {
|
ast_map::node_trait_method(@ast::provided(mth), _, pt) => {
|
||||||
let d = mk_lldecl();
|
let d = mk_lldecl();
|
||||||
set_inline_hint_if_appr(/*bad*/copy mth.attrs, d);
|
set_inline_hint_if_appr(mth.attrs.clone(), d);
|
||||||
meth::trans_method(ccx, /*bad*/copy *pt, mth, Some(psubsts), d);
|
meth::trans_method(ccx, (*pt).clone(), mth, Some(psubsts), d);
|
||||||
d
|
d
|
||||||
}
|
}
|
||||||
ast_map::node_struct_ctor(struct_def, _, _) => {
|
ast_map::node_struct_ctor(struct_def, _, _) => {
|
||||||
let d = mk_lldecl();
|
let d = mk_lldecl();
|
||||||
set_inline_hint(d);
|
set_inline_hint(d);
|
||||||
base::trans_tuple_struct(ccx,
|
base::trans_tuple_struct(ccx,
|
||||||
/*bad*/copy struct_def.fields,
|
struct_def.fields,
|
||||||
struct_def.ctor_id.expect("ast-mapped tuple struct \
|
struct_def.ctor_id.expect("ast-mapped tuple struct \
|
||||||
didn't have a ctor id"),
|
didn't have a ctor id"),
|
||||||
Some(psubsts),
|
Some(psubsts),
|
||||||
|
@ -372,7 +377,7 @@ pub fn make_mono_id(ccx: @mut CrateContext,
|
||||||
Some(vts) => {
|
Some(vts) => {
|
||||||
debug!("make_mono_id vtables=%s substs=%s",
|
debug!("make_mono_id vtables=%s substs=%s",
|
||||||
vts.repr(ccx.tcx), substs.tys.repr(ccx.tcx));
|
vts.repr(ccx.tcx), substs.tys.repr(ccx.tcx));
|
||||||
let self_vtables = substs.self_vtable.map(|vtbl| @~[copy *vtbl]);
|
let self_vtables = substs.self_vtable.map(|vtbl| @~[(*vtbl).clone()]);
|
||||||
let vts_iter = self_vtables.iter().chain_(vts.iter());
|
let vts_iter = self_vtables.iter().chain_(vts.iter());
|
||||||
vts_iter.zip(substs_iter).transform(|(vtable, subst)| {
|
vts_iter.zip(substs_iter).transform(|(vtable, subst)| {
|
||||||
let v = vtable.map(|vt| meth::vtable_id(ccx, vt));
|
let v = vtable.map(|vt| meth::vtable_id(ccx, vt));
|
||||||
|
|
|
@ -92,7 +92,7 @@ impl Reflector {
|
||||||
*self.visitor_methods).expect(fmt!("Couldn't find visit method \
|
*self.visitor_methods).expect(fmt!("Couldn't find visit method \
|
||||||
for %s", ty_name));
|
for %s", ty_name));
|
||||||
let mth_ty =
|
let mth_ty =
|
||||||
ty::mk_bare_fn(tcx, copy self.visitor_methods[mth_idx].fty);
|
ty::mk_bare_fn(tcx, self.visitor_methods[mth_idx].fty.clone());
|
||||||
let v = self.visitor_val;
|
let v = self.visitor_val;
|
||||||
debug!("passing %u args:", args.len());
|
debug!("passing %u args:", args.len());
|
||||||
let mut bcx = self.bcx;
|
let mut bcx = self.bcx;
|
||||||
|
|
|
@ -25,7 +25,7 @@ use std::cast;
|
||||||
|
|
||||||
use std::libc::{c_uint};
|
use std::libc::{c_uint};
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Type {
|
pub struct Type {
|
||||||
priv rf: TypeRef
|
priv rf: TypeRef
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
|
||||||
|
|
||||||
let cx = Context {
|
let cx = Context {
|
||||||
ccx: ccx,
|
ccx: ccx,
|
||||||
uses: @mut vec::from_elem(n_tps, 0)
|
uses: @mut vec::from_elem(n_tps, 0u)
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the method is a default method, we mark all of the types as
|
// If the method is a default method, we mark all of the types as
|
||||||
|
@ -99,10 +99,15 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
|
||||||
}
|
}
|
||||||
|
|
||||||
let map_node = match ccx.tcx.items.find(&fn_id_loc.node) {
|
let map_node = match ccx.tcx.items.find(&fn_id_loc.node) {
|
||||||
Some(x) => (/*bad*/copy *x),
|
Some(x) => {
|
||||||
None => ccx.sess.bug(fmt!("type_uses_for: unbound item ID %?",
|
(*x).clone()
|
||||||
fn_id_loc))
|
}
|
||||||
|
None => {
|
||||||
|
ccx.sess.bug(fmt!("type_uses_for: unbound item ID %?",
|
||||||
|
fn_id_loc))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match map_node {
|
match map_node {
|
||||||
ast_map::node_item(@ast::item { node: item_fn(_, _, _, _, ref body),
|
ast_map::node_item(@ast::item { node: item_fn(_, _, _, _, ref body),
|
||||||
_ }, _) |
|
_ }, _) |
|
||||||
|
@ -121,11 +126,13 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
|
||||||
ast_map::node_variant(_, _, _) => {
|
ast_map::node_variant(_, _, _) => {
|
||||||
for uint::range(0u, n_tps) |n| { cx.uses[n] |= use_repr;}
|
for uint::range(0u, n_tps) |n| { cx.uses[n] |= use_repr;}
|
||||||
}
|
}
|
||||||
ast_map::node_foreign_item(i@@foreign_item { node: foreign_item_fn(*),
|
ast_map::node_foreign_item(i@@foreign_item {
|
||||||
_ },
|
node: foreign_item_fn(*),
|
||||||
abi,
|
_
|
||||||
_,
|
},
|
||||||
_) => {
|
abi,
|
||||||
|
_,
|
||||||
|
_) => {
|
||||||
if abi.is_intrinsic() {
|
if abi.is_intrinsic() {
|
||||||
let nm = cx.ccx.sess.str_of(i.ident);
|
let nm = cx.ccx.sess.str_of(i.ident);
|
||||||
let name = nm.as_slice();
|
let name = nm.as_slice();
|
||||||
|
@ -161,7 +168,8 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
|
||||||
|
|
||||||
"bswap16" | "bswap32" | "bswap64" => 0,
|
"bswap16" | "bswap32" | "bswap64" => 0,
|
||||||
|
|
||||||
// would be cool to make these an enum instead of strings!
|
// would be cool to make these an enum instead of
|
||||||
|
// strings!
|
||||||
_ => fail!("unknown intrinsic in type_use")
|
_ => fail!("unknown intrinsic in type_use")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -169,8 +177,8 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast_map::node_struct_ctor(*) => {
|
ast_map::node_struct_ctor(*) => {
|
||||||
// Similarly to node_variant, this monomorphized function just uses
|
// Similarly to node_variant, this monomorphized function just
|
||||||
// the representations of all of its type parameters.
|
// uses the representations of all of its type parameters.
|
||||||
for uint::range(0, n_tps) |n| { cx.uses[n] |= use_repr; }
|
for uint::range(0, n_tps) |n| { cx.uses[n] |= use_repr; }
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -96,13 +96,13 @@ impl Method {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct mt {
|
pub struct mt {
|
||||||
ty: t,
|
ty: t,
|
||||||
mutbl: ast::mutability,
|
mutbl: ast::mutability,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||||
pub enum vstore {
|
pub enum vstore {
|
||||||
vstore_fixed(uint),
|
vstore_fixed(uint),
|
||||||
vstore_uniq,
|
vstore_uniq,
|
||||||
|
@ -110,7 +110,7 @@ pub enum vstore {
|
||||||
vstore_slice(Region)
|
vstore_slice(Region)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes, Encodable, Decodable)]
|
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
|
||||||
pub enum TraitStore {
|
pub enum TraitStore {
|
||||||
BoxTraitStore, // @Trait
|
BoxTraitStore, // @Trait
|
||||||
UniqTraitStore, // ~Trait
|
UniqTraitStore, // ~Trait
|
||||||
|
@ -119,7 +119,7 @@ pub enum TraitStore {
|
||||||
|
|
||||||
// XXX: This should probably go away at some point. Maybe after destructors
|
// XXX: This should probably go away at some point. Maybe after destructors
|
||||||
// do?
|
// do?
|
||||||
#[deriving(Eq, Encodable, Decodable)]
|
#[deriving(Clone, Eq, Encodable, Decodable)]
|
||||||
pub enum SelfMode {
|
pub enum SelfMode {
|
||||||
ByCopy,
|
ByCopy,
|
||||||
ByRef,
|
ByRef,
|
||||||
|
@ -177,8 +177,12 @@ pub enum ast_ty_to_ty_cache_entry {
|
||||||
|
|
||||||
pub type opt_region_variance = Option<region_variance>;
|
pub type opt_region_variance = Option<region_variance>;
|
||||||
|
|
||||||
#[deriving(Eq, Decodable, Encodable)]
|
#[deriving(Clone, Eq, Decodable, Encodable)]
|
||||||
pub enum region_variance { rv_covariant, rv_invariant, rv_contravariant }
|
pub enum region_variance {
|
||||||
|
rv_covariant,
|
||||||
|
rv_invariant,
|
||||||
|
rv_contravariant,
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Decodable, Encodable)]
|
#[deriving(Decodable, Encodable)]
|
||||||
pub enum AutoAdjustment {
|
pub enum AutoAdjustment {
|
||||||
|
@ -366,14 +370,14 @@ pub fn type_has_regions(t: t) -> bool {
|
||||||
}
|
}
|
||||||
pub fn type_id(t: t) -> uint { get(t).id }
|
pub fn type_id(t: t) -> uint { get(t).id }
|
||||||
|
|
||||||
#[deriving(Eq,IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct BareFnTy {
|
pub struct BareFnTy {
|
||||||
purity: ast::purity,
|
purity: ast::purity,
|
||||||
abis: AbiSet,
|
abis: AbiSet,
|
||||||
sig: FnSig
|
sig: FnSig
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq,IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct ClosureTy {
|
pub struct ClosureTy {
|
||||||
purity: ast::purity,
|
purity: ast::purity,
|
||||||
sigil: ast::Sigil,
|
sigil: ast::Sigil,
|
||||||
|
@ -390,21 +394,21 @@ pub struct ClosureTy {
|
||||||
* - `lifetimes` is the list of region names bound in this fn.
|
* - `lifetimes` is the list of region names bound in this fn.
|
||||||
* - `inputs` is the list of arguments and their modes.
|
* - `inputs` is the list of arguments and their modes.
|
||||||
* - `output` is the return type. */
|
* - `output` is the return type. */
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct FnSig {
|
pub struct FnSig {
|
||||||
bound_lifetime_names: OptVec<ast::ident>,
|
bound_lifetime_names: OptVec<ast::ident>,
|
||||||
inputs: ~[t],
|
inputs: ~[t],
|
||||||
output: t
|
output: t
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct param_ty {
|
pub struct param_ty {
|
||||||
idx: uint,
|
idx: uint,
|
||||||
def_id: def_id
|
def_id: def_id
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Representation of regions:
|
/// Representation of regions:
|
||||||
#[deriving(Eq, IterBytes, Encodable, Decodable)]
|
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
|
||||||
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
|
||||||
|
@ -450,13 +454,13 @@ impl Region {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes, Encodable, Decodable)]
|
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
|
||||||
pub struct FreeRegion {
|
pub struct FreeRegion {
|
||||||
scope_id: node_id,
|
scope_id: node_id,
|
||||||
bound_region: bound_region
|
bound_region: bound_region
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes, Encodable, Decodable)]
|
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
|
||||||
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,
|
||||||
|
@ -501,7 +505,7 @@ type opt_region = Option<Region>;
|
||||||
* - `self_ty` is the type to which `self` should be remapped, if any. The
|
* - `self_ty` is the type to which `self` should be remapped, if any. The
|
||||||
* `self` type is rather funny in that it can only appear on traits and is
|
* `self` type is rather funny in that it can only appear on traits and is
|
||||||
* always substituted away to the implementing type for a trait. */
|
* always substituted away to the implementing type for a trait. */
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct substs {
|
pub struct substs {
|
||||||
self_r: opt_region,
|
self_r: opt_region,
|
||||||
self_ty: Option<ty::t>,
|
self_ty: Option<ty::t>,
|
||||||
|
@ -557,7 +561,7 @@ mod primitives {
|
||||||
|
|
||||||
// NB: If you change this, you'll probably want to change the corresponding
|
// NB: If you change this, you'll probably want to change the corresponding
|
||||||
// AST structure in libsyntax/ast.rs as well.
|
// AST structure in libsyntax/ast.rs as well.
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub enum sty {
|
pub enum sty {
|
||||||
ty_nil,
|
ty_nil,
|
||||||
ty_bot,
|
ty_bot,
|
||||||
|
@ -600,22 +604,25 @@ pub struct TraitRef {
|
||||||
substs: substs
|
substs: substs
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum IntVarValue {
|
pub enum IntVarValue {
|
||||||
IntType(ast::int_ty),
|
IntType(ast::int_ty),
|
||||||
UintType(ast::uint_ty),
|
UintType(ast::uint_ty),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
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)]
|
||||||
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)]
|
||||||
pub enum type_err {
|
pub enum type_err {
|
||||||
terr_mismatch,
|
terr_mismatch,
|
||||||
terr_purity_mismatch(expected_found<purity>),
|
terr_purity_mismatch(expected_found<purity>),
|
||||||
|
@ -657,7 +664,7 @@ pub struct ParamBounds {
|
||||||
|
|
||||||
pub type BuiltinBounds = EnumSet<BuiltinBound>;
|
pub type BuiltinBounds = EnumSet<BuiltinBound>;
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub enum BuiltinBound {
|
pub enum BuiltinBound {
|
||||||
BoundCopy,
|
BoundCopy,
|
||||||
BoundStatic,
|
BoundStatic,
|
||||||
|
@ -689,28 +696,28 @@ impl CLike for BuiltinBound {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct TyVid(uint);
|
pub struct TyVid(uint);
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct IntVid(uint);
|
pub struct IntVid(uint);
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub struct FloatVid(uint);
|
pub struct FloatVid(uint);
|
||||||
|
|
||||||
#[deriving(Eq, Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||||
pub struct RegionVid {
|
pub struct RegionVid {
|
||||||
id: uint
|
id: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, IterBytes)]
|
#[deriving(Clone, Eq, IterBytes)]
|
||||||
pub enum InferTy {
|
pub enum InferTy {
|
||||||
TyVar(TyVid),
|
TyVar(TyVid),
|
||||||
IntVar(IntVid),
|
IntVar(IntVid),
|
||||||
FloatVar(FloatVid)
|
FloatVar(FloatVid)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Encodable, Decodable, IterBytes)]
|
||||||
pub enum InferRegion {
|
pub enum InferRegion {
|
||||||
ReVar(RegionVid),
|
ReVar(RegionVid),
|
||||||
ReSkolemized(uint, bound_region)
|
ReSkolemized(uint, bound_region)
|
||||||
|
@ -795,6 +802,7 @@ impl ToStr for IntVarValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct TypeParameterDef {
|
pub struct TypeParameterDef {
|
||||||
ident: ast::ident,
|
ident: ast::ident,
|
||||||
def_id: ast::def_id,
|
def_id: ast::def_id,
|
||||||
|
@ -803,6 +811,7 @@ pub struct TypeParameterDef {
|
||||||
|
|
||||||
/// Information about the type/lifetime parametesr associated with an item.
|
/// Information about the type/lifetime parametesr associated with an item.
|
||||||
/// Analogous to ast::Generics.
|
/// Analogous to ast::Generics.
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct Generics {
|
pub struct Generics {
|
||||||
type_param_defs: @~[TypeParameterDef],
|
type_param_defs: @~[TypeParameterDef],
|
||||||
region_param: Option<region_variance>,
|
region_param: Option<region_variance>,
|
||||||
|
@ -824,6 +833,7 @@ impl Generics {
|
||||||
///
|
///
|
||||||
/// - `ty`: the base type. May have reference to the (unsubstituted) bound
|
/// - `ty`: the base type. May have reference to the (unsubstituted) bound
|
||||||
/// region `&self` or to (unsubstituted) ty_param types
|
/// region `&self` or to (unsubstituted) ty_param types
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct ty_param_bounds_and_ty {
|
pub struct ty_param_bounds_and_ty {
|
||||||
generics: Generics,
|
generics: Generics,
|
||||||
ty: t
|
ty: t
|
||||||
|
@ -1264,7 +1274,7 @@ pub fn fold_sig(sig: &FnSig, fldop: &fn(t) -> t) -> FnSig {
|
||||||
let args = sig.inputs.map(|arg| fldop(*arg));
|
let args = sig.inputs.map(|arg| fldop(*arg));
|
||||||
|
|
||||||
FnSig {
|
FnSig {
|
||||||
bound_lifetime_names: copy sig.bound_lifetime_names,
|
bound_lifetime_names: sig.bound_lifetime_names.clone(),
|
||||||
inputs: args,
|
inputs: args,
|
||||||
output: fldop(sig.output)
|
output: fldop(sig.output)
|
||||||
}
|
}
|
||||||
|
@ -1314,7 +1324,14 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
|
||||||
}
|
}
|
||||||
ty_closure(ref f) => {
|
ty_closure(ref f) => {
|
||||||
let sig = fold_sig(&f.sig, fldop);
|
let sig = fold_sig(&f.sig, fldop);
|
||||||
ty_closure(ClosureTy {sig: sig, ..copy *f})
|
ty_closure(ClosureTy {
|
||||||
|
sig: sig,
|
||||||
|
purity: f.purity,
|
||||||
|
sigil: f.sigil,
|
||||||
|
onceness: f.onceness,
|
||||||
|
region: f.region,
|
||||||
|
bounds: f.bounds,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
ty_rptr(r, ref tm) => {
|
ty_rptr(r, ref tm) => {
|
||||||
ty_rptr(r, mt {ty: fldop(tm.ty), mutbl: tm.mutbl})
|
ty_rptr(r, mt {ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||||
|
@ -1325,7 +1342,7 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
|
||||||
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
|
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
|
||||||
ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) | ty_err |
|
ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) | ty_err |
|
||||||
ty_opaque_box | ty_infer(_) | ty_param(*) | ty_self(_) => {
|
ty_opaque_box | ty_infer(_) | ty_param(*) | ty_self(_) => {
|
||||||
/*bad*/copy *sty
|
(*sty).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1400,13 +1417,21 @@ pub fn fold_regions_and_ty(
|
||||||
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st, mutbl, bounds)
|
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st, mutbl, bounds)
|
||||||
}
|
}
|
||||||
ty_bare_fn(ref f) => {
|
ty_bare_fn(ref f) => {
|
||||||
ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt),
|
ty::mk_bare_fn(cx, BareFnTy {
|
||||||
..copy *f})
|
sig: fold_sig(&f.sig, fldfnt),
|
||||||
|
purity: f.purity,
|
||||||
|
abis: f.abis.clone(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
ty_closure(ref f) => {
|
ty_closure(ref f) => {
|
||||||
ty::mk_closure(cx, ClosureTy {region: fldr(f.region),
|
ty::mk_closure(cx, ClosureTy {
|
||||||
sig: fold_sig(&f.sig, fldfnt),
|
region: fldr(f.region),
|
||||||
..copy *f})
|
sig: fold_sig(&f.sig, fldfnt),
|
||||||
|
purity: f.purity,
|
||||||
|
sigil: f.sigil,
|
||||||
|
onceness: f.onceness,
|
||||||
|
bounds: f.bounds,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
ref sty => {
|
ref sty => {
|
||||||
fold_sty_to_ty(cx, sty, |t| fldt(t))
|
fold_sty_to_ty(cx, sty, |t| fldt(t))
|
||||||
|
@ -2493,9 +2518,11 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
|
||||||
ty_enum(did, ref substs) => {
|
ty_enum(did, ref substs) => {
|
||||||
let variants = enum_variants(cx, did);
|
let variants = enum_variants(cx, did);
|
||||||
for (*variants).iter().advance |variant| {
|
for (*variants).iter().advance |variant| {
|
||||||
let tup_ty = mk_tup(cx, /*bad*/copy variant.args);
|
// XXX(pcwalton): This is an inefficient way to do this. Don't
|
||||||
|
// synthesize a tuple!
|
||||||
|
//
|
||||||
// Perform any type parameter substitutions.
|
// Perform any type parameter substitutions.
|
||||||
|
let tup_ty = mk_tup(cx, variant.args.clone());
|
||||||
let tup_ty = subst(cx, substs, tup_ty);
|
let tup_ty = subst(cx, substs, tup_ty);
|
||||||
if !type_is_pod(cx, tup_ty) { result = false; }
|
if !type_is_pod(cx, tup_ty) { result = false; }
|
||||||
}
|
}
|
||||||
|
@ -2711,10 +2738,11 @@ pub fn node_id_to_type(cx: ctxt, id: ast::node_id) -> t {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX(pcwalton): Makes a copy, bleh. Probably better to not do that.
|
||||||
pub fn node_id_to_type_params(cx: ctxt, id: ast::node_id) -> ~[t] {
|
pub fn node_id_to_type_params(cx: ctxt, id: ast::node_id) -> ~[t] {
|
||||||
match cx.node_type_substs.find(&id) {
|
match cx.node_type_substs.find(&id) {
|
||||||
None => return ~[],
|
None => return ~[],
|
||||||
Some(ts) => return /*bad*/ copy *ts
|
Some(ts) => return (*ts).clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2724,8 +2752,8 @@ fn node_id_has_type_params(cx: ctxt, id: ast::node_id) -> bool {
|
||||||
|
|
||||||
pub fn ty_fn_sig(fty: t) -> FnSig {
|
pub fn ty_fn_sig(fty: t) -> FnSig {
|
||||||
match get(fty).sty {
|
match get(fty).sty {
|
||||||
ty_bare_fn(ref f) => copy f.sig,
|
ty_bare_fn(ref f) => f.sig.clone(),
|
||||||
ty_closure(ref f) => copy f.sig,
|
ty_closure(ref f) => f.sig.clone(),
|
||||||
ref s => {
|
ref s => {
|
||||||
fail!("ty_fn_sig() called on non-fn type: %?", s)
|
fail!("ty_fn_sig() called on non-fn type: %?", s)
|
||||||
}
|
}
|
||||||
|
@ -2735,8 +2763,8 @@ pub fn ty_fn_sig(fty: t) -> FnSig {
|
||||||
// Type accessors for substructures of types
|
// Type accessors for substructures of types
|
||||||
pub fn ty_fn_args(fty: t) -> ~[t] {
|
pub fn ty_fn_args(fty: t) -> ~[t] {
|
||||||
match get(fty).sty {
|
match get(fty).sty {
|
||||||
ty_bare_fn(ref f) => copy f.sig.inputs,
|
ty_bare_fn(ref f) => f.sig.inputs.clone(),
|
||||||
ty_closure(ref f) => copy f.sig.inputs,
|
ty_closure(ref f) => f.sig.inputs.clone(),
|
||||||
ref s => {
|
ref s => {
|
||||||
fail!("ty_fn_args() called on non-fn type: %?", s)
|
fail!("ty_fn_args() called on non-fn type: %?", s)
|
||||||
}
|
}
|
||||||
|
@ -2823,8 +2851,8 @@ pub fn replace_closure_return_type(tcx: ctxt, fn_type: t, ret_type: t) -> t {
|
||||||
match ty::get(fn_type).sty {
|
match ty::get(fn_type).sty {
|
||||||
ty::ty_closure(ref fty) => {
|
ty::ty_closure(ref fty) => {
|
||||||
ty::mk_closure(tcx, ClosureTy {
|
ty::mk_closure(tcx, ClosureTy {
|
||||||
sig: FnSig {output: ret_type, ..copy fty.sig},
|
sig: FnSig {output: ret_type, ..fty.sig.clone()},
|
||||||
..copy *fty
|
..(*fty).clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -2906,7 +2934,7 @@ pub fn adjust_ty(cx: ctxt,
|
||||||
onceness: ast::Many,
|
onceness: ast::Many,
|
||||||
region: r,
|
region: r,
|
||||||
bounds: ty::AllBuiltinBounds(),
|
bounds: ty::AllBuiltinBounds(),
|
||||||
sig: copy b.sig})
|
sig: b.sig.clone()})
|
||||||
}
|
}
|
||||||
ref b => {
|
ref b => {
|
||||||
cx.sess.bug(
|
cx.sess.bug(
|
||||||
|
@ -2990,7 +3018,7 @@ pub fn adjust_ty(cx: ctxt,
|
||||||
ty::mk_closure(cx, ClosureTy {
|
ty::mk_closure(cx, ClosureTy {
|
||||||
sigil: BorrowedSigil,
|
sigil: BorrowedSigil,
|
||||||
region: r,
|
region: r,
|
||||||
..copy *fty
|
..(*fty).clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3034,11 +3062,10 @@ pub fn expr_has_ty_params(cx: ctxt, expr: &ast::expr) -> bool {
|
||||||
return node_id_has_type_params(cx, expr.id);
|
return node_id_has_type_params(cx, expr.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn method_call_type_param_defs(
|
pub fn method_call_type_param_defs(tcx: ctxt,
|
||||||
tcx: ctxt,
|
method_map: typeck::method_map,
|
||||||
method_map: typeck::method_map,
|
id: ast::node_id)
|
||||||
id: ast::node_id) -> Option<@~[TypeParameterDef]>
|
-> Option<@~[TypeParameterDef]> {
|
||||||
{
|
|
||||||
do method_map.find(&id).map |method| {
|
do method_map.find(&id).map |method| {
|
||||||
match method.origin {
|
match method.origin {
|
||||||
typeck::method_static(did) => {
|
typeck::method_static(did) => {
|
||||||
|
@ -3059,8 +3086,10 @@ pub fn method_call_type_param_defs(
|
||||||
let trait_type_param_defs =
|
let trait_type_param_defs =
|
||||||
ty::lookup_trait_def(tcx, trt_id).generics.type_param_defs;
|
ty::lookup_trait_def(tcx, trt_id).generics.type_param_defs;
|
||||||
@vec::append(
|
@vec::append(
|
||||||
copy *trait_type_param_defs,
|
(*trait_type_param_defs).clone(),
|
||||||
*ty::trait_method(tcx, trt_id, n_mth).generics.type_param_defs)
|
*ty::trait_method(tcx,
|
||||||
|
trt_id,
|
||||||
|
n_mth).generics.type_param_defs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3548,7 +3577,7 @@ pub fn trait_ref_supertraits(cx: ctxt, trait_ref: &ty::TraitRef) -> ~[@TraitRef]
|
||||||
|supertrait_ref| supertrait_ref.subst(cx, &trait_ref.substs))
|
|supertrait_ref| supertrait_ref.subst(cx, &trait_ref.substs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_locally_or_in_crate_store<V:Copy>(
|
fn lookup_locally_or_in_crate_store<V:Clone>(
|
||||||
descr: &str,
|
descr: &str,
|
||||||
def_id: ast::def_id,
|
def_id: ast::def_id,
|
||||||
map: &mut HashMap<ast::def_id, V>,
|
map: &mut HashMap<ast::def_id, V>,
|
||||||
|
@ -3566,7 +3595,7 @@ fn lookup_locally_or_in_crate_store<V:Copy>(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
match map.find(&def_id) {
|
match map.find(&def_id) {
|
||||||
Some(&ref v) => { return copy *v; }
|
Some(&ref v) => { return (*v).clone(); }
|
||||||
None => { }
|
None => { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3574,8 +3603,8 @@ fn lookup_locally_or_in_crate_store<V:Copy>(
|
||||||
fail!("No def'n found for %? in tcx.%s", def_id, descr);
|
fail!("No def'n found for %? in tcx.%s", def_id, descr);
|
||||||
}
|
}
|
||||||
let v = load_external();
|
let v = load_external();
|
||||||
map.insert(def_id, copy v);
|
map.insert(def_id, v.clone());
|
||||||
return copy v;
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_method(cx: ctxt, trait_did: ast::def_id, idx: uint) -> @Method {
|
pub fn trait_method(cx: ctxt, trait_did: ast::def_id, idx: uint) -> @Method {
|
||||||
|
@ -3679,6 +3708,7 @@ fn struct_ctor_id(cx: ctxt, struct_did: ast::def_id) -> Option<ast::def_id> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enum information
|
// Enum information
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct VariantInfo_ {
|
pub struct VariantInfo_ {
|
||||||
args: ~[t],
|
args: ~[t],
|
||||||
ctor_ty: t,
|
ctor_ty: t,
|
||||||
|
@ -3700,8 +3730,11 @@ pub fn substd_enum_variants(cx: ctxt,
|
||||||
|
|
||||||
let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty);
|
let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty);
|
||||||
|
|
||||||
@VariantInfo_{args: substd_args, ctor_ty: substd_ctor_ty,
|
@VariantInfo_ {
|
||||||
../*bad*/copy **variant_info}
|
args: substd_args,
|
||||||
|
ctor_ty: substd_ctor_ty,
|
||||||
|
..(**variant_info).clone()
|
||||||
|
}
|
||||||
}.collect()
|
}.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3770,21 +3803,21 @@ pub fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
|
||||||
ast_map::path_name(item.ident)
|
ast_map::path_name(item.ident)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
vec::append_one(/*bad*/copy *path, item_elt)
|
vec::append_one((*path).clone(), item_elt)
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_map::node_foreign_item(nitem, _, _, path) => {
|
ast_map::node_foreign_item(nitem, _, _, path) => {
|
||||||
vec::append_one(/*bad*/copy *path,
|
vec::append_one((*path).clone(),
|
||||||
ast_map::path_name(nitem.ident))
|
ast_map::path_name(nitem.ident))
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_map::node_method(method, _, path) => {
|
ast_map::node_method(method, _, path) => {
|
||||||
vec::append_one(/*bad*/copy *path,
|
vec::append_one((*path).clone(),
|
||||||
ast_map::path_name(method.ident))
|
ast_map::path_name(method.ident))
|
||||||
}
|
}
|
||||||
ast_map::node_trait_method(trait_method, _, path) => {
|
ast_map::node_trait_method(trait_method, _, path) => {
|
||||||
let method = ast_util::trait_method_to_ty_method(&*trait_method);
|
let method = ast_util::trait_method_to_ty_method(&*trait_method);
|
||||||
vec::append_one(/*bad*/copy *path,
|
vec::append_one((*path).clone(),
|
||||||
ast_map::path_name(method.ident))
|
ast_map::path_name(method.ident))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3794,7 +3827,7 @@ pub fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_map::node_struct_ctor(_, item, path) => {
|
ast_map::node_struct_ctor(_, item, path) => {
|
||||||
vec::append_one(/*bad*/copy *path, ast_map::path_name(item.ident))
|
vec::append_one((*path).clone(), ast_map::path_name(item.ident))
|
||||||
}
|
}
|
||||||
|
|
||||||
ref node => {
|
ref node => {
|
||||||
|
@ -4193,7 +4226,7 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
|
||||||
ty_closure(ref closure_ty) => {
|
ty_closure(ref closure_ty) => {
|
||||||
mk_closure(cx, ClosureTy {
|
mk_closure(cx, ClosureTy {
|
||||||
region: ty::re_static,
|
region: ty::re_static,
|
||||||
..copy *closure_ty
|
..(*closure_ty).clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4205,7 +4238,7 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
|
||||||
substs {
|
substs {
|
||||||
self_r: Some(ty::re_static),
|
self_r: Some(ty::re_static),
|
||||||
self_ty: None,
|
self_ty: None,
|
||||||
tps: /*bad*/copy (*r).tps
|
tps: (*r).tps.clone()
|
||||||
}),
|
}),
|
||||||
None =>
|
None =>
|
||||||
t
|
t
|
||||||
|
@ -4217,7 +4250,7 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
|
||||||
// Ditto.
|
// Ditto.
|
||||||
mk_struct(cx, did, substs {self_r: Some(ty::re_static),
|
mk_struct(cx, did, substs {self_r: Some(ty::re_static),
|
||||||
self_ty: None,
|
self_ty: None,
|
||||||
tps: /*bad*/copy (*r).tps}),
|
tps: (*r).tps.clone()}),
|
||||||
None =>
|
None =>
|
||||||
t
|
t
|
||||||
},
|
},
|
||||||
|
@ -4403,6 +4436,10 @@ pub fn visitor_object_ty(tcx: ctxt) -> Result<(@TraitRef, t), ~str> {
|
||||||
let mut static_trait_bound = EmptyBuiltinBounds();
|
let mut static_trait_bound = EmptyBuiltinBounds();
|
||||||
static_trait_bound.add(BoundStatic);
|
static_trait_bound.add(BoundStatic);
|
||||||
Ok((trait_ref,
|
Ok((trait_ref,
|
||||||
mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs,
|
mk_trait(tcx,
|
||||||
BoxTraitStore, ast::m_imm, static_trait_bound)))
|
trait_ref.def_id,
|
||||||
|
trait_ref.substs.clone(),
|
||||||
|
BoxTraitStore,
|
||||||
|
ast::m_imm,
|
||||||
|
static_trait_bound)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ pub fn get_region_reporting_err(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + 'static>(
|
pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
default_span: span,
|
default_span: span,
|
||||||
|
@ -130,7 +130,7 @@ pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
get_region_reporting_err(this.tcx(), span, opt_lifetime, res)
|
get_region_reporting_err(this.tcx(), span, opt_lifetime, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
|
fn ast_path_substs<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
def_id: ast::def_id,
|
def_id: ast::def_id,
|
||||||
|
@ -184,12 +184,13 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
substs {self_r:self_r, self_ty:self_ty, tps:tps}
|
substs {self_r:self_r, self_ty:self_ty, tps:tps}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
|
pub fn ast_path_to_substs_and_ty<AC:AstConv,
|
||||||
this: &AC,
|
RS:region_scope + Clone + 'static>(
|
||||||
rscope: &RS,
|
this: &AC,
|
||||||
did: ast::def_id,
|
rscope: &RS,
|
||||||
path: &ast::Path) -> ty_param_substs_and_ty
|
did: ast::def_id,
|
||||||
{
|
path: &ast::Path)
|
||||||
|
-> ty_param_substs_and_ty {
|
||||||
let tcx = this.tcx();
|
let tcx = this.tcx();
|
||||||
let ty::ty_param_bounds_and_ty {
|
let ty::ty_param_bounds_and_ty {
|
||||||
generics: generics,
|
generics: generics,
|
||||||
|
@ -201,7 +202,7 @@ pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
ty_param_substs_and_ty { substs: substs, ty: ty }
|
ty_param_substs_and_ty { substs: substs, ty: ty }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast_path_to_trait_ref<AC:AstConv,RS:region_scope + Copy + 'static>(
|
pub fn ast_path_to_trait_ref<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
trait_def_id: ast::def_id,
|
trait_def_id: ast::def_id,
|
||||||
|
@ -224,7 +225,7 @@ pub fn ast_path_to_trait_ref<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
return trait_ref;
|
return trait_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast_path_to_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
|
pub fn ast_path_to_ty<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
did: ast::def_id,
|
did: ast::def_id,
|
||||||
|
@ -246,10 +247,10 @@ pub static NO_TPS: uint = 2;
|
||||||
// Parses the programmer's textual representation of a type into our
|
// Parses the programmer's textual representation of a type into our
|
||||||
// internal notion of a type. `getter` is a function that returns the type
|
// internal notion of a type. `getter` is a function that returns the type
|
||||||
// corresponding to a definition ID:
|
// corresponding to a definition ID:
|
||||||
pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Clone + 'static>(
|
||||||
this: &AC, rscope: &RS, ast_ty: &ast::Ty) -> ty::t {
|
this: &AC, rscope: &RS, ast_ty: &ast::Ty) -> ty::t {
|
||||||
|
|
||||||
fn ast_mt_to_mt<AC:AstConv, RS:region_scope + Copy + 'static>(
|
fn ast_mt_to_mt<AC:AstConv, RS:region_scope + Clone + 'static>(
|
||||||
this: &AC, rscope: &RS, mt: &ast::mt) -> ty::mt {
|
this: &AC, rscope: &RS, mt: &ast::mt) -> ty::mt {
|
||||||
|
|
||||||
ty::mt {ty: ast_ty_to_ty(this, rscope, mt.ty), mutbl: mt.mutbl}
|
ty::mt {ty: ast_ty_to_ty(this, rscope, mt.ty), mutbl: mt.mutbl}
|
||||||
|
@ -258,7 +259,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||||
// Handle @, ~, and & being able to mean estrs and evecs.
|
// Handle @, ~, and & being able to mean estrs and evecs.
|
||||||
// If a_seq_ty is a str or a vec, make it an estr/evec.
|
// If a_seq_ty is a str or a vec, make it an estr/evec.
|
||||||
// Also handle first-class trait types.
|
// Also handle first-class trait types.
|
||||||
fn mk_pointer<AC:AstConv,RS:region_scope + Copy + 'static>(
|
fn mk_pointer<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
a_seq_ty: &ast::mt,
|
a_seq_ty: &ast::mt,
|
||||||
|
@ -305,7 +306,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||||
let bounds = conv_builtin_bounds(this.tcx(), bounds, trait_store);
|
let bounds = conv_builtin_bounds(this.tcx(), bounds, trait_store);
|
||||||
return ty::mk_trait(tcx,
|
return ty::mk_trait(tcx,
|
||||||
result.def_id,
|
result.def_id,
|
||||||
copy result.substs,
|
result.substs.clone(),
|
||||||
trait_store,
|
trait_store,
|
||||||
a_seq_ty.mutbl,
|
a_seq_ty.mutbl,
|
||||||
bounds);
|
bounds);
|
||||||
|
@ -522,7 +523,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_of_arg<AC:AstConv,
|
pub fn ty_of_arg<AC:AstConv,
|
||||||
RS:region_scope + Copy + 'static>(
|
RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
a: &ast::arg,
|
a: &ast::arg,
|
||||||
|
@ -570,7 +571,7 @@ struct SelfInfo {
|
||||||
explicit_self: ast::explicit_self
|
explicit_self: ast::explicit_self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + 'static>(
|
pub fn ty_of_method<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
purity: ast::purity,
|
purity: ast::purity,
|
||||||
|
@ -588,7 +589,7 @@ pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
(a.get(), b)
|
(a.get(), b)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
purity: ast::purity,
|
purity: ast::purity,
|
||||||
|
@ -601,7 +602,7 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
purity: ast::purity,
|
purity: ast::purity,
|
||||||
|
@ -615,7 +616,9 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
// new region names that appear inside of the fn decl are bound to
|
// new region names that appear inside of the fn decl are bound to
|
||||||
// that function type
|
// that function type
|
||||||
let bound_lifetime_names = bound_lifetimes(this, lifetimes);
|
let bound_lifetime_names = bound_lifetimes(this, lifetimes);
|
||||||
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
|
let rb =
|
||||||
|
in_binding_rscope(rscope,
|
||||||
|
RegionParamNames(bound_lifetime_names.clone()));
|
||||||
|
|
||||||
let opt_transformed_self_ty = opt_self_info.map(|&self_info| {
|
let opt_transformed_self_ty = opt_self_info.map(|&self_info| {
|
||||||
transform_self_ty(this, &rb, self_info)
|
transform_self_ty(this, &rb, self_info)
|
||||||
|
@ -637,7 +640,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
output: output_ty}
|
output: output_ty}
|
||||||
});
|
});
|
||||||
|
|
||||||
fn transform_self_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
|
fn transform_self_ty<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
self_info: &SelfInfo) -> Option<ty::t>
|
self_info: &SelfInfo) -> Option<ty::t>
|
||||||
|
@ -670,7 +673,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
|
pub fn ty_of_closure<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
this: &AC,
|
this: &AC,
|
||||||
rscope: &RS,
|
rscope: &RS,
|
||||||
sigil: ast::Sigil,
|
sigil: ast::Sigil,
|
||||||
|
@ -716,7 +719,9 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
|
||||||
// new region names that appear inside of the fn decl are bound to
|
// new region names that appear inside of the fn decl are bound to
|
||||||
// that function type
|
// that function type
|
||||||
let bound_lifetime_names = bound_lifetimes(this, lifetimes);
|
let bound_lifetime_names = bound_lifetimes(this, lifetimes);
|
||||||
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
|
let rb =
|
||||||
|
in_binding_rscope(rscope,
|
||||||
|
RegionParamNames(bound_lifetime_names.clone()));
|
||||||
|
|
||||||
let input_tys = do decl.inputs.iter().enumerate().transform |(i, a)| {
|
let input_tys = do decl.inputs.iter().enumerate().transform |(i, a)| {
|
||||||
let expected_arg_ty = do expected_sig.chain_ref |e| {
|
let expected_arg_ty = do expected_sig.chain_ref |e| {
|
||||||
|
|
|
@ -120,7 +120,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
|
||||||
// contains type variables.
|
// contains type variables.
|
||||||
|
|
||||||
// Check to see whether this is an enum or a struct.
|
// Check to see whether this is an enum or a struct.
|
||||||
match structure_of(pcx.fcx, pat.span, expected) {
|
match *structure_of(pcx.fcx, pat.span, expected) {
|
||||||
ty::ty_enum(_, ref expected_substs) => {
|
ty::ty_enum(_, ref expected_substs) => {
|
||||||
// Lookup the enum and variant def ids:
|
// Lookup the enum and variant def ids:
|
||||||
let v_def = lookup_def(pcx.fcx, pat.span, pat.id);
|
let v_def = lookup_def(pcx.fcx, pat.span, pat.id);
|
||||||
|
@ -165,8 +165,9 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
|
||||||
None);
|
None);
|
||||||
fcx.write_error(pat.id);
|
fcx.write_error(pat.id);
|
||||||
kind_name = "[error]";
|
kind_name = "[error]";
|
||||||
arg_types = (copy *subpats).get_or_default(~[]).map(|_|
|
arg_types = (*subpats).clone()
|
||||||
ty::mk_err());
|
.get_or_default(~[])
|
||||||
|
.map(|_| ty::mk_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,8 +208,9 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
|
||||||
None);
|
None);
|
||||||
fcx.write_error(pat.id);
|
fcx.write_error(pat.id);
|
||||||
kind_name = "[error]";
|
kind_name = "[error]";
|
||||||
arg_types = (copy *subpats).get_or_default(~[]).map(|_|
|
arg_types = (*subpats).clone()
|
||||||
ty::mk_err());
|
.get_or_default(~[])
|
||||||
|
.map(|_| ty::mk_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,7 +488,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||||
// Grab the class data that we care about.
|
// Grab the class data that we care about.
|
||||||
let structure = structure_of(fcx, pat.span, expected);
|
let structure = structure_of(fcx, pat.span, expected);
|
||||||
let mut error_happened = false;
|
let mut error_happened = false;
|
||||||
match structure {
|
match *structure {
|
||||||
ty::ty_struct(cid, ref substs) => {
|
ty::ty_struct(cid, ref substs) => {
|
||||||
check_struct_pat(pcx, pat.id, pat.span, expected, path,
|
check_struct_pat(pcx, pat.id, pat.span, expected, path,
|
||||||
*fields, etc, cid, substs);
|
*fields, etc, cid, substs);
|
||||||
|
@ -507,15 +509,14 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||||
// Finally, write in the type.
|
// Finally, write in the type.
|
||||||
if error_happened {
|
if error_happened {
|
||||||
fcx.write_error(pat.id);
|
fcx.write_error(pat.id);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fcx.write_ty(pat.id, expected);
|
fcx.write_ty(pat.id, expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::pat_tup(ref elts) => {
|
ast::pat_tup(ref elts) => {
|
||||||
let s = structure_of(fcx, pat.span, expected);
|
let s = structure_of(fcx, pat.span, expected);
|
||||||
let e_count = elts.len();
|
let e_count = elts.len();
|
||||||
match s {
|
match *s {
|
||||||
ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => {
|
ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => {
|
||||||
for elts.iter().enumerate().advance |(i, elt)| {
|
for elts.iter().enumerate().advance |(i, elt)| {
|
||||||
check_pat(pcx, *elt, ex_elts[i]);
|
check_pat(pcx, *elt, ex_elts[i]);
|
||||||
|
@ -527,7 +528,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||||
check_pat(pcx, *elt, ty::mk_err());
|
check_pat(pcx, *elt, ty::mk_err());
|
||||||
}
|
}
|
||||||
// use terr_tuple_size if both types are tuples
|
// use terr_tuple_size if both types are tuples
|
||||||
let type_error = match s {
|
let type_error = match *s {
|
||||||
ty::ty_tup(ref ex_elts) =>
|
ty::ty_tup(ref ex_elts) =>
|
||||||
ty::terr_tuple_size(ty::expected_found{expected: ex_elts.len(),
|
ty::terr_tuple_size(ty::expected_found{expected: ex_elts.len(),
|
||||||
found: e_count}),
|
found: e_count}),
|
||||||
|
@ -555,9 +556,9 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||||
fcx.infcx().next_region_var(
|
fcx.infcx().next_region_var(
|
||||||
infer::PatternRegion(pat.span));
|
infer::PatternRegion(pat.span));
|
||||||
|
|
||||||
let (elt_type, region_var) = match structure_of(
|
let (elt_type, region_var) = match *structure_of(fcx,
|
||||||
fcx, pat.span, expected
|
pat.span,
|
||||||
) {
|
expected) {
|
||||||
ty::ty_evec(mt, vstore) => {
|
ty::ty_evec(mt, vstore) => {
|
||||||
let region_var = match vstore {
|
let region_var = match vstore {
|
||||||
ty::vstore_slice(r) => r,
|
ty::vstore_slice(r) => r,
|
||||||
|
@ -626,7 +627,7 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
|
||||||
check_pat(pcx, inner, e_inner.ty);
|
check_pat(pcx, inner, e_inner.ty);
|
||||||
fcx.write_ty(pat_id, expected);
|
fcx.write_ty(pat_id, expected);
|
||||||
};
|
};
|
||||||
match structure_of(fcx, span, expected) {
|
match *structure_of(fcx, span, expected) {
|
||||||
ty::ty_box(e_inner) if pointer_kind == Managed => {
|
ty::ty_box(e_inner) if pointer_kind == Managed => {
|
||||||
check_inner(e_inner);
|
check_inner(e_inner);
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,6 +171,7 @@ pub struct LookupContext<'self> {
|
||||||
* A potential method that might be called, assuming the receiver
|
* A potential method that might be called, assuming the receiver
|
||||||
* is of a suitable type.
|
* is of a suitable type.
|
||||||
*/
|
*/
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct Candidate {
|
pub struct Candidate {
|
||||||
rcvr_ty: ty::t,
|
rcvr_ty: ty::t,
|
||||||
rcvr_substs: ty::substs,
|
rcvr_substs: ty::substs,
|
||||||
|
@ -384,7 +385,7 @@ impl<'self> LookupContext<'self> {
|
||||||
|
|
||||||
let cand = Candidate {
|
let cand = Candidate {
|
||||||
rcvr_ty: rcvr_ty,
|
rcvr_ty: rcvr_ty,
|
||||||
rcvr_substs: copy bound_trait_ref.substs,
|
rcvr_substs: bound_trait_ref.substs.clone(),
|
||||||
method_ty: method,
|
method_ty: method,
|
||||||
origin: method_param(
|
origin: method_param(
|
||||||
method_param {
|
method_param {
|
||||||
|
@ -441,7 +442,7 @@ impl<'self> LookupContext<'self> {
|
||||||
// for Self.
|
// for Self.
|
||||||
let rcvr_substs = substs {
|
let rcvr_substs = substs {
|
||||||
self_ty: Some(self_ty),
|
self_ty: Some(self_ty),
|
||||||
../*bad*/copy *substs
|
..(*substs).clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
self.inherent_candidates.push(Candidate {
|
self.inherent_candidates.push(Candidate {
|
||||||
|
@ -506,7 +507,7 @@ impl<'self> LookupContext<'self> {
|
||||||
};
|
};
|
||||||
self.inherent_candidates.push(Candidate {
|
self.inherent_candidates.push(Candidate {
|
||||||
rcvr_ty: self_ty,
|
rcvr_ty: self_ty,
|
||||||
rcvr_substs: copy info.trait_ref.substs,
|
rcvr_substs: info.trait_ref.substs.clone(),
|
||||||
method_ty: info.method_ty,
|
method_ty: info.method_ty,
|
||||||
origin: origin
|
origin: origin
|
||||||
});
|
});
|
||||||
|
@ -814,8 +815,9 @@ impl<'self> LookupContext<'self> {
|
||||||
rcvr_ty: ty::t,
|
rcvr_ty: ty::t,
|
||||||
candidates: &mut ~[Candidate])
|
candidates: &mut ~[Candidate])
|
||||||
-> Option<method_map_entry> {
|
-> Option<method_map_entry> {
|
||||||
|
// XXX(pcwalton): Do we need to clone here?
|
||||||
let relevant_candidates: ~[Candidate] =
|
let relevant_candidates: ~[Candidate] =
|
||||||
candidates.iter().transform(|c| copy *c).
|
candidates.iter().transform(|c| (*c).clone()).
|
||||||
filter(|c| self.is_relevant(rcvr_ty, c)).collect();
|
filter(|c| self.is_relevant(rcvr_ty, c)).collect();
|
||||||
|
|
||||||
let relevant_candidates = self.merge_candidates(relevant_candidates);
|
let relevant_candidates = self.merge_candidates(relevant_candidates);
|
||||||
|
@ -840,7 +842,7 @@ impl<'self> LookupContext<'self> {
|
||||||
let mut merged = ~[];
|
let mut merged = ~[];
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < candidates.len() {
|
while i < candidates.len() {
|
||||||
let candidate_a = /*bad*/copy candidates[i];
|
let candidate_a = &candidates[i];
|
||||||
|
|
||||||
let mut skip = false;
|
let mut skip = false;
|
||||||
|
|
||||||
|
@ -875,7 +877,7 @@ impl<'self> LookupContext<'self> {
|
||||||
// There are more than one of these and we need only one
|
// There are more than one of these and we need only one
|
||||||
loop;
|
loop;
|
||||||
} else {
|
} else {
|
||||||
merged.push(candidate_a);
|
merged.push(candidate_a.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,9 +953,9 @@ impl<'self> LookupContext<'self> {
|
||||||
// Construct the full set of type parameters for the method,
|
// Construct the full set of type parameters for the method,
|
||||||
// which is equal to the class tps + the method tps.
|
// which is equal to the class tps + the method tps.
|
||||||
let all_substs = substs {
|
let all_substs = substs {
|
||||||
tps: vec::append(/*bad*/copy candidate.rcvr_substs.tps,
|
tps: vec::append(candidate.rcvr_substs.tps.clone(), m_substs),
|
||||||
m_substs),
|
self_r: candidate.rcvr_substs.self_r,
|
||||||
../*bad*/copy candidate.rcvr_substs
|
self_ty: candidate.rcvr_substs.self_ty,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Compute the method type with type parameters substituted
|
// Compute the method type with type parameters substituted
|
||||||
|
@ -966,7 +968,7 @@ impl<'self> LookupContext<'self> {
|
||||||
// Replace any bound regions that appear in the function
|
// Replace any bound regions that appear in the function
|
||||||
// signature with region variables
|
// signature with region variables
|
||||||
let bare_fn_ty = match ty::get(fty).sty {
|
let bare_fn_ty = match ty::get(fty).sty {
|
||||||
ty::ty_bare_fn(ref f) => copy *f,
|
ty::ty_bare_fn(ref f) => f,
|
||||||
ref s => {
|
ref s => {
|
||||||
tcx.sess.span_bug(
|
tcx.sess.span_bug(
|
||||||
self.expr.span,
|
self.expr.span,
|
||||||
|
@ -979,7 +981,11 @@ impl<'self> LookupContext<'self> {
|
||||||
|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.get();
|
||||||
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty});
|
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||||
|
sig: fn_sig,
|
||||||
|
purity: bare_fn_ty.purity,
|
||||||
|
abis: bare_fn_ty.abis.clone(),
|
||||||
|
});
|
||||||
debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty));
|
debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty));
|
||||||
|
|
||||||
let self_mode = get_mode_from_explicit_self(candidate.method_ty.explicit_self);
|
let self_mode = get_mode_from_explicit_self(candidate.method_ty.explicit_self);
|
||||||
|
@ -1178,7 +1184,7 @@ impl<'self> LookupContext<'self> {
|
||||||
trait_did: def_id,
|
trait_did: def_id,
|
||||||
method_num: uint) -> ty::t {
|
method_num: uint) -> ty::t {
|
||||||
let trait_methods = ty::trait_methods(tcx, trait_did);
|
let trait_methods = ty::trait_methods(tcx, trait_did);
|
||||||
ty::mk_bare_fn(tcx, copy trait_methods[method_num].fty)
|
ty::mk_bare_fn(tcx, trait_methods[method_num].fty.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,7 @@ pub struct inherited {
|
||||||
vtable_map: vtable_map,
|
vtable_map: vtable_map,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum FnKind {
|
pub enum FnKind {
|
||||||
// This is a for-closure. The ty::t is the return type of the
|
// This is a for-closure. The ty::t is the return type of the
|
||||||
// enclosing function.
|
// enclosing function.
|
||||||
|
@ -180,6 +181,7 @@ pub enum FnKind {
|
||||||
Vanilla
|
Vanilla
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct PurityState {
|
pub struct PurityState {
|
||||||
def: ast::node_id,
|
def: ast::node_id,
|
||||||
purity: ast::purity,
|
purity: ast::purity,
|
||||||
|
@ -219,6 +221,7 @@ enum AllowOverloadedOperatorsFlag {
|
||||||
DontAllowOverloadedOperators,
|
DontAllowOverloadedOperators,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct FnCtxt {
|
pub struct FnCtxt {
|
||||||
// Number of errors that had been reported when we started
|
// Number of errors that had been reported when we started
|
||||||
// checking this function. On exit, if we find that *more* errors
|
// checking this function. On exit, if we find that *more* errors
|
||||||
|
@ -833,7 +836,7 @@ impl FnCtxt {
|
||||||
|
|
||||||
pub fn node_ty_substs(&self, id: ast::node_id) -> ty::substs {
|
pub fn node_ty_substs(&self, id: ast::node_id) -> ty::substs {
|
||||||
match self.inh.node_type_substs.find(&id) {
|
match self.inh.node_type_substs.find(&id) {
|
||||||
Some(ts) => (/*bad*/copy *ts),
|
Some(ts) => (*ts).clone(),
|
||||||
None => {
|
None => {
|
||||||
self.tcx().sess.bug(
|
self.tcx().sess.bug(
|
||||||
fmt!("no type substs for node %d: %s in fcx %s",
|
fmt!("no type substs for node %d: %s in fcx %s",
|
||||||
|
@ -986,7 +989,7 @@ pub fn do_autoderef(fcx: @mut FnCtxt, sp: span, t: ty::t) -> (ty::t, uint) {
|
||||||
let sty = structure_of(fcx, sp, t1);
|
let sty = structure_of(fcx, sp, t1);
|
||||||
|
|
||||||
// Some extra checks to detect weird cycles and so forth:
|
// Some extra checks to detect weird cycles and so forth:
|
||||||
match sty {
|
match *sty {
|
||||||
ty::ty_box(inner) | ty::ty_uniq(inner) |
|
ty::ty_box(inner) | ty::ty_uniq(inner) |
|
||||||
ty::ty_rptr(_, inner) => {
|
ty::ty_rptr(_, inner) => {
|
||||||
match ty::get(t1).sty {
|
match ty::get(t1).sty {
|
||||||
|
@ -1014,7 +1017,7 @@ pub fn do_autoderef(fcx: @mut FnCtxt, sp: span, t: ty::t) -> (ty::t, uint) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, deref if type is derefable:
|
// Otherwise, deref if type is derefable:
|
||||||
match ty::deref_sty(fcx.ccx.tcx, &sty, false) {
|
match ty::deref_sty(fcx.ccx.tcx, sty, false) {
|
||||||
None => {
|
None => {
|
||||||
return (t1, autoderefs);
|
return (t1, autoderefs);
|
||||||
}
|
}
|
||||||
|
@ -1352,28 +1355,35 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
// Extract the function signature from `in_fty`.
|
// Extract the function signature from `in_fty`.
|
||||||
let fn_sty = structure_of(fcx, f.span, fn_ty);
|
let fn_sty = structure_of(fcx, f.span, fn_ty);
|
||||||
|
|
||||||
let fn_sig = match fn_sty {
|
// This is the "default" function signature, used in case of error.
|
||||||
ty::ty_bare_fn(ty::BareFnTy {sig: sig, _}) |
|
// In that case, we check each argument against "error" in order to
|
||||||
ty::ty_closure(ty::ClosureTy {sig: sig, _}) => sig,
|
// set up all the node type bindings.
|
||||||
|
let error_fn_sig = FnSig {
|
||||||
|
bound_lifetime_names: opt_vec::Empty,
|
||||||
|
inputs: err_args(args.len()),
|
||||||
|
output: ty::mk_err()
|
||||||
|
};
|
||||||
|
|
||||||
|
let fn_sig = match *fn_sty {
|
||||||
|
ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) |
|
||||||
|
ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => sig,
|
||||||
_ => {
|
_ => {
|
||||||
fcx.type_error_message(call_expr.span, |actual| {
|
fcx.type_error_message(call_expr.span, |actual| {
|
||||||
fmt!("expected function but \
|
fmt!("expected function but \
|
||||||
found `%s`", actual) }, fn_ty, None);
|
found `%s`", actual) }, fn_ty, None);
|
||||||
|
&error_fn_sig
|
||||||
// check each arg against "error", in order to set up
|
|
||||||
// all the node type bindings
|
|
||||||
FnSig {bound_lifetime_names: opt_vec::Empty,
|
|
||||||
inputs: err_args(args.len()),
|
|
||||||
output: ty::mk_err()}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Replace any bound regions that appear in the function
|
// Replace any bound regions that appear in the function
|
||||||
// signature with region variables
|
// signature with region variables
|
||||||
let (_, _, fn_sig) =
|
let (_, _, fn_sig) =
|
||||||
replace_bound_regions_in_fn_sig(
|
replace_bound_regions_in_fn_sig(fcx.tcx(),
|
||||||
fcx.tcx(), @Nil, None, &fn_sig,
|
@Nil,
|
||||||
|br| fcx.infcx().next_region_var(
|
None,
|
||||||
|
fn_sig,
|
||||||
|
|br| fcx.infcx()
|
||||||
|
.next_region_var(
|
||||||
infer::BoundRegionInFnCall(call_expr.span, br)));
|
infer::BoundRegionInFnCall(call_expr.span, br)));
|
||||||
|
|
||||||
// Call the generic checker.
|
// Call the generic checker.
|
||||||
|
@ -1708,7 +1718,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
// to impure and block. Note that we only will use those for
|
// to impure and block. Note that we only will use those for
|
||||||
// block syntax lambdas; that is, lambdas without explicit
|
// block syntax lambdas; that is, lambdas without explicit
|
||||||
// sigils.
|
// sigils.
|
||||||
let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
|
let expected_sty = unpack_expected(fcx,
|
||||||
|
expected,
|
||||||
|
|x| Some((*x).clone()));
|
||||||
let error_happened = false;
|
let error_happened = false;
|
||||||
let (expected_sig,
|
let (expected_sig,
|
||||||
expected_purity,
|
expected_purity,
|
||||||
|
@ -1761,10 +1773,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
output: ty::mk_err()
|
output: ty::mk_err()
|
||||||
};
|
};
|
||||||
ty::mk_err()
|
ty::mk_err()
|
||||||
}
|
} else {
|
||||||
else {
|
let fn_ty_copy = fn_ty.clone();
|
||||||
let fn_ty_copy = copy fn_ty;
|
fty_sig = fn_ty.sig.clone();
|
||||||
fty_sig = copy fn_ty.sig;
|
|
||||||
ty::mk_closure(tcx, fn_ty_copy)
|
ty::mk_closure(tcx, fn_ty_copy)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1795,7 +1806,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
fcx.expr_ty(base));
|
fcx.expr_ty(base));
|
||||||
let (base_t, derefs) = do_autoderef(fcx, expr.span, expr_t);
|
let (base_t, derefs) = do_autoderef(fcx, expr.span, expr_t);
|
||||||
|
|
||||||
match structure_of(fcx, expr.span, base_t) {
|
match *structure_of(fcx, expr.span, base_t) {
|
||||||
ty::ty_struct(base_id, ref substs) => {
|
ty::ty_struct(base_id, ref substs) => {
|
||||||
// This is just for fields -- the same code handles
|
// This is just for fields -- the same code handles
|
||||||
// methods in both classes and traits
|
// methods in both classes and traits
|
||||||
|
@ -2119,16 +2130,20 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
// 2. the closure that was given returns unit
|
// 2. the closure that was given returns unit
|
||||||
let tcx = fcx.tcx();
|
let tcx = fcx.tcx();
|
||||||
let mut err_happened = false;
|
let mut err_happened = false;
|
||||||
let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
|
let expected_sty = unpack_expected(fcx,
|
||||||
|
expected,
|
||||||
|
|x| Some((*x).clone()));
|
||||||
let inner_ty = match expected_sty {
|
let inner_ty = match expected_sty {
|
||||||
Some(ty::ty_closure(ref fty)) => {
|
Some(ty::ty_closure(ref fty)) => {
|
||||||
match fcx.mk_subty(false, infer::Misc(expr.span),
|
match fcx.mk_subty(false, infer::Misc(expr.span),
|
||||||
fty.sig.output, ty::mk_bool()) {
|
fty.sig.output, ty::mk_bool()) {
|
||||||
result::Ok(_) => {
|
result::Ok(_) => {
|
||||||
ty::mk_closure(tcx, ty::ClosureTy {
|
ty::mk_closure(tcx, ty::ClosureTy {
|
||||||
sig: FnSig {output: ty::mk_nil(),
|
sig: FnSig {
|
||||||
..copy fty.sig},
|
output: ty::mk_nil(),
|
||||||
..copy *fty
|
..fty.sig.clone()
|
||||||
|
},
|
||||||
|
..(*fty).clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
result::Err(_) => {
|
result::Err(_) => {
|
||||||
|
@ -2361,13 +2376,13 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
}
|
}
|
||||||
ast::deref => {
|
ast::deref => {
|
||||||
let sty = structure_of(fcx, expr.span, oprnd_t);
|
let sty = structure_of(fcx, expr.span, oprnd_t);
|
||||||
let operand_ty = ty::deref_sty(tcx, &sty, true);
|
let operand_ty = ty::deref_sty(tcx, sty, true);
|
||||||
match operand_ty {
|
match operand_ty {
|
||||||
Some(mt) => {
|
Some(mt) => {
|
||||||
oprnd_t = mt.ty
|
oprnd_t = mt.ty
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
match sty {
|
match *sty {
|
||||||
ty::ty_enum(*) => {
|
ty::ty_enum(*) => {
|
||||||
tcx.sess.span_err(
|
tcx.sess.span_err(
|
||||||
expr.span,
|
expr.span,
|
||||||
|
@ -2564,7 +2579,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
check_loop_body(fcx, expr, expected, loop_body);
|
check_loop_body(fcx, expr, expected, loop_body);
|
||||||
}
|
}
|
||||||
ast::expr_do_body(b) => {
|
ast::expr_do_body(b) => {
|
||||||
let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
|
let expected_sty = unpack_expected(fcx,
|
||||||
|
expected,
|
||||||
|
|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.get(),
|
||||||
_ => match expected {
|
_ => match expected {
|
||||||
|
@ -2759,7 +2776,10 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
}
|
}
|
||||||
ast::expr_tup(ref elts) => {
|
ast::expr_tup(ref elts) => {
|
||||||
let flds = unpack_expected(fcx, expected, |sty| {
|
let flds = unpack_expected(fcx, expected, |sty| {
|
||||||
match *sty { ty::ty_tup(ref flds) => Some(copy *flds), _ => None }
|
match *sty {
|
||||||
|
ty::ty_tup(ref flds) => Some((*flds).clone()),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
});
|
});
|
||||||
let mut bot_field = false;
|
let mut bot_field = false;
|
||||||
let mut err_field = false;
|
let mut err_field = false;
|
||||||
|
@ -2816,7 +2836,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
} else {
|
} else {
|
||||||
let (base_t, derefs) = do_autoderef(fcx, expr.span, raw_base_t);
|
let (base_t, derefs) = do_autoderef(fcx, expr.span, raw_base_t);
|
||||||
let base_sty = structure_of(fcx, expr.span, base_t);
|
let base_sty = structure_of(fcx, expr.span, base_t);
|
||||||
match ty::index_sty(&base_sty) {
|
match ty::index_sty(base_sty) {
|
||||||
Some(mt) => {
|
Some(mt) => {
|
||||||
require_integral(fcx, idx.span, idx_t);
|
require_integral(fcx, idx.span, idx_t);
|
||||||
fcx.write_ty(id, mt.ty);
|
fcx.write_ty(id, mt.ty);
|
||||||
|
@ -3374,8 +3394,9 @@ pub fn structurally_resolved_type(fcx: @mut FnCtxt, sp: span, tp: ty::t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the one-level-deep structure of the given type.
|
// Returns the one-level-deep structure of the given type.
|
||||||
pub fn structure_of(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> ty::sty {
|
pub fn structure_of<'a>(fcx: @mut FnCtxt, sp: span, typ: ty::t)
|
||||||
/*bad*/copy ty::get(structurally_resolved_type(fcx, sp, typ)).sty
|
-> &'a ty::sty {
|
||||||
|
&ty::get(structurally_resolved_type(fcx, sp, typ)).sty
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_is_integral(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> bool {
|
pub fn type_is_integral(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> bool {
|
||||||
|
|
|
@ -132,9 +132,12 @@ fn lookup_vtables(vcx: &VtableContext,
|
||||||
@result
|
@result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
|
fn fixup_substs(vcx: &VtableContext,
|
||||||
id: ast::def_id, substs: ty::substs,
|
location_info: &LocationInfo,
|
||||||
is_early: bool) -> Option<ty::substs> {
|
id: ast::def_id,
|
||||||
|
substs: ty::substs,
|
||||||
|
is_early: bool)
|
||||||
|
-> Option<ty::substs> {
|
||||||
let tcx = vcx.tcx();
|
let tcx = vcx.tcx();
|
||||||
// use a dummy type just to package up the substs that need fixing up
|
// use a dummy type just to package up the substs that need fixing up
|
||||||
let t = ty::mk_trait(tcx,
|
let t = ty::mk_trait(tcx,
|
||||||
|
@ -144,7 +147,7 @@ fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
|
||||||
ty::EmptyBuiltinBounds());
|
ty::EmptyBuiltinBounds());
|
||||||
do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
|
do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
|
||||||
match ty::get(*t_f).sty {
|
match ty::get(*t_f).sty {
|
||||||
ty::ty_trait(_, ref substs_f, _, _, _) => (/*bad*/copy *substs_f),
|
ty::ty_trait(_, ref substs_f, _, _, _) => (*substs_f).clone(),
|
||||||
_ => fail!("t_f should be a trait")
|
_ => fail!("t_f should be a trait")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,7 +368,7 @@ fn lookup_vtable(vcx: &VtableContext,
|
||||||
trait_ref.def_id,
|
trait_ref.def_id,
|
||||||
substs,
|
substs,
|
||||||
is_early) {
|
is_early) {
|
||||||
Some(ref substs) => (/*bad*/copy *substs),
|
Some(ref substs) => (*substs).clone(),
|
||||||
None => {
|
None => {
|
||||||
assert!(is_early);
|
assert!(is_early);
|
||||||
// Bail out with a bogus answer
|
// Bail out with a bogus answer
|
||||||
|
@ -403,10 +406,9 @@ fn lookup_vtable(vcx: &VtableContext,
|
||||||
// the impl as well as the resolved list
|
// the impl as well as the resolved list
|
||||||
// of type substitutions for the target
|
// of type substitutions for the target
|
||||||
// trait.
|
// trait.
|
||||||
found.push(
|
found.push(vtable_static(im.did,
|
||||||
vtable_static(im.did,
|
substs_f.tps.clone(),
|
||||||
/*bad*/copy substs_f.tps,
|
subres));
|
||||||
subres));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -414,14 +416,14 @@ fn lookup_vtable(vcx: &VtableContext,
|
||||||
|
|
||||||
match found.len() {
|
match found.len() {
|
||||||
0 => { /* fallthrough */ }
|
0 => { /* fallthrough */ }
|
||||||
1 => { return Some(/*bad*/copy found[0]); }
|
1 => return Some(found[0].clone()),
|
||||||
_ => {
|
_ => {
|
||||||
if !is_early {
|
if !is_early {
|
||||||
vcx.tcx().sess.span_err(
|
vcx.tcx().sess.span_err(
|
||||||
location_info.span,
|
location_info.span,
|
||||||
"multiple applicable methods in scope");
|
"multiple applicable methods in scope");
|
||||||
}
|
}
|
||||||
return Some(/*bad*/copy found[0]);
|
return Some(found[0].clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -587,7 +589,7 @@ pub fn early_resolve_expr(ex: @ast::expr,
|
||||||
let target_trait_ref = @ty::TraitRef {
|
let target_trait_ref = @ty::TraitRef {
|
||||||
def_id: target_def_id,
|
def_id: target_def_id,
|
||||||
substs: ty::substs {
|
substs: ty::substs {
|
||||||
tps: copy target_substs.tps,
|
tps: target_substs.tps.clone(),
|
||||||
self_r: target_substs.self_r,
|
self_r: target_substs.self_r,
|
||||||
self_ty: Some(mt.ty)
|
self_ty: Some(mt.ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,9 +208,10 @@ impl CoherenceChecker {
|
||||||
|
|
||||||
match item.node {
|
match item.node {
|
||||||
item_impl(_, ref opt_trait, _, _) => {
|
item_impl(_, ref opt_trait, _, _) => {
|
||||||
let opt_trait : ~[trait_ref] = opt_trait.iter()
|
let opt_trait : ~[trait_ref] =
|
||||||
.transform(|x| copy *x)
|
opt_trait.iter()
|
||||||
.collect();
|
.transform(|x| (*x).clone())
|
||||||
|
.collect();
|
||||||
self.check_implementation(item, opt_trait);
|
self.check_implementation(item, opt_trait);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -358,14 +359,14 @@ impl CoherenceChecker {
|
||||||
let new_generics = ty::Generics {
|
let new_generics = ty::Generics {
|
||||||
type_param_defs:
|
type_param_defs:
|
||||||
@vec::append(
|
@vec::append(
|
||||||
copy *impl_poly_type.generics.type_param_defs,
|
(*impl_poly_type.generics.type_param_defs).clone(),
|
||||||
*new_method_ty.generics.type_param_defs),
|
*new_method_ty.generics.type_param_defs),
|
||||||
region_param:
|
region_param:
|
||||||
impl_poly_type.generics.region_param
|
impl_poly_type.generics.region_param
|
||||||
};
|
};
|
||||||
let new_polytype = ty::ty_param_bounds_and_ty {
|
let new_polytype = ty::ty_param_bounds_and_ty {
|
||||||
generics: new_generics,
|
generics: new_generics,
|
||||||
ty: ty::mk_bare_fn(tcx, copy new_method_ty.fty)
|
ty: ty::mk_bare_fn(tcx, new_method_ty.fty.clone())
|
||||||
};
|
};
|
||||||
debug!("new_polytype=%s", new_polytype.repr(tcx));
|
debug!("new_polytype=%s", new_polytype.repr(tcx));
|
||||||
|
|
||||||
|
@ -901,7 +902,7 @@ impl CoherenceChecker {
|
||||||
|
|
||||||
// XXX(sully): We could probably avoid this copy if there are no
|
// XXX(sully): We could probably avoid this copy if there are no
|
||||||
// default methods.
|
// default methods.
|
||||||
let mut methods = copy implementation.methods;
|
let mut methods = implementation.methods.clone();
|
||||||
self.add_provided_methods_to_impl(&mut methods,
|
self.add_provided_methods_to_impl(&mut methods,
|
||||||
&trait_ref.def_id,
|
&trait_ref.def_id,
|
||||||
&implementation.did);
|
&implementation.did);
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToTy {
|
pub trait ToTy {
|
||||||
fn to_ty<RS:region_scope + Copy + 'static>(
|
fn to_ty<RS:region_scope + Clone + 'static>(
|
||||||
&self,
|
&self,
|
||||||
rs: &RS,
|
rs: &RS,
|
||||||
ast_ty: &ast::Ty)
|
ast_ty: &ast::Ty)
|
||||||
|
@ -94,7 +94,7 @@ pub trait ToTy {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTy for CrateCtxt {
|
impl ToTy for CrateCtxt {
|
||||||
fn to_ty<RS:region_scope + Copy + 'static>(
|
fn to_ty<RS:region_scope + Clone + 'static>(
|
||||||
&self,
|
&self,
|
||||||
rs: &RS,
|
rs: &RS,
|
||||||
ast_ty: &ast::Ty)
|
ast_ty: &ast::Ty)
|
||||||
|
@ -309,7 +309,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
|
||||||
// create the type of `foo`, applying the substitution above
|
// create the type of `foo`, applying the substitution above
|
||||||
let ty = ty::subst(tcx,
|
let ty = ty::subst(tcx,
|
||||||
&substs,
|
&substs,
|
||||||
ty::mk_bare_fn(tcx, copy m.fty));
|
ty::mk_bare_fn(tcx, m.fty.clone()));
|
||||||
|
|
||||||
// create the type parameter definitions for `foo`, applying
|
// create the type parameter definitions for `foo`, applying
|
||||||
// the substitution to any traits that appear in their bounds.
|
// the substitution to any traits that appear in their bounds.
|
||||||
|
@ -569,27 +569,35 @@ pub fn compare_impl_method(tcx: ty::ctxt,
|
||||||
|
|
||||||
// Create a bare fn type for trait/impl that includes self argument
|
// Create a bare fn type for trait/impl that includes self argument
|
||||||
let trait_fty =
|
let trait_fty =
|
||||||
ty::mk_bare_fn(
|
ty::mk_bare_fn(tcx,
|
||||||
tcx,
|
ty::BareFnTy {
|
||||||
ty::BareFnTy {purity: trait_m.fty.purity,
|
purity: trait_m.fty.purity,
|
||||||
abis: trait_m.fty.abis,
|
abis: trait_m.fty.abis,
|
||||||
sig: ty::FnSig {
|
sig: ty::FnSig {
|
||||||
bound_lifetime_names:
|
bound_lifetime_names:
|
||||||
copy trait_m.fty.sig.bound_lifetime_names,
|
trait_m.fty
|
||||||
inputs: trait_fn_args,
|
.sig
|
||||||
output: trait_m.fty.sig.output
|
.bound_lifetime_names
|
||||||
}});
|
.clone(),
|
||||||
|
inputs: trait_fn_args,
|
||||||
|
output: trait_m.fty.sig.output
|
||||||
|
}
|
||||||
|
});
|
||||||
let impl_fty =
|
let impl_fty =
|
||||||
ty::mk_bare_fn(
|
ty::mk_bare_fn(tcx,
|
||||||
tcx,
|
ty::BareFnTy {
|
||||||
ty::BareFnTy {purity: impl_m.fty.purity,
|
purity: impl_m.fty.purity,
|
||||||
abis: impl_m.fty.abis,
|
abis: impl_m.fty.abis,
|
||||||
sig: ty::FnSig {
|
sig: ty::FnSig {
|
||||||
bound_lifetime_names:
|
bound_lifetime_names:
|
||||||
copy impl_m.fty.sig.bound_lifetime_names,
|
impl_m.fty
|
||||||
inputs: impl_fn_args,
|
.sig
|
||||||
output: impl_m.fty.sig.output
|
.bound_lifetime_names
|
||||||
}});
|
.clone(),
|
||||||
|
inputs: impl_fn_args,
|
||||||
|
output: impl_m.fty.sig.output
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Perform substitutions so that the trait/impl methods are expressed
|
// Perform substitutions so that the trait/impl methods are expressed
|
||||||
// in terms of the same set of type/region parameters:
|
// in terms of the same set of type/region parameters:
|
||||||
|
@ -730,8 +738,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
|
||||||
untransformed_rcvr_ty,
|
untransformed_rcvr_ty,
|
||||||
rcvr_ast_generics, rcvr_visibility,
|
rcvr_ast_generics, rcvr_visibility,
|
||||||
&m.generics);
|
&m.generics);
|
||||||
let fty =
|
let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
|
||||||
ty::mk_bare_fn(tcx, copy mty.fty);
|
|
||||||
tcx.tcache.insert(
|
tcx.tcache.insert(
|
||||||
local_def(m.id),
|
local_def(m.id),
|
||||||
|
|
||||||
|
@ -740,7 +747,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
|
||||||
ty_param_bounds_and_ty {
|
ty_param_bounds_and_ty {
|
||||||
generics: ty::Generics {
|
generics: ty::Generics {
|
||||||
type_param_defs: @vec::append(
|
type_param_defs: @vec::append(
|
||||||
copy *rcvr_ty_generics.type_param_defs,
|
(*rcvr_ty_generics.type_param_defs).clone(),
|
||||||
*m_ty_generics.type_param_defs),
|
*m_ty_generics.type_param_defs),
|
||||||
region_param: rcvr_ty_generics.region_param
|
region_param: rcvr_ty_generics.region_param
|
||||||
},
|
},
|
||||||
|
|
|
@ -275,8 +275,10 @@ impl Coerce {
|
||||||
b.inf_str(self.infcx));
|
b.inf_str(self.infcx));
|
||||||
|
|
||||||
let fn_ty = match *sty_a {
|
let fn_ty = match *sty_a {
|
||||||
ty::ty_closure(ref f) if f.sigil == ast::ManagedSigil => copy *f,
|
ty::ty_closure(ref f) if f.sigil == ast::ManagedSigil ||
|
||||||
ty::ty_closure(ref f) if f.sigil == ast::OwnedSigil => copy *f,
|
f.sigil == ast::OwnedSigil => {
|
||||||
|
(*f).clone()
|
||||||
|
}
|
||||||
ty::ty_bare_fn(ref f) => {
|
ty::ty_bare_fn(ref f) => {
|
||||||
return self.coerce_from_bare_fn(a, f, b);
|
return self.coerce_from_bare_fn(a, f, b);
|
||||||
}
|
}
|
||||||
|
@ -331,16 +333,16 @@ impl Coerce {
|
||||||
}
|
}
|
||||||
|
|
||||||
let fn_ty_b = match *sty_b {
|
let fn_ty_b = match *sty_b {
|
||||||
ty::ty_closure(ref f) => {copy *f}
|
ty::ty_closure(ref f) => (*f).clone(),
|
||||||
_ => {
|
_ => return self.subtype(a, b),
|
||||||
return self.subtype(a, b);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
|
let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
|
||||||
let a_closure = ty::mk_closure(
|
let a_closure = ty::mk_closure(self.infcx.tcx,
|
||||||
self.infcx.tcx,
|
ty::ClosureTy {
|
||||||
ty::ClosureTy {sig: copy fn_ty_a.sig, ..fn_ty_b});
|
sig: fn_ty_a.sig.clone(),
|
||||||
|
..fn_ty_b
|
||||||
|
});
|
||||||
if_ok!(self.subtype(a_closure, b));
|
if_ok!(self.subtype(a_closure, b));
|
||||||
Ok(Some(adj))
|
Ok(Some(adj))
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,13 +241,14 @@ pub fn super_substs<C:Combine>(
|
||||||
|
|
||||||
do this.tps(a.tps, b.tps).chain |tps| {
|
do this.tps(a.tps, b.tps).chain |tps| {
|
||||||
do this.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
|
do this.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
|
||||||
do relate_region_param(this, generics,
|
do relate_region_param(this,
|
||||||
a.self_r, b.self_r).chain |self_r|
|
generics,
|
||||||
{
|
a.self_r,
|
||||||
|
b.self_r).chain |self_r| {
|
||||||
Ok(substs {
|
Ok(substs {
|
||||||
self_r: self_r,
|
self_r: self_r,
|
||||||
self_ty: self_ty,
|
self_ty: self_ty,
|
||||||
tps: /*bad*/copy tps
|
tps: tps.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,7 +426,7 @@ pub fn super_fn_sigs<C:Combine>(
|
||||||
.chain |inputs| {
|
.chain |inputs| {
|
||||||
do this.tys(a_f.output, b_f.output).chain |output| {
|
do this.tys(a_f.output, b_f.output).chain |output| {
|
||||||
Ok(FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
|
Ok(FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
|
||||||
inputs: /*bad*/copy inputs,
|
inputs: inputs.clone(),
|
||||||
output: output})
|
output: output})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -515,7 +516,12 @@ pub fn super_tys<C:Combine>(
|
||||||
do this.substs(&trait_def.generics, a_substs, b_substs).chain |substs| {
|
do this.substs(&trait_def.generics, a_substs, b_substs).chain |substs| {
|
||||||
do this.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
|
do this.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
|
||||||
do this.bounds(a_bounds, b_bounds).chain |bounds| {
|
do this.bounds(a_bounds, b_bounds).chain |bounds| {
|
||||||
Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s, a_mutbl, bounds))
|
Ok(ty::mk_trait(tcx,
|
||||||
|
a_id,
|
||||||
|
substs.clone(),
|
||||||
|
s,
|
||||||
|
a_mutbl,
|
||||||
|
bounds))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,39 +71,39 @@ impl LatticeValue for ty::t {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CombineFieldsLatticeMethods {
|
pub trait CombineFieldsLatticeMethods {
|
||||||
fn var_sub_var<T:Copy + InferStr + LatticeValue,
|
fn var_sub_var<T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(&self,
|
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(&self,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
b_id: V)
|
b_id: V)
|
||||||
-> ures;
|
-> ures;
|
||||||
/// make variable a subtype of T
|
/// make variable a subtype of T
|
||||||
fn var_sub_t<T:Copy + InferStr + LatticeValue,
|
fn var_sub_t<T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||||
&self,
|
&self,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
b: T)
|
b: T)
|
||||||
-> ures;
|
-> ures;
|
||||||
fn t_sub_var<T:Copy + InferStr + LatticeValue,
|
fn t_sub_var<T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||||
&self,
|
&self,
|
||||||
a: T,
|
a: T,
|
||||||
b_id: V)
|
b_id: V)
|
||||||
-> ures;
|
-> ures;
|
||||||
fn merge_bnd<T:Copy + InferStr + LatticeValue>(
|
fn merge_bnd<T:Clone + InferStr + LatticeValue>(
|
||||||
&self,
|
&self,
|
||||||
a: &Bound<T>,
|
a: &Bound<T>,
|
||||||
b: &Bound<T>,
|
b: &Bound<T>,
|
||||||
lattice_op: LatticeOp<T>)
|
lattice_op: LatticeOp<T>)
|
||||||
-> cres<Bound<T>>;
|
-> cres<Bound<T>>;
|
||||||
fn set_var_to_merged_bounds<T:Copy + InferStr + LatticeValue,
|
fn set_var_to_merged_bounds<T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy+Eq+ToStr+Vid+UnifyVid<Bounds<T>>>(
|
V:Clone+Eq+ToStr+Vid+UnifyVid<Bounds<T>>>(
|
||||||
&self,
|
&self,
|
||||||
v_id: V,
|
v_id: V,
|
||||||
a: &Bounds<T>,
|
a: &Bounds<T>,
|
||||||
b: &Bounds<T>,
|
b: &Bounds<T>,
|
||||||
rank: uint)
|
rank: uint)
|
||||||
-> ures;
|
-> ures;
|
||||||
fn bnds<T:Copy + InferStr + LatticeValue>(
|
fn bnds<T:Clone + InferStr + LatticeValue>(
|
||||||
&self,
|
&self,
|
||||||
a: &Bound<T>,
|
a: &Bound<T>,
|
||||||
b: &Bound<T>)
|
b: &Bound<T>)
|
||||||
|
@ -111,8 +111,8 @@ pub trait CombineFieldsLatticeMethods {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CombineFieldsLatticeMethods for CombineFields {
|
impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
fn var_sub_var<T:Copy + InferStr + LatticeValue,
|
fn var_sub_var<T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||||
&self,
|
&self,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
b_id: V)
|
b_id: V)
|
||||||
|
@ -126,10 +126,10 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
// Need to make sub_id a subtype of sup_id.
|
// Need to make sub_id a subtype of sup_id.
|
||||||
let node_a = self.infcx.get(a_id);
|
let node_a = self.infcx.get(a_id);
|
||||||
let node_b = self.infcx.get(b_id);
|
let node_b = self.infcx.get(b_id);
|
||||||
let a_id = copy node_a.root;
|
let a_id = node_a.root.clone();
|
||||||
let b_id = copy node_b.root;
|
let b_id = node_b.root.clone();
|
||||||
let a_bounds = copy node_a.possible_types;
|
let a_bounds = node_a.possible_types.clone();
|
||||||
let b_bounds = copy node_b.possible_types;
|
let b_bounds = node_b.possible_types.clone();
|
||||||
|
|
||||||
debug!("vars(%s=%s <: %s=%s)",
|
debug!("vars(%s=%s <: %s=%s)",
|
||||||
a_id.to_str(), a_bounds.inf_str(self.infcx),
|
a_id.to_str(), a_bounds.inf_str(self.infcx),
|
||||||
|
@ -164,8 +164,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// make variable a subtype of T
|
/// make variable a subtype of T
|
||||||
fn var_sub_t<T:Copy + InferStr + LatticeValue,
|
fn var_sub_t<T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||||
&self,
|
&self,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
b: T)
|
b: T)
|
||||||
|
@ -175,9 +175,9 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
* Make a variable (`a_id`) a subtype of the concrete type `b` */
|
* Make a variable (`a_id`) a subtype of the concrete type `b` */
|
||||||
|
|
||||||
let node_a = self.infcx.get(a_id);
|
let node_a = self.infcx.get(a_id);
|
||||||
let a_id = copy node_a.root;
|
let a_id = node_a.root.clone();
|
||||||
let a_bounds = &node_a.possible_types;
|
let a_bounds = &node_a.possible_types;
|
||||||
let b_bounds = &Bounds { lb: None, ub: Some(copy b) };
|
let b_bounds = &Bounds { lb: None, ub: Some(b.clone()) };
|
||||||
|
|
||||||
debug!("var_sub_t(%s=%s <: %s)",
|
debug!("var_sub_t(%s=%s <: %s)",
|
||||||
a_id.to_str(),
|
a_id.to_str(),
|
||||||
|
@ -188,8 +188,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
a_id, a_bounds, b_bounds, node_a.rank)
|
a_id, a_bounds, b_bounds, node_a.rank)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn t_sub_var<T:Copy + InferStr + LatticeValue,
|
fn t_sub_var<T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||||
&self,
|
&self,
|
||||||
a: T,
|
a: T,
|
||||||
b_id: V)
|
b_id: V)
|
||||||
|
@ -198,9 +198,9 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
*
|
*
|
||||||
* Make a concrete type (`a`) a subtype of the variable `b_id` */
|
* Make a concrete type (`a`) a subtype of the variable `b_id` */
|
||||||
|
|
||||||
let a_bounds = &Bounds { lb: Some(copy a), ub: None };
|
let a_bounds = &Bounds { lb: Some(a.clone()), ub: None };
|
||||||
let node_b = self.infcx.get(b_id);
|
let node_b = self.infcx.get(b_id);
|
||||||
let b_id = copy node_b.root;
|
let b_id = node_b.root.clone();
|
||||||
let b_bounds = &node_b.possible_types;
|
let b_bounds = &node_b.possible_types;
|
||||||
|
|
||||||
debug!("t_sub_var(%s <: %s=%s)",
|
debug!("t_sub_var(%s <: %s=%s)",
|
||||||
|
@ -212,7 +212,7 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
b_id, a_bounds, b_bounds, node_b.rank)
|
b_id, a_bounds, b_bounds, node_b.rank)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_bnd<T:Copy + InferStr + LatticeValue>(
|
fn merge_bnd<T:Clone + InferStr + LatticeValue>(
|
||||||
&self,
|
&self,
|
||||||
a: &Bound<T>,
|
a: &Bound<T>,
|
||||||
b: &Bound<T>,
|
b: &Bound<T>,
|
||||||
|
@ -229,8 +229,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
|
|
||||||
match (a, b) {
|
match (a, b) {
|
||||||
(&None, &None) => Ok(None),
|
(&None, &None) => Ok(None),
|
||||||
(&Some(_), &None) => Ok(copy *a),
|
(&Some(_), &None) => Ok((*a).clone()),
|
||||||
(&None, &Some(_)) => Ok(copy *b),
|
(&None, &Some(_)) => Ok((*b).clone()),
|
||||||
(&Some(ref v_a), &Some(ref v_b)) => {
|
(&Some(ref v_a), &Some(ref v_b)) => {
|
||||||
do lattice_op(self, v_a, v_b).chain |v| {
|
do lattice_op(self, v_a, v_b).chain |v| {
|
||||||
Ok(Some(v))
|
Ok(Some(v))
|
||||||
|
@ -239,8 +239,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_var_to_merged_bounds<T:Copy + InferStr + LatticeValue,
|
fn set_var_to_merged_bounds<T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy+Eq+ToStr+Vid+UnifyVid<Bounds<T>>>(
|
V:Clone+Eq+ToStr+Vid+UnifyVid<Bounds<T>>>(
|
||||||
&self,
|
&self,
|
||||||
v_id: V,
|
v_id: V,
|
||||||
a: &Bounds<T>,
|
a: &Bounds<T>,
|
||||||
|
@ -301,10 +301,10 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
uok()
|
uok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bnds<T:Copy + InferStr + LatticeValue>(&self,
|
fn bnds<T:Clone + InferStr + LatticeValue>(&self,
|
||||||
a: &Bound<T>,
|
a: &Bound<T>,
|
||||||
b: &Bound<T>)
|
b: &Bound<T>)
|
||||||
-> ures {
|
-> ures {
|
||||||
debug!("bnds(%s <: %s)", a.inf_str(self.infcx),
|
debug!("bnds(%s <: %s)", a.inf_str(self.infcx),
|
||||||
b.inf_str(self.infcx));
|
b.inf_str(self.infcx));
|
||||||
let _r = indenter();
|
let _r = indenter();
|
||||||
|
@ -330,8 +330,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||||
|
|
||||||
pub trait LatticeDir {
|
pub trait LatticeDir {
|
||||||
fn combine_fields(&self) -> CombineFields;
|
fn combine_fields(&self) -> CombineFields;
|
||||||
fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T>;
|
fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T>;
|
||||||
fn with_bnd<T:Copy>(&self, b: &Bounds<T>, t: T) -> Bounds<T>;
|
fn with_bnd<T:Clone>(&self, b: &Bounds<T>, t: T) -> Bounds<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TyLatticeDir {
|
pub trait TyLatticeDir {
|
||||||
|
@ -340,9 +340,9 @@ pub trait TyLatticeDir {
|
||||||
|
|
||||||
impl LatticeDir for Lub {
|
impl LatticeDir for Lub {
|
||||||
fn combine_fields(&self) -> CombineFields { **self }
|
fn combine_fields(&self) -> CombineFields { **self }
|
||||||
fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { copy b.ub }
|
fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T> { b.ub.clone() }
|
||||||
fn with_bnd<T:Copy>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
|
fn with_bnd<T:Clone>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
|
||||||
Bounds { ub: Some(t), ..copy *b }
|
Bounds { ub: Some(t), ..(*b).clone() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,9 +354,9 @@ impl TyLatticeDir for Lub {
|
||||||
|
|
||||||
impl LatticeDir for Glb {
|
impl LatticeDir for Glb {
|
||||||
fn combine_fields(&self) -> CombineFields { **self }
|
fn combine_fields(&self) -> CombineFields { **self }
|
||||||
fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { copy b.lb }
|
fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T> { b.lb.clone() }
|
||||||
fn with_bnd<T:Copy>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
|
fn with_bnd<T:Clone>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
|
||||||
Bounds { lb: Some(t), ..copy *b }
|
Bounds { lb: Some(t), ..(*b).clone() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,6 +412,7 @@ pub fn super_lattice_tys<L:LatticeDir + TyLatticeDir + Combine>(
|
||||||
|
|
||||||
pub type LatticeDirOp<'self, T> = &'self fn(a: &T, b: &T) -> cres<T>;
|
pub type LatticeDirOp<'self, T> = &'self fn(a: &T, b: &T) -> cres<T>;
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum LatticeVarResult<V,T> {
|
pub enum LatticeVarResult<V,T> {
|
||||||
VarResult(V),
|
VarResult(V),
|
||||||
ValueResult(T)
|
ValueResult(T)
|
||||||
|
@ -433,8 +434,8 @@ pub enum LatticeVarResult<V,T> {
|
||||||
* result is a variable. This is indicated with a `VarResult`
|
* result is a variable. This is indicated with a `VarResult`
|
||||||
* return. */
|
* return. */
|
||||||
pub fn lattice_vars<L:LatticeDir + Combine,
|
pub fn lattice_vars<L:LatticeDir + Combine,
|
||||||
T:Copy + InferStr + LatticeValue,
|
T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||||
this: &L, // defines whether we want LUB or GLB
|
this: &L, // defines whether we want LUB or GLB
|
||||||
a_vid: V, // first variable
|
a_vid: V, // first variable
|
||||||
b_vid: V, // second variable
|
b_vid: V, // second variable
|
||||||
|
@ -442,8 +443,8 @@ pub fn lattice_vars<L:LatticeDir + Combine,
|
||||||
-> cres<LatticeVarResult<V,T>> {
|
-> cres<LatticeVarResult<V,T>> {
|
||||||
let nde_a = this.infcx().get(a_vid);
|
let nde_a = this.infcx().get(a_vid);
|
||||||
let nde_b = this.infcx().get(b_vid);
|
let nde_b = this.infcx().get(b_vid);
|
||||||
let a_vid = copy nde_a.root;
|
let a_vid = nde_a.root.clone();
|
||||||
let b_vid = copy nde_b.root;
|
let b_vid = nde_b.root.clone();
|
||||||
let a_bounds = &nde_a.possible_types;
|
let a_bounds = &nde_a.possible_types;
|
||||||
let b_bounds = &nde_b.possible_types;
|
let b_bounds = &nde_b.possible_types;
|
||||||
|
|
||||||
|
@ -473,21 +474,21 @@ pub fn lattice_vars<L:LatticeDir + Combine,
|
||||||
// Otherwise, we need to merge A and B into one variable. We can
|
// Otherwise, we need to merge A and B into one variable. We can
|
||||||
// then use either variable as an upper bound:
|
// then use either variable as an upper bound:
|
||||||
let cf = this.combine_fields();
|
let cf = this.combine_fields();
|
||||||
do cf.var_sub_var(copy a_vid, copy b_vid).then {
|
do cf.var_sub_var(a_vid.clone(), b_vid.clone()).then {
|
||||||
Ok(VarResult(copy a_vid))
|
Ok(VarResult(a_vid.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lattice_var_and_t<L:LatticeDir + Combine,
|
pub fn lattice_var_and_t<L:LatticeDir + Combine,
|
||||||
T:Copy + InferStr + LatticeValue,
|
T:Clone + InferStr + LatticeValue,
|
||||||
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
|
||||||
this: &L,
|
this: &L,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
b: &T,
|
b: &T,
|
||||||
lattice_dir_op: LatticeDirOp<T>)
|
lattice_dir_op: LatticeDirOp<T>)
|
||||||
-> cres<T> {
|
-> cres<T> {
|
||||||
let nde_a = this.infcx().get(a_id);
|
let nde_a = this.infcx().get(a_id);
|
||||||
let a_id = copy nde_a.root;
|
let a_id = nde_a.root.clone();
|
||||||
let a_bounds = &nde_a.possible_types;
|
let a_bounds = &nde_a.possible_types;
|
||||||
|
|
||||||
// The comments in this function are written for LUB, but they
|
// The comments in this function are written for LUB, but they
|
||||||
|
@ -509,10 +510,11 @@ pub fn lattice_var_and_t<L:LatticeDir + Combine,
|
||||||
// If a does not have an upper bound, make b the upper bound of a
|
// If a does not have an upper bound, make b the upper bound of a
|
||||||
// and then return b.
|
// and then return b.
|
||||||
debug!("bnd=None");
|
debug!("bnd=None");
|
||||||
let a_bounds = this.with_bnd(a_bounds, copy *b);
|
let a_bounds = this.with_bnd(a_bounds, (*b).clone());
|
||||||
do this.combine_fields().bnds(&a_bounds.lb, &a_bounds.ub).then {
|
do this.combine_fields().bnds(&a_bounds.lb, &a_bounds.ub).then {
|
||||||
this.infcx().set(copy a_id, Root(copy a_bounds, nde_a.rank));
|
this.infcx().set(a_id.clone(),
|
||||||
Ok(copy *b)
|
Root(a_bounds.clone(), nde_a.rank));
|
||||||
|
Ok((*b).clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ pub mod coercion;
|
||||||
pub mod error_reporting;
|
pub mod error_reporting;
|
||||||
|
|
||||||
pub type Bound<T> = Option<T>;
|
pub type Bound<T> = Option<T>;
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct Bounds<T> {
|
pub struct Bounds<T> {
|
||||||
lb: Bound<T>,
|
lb: Bound<T>,
|
||||||
ub: Bound<T>
|
ub: Bound<T>
|
||||||
|
@ -96,6 +98,7 @@ pub struct InferCtxt {
|
||||||
/// Why did we require that the two types be related?
|
/// Why did we require that the two types be related?
|
||||||
///
|
///
|
||||||
/// See `error_reporting.rs` for more details
|
/// See `error_reporting.rs` for more details
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum TypeOrigin {
|
pub enum TypeOrigin {
|
||||||
// Not yet categorized in a better way
|
// Not yet categorized in a better way
|
||||||
Misc(span),
|
Misc(span),
|
||||||
|
@ -120,6 +123,7 @@ pub enum TypeOrigin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See `error_reporting.rs` for more details
|
/// See `error_reporting.rs` for more details
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum ValuePairs {
|
pub enum ValuePairs {
|
||||||
Types(ty::expected_found<ty::t>),
|
Types(ty::expected_found<ty::t>),
|
||||||
TraitRefs(ty::expected_found<@ty::TraitRef>),
|
TraitRefs(ty::expected_found<@ty::TraitRef>),
|
||||||
|
@ -129,6 +133,7 @@ pub enum ValuePairs {
|
||||||
/// encounter an error or subtyping constraint.
|
/// encounter an error or subtyping constraint.
|
||||||
///
|
///
|
||||||
/// See `error_reporting.rs` for more details.
|
/// See `error_reporting.rs` for more details.
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct TypeTrace {
|
pub struct TypeTrace {
|
||||||
origin: TypeOrigin,
|
origin: TypeOrigin,
|
||||||
values: ValuePairs,
|
values: ValuePairs,
|
||||||
|
@ -137,6 +142,7 @@ pub struct TypeTrace {
|
||||||
/// The origin of a `r1 <= r2` constraint.
|
/// The origin of a `r1 <= r2` constraint.
|
||||||
///
|
///
|
||||||
/// See `error_reporting.rs` for more details
|
/// See `error_reporting.rs` for more details
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum SubregionOrigin {
|
pub enum SubregionOrigin {
|
||||||
// Arose from a subtyping relation
|
// Arose from a subtyping relation
|
||||||
Subtype(TypeTrace),
|
Subtype(TypeTrace),
|
||||||
|
@ -245,7 +251,7 @@ pub fn fixup_err_to_str(f: fixup_err) -> ~str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_ValsAndBindings<V:Copy,T:Copy>() -> ValsAndBindings<V, T> {
|
fn new_ValsAndBindings<V:Clone,T:Clone>() -> ValsAndBindings<V, T> {
|
||||||
ValsAndBindings {
|
ValsAndBindings {
|
||||||
vals: SmallIntMap::new(),
|
vals: SmallIntMap::new(),
|
||||||
bindings: ~[]
|
bindings: ~[]
|
||||||
|
@ -439,12 +445,12 @@ pub fn resolve_region(cx: @mut InferCtxt, r: ty::Region, modes: uint)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait then {
|
trait then {
|
||||||
fn then<T:Copy>(&self, f: &fn() -> Result<T,ty::type_err>)
|
fn then<T:Clone>(&self, f: &fn() -> Result<T,ty::type_err>)
|
||||||
-> Result<T,ty::type_err>;
|
-> Result<T,ty::type_err>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl then for ures {
|
impl then for ures {
|
||||||
fn then<T:Copy>(&self, f: &fn() -> Result<T,ty::type_err>)
|
fn then<T:Clone>(&self, f: &fn() -> Result<T,ty::type_err>)
|
||||||
-> Result<T,ty::type_err> {
|
-> Result<T,ty::type_err> {
|
||||||
self.chain(|_i| f())
|
self.chain(|_i| f())
|
||||||
}
|
}
|
||||||
|
@ -467,11 +473,11 @@ trait CresCompare<T> {
|
||||||
fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres<T>;
|
fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Copy + Eq> CresCompare<T> for cres<T> {
|
impl<T:Clone + Eq> CresCompare<T> for cres<T> {
|
||||||
fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres<T> {
|
fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres<T> {
|
||||||
do (copy *self).chain |s| {
|
do (*self).clone().chain |s| {
|
||||||
if s == t {
|
if s == t {
|
||||||
copy *self
|
(*self).clone()
|
||||||
} else {
|
} else {
|
||||||
Err(f())
|
Err(f())
|
||||||
}
|
}
|
||||||
|
@ -483,10 +489,8 @@ pub fn uok() -> ures {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rollback_to<V:Copy + Vid,T:Copy>(
|
fn rollback_to<V:Clone + Vid,T:Clone>(vb: &mut ValsAndBindings<V, T>,
|
||||||
vb: &mut ValsAndBindings<V, T>,
|
len: uint) {
|
||||||
len: uint)
|
|
||||||
{
|
|
||||||
while vb.bindings.len() != len {
|
while vb.bindings.len() != len {
|
||||||
let (vid, old_v) = vb.bindings.pop();
|
let (vid, old_v) = vb.bindings.pop();
|
||||||
vb.vals.insert(vid.to_uint(), old_v);
|
vb.vals.insert(vid.to_uint(), old_v);
|
||||||
|
@ -588,10 +592,10 @@ impl InferCtxt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_simple_var<V:Copy,T:Copy>(
|
fn next_simple_var<V:Clone,T:Clone>(counter: &mut uint,
|
||||||
counter: &mut uint,
|
bindings: &mut ValsAndBindings<V,
|
||||||
bindings: &mut ValsAndBindings<V,Option<T>>)
|
Option<T>>)
|
||||||
-> uint {
|
-> uint {
|
||||||
let id = *counter;
|
let id = *counter;
|
||||||
*counter += 1;
|
*counter += 1;
|
||||||
bindings.vals.insert(id, Root(None, 0));
|
bindings.vals.insert(id, Root(None, 0));
|
||||||
|
@ -668,15 +672,17 @@ impl InferCtxt {
|
||||||
// make up a dummy type just to reuse/abuse the resolve machinery
|
// make up a dummy type just to reuse/abuse the resolve machinery
|
||||||
let dummy0 = ty::mk_trait(self.tcx,
|
let dummy0 = ty::mk_trait(self.tcx,
|
||||||
trait_ref.def_id,
|
trait_ref.def_id,
|
||||||
copy trait_ref.substs,
|
trait_ref.substs.clone(),
|
||||||
ty::UniqTraitStore,
|
ty::UniqTraitStore,
|
||||||
ast::m_imm,
|
ast::m_imm,
|
||||||
ty::EmptyBuiltinBounds());
|
ty::EmptyBuiltinBounds());
|
||||||
let dummy1 = self.resolve_type_vars_if_possible(dummy0);
|
let dummy1 = self.resolve_type_vars_if_possible(dummy0);
|
||||||
match ty::get(dummy1).sty {
|
match ty::get(dummy1).sty {
|
||||||
ty::ty_trait(ref def_id, ref substs, _, _, _) => {
|
ty::ty_trait(ref def_id, ref substs, _, _, _) => {
|
||||||
ty::TraitRef {def_id: *def_id,
|
ty::TraitRef {
|
||||||
substs: copy *substs}
|
def_id: *def_id,
|
||||||
|
substs: (*substs).clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.tcx.sess.bug(
|
self.tcx.sess.bug(
|
||||||
|
|
|
@ -18,6 +18,7 @@ use middle::typeck::infer::InferCtxt;
|
||||||
use middle::typeck::infer::to_str::InferStr;
|
use middle::typeck::infer::to_str::InferStr;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum VarValue<V, T> {
|
pub enum VarValue<V, T> {
|
||||||
Redirect(V),
|
Redirect(V),
|
||||||
Root(T, uint),
|
Root(T, uint),
|
||||||
|
@ -40,18 +41,18 @@ pub trait UnifyVid<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait UnifyInferCtxtMethods {
|
pub trait UnifyInferCtxtMethods {
|
||||||
fn get<T:Copy,
|
fn get<T:Clone,
|
||||||
V:Copy + Eq + Vid + UnifyVid<T>>(
|
V:Clone + Eq + Vid + UnifyVid<T>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
vid: V)
|
vid: V)
|
||||||
-> Node<V, T>;
|
-> Node<V, T>;
|
||||||
fn set<T:Copy + InferStr,
|
fn set<T:Clone + InferStr,
|
||||||
V:Copy + Vid + ToStr + UnifyVid<T>>(
|
V:Clone + Vid + ToStr + UnifyVid<T>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
vid: V,
|
vid: V,
|
||||||
new_v: VarValue<V, T>);
|
new_v: VarValue<V, T>);
|
||||||
fn unify<T:Copy + InferStr,
|
fn unify<T:Clone + InferStr,
|
||||||
V:Copy + Vid + ToStr + UnifyVid<T>>(
|
V:Clone + Vid + ToStr + UnifyVid<T>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
node_a: &Node<V, T>,
|
node_a: &Node<V, T>,
|
||||||
node_b: &Node<V, T>)
|
node_b: &Node<V, T>)
|
||||||
|
@ -59,8 +60,8 @@ pub trait UnifyInferCtxtMethods {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnifyInferCtxtMethods for InferCtxt {
|
impl UnifyInferCtxtMethods for InferCtxt {
|
||||||
fn get<T:Copy,
|
fn get<T:Clone,
|
||||||
V:Copy + Eq + Vid + UnifyVid<T>>(
|
V:Clone + Eq + Vid + UnifyVid<T>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
vid: V)
|
vid: V)
|
||||||
-> Node<V, T> {
|
-> Node<V, T> {
|
||||||
|
@ -75,14 +76,14 @@ impl UnifyInferCtxtMethods for InferCtxt {
|
||||||
let vb = UnifyVid::appropriate_vals_and_bindings(self);
|
let vb = UnifyVid::appropriate_vals_and_bindings(self);
|
||||||
return helper(tcx, vb, vid);
|
return helper(tcx, vb, vid);
|
||||||
|
|
||||||
fn helper<T:Copy, V:Copy+Eq+Vid>(
|
fn helper<T:Clone, V:Clone+Eq+Vid>(
|
||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
vb: &mut ValsAndBindings<V,T>,
|
vb: &mut ValsAndBindings<V,T>,
|
||||||
vid: V) -> Node<V, T>
|
vid: V) -> Node<V, T>
|
||||||
{
|
{
|
||||||
let vid_u = vid.to_uint();
|
let vid_u = vid.to_uint();
|
||||||
let var_val = match vb.vals.find(&vid_u) {
|
let var_val = match vb.vals.find(&vid_u) {
|
||||||
Some(&ref var_val) => copy *var_val,
|
Some(&ref var_val) => (*var_val).clone(),
|
||||||
None => {
|
None => {
|
||||||
tcx.sess.bug(fmt!(
|
tcx.sess.bug(fmt!(
|
||||||
"failed lookup of vid `%u`", vid_u));
|
"failed lookup of vid `%u`", vid_u));
|
||||||
|
@ -90,11 +91,11 @@ impl UnifyInferCtxtMethods for InferCtxt {
|
||||||
};
|
};
|
||||||
match var_val {
|
match var_val {
|
||||||
Redirect(vid) => {
|
Redirect(vid) => {
|
||||||
let node: Node<V,T> = helper(tcx, vb, copy vid);
|
let node: Node<V,T> = helper(tcx, vb, vid.clone());
|
||||||
if node.root != vid {
|
if node.root != vid {
|
||||||
// Path compression
|
// Path compression
|
||||||
vb.vals.insert(vid.to_uint(),
|
vb.vals.insert(vid.to_uint(),
|
||||||
Redirect(copy node.root));
|
Redirect(node.root.clone()));
|
||||||
}
|
}
|
||||||
node
|
node
|
||||||
}
|
}
|
||||||
|
@ -105,8 +106,8 @@ impl UnifyInferCtxtMethods for InferCtxt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set<T:Copy + InferStr,
|
fn set<T:Clone + InferStr,
|
||||||
V:Copy + Vid + ToStr + UnifyVid<T>>(
|
V:Clone + Vid + ToStr + UnifyVid<T>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
vid: V,
|
vid: V,
|
||||||
new_v: VarValue<V, T>) {
|
new_v: VarValue<V, T>) {
|
||||||
|
@ -119,13 +120,13 @@ impl UnifyInferCtxtMethods for InferCtxt {
|
||||||
vid.to_str(), new_v.inf_str(self));
|
vid.to_str(), new_v.inf_str(self));
|
||||||
|
|
||||||
let vb = UnifyVid::appropriate_vals_and_bindings(self);
|
let vb = UnifyVid::appropriate_vals_and_bindings(self);
|
||||||
let old_v = copy *vb.vals.get(&vid.to_uint());
|
let old_v = (*vb.vals.get(&vid.to_uint())).clone();
|
||||||
vb.bindings.push((copy vid, old_v));
|
vb.bindings.push((vid.clone(), old_v));
|
||||||
vb.vals.insert(vid.to_uint(), new_v);
|
vb.vals.insert(vid.to_uint(), new_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unify<T:Copy + InferStr,
|
fn unify<T:Clone + InferStr,
|
||||||
V:Copy + Vid + ToStr + UnifyVid<T>>(
|
V:Clone + Vid + ToStr + UnifyVid<T>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
node_a: &Node<V, T>,
|
node_a: &Node<V, T>,
|
||||||
node_b: &Node<V, T>)
|
node_b: &Node<V, T>)
|
||||||
|
@ -141,18 +142,18 @@ impl UnifyInferCtxtMethods for InferCtxt {
|
||||||
if node_a.rank > node_b.rank {
|
if node_a.rank > node_b.rank {
|
||||||
// a has greater rank, so a should become b's parent,
|
// a has greater rank, so a should become b's parent,
|
||||||
// i.e., b should redirect to a.
|
// i.e., b should redirect to a.
|
||||||
self.set(copy node_b.root, Redirect(copy node_a.root));
|
self.set(node_b.root.clone(), Redirect(node_a.root.clone()));
|
||||||
(copy node_a.root, node_a.rank)
|
(node_a.root.clone(), node_a.rank)
|
||||||
} else if node_a.rank < node_b.rank {
|
} else if node_a.rank < node_b.rank {
|
||||||
// b has greater rank, so a should redirect to b.
|
// b has greater rank, so a should redirect to b.
|
||||||
self.set(copy node_a.root, Redirect(copy node_b.root));
|
self.set(node_a.root.clone(), Redirect(node_b.root.clone()));
|
||||||
(copy node_b.root, node_b.rank)
|
(node_b.root.clone(), node_b.rank)
|
||||||
} else {
|
} else {
|
||||||
// If equal, redirect one to the other and increment the
|
// If equal, redirect one to the other and increment the
|
||||||
// other's rank.
|
// other's rank.
|
||||||
assert_eq!(node_a.rank, node_b.rank);
|
assert_eq!(node_a.rank, node_b.rank);
|
||||||
self.set(copy node_b.root, Redirect(copy node_a.root));
|
self.set(node_b.root.clone(), Redirect(node_a.root.clone()));
|
||||||
(copy node_a.root, node_a.rank + 1)
|
(node_a.root.clone(), node_a.rank + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,15 +180,15 @@ pub fn mk_err<T:SimplyUnifiable>(a_is_expected: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InferCtxtMethods {
|
pub trait InferCtxtMethods {
|
||||||
fn simple_vars<T:Copy + Eq + InferStr + SimplyUnifiable,
|
fn simple_vars<T:Clone + Eq + InferStr + SimplyUnifiable,
|
||||||
V:Copy + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
|
V:Clone + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
a_is_expected: bool,
|
a_is_expected: bool,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
b_id: V)
|
b_id: V)
|
||||||
-> ures;
|
-> ures;
|
||||||
fn simple_var_t<T:Copy + Eq + InferStr + SimplyUnifiable,
|
fn simple_var_t<T:Clone + Eq + InferStr + SimplyUnifiable,
|
||||||
V:Copy + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
|
V:Clone + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
a_is_expected: bool,
|
a_is_expected: bool,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
|
@ -196,8 +197,8 @@ pub trait InferCtxtMethods {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InferCtxtMethods for InferCtxt {
|
impl InferCtxtMethods for InferCtxt {
|
||||||
fn simple_vars<T:Copy + Eq + InferStr + SimplyUnifiable,
|
fn simple_vars<T:Clone + Eq + InferStr + SimplyUnifiable,
|
||||||
V:Copy + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
|
V:Clone + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
a_is_expected: bool,
|
a_is_expected: bool,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
|
@ -212,20 +213,22 @@ impl InferCtxtMethods for InferCtxt {
|
||||||
|
|
||||||
let node_a = self.get(a_id);
|
let node_a = self.get(a_id);
|
||||||
let node_b = self.get(b_id);
|
let node_b = self.get(b_id);
|
||||||
let a_id = copy node_a.root;
|
let a_id = node_a.root.clone();
|
||||||
let b_id = copy node_b.root;
|
let b_id = node_b.root.clone();
|
||||||
|
|
||||||
if a_id == b_id { return uok(); }
|
if a_id == b_id { return uok(); }
|
||||||
|
|
||||||
let combined = match (&node_a.possible_types, &node_b.possible_types)
|
let combined = match (&node_a.possible_types, &node_b.possible_types)
|
||||||
{
|
{
|
||||||
(&None, &None) => None,
|
(&None, &None) => None,
|
||||||
(&Some(ref v), &None) | (&None, &Some(ref v)) => Some(copy *v),
|
(&Some(ref v), &None) | (&None, &Some(ref v)) => {
|
||||||
|
Some((*v).clone())
|
||||||
|
}
|
||||||
(&Some(ref v1), &Some(ref v2)) => {
|
(&Some(ref v1), &Some(ref v2)) => {
|
||||||
if *v1 != *v2 {
|
if *v1 != *v2 {
|
||||||
return mk_err(a_is_expected, copy *v1, copy *v2);
|
return mk_err(a_is_expected, (*v1).clone(), (*v2).clone())
|
||||||
}
|
}
|
||||||
Some(copy *v1)
|
Some((*v1).clone())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -234,8 +237,8 @@ impl InferCtxtMethods for InferCtxt {
|
||||||
return uok();
|
return uok();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn simple_var_t<T:Copy + Eq + InferStr + SimplyUnifiable,
|
fn simple_var_t<T:Clone + Eq + InferStr + SimplyUnifiable,
|
||||||
V:Copy + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
|
V:Clone + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
a_is_expected: bool,
|
a_is_expected: bool,
|
||||||
a_id: V,
|
a_id: V,
|
||||||
|
@ -249,7 +252,7 @@ impl InferCtxtMethods for InferCtxt {
|
||||||
* `b`. */
|
* `b`. */
|
||||||
|
|
||||||
let node_a = self.get(a_id);
|
let node_a = self.get(a_id);
|
||||||
let a_id = copy node_a.root;
|
let a_id = node_a.root.clone();
|
||||||
|
|
||||||
match node_a.possible_types {
|
match node_a.possible_types {
|
||||||
None => {
|
None => {
|
||||||
|
@ -261,7 +264,7 @@ impl InferCtxtMethods for InferCtxt {
|
||||||
if *a_t == b {
|
if *a_t == b {
|
||||||
return uok();
|
return uok();
|
||||||
} else {
|
} else {
|
||||||
return mk_err(a_is_expected, copy *a_t, b);
|
return mk_err(a_is_expected, (*a_t).clone(), b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ pub mod infer;
|
||||||
pub mod collect;
|
pub mod collect;
|
||||||
pub mod coherence;
|
pub mod coherence;
|
||||||
|
|
||||||
#[deriving(Encodable, Decodable)]
|
#[deriving(Clone, Encodable, Decodable)]
|
||||||
pub enum method_origin {
|
pub enum method_origin {
|
||||||
// supertrait method invoked on "self" inside a default method
|
// supertrait method invoked on "self" inside a default method
|
||||||
// first field is supertrait ID;
|
// first field is supertrait ID;
|
||||||
|
@ -99,7 +99,7 @@ pub enum method_origin {
|
||||||
|
|
||||||
// details for a method invoked with a receiver whose type is a type parameter
|
// details for a method invoked with a receiver whose type is a type parameter
|
||||||
// with a bounded trait.
|
// with a bounded trait.
|
||||||
#[deriving(Encodable, Decodable)]
|
#[deriving(Clone, Encodable, Decodable)]
|
||||||
pub struct method_param {
|
pub struct method_param {
|
||||||
// the trait containing the method to be invoked
|
// the trait containing the method to be invoked
|
||||||
trait_id: ast::def_id,
|
trait_id: ast::def_id,
|
||||||
|
@ -115,6 +115,7 @@ pub struct method_param {
|
||||||
bound_num: uint,
|
bound_num: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct method_map_entry {
|
pub struct method_map_entry {
|
||||||
// the type of the self parameter, which is not reflected in the fn type
|
// the type of the self parameter, which is not reflected in the fn type
|
||||||
// (FIXME #3446)
|
// (FIXME #3446)
|
||||||
|
@ -138,6 +139,7 @@ pub type vtable_param_res = @~[vtable_origin];
|
||||||
// Resolutions for bounds of all parameters, left to right, for a given path.
|
// Resolutions for bounds of all parameters, left to right, for a given path.
|
||||||
pub type vtable_res = @~[vtable_param_res];
|
pub type vtable_res = @~[vtable_param_res];
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum vtable_origin {
|
pub enum vtable_origin {
|
||||||
/*
|
/*
|
||||||
Statically known vtable. def_id gives the class or impl item
|
Statically known vtable. def_id gives the class or impl item
|
||||||
|
@ -215,7 +217,7 @@ pub fn write_tpt_to_tcx(tcx: ty::ctxt,
|
||||||
tpt: &ty::ty_param_substs_and_ty) {
|
tpt: &ty::ty_param_substs_and_ty) {
|
||||||
write_ty_to_tcx(tcx, node_id, tpt.ty);
|
write_ty_to_tcx(tcx, node_id, tpt.ty);
|
||||||
if !tpt.substs.tps.is_empty() {
|
if !tpt.substs.tps.is_empty() {
|
||||||
write_substs_to_tcx(tcx, node_id, copy tpt.substs.tps);
|
write_substs_to_tcx(tcx, node_id, tpt.substs.tps.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ pub trait region_scope {
|
||||||
-> Result<ty::Region, RegionError>;
|
-> Result<ty::Region, RegionError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub enum empty_rscope { empty_rscope }
|
pub enum empty_rscope { empty_rscope }
|
||||||
impl region_scope for empty_rscope {
|
impl region_scope for empty_rscope {
|
||||||
fn anon_region(&self, _span: span) -> Result<ty::Region, RegionError> {
|
fn anon_region(&self, _span: span) -> Result<ty::Region, RegionError> {
|
||||||
|
@ -48,6 +49,7 @@ impl region_scope for empty_rscope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct RegionParamNames(OptVec<ast::ident>);
|
pub struct RegionParamNames(OptVec<ast::ident>);
|
||||||
|
|
||||||
impl RegionParamNames {
|
impl RegionParamNames {
|
||||||
|
@ -121,6 +123,7 @@ impl RegionParamNames {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
struct RegionParameterization {
|
struct RegionParameterization {
|
||||||
variance: ty::region_variance,
|
variance: ty::region_variance,
|
||||||
region_param_names: RegionParamNames,
|
region_param_names: RegionParamNames,
|
||||||
|
@ -143,6 +146,7 @@ impl RegionParameterization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct MethodRscope {
|
pub struct MethodRscope {
|
||||||
explicit_self: ast::explicit_self_,
|
explicit_self: ast::explicit_self_,
|
||||||
variance: Option<ty::region_variance>,
|
variance: Option<ty::region_variance>,
|
||||||
|
@ -166,7 +170,7 @@ impl MethodRscope {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn region_param_names(&self) -> RegionParamNames {
|
pub fn region_param_names(&self) -> RegionParamNames {
|
||||||
copy self.region_param_names
|
self.region_param_names.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +210,7 @@ impl region_scope for MethodRscope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct type_rscope(Option<RegionParameterization>);
|
pub struct type_rscope(Option<RegionParameterization>);
|
||||||
|
|
||||||
impl type_rscope {
|
impl type_rscope {
|
||||||
|
@ -268,11 +273,21 @@ pub struct binding_rscope {
|
||||||
region_param_names: RegionParamNames,
|
region_param_names: RegionParamNames,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn in_binding_rscope<RS:region_scope + Copy + 'static>(
|
impl Clone for binding_rscope {
|
||||||
|
fn clone(&self) -> binding_rscope {
|
||||||
|
binding_rscope {
|
||||||
|
base: self.base,
|
||||||
|
anon_bindings: self.anon_bindings,
|
||||||
|
region_param_names: self.region_param_names.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn in_binding_rscope<RS:region_scope + Clone + 'static>(
|
||||||
this: &RS,
|
this: &RS,
|
||||||
region_param_names: RegionParamNames)
|
region_param_names: RegionParamNames)
|
||||||
-> binding_rscope {
|
-> binding_rscope {
|
||||||
let base = @copy *this;
|
let base = @(*this).clone();
|
||||||
let base = base as @region_scope;
|
let base = base as @region_scope;
|
||||||
binding_rscope {
|
binding_rscope {
|
||||||
base: base,
|
base: base,
|
||||||
|
|
|
@ -116,6 +116,7 @@ pub mod lib {
|
||||||
// macros.
|
// macros.
|
||||||
/*
|
/*
|
||||||
mod std {
|
mod std {
|
||||||
|
pub use std::clone;
|
||||||
pub use std::cmp;
|
pub use std::cmp;
|
||||||
pub use std::os;
|
pub use std::os;
|
||||||
pub use std::str;
|
pub use std::str;
|
||||||
|
@ -184,9 +185,12 @@ Available lint options:
|
||||||
pub fn describe_debug_flags() {
|
pub fn describe_debug_flags() {
|
||||||
io::println(fmt!("\nAvailable debug options:\n"));
|
io::println(fmt!("\nAvailable debug options:\n"));
|
||||||
let r = session::debugging_opts_map();
|
let r = session::debugging_opts_map();
|
||||||
for r.iter().advance |pair| {
|
for r.iter().advance |tuple| {
|
||||||
let (name, desc, _) = /*bad*/copy *pair;
|
match *tuple {
|
||||||
io::println(fmt!(" -Z %-20s -- %s", name, desc));
|
(ref name, ref desc, _) => {
|
||||||
|
io::println(fmt!(" -Z %-20s -- %s", *name, *desc));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +198,7 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) {
|
||||||
// Don't display log spew by default. Can override with RUST_LOG.
|
// Don't display log spew by default. Can override with RUST_LOG.
|
||||||
::std::logging::console_off();
|
::std::logging::console_off();
|
||||||
|
|
||||||
let mut args = /*bad*/copy *args;
|
let mut args = (*args).clone();
|
||||||
let binary = args.shift().to_managed();
|
let binary = args.shift().to_managed();
|
||||||
|
|
||||||
if args.is_empty() { usage(binary); return; }
|
if args.is_empty() { usage(binary); return; }
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue