librustc: Remove all uses of "copy".

This commit is contained in:
Patrick Walton 2013-07-02 12:47:32 -07:00
parent b4e674f6e6
commit 99b33f7219
278 changed files with 3196 additions and 2610 deletions

View File

@ -117,9 +117,11 @@ pub fn parse_config(args: ~[~str]) -> config {
mode: str_mode(getopts::opt_str(matches, "mode")),
run_ignored: getopts::opt_present(matches, "ignored"),
filter:
if !matches.free.is_empty() {
Some(copy matches.free[0])
} else { None },
if !matches.free.is_empty() {
Some(matches.free[0].clone())
} else {
None
},
logfile: getopts::opt_maybe_str(matches, "logfile").map(|s| Path(*s)),
save_metrics: getopts::opt_maybe_str(matches, "save-metrics").map(|s| Path(*s)),
ratchet_metrics:
@ -223,9 +225,9 @@ pub fn run_tests(config: &config) {
pub fn test_opts(config: &config) -> test::TestOpts {
test::TestOpts {
filter: copy config.filter,
filter: config.filter.clone(),
run_ignored: config.run_ignored,
logfile: copy config.logfile,
logfile: config.logfile.clone(),
run_tests: true,
run_benchmarks: true,
ratchet_metrics: copy config.ratchet_metrics,
@ -240,7 +242,7 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] {
let mut tests = ~[];
let dirs = os::list_dir_path(&config.src_base);
for dirs.iter().advance |file| {
let file = copy *file;
let file = (*file).clone();
debug!("inspecting file %s", file.to_str());
if is_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 {
use std::cell::Cell;
let config = Cell::new(copy *config);
let config = Cell::new((*config).clone());
let testfile = Cell::new(testfile.to_str());
test::DynTestFn(|| { runtest::run(config.take(), testfile.take()) })
}

View File

@ -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";
env = do env.map() |pair| {
let (k,v) = copy *pair;
let (k,v) = (*pair).clone();
if k == ~"PATH" { (~"PATH", v + ";" + lib_path + ";" + aux_path) }
else { (k,v) }
};

View File

@ -150,7 +150,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
let mut round = 0;
while round < rounds {
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 {
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);
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() {
// 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 {
Some(ref flags) => config {
rustcflags: Some(flags.replace("-O", "")),
.. copy *config
.. (*config).clone()
},
None => copy *config
None => (*config).clone()
};
let config = &mut config;
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)
let mut ProcRes = compile_test(config, props, testfile);
@ -498,7 +498,7 @@ fn exec_compiled_test(config: &config, props: &TestProps,
testfile: &Path) -> ProcRes {
// 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 };
match config.target {
@ -742,7 +742,7 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps,
// copy to target
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(~""));
if config.verbose {
@ -832,7 +832,7 @@ fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
if (file.filetype() == Some(~".so")) {
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(~""));
if config.verbose {

View File

@ -534,7 +534,7 @@ mod tests {
let arc_v : ARC<~[int]> = p.recv();
let v = copy (*arc_v.get());
let v = (*arc_v.get()).clone();
assert_eq!(v[3], 4);
};

View File

@ -211,14 +211,14 @@ impl<'self> FromBase64 for &'self [u8] {
let val = byte as u32;
match ch {
'A'..'Z' => buf |= val - 0x41,
'a'..'z' => buf |= val - 0x47,
'0'..'9' => buf |= val + 0x04,
'+'|'-' => buf |= 0x3E,
'/'|'_' => buf |= 0x3F,
'A'..'Z' => buf |= val - 0x41,
'a'..'z' => buf |= val - 0x47,
'0'..'9' => buf |= val + 0x04,
'+'|'-' => buf |= 0x3E,
'/'|'_' => buf |= 0x3F,
'\r'|'\n' => loop,
'=' => break,
_ => return Err(~"Invalid Base64 character")
'=' => break,
_ => return Err(~"Invalid Base64 character")
}
buf <<= 6;

View File

@ -266,7 +266,7 @@ impl Bitv {
else {
let nelems = nbits/uint::bits +
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);
Big(~BigBitv::new(s))
};
@ -518,7 +518,7 @@ impl Clone for Bitv {
Bitv{nbits: self.nbits, rep: Small(~SmallBitv{bits: b.bits})}
}
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();
for uint::range(0, len) |i| { st[i] = b.storage[i]; };
Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: st})}

View File

@ -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
*/
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));
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
*/
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));
unsafe { *ptr::mut_offset(t.base, ofs) = v };
}

View File

@ -609,8 +609,8 @@ mod tests {
}
#[cfg(test)]
fn list_from<T: Copy>(v: &[T]) -> DList<T> {
v.iter().transform(|x| copy *x).collect()
fn list_from<T: Clone>(v: &[T]) -> DList<T> {
v.iter().transform(|x| (*x).clone()).collect()
}
#[test]

View File

@ -29,6 +29,7 @@ struct EbmlState {
data_pos: uint,
}
#[deriving(Clone)]
pub struct Doc {
data: @~[u8],
start: uint,
@ -615,6 +616,7 @@ pub mod writer {
use super::*;
use std::cast;
use std::clone::Clone;
use std::io;
// ebml writing
@ -623,6 +625,15 @@ pub mod writer {
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) {
match size {
1u => w.write(&[0x80u8 | (n as u8)]),

View File

@ -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
file is `stdin`.
*/
#[deriving(Clone)]
pub struct FileInputState {
current_path: Option<Path>,
line_num: uint,
@ -223,7 +224,7 @@ impl FileInput {
let path_option = self.fi.files.shift();
let file = match path_option {
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);
@ -259,7 +260,7 @@ impl FileInput {
*/
pub fn each_line_state(&self,
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.
*/
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")),
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([~"-"], true), ~[None]);
@ -449,7 +450,7 @@ mod test {
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)| {
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_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);
@ -542,13 +543,13 @@ mod test {
make_file(filenames[2].get_ref(), [~"3", ~"4"]);
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 {
"1" | "2" => copy filenames[0],
"3" | "4" => copy filenames[2],
"1" | "2" => filenames[0].clone(),
"3" | "4" => filenames[2].clone(),
_ => fail!("unexpected line")
};
assert_eq!(copy state.current_path, expected_path);
assert_eq!(state.current_path.clone(), expected_path);
count += 1;
}
assert_eq!(count, 4);

View File

@ -164,8 +164,8 @@ Constructors for flat pipes that send POD types using memcpy.
# Safety Note
This module is currently unsafe because it uses `Copy Send` as a type
parameter bounds meaning POD (plain old data), but `Copy Send` and
This module is currently unsafe because it uses `Clone + Send` as a type
parameter bounds meaning POD (plain old data), but `Clone + Send` and
POD are not equivelant.
*/
@ -188,7 +188,7 @@ pub mod pod {
pub type PipeChan<T> = FlatChan<T, PodFlattener<T>, PipeByteChan>;
/// 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
) -> ReaderPort<T, R> {
let unflat: PodUnflattener<T> = PodUnflattener::new();
@ -197,7 +197,7 @@ pub mod pod {
}
/// 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
) -> WriterChan<T, W> {
let flat: PodFlattener<T> = PodFlattener::new();
@ -206,21 +206,21 @@ pub mod pod {
}
/// 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 byte_port = PipeBytePort::new(port);
FlatPort::new(unflat, byte_port)
}
/// 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 byte_chan = PipeByteChan::new(chan);
FlatChan::new(flat, byte_chan)
}
/// 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();
return (pipe_port(port), pipe_chan(chan));
}
@ -348,7 +348,7 @@ pub mod flatteners {
use std::sys::size_of;
use std::vec;
// FIXME #4074: Copy + Send != POD
// FIXME #4074: Clone + Send != POD
pub struct PodUnflattener<T> {
bogus: ()
}
@ -357,17 +357,17 @@ pub mod flatteners {
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 {
assert!(size_of::<T>() != 0);
assert_eq!(size_of::<T>(), buf.len());
let addr_of_init: &u8 = unsafe { &*vec::raw::to_ptr(buf) };
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] {
assert!(size_of::<T>() != 0);
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> {
PodUnflattener {
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> {
PodFlattener {
bogus: ()
@ -655,7 +655,7 @@ mod test {
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 port = serial::reader_port(reader);
@ -703,7 +703,7 @@ mod test {
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 port = pod::reader_port(reader);
@ -785,13 +785,13 @@ mod test {
let accept_chan = Cell::new(accept_chan);
// The server task
let addr = copy addr0;
let addr = addr0.clone();
do task::spawn || {
let iotask = &uv::global_loop::get();
let begin_connect_chan = begin_connect_chan.take();
let accept_chan = accept_chan.take();
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
debug!("listening");
begin_connect_chan.send(())
@ -811,14 +811,14 @@ mod test {
}
// Client task
let addr = copy addr0;
let addr = addr0.clone();
do task::spawn || {
// Wait for the server to start listening
begin_connect_port.recv();
debug!("connecting");
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());
let sock = result::unwrap(connect_result);
let socket_buf: tcp::TcpSocketBuf = tcp::socket_buf(sock);

View File

@ -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
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 {
Empty => None,
Node(kk, v, left, right) => cond!(
(k == *kk) { Some(copy *v) }
(k == *kk) { Some((*v).clone()) }
(k < *kk) { find(left, 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.
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 {
Empty => (),
// Previously, this had what looked like redundant

View File

@ -53,10 +53,10 @@ priv enum FutureState<A> {
}
/// Methods on the `future` type
impl<A:Copy> Future<A> {
impl<A:Clone> Future<A> {
pub fn get(&mut self) -> A {
//! Get the value of the future.
copy *(self.get_ref())
(*(self.get_ref())).clone()
}
}

View File

@ -52,7 +52,7 @@
* fn main() {
* let args = os::args();
*
* let program = copy args[0];
* let program = args[0].clone();
*
* let opts = ~[
* optopt("o"),
@ -69,7 +69,7 @@
* }
* let output = opt_maybe_str(&matches, "o");
* let input: &str = if !matches.free.is_empty() {
* copy matches.free[0]
* matches.free[0].clone()
* } else {
* print_usage(program, opts);
* return;
@ -89,20 +89,28 @@ use std::option::{Some, None};
use std::str;
use std::vec;
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum Name {
Long(~str),
Short(char),
}
#[deriving(Eq)]
pub enum HasArg { Yes, No, Maybe, }
#[deriving(Clone, Eq)]
pub enum HasArg {
Yes,
No,
Maybe,
}
#[deriving(Eq)]
pub enum Occur { Req, Optional, Multi, }
#[deriving(Clone, Eq)]
pub enum Occur {
Req,
Optional,
Multi,
}
/// A description of a possible option
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub struct Opt {
name: Name,
hasarg: HasArg,
@ -150,14 +158,17 @@ pub fn optmulti(name: &str) -> Opt {
return Opt {name: mkname(name), hasarg: Yes, occur: Multi};
}
#[deriving(Eq)]
enum Optval { Val(~str), Given, }
#[deriving(Clone, Eq)]
enum Optval {
Val(~str),
Given,
}
/**
* The result of checking command line arguments. Contains a vector
* of matches and a vector of free strings.
*/
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub struct Matches {
opts: ~[Opt],
vals: ~[~[Optval]],
@ -171,7 +182,7 @@ fn is_arg(arg: &str) -> bool {
fn name_str(nm: &Name) -> ~str {
return match *nm {
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
* expected format. Pass this value to <fail_str> to get an error message.
*/
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum Fail_ {
ArgumentMissing(~str),
UnrecognizedOption(~str),
@ -234,13 +245,13 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
let l = args.len();
let mut i = 0;
while i < l {
let cur = copy args[i];
let cur = args[i].clone();
let curlen = cur.len();
if !is_arg(cur) {
free.push(cur);
} else if cur == ~"--" {
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;
} else {
let mut names;
@ -270,7 +281,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
interpreted correctly
*/
match find_opt(opts, copy opt) {
match find_opt(opts, opt.clone()) {
Some(id) => last_valid_opt_id = Some(id),
None => {
let arg_follows =
@ -296,7 +307,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
let mut name_pos = 0;
for names.iter().advance() |nm| {
name_pos += 1;
let optid = match find_opt(opts, copy *nm) {
let optid = match find_opt(opts, (*nm).clone()) {
Some(id) => id,
None => return Err(UnrecognizedOption(name_str(nm)))
};
@ -309,18 +320,18 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
}
Maybe => {
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() ||
i + 1 == l || is_arg(args[i + 1]) {
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 => {
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 {
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] {
return match find_opt(mm.opts, mkname(nm)) {
Some(id) => copy mm.vals[id],
Some(id) => mm.vals[id].clone(),
None => {
error!("No option '%s' defined", nm);
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
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 {
for names.iter().advance |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 r = opt_vals(mm, nm);
for r.iter().advance |v| {
match *v { Val(ref s) => acc.push(copy *s), _ => () }
match *v { Val(ref s) => acc.push((*s).clone()), _ => () }
}
acc
}
@ -429,7 +440,7 @@ pub fn opt_maybe_str(mm: &Matches, nm: &str) -> Option<~str> {
let vals = opt_vals(mm, nm);
if vals.is_empty() { return None::<~str>; }
return match vals[0] {
Val(ref s) => Some(copy *s),
Val(ref s) => Some((*s).clone()),
_ => 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> {
let vals = opt_vals(mm, nm);
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)) }
}
@ -471,7 +482,7 @@ pub mod groups {
/** one group of options, e.g., both -h and --help, along with
* their shared description and properties
*/
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub struct OptGroup {
short_name: ~str,
long_name: ~str,
@ -556,7 +567,7 @@ pub mod groups {
long_name: long_name,
hasarg: hasarg,
occur: occur,
_} = copy *lopt;
_} = (*lopt).clone();
match (short_name.len(), long_name.len()) {
(0,0) => fail!("this long-format option was given no name"),
@ -600,7 +611,7 @@ pub mod groups {
hint: hint,
desc: desc,
hasarg: hasarg,
_} = copy *optref;
_} = (*optref).clone();
let mut row = " ".repeat(4);
@ -916,7 +927,7 @@ mod tests {
let rs = getopts(args, opts);
match rs {
Err(f) => {
error!(fail_str(copy f));
error!(fail_str(f.clone()));
check_fail_type(f, UnexpectedArgument_);
}
_ => fail!()

View File

@ -30,6 +30,7 @@ use sort::Sort;
use treemap::TreeMap;
/// Represents a json value
#[deriving(Clone, Eq)]
pub enum Json {
Number(float),
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
impl Ord for Json {
fn lt(&self, other: &Json) -> bool {
@ -1195,12 +1159,12 @@ impl Ord for Json {
// FIXME #4430: this is horribly inefficient...
for d0.iter().advance |(k, v)| {
d0_flat.push((@copy *k, @copy *v));
d0_flat.push((@(*k).clone(), @(*v).clone()));
}
d0_flat.qsort();
for d1.iter().advance |(k, v)| {
d1_flat.push((@copy *k, @copy *v));
d1_flat.push((@(*k).clone(), @(*v).clone()));
}
d1_flat.qsort();
@ -1232,7 +1196,7 @@ pub trait ToJson {
}
impl ToJson for Json {
fn to_json(&self) -> Json { copy *self }
fn to_json(&self) -> Json { (*self).clone() }
}
impl ToJson for @Json {
@ -1300,11 +1264,11 @@ impl ToJson for bool {
}
impl ToJson for ~str {
fn to_json(&self) -> Json { String(copy *self) }
fn to_json(&self) -> Json { String((*self).clone()) }
}
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) {
@ -1335,7 +1299,7 @@ impl<A:ToJson> ToJson for HashMap<~str, A> {
fn to_json(&self) -> Json {
let mut d = HashMap::new();
for self.iter().advance |(key, value)| {
d.insert(copy *key, value.to_json());
d.insert((*key).clone(), value.to_json());
}
Object(~d)
}
@ -1345,7 +1309,7 @@ impl<A:ToJson> ToJson for TreeMap<~str, A> {
fn to_json(&self) -> Json {
let mut d = HashMap::new();
for self.iter().advance |(key, value)| {
d.insert(copy *key, value.to_json());
d.insert((*key).clone(), value.to_json());
}
Object(~d)
}
@ -1404,7 +1368,7 @@ mod tests {
for items.iter().advance |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
// printed in a different order.
assert_eq!(copy a, from_str(to_str(&a)).unwrap());
assert_eq!(copy a, from_str(to_pretty_str(&a)).unwrap());
assert_eq!(a.clone(), from_str(to_str(&a)).unwrap());
assert_eq!(a.clone(), from_str(to_pretty_str(&a)).unwrap());
}
#[test]

View File

@ -25,8 +25,8 @@ pub enum MutList<T> {
}
/// Create a list from a vector
pub fn from_vec<T:Copy>(v: &[T]) -> @List<T> {
v.rev_iter().fold(@Nil::<T>, |t, h| @Cons(copy *h, t))
pub fn from_vec<T:Clone>(v: &[T]) -> @List<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
* * 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;
do iter(ls) |elt| { accum = f(&accum, elt);}
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
* 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;
loop {
ls = match *ls {
Cons(ref hd, tl) => {
if f(hd) { return Some(copy *hd); }
if f(hd) { return Some((*hd).clone()); }
tl
}
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
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| {
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
pub fn is_empty<T:Copy>(ls: @List<T>) -> bool {
pub fn is_empty<T>(ls: @List<T>) -> bool {
match *ls {
Nil => true,
_ => false
@ -92,7 +92,7 @@ pub fn len<T>(ls: @List<T>) -> uint {
}
/// 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 {
Cons(_, tl) => return tl,
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
pub fn head<T:Copy>(ls: @List<T>) -> T {
pub fn head<T:Clone>(ls: @List<T>) -> T {
match *ls {
Cons(ref hd, _) => copy *hd,
Cons(ref hd, _) => (*hd).clone(),
// makes me sad
_ => fail!("head invoked on empty list")
}
}
/// 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 {
Nil => return m,
Cons(ref x, xs) => {
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
/// 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)
}
*/

View File

@ -176,12 +176,19 @@ pub mod v4 {
pub fn parse_addr(ip: &str) -> IpAddr {
match try_parse_addr(ip) {
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
// 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 {
unsafe fn as_u32(&self) -> u32;
@ -271,7 +278,7 @@ pub mod v6 {
pub fn parse_addr(ip: &str) -> IpAddr {
match try_parse_addr(ip) {
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> {

View File

@ -86,6 +86,7 @@ pub fn TcpSocketBuf(data: @mut TcpBufferedSocketData) -> TcpSocketBuf {
}
/// Contains raw, string-based, error information returned from libuv
#[deriving(Clone)]
pub struct TcpErrData {
err_name: ~str,
err_msg: ~str,
@ -278,8 +279,8 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
as *libc::c_void);
let tcp_conn_err = match err_data.err_name {
~"ECONNREFUSED" => ConnectionRefused,
_ => GenericConnectErr(copy err_data.err_name,
copy err_data.err_msg)
_ => GenericConnectErr(err_data.err_name.clone(),
err_data.err_msg.clone())
};
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;
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)
}
}
@ -770,8 +771,8 @@ fn listen_common(host_ip: ip::IpAddr,
debug!("Got '%s' '%s' libuv error",
err_data.err_name, err_data.err_msg);
result::Err(
GenericListenErr(copy err_data.err_name,
copy err_data.err_msg))
GenericListenErr(err_data.err_name.clone(),
err_data.err_msg.clone()))
}
}
}
@ -791,8 +792,8 @@ fn listen_common(host_ip: ip::IpAddr,
match kill_result {
// some failure post bind/listen
Some(ref err_data) => result::Err(GenericListenErr(
copy err_data.err_name,
copy err_data.err_msg)),
err_data.err_name.clone(),
err_data.err_msg.clone())),
// clean exit
None => result::Ok(())
}
@ -1263,7 +1264,10 @@ trait ToTcpErr {
impl ToTcpErr for uv::ll::uv_err_data {
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(),
}
}
}

View File

@ -282,7 +282,7 @@ impl Mul<BigUint, BigUint> for BigUint {
fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
if n == 0 { return Zero::zero(); }
if n == 1 { return copy *a; }
if n == 1 { return (*a).clone(); }
let mut carry = 0;
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) {
if other.is_zero() { fail!() }
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) {
Less => return (Zero::zero(), copy *self),
Less => return (Zero::zero(), (*self).clone()),
Equal => return (One::one(), Zero::zero()),
Greater => {} // Do nothing
}
@ -411,7 +411,7 @@ impl Integer for BigUint {
fn div_estimate(a: &BigUint, b: &BigUint, n: uint)
-> (BigUint, BigUint, BigUint) {
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());
@ -428,7 +428,7 @@ impl Integer for BigUint {
let shift = (a.data.len() - an.len()) - (b.data.len() - 1);
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),
One::one::<BigUint>().shl_unit(shift),
@ -444,8 +444,8 @@ impl Integer for BigUint {
fn gcd(&self, other: &BigUint) -> BigUint {
// Use Euclid's algorithm
let mut m = copy *self;
let mut n = copy *other;
let mut m = (*self).clone();
let mut n = (*other).clone();
while !m.is_zero() {
let temp = m;
m = n % temp;
@ -500,7 +500,7 @@ impl ToStrRadix for BigUint {
if base == BigDigit::base {
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] {
@ -612,14 +612,14 @@ impl 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 {
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 shifted = do self.data.iter().transform |elem| {
@ -635,7 +635,7 @@ impl 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(); }
return BigUint::from_slice(
self.data.slice(n_unit, self.data.len())
@ -644,7 +644,7 @@ impl 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 shifted = ~[];

View File

@ -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
// 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,
* like map or alli.
*/
fn map_slices<A:Copy + Send,B:Copy + Send>(
fn map_slices<A:Clone + Send,B:Clone + Send>(
xs: &[A],
f: &fn() -> ~fn(uint, v: &[A]) -> B)
-> ~[B] {
@ -42,8 +42,7 @@ fn map_slices<A:Copy + Send,B:Copy + Send>(
info!("small slice");
// This is a small vector, fall back on the normal map.
~[f()(0u, xs)]
}
else {
} else {
let num_tasks = num::min(MAX_TASKS, len / MIN_GRANULARITY);
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.
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] {
vec::concat(map_slices(xs, || {
let f = fn_factory();
@ -97,7 +96,7 @@ pub fn map<A:Copy + Send,B:Copy + Send>(
}
/// 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],
fn_factory: &fn() -> ~fn(uint, &A) -> B) -> ~[B] {
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.
pub fn alli<A:Copy + Send>(
pub fn alli<A:Clone + Send>(
xs: &[A],
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.
pub fn any<A:Copy + Send>(
pub fn any<A:Clone + Send>(
xs: &[A],
fn_factory: &fn() -> ~fn(&A) -> bool) -> bool {
let mapped = map_slices(xs, || {

View File

@ -308,8 +308,8 @@ mod tests {
}
fn check_to_vec(data: ~[int]) {
let heap = PriorityQueue::from_vec(copy data);
assert_eq!(merge_sort((copy heap).to_vec(), |x, y| x.le(y)),
let heap = PriorityQueue::from_vec(data.clone());
assert_eq!(merge_sort(heap.clone().to_vec(), |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)));
}

View File

@ -329,8 +329,8 @@ impl<A, T: Iterator<A>> FromIterator<A, T> for RingBuf<A> {
#[cfg(test)]
mod tests {
use super::*;
use std::clone::Clone;
use std::cmp::Eq;
use std::kinds::Copy;
use std::{int, uint};
use extra::test;
@ -416,34 +416,34 @@ mod tests {
}
#[cfg(test)]
fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
let mut deq = RingBuf::new();
fn test_parameterized<T:Clone + Eq>(a: T, b: T, c: T, d: T) {
let mut deq = Deque::new();
assert_eq!(deq.len(), 0);
deq.push_front(copy a);
deq.push_front(copy b);
deq.push_back(copy c);
deq.add_front(a.clone());
deq.add_front(b.clone());
deq.add_back(c.clone());
assert_eq!(deq.len(), 3);
deq.push_back(copy d);
deq.add_back(d.clone());
assert_eq!(deq.len(), 4);
assert_eq!(deq.front(), Some(&b));
assert_eq!(deq.back(), Some(&d));
assert_eq!(deq.pop_front(), Some(copy b));
assert_eq!(deq.pop_back(), Some(copy d));
assert_eq!(deq.pop_back(), Some(copy c));
assert_eq!(deq.pop_back(), Some(copy a));
assert_eq!((*deq.peek_front()).clone(), b.clone());
assert_eq!((*deq.peek_back()).clone(), d.clone());
assert_eq!(deq.pop_front(), b.clone());
assert_eq!(deq.pop_back(), d.clone());
assert_eq!(deq.pop_back(), c.clone());
assert_eq!(deq.pop_back(), a.clone());
assert_eq!(deq.len(), 0);
deq.push_back(copy c);
deq.add_back(c.clone());
assert_eq!(deq.len(), 1);
deq.push_front(copy b);
deq.add_front(b.clone());
assert_eq!(deq.len(), 2);
deq.push_back(copy d);
deq.add_back(d.clone());
assert_eq!(deq.len(), 3);
deq.push_front(copy a);
deq.add_front(a.clone());
assert_eq!(deq.len(), 4);
assert_eq!(copy *deq.get(0), copy a);
assert_eq!(copy *deq.get(1), copy b);
assert_eq!(copy *deq.get(2), copy c);
assert_eq!(copy *deq.get(3), copy d);
assert_eq!((*deq.get(0)).clone(), a.clone());
assert_eq!((*deq.get(1)).clone(), b.clone());
assert_eq!((*deq.get(2)).clone(), c.clone());
assert_eq!((*deq.get(3)).clone(), d.clone());
}
#[test]
@ -501,15 +501,21 @@ mod tests {
}
}
#[deriving(Eq)]
enum Taggy { One(int), Two(int, int), Three(int, int, int), }
#[deriving(Eq)]
enum Taggypar<T> {
Onepar(int), Twopar(int, int), Threepar(int, int, int),
#[deriving(Clone, Eq)]
enum Taggy {
One(int),
Two(int, int),
Three(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 {
x: int,
y: int,

View File

@ -21,7 +21,7 @@ use std::option::{Option, Some, None};
use std::to_str::ToStr;
use std::uint;
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum Identifier {
Numeric(uint),
AlphaNumeric(~str)
@ -62,7 +62,7 @@ impl ToStr for Identifier {
}
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub struct Version {
major: uint,
minor: uint,

View File

@ -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,
ff: &fn(uint, V, V) -> V) -> bool {
let new_val = match self.find(&key) {
None => val,
Some(orig) => ff(key, copy *orig, val)
Some(orig) => ff(key, (*orig).clone(), val)
};
self.insert(key, new_val)
}

View File

@ -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
* 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);
return merge_sort_(v, (0u, v.len()), le);
fn merge_sort_<T:Copy>(v: &[T], slice: Slice, le: Le<T>)
-> ~[T] {
fn merge_sort_<T:Copy + Clone>(v: &[T], slice: Slice, le: Le<T>) -> ~[T] {
let begin = slice.first();
let end = slice.second();
let v_len = end - begin;
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 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)));
}
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 a_len = a.len();
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;
while a_ix < a_len && b_ix < b_len {
if le(&a[a_ix], &b[b_ix]) {
rs.push(copy a[a_ix]);
rs.push(a[a_ix].clone());
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(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);
}
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; }
let v: T = copy arr[right];
let v: T = arr[right].clone();
let mut i: int = left - 1;
let mut j: int = right;
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.
*/
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; }
let len = arr.len(); // FIXME(#5074) nested calls
qsort3(arr, 0, (len - 1) as int);
@ -172,7 +174,7 @@ pub trait Sort {
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); }
}
@ -181,7 +183,7 @@ static MIN_GALLOP: uint = 7;
static INITIAL_TMP_STORAGE: uint = 128;
#[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();
if size < 2 {
return;
@ -225,7 +227,7 @@ pub fn tim_sort<T:Copy + Ord>(array: &mut [T]) {
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 mut start = start;
assert!(start <= size);
@ -233,7 +235,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
if start == 0 { start += 1; }
while start < size {
let pivot = copy array[start];
let pivot = array[start].clone();
let mut left = 0;
let mut right = start;
assert!(left <= right);
@ -275,7 +277,7 @@ fn min_run_length(n: uint) -> uint {
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();
assert!(size > 0);
if size == 1 { return 1; }
@ -295,7 +297,7 @@ fn count_run_ascending<T:Copy + Ord>(array: &mut [T]) -> uint {
return run;
}
fn gallop_left<T:Copy + Ord>(key: &T,
fn gallop_left<T:Clone + Ord>(key: &T,
array: &[T],
hint: uint)
-> uint {
@ -346,7 +348,7 @@ fn gallop_left<T:Copy + Ord>(key: &T,
return ofs;
}
fn gallop_right<T:Copy + Ord>(key: &T,
fn gallop_right<T:Clone + Ord>(key: &T,
array: &[T],
hint: 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) {
let tmp = RunState{base: run_base, len: run_len};
self.runs.push(tmp);
@ -470,7 +472,7 @@ impl<T:Copy + Ord> MergeState<T> {
let mut tmp = ~[];
for uint::range(base1, base1+len1) |i| {
tmp.push(copy array[i]);
tmp.push(array[i].clone());
}
let mut c1 = 0;
@ -580,7 +582,7 @@ impl<T:Copy + Ord> MergeState<T> {
let mut tmp = ~[];
for uint::range(base2, base2+len2) |i| {
tmp.push(copy array[i]);
tmp.push(array[i].clone());
}
let mut c1 = base1 + len1 - 1;
@ -726,21 +728,21 @@ impl<T:Copy + Ord> MergeState<T> {
}
#[inline]
fn copy_vec<T:Copy>(dest: &mut [T],
fn copy_vec<T:Clone>(dest: &mut [T],
s1: uint,
from: &[T]) {
assert!(s1+from.len() <= dest.len());
for from.iter().enumerate().advance |(i, v)| {
dest[s1+i] = copy *v;
dest[s1+i] = (*v).clone();
}
}
#[inline]
fn shift_vec<T:Copy>(dest: &mut [T],
s1: uint,
s2: uint,
len: uint) {
fn shift_vec<T:Copy + Clone>(dest: &mut [T],
s1: uint,
s2: uint,
len: uint) {
assert!(s1+len <= dest.len());
let tmp = dest.slice(s2, s2+len).to_owned();
@ -902,7 +904,7 @@ mod tests {
fn ile(x: &(&'static str), y: &(&'static str)) -> bool
{
// 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
// Ascii)
let x = x.to_ascii().to_lower().to_str_ascii();
@ -1038,17 +1040,17 @@ mod big_tests {
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 res = do vec::from_fn(num) |i| {
copy arr[i % size]
arr[i % size].clone()
};
res
}
fn makeRange(n: uint) -> ~[uint] {
let one = do vec::from_fn(n) |i| { i };
let mut two = copy one;
let mut two = one.clone();
two.reverse();
vec::append(two, one)
}

View File

@ -99,7 +99,7 @@ pub trait Stats {
}
/// Extracted collection of all the summary statistics of a sample set.
#[deriving(Eq)]
#[deriving(Clone, Eq)]
struct Summary {
sum: f64,
min: f64,

View File

@ -39,6 +39,7 @@ enum FormatState {
}
/// Types of parameters a capability can use
#[deriving(Clone)]
pub enum Param {
String(~str),
Number(int)
@ -82,7 +83,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
// Copy parameters into a local vector for mutability
let mut mparams = [Number(0), ..9];
for mparams.mut_iter().zip(params.iter()).advance |(dst, src)| {
*dst = copy *src;
*dst = (*src).clone();
}
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 %~")
}
} 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)) => {
mparams[0] = Number(x+1);
mparams[1] = Number(y+1);
@ -263,10 +264,10 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
},
PushParam => {
// 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,
None => return Err(~"bad param number")
}]);
}].clone());
},
SetVar => {
if cur >= 'A' && cur <= 'Z' {
@ -286,10 +287,10 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
GetVar => {
if cur >= 'A' && cur <= 'Z' {
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' {
let idx = (cur as u8) - ('a' as u8);
stack.push(copy vars.dyn[idx]);
stack.push(vars.dyn[idx].clone());
} else {
return Err(~"bad variable name in %g");
}

View File

@ -44,13 +44,14 @@ use std::os;
// colons. This way if some test runner wants to arrange the tests
// hierarchically it may.
#[deriving(Clone)]
pub enum TestName {
StaticTestName(&'static str),
DynTestName(~str)
}
impl ToStr for TestName {
fn to_str(&self) -> ~str {
match copy *self {
match (*self).clone() {
StaticTestName(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
// these.
#[deriving(Clone)]
pub struct TestDesc {
name: TestName,
ignore: bool,
@ -134,10 +136,10 @@ pub fn test_main_static(args: &[~str], tests: &[TestDescAndFn]) {
let owned_tests = do tests.map |t| {
match t.testfn {
StaticTestFn(f) =>
TestDescAndFn { testfn: StaticTestFn(f), desc: copy t.desc },
TestDescAndFn { testfn: StaticTestFn(f), desc: t.desc.clone() },
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");
@ -178,8 +180,10 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
let filter =
if matches.free.len() > 0 {
Some(copy (matches).free[0])
} else { None };
Some((matches).free[0].clone())
} else {
None
};
let run_ignored = getopts::opt_present(&matches, "ignored");
@ -214,19 +218,19 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
either::Left(test_opts)
}
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub struct BenchSamples {
ns_iter_summ: stats::Summary,
mb_s: uint
}
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum TestResult {
TrOk,
TrFailed,
TrIgnored,
TrMetrics(MetricMap),
TrBench(BenchSamples)
TrBench(BenchSamples),
}
struct ConsoleTestState {
@ -500,7 +504,7 @@ pub fn run_tests_console(opts: &TestOpts,
tests: ~[TestDescAndFn]) -> bool {
fn callback(event: &TestEvent, st: &mut ConsoleTestState) {
debug!("callback(event=%?)", event);
match copy *event {
match (*event).clone() {
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
TeWait(ref test) => st.write_test_start(test),
TeResult(test, result) => {
@ -584,6 +588,7 @@ fn should_sort_failures_before_printing_them() {
fn use_color() -> bool { return get_concurrency() == 1; }
#[deriving(Clone)]
enum TestEvent {
TeFiltered(~[TestDesc]),
TeWait(TestDesc),
@ -597,7 +602,7 @@ fn run_tests(opts: &TestOpts,
callback: &fn(e: TestEvent)) {
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));
@ -628,7 +633,7 @@ fn run_tests(opts: &TestOpts,
// 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
// that hang forever.
callback(TeWait(copy test.desc));
callback(TeWait(test.desc.clone()));
}
run_test(!opts.run_tests, test, ch.clone());
pending += 1;
@ -636,7 +641,7 @@ fn run_tests(opts: &TestOpts,
let (desc, result) = p.recv();
if concurrency != 1 {
callback(TeWait(copy desc));
callback(TeWait(desc.clone()));
}
callback(TeResult(desc, result));
pending -= 1;
@ -645,7 +650,7 @@ fn run_tests(opts: &TestOpts,
// All benchmarks run at the end, in serial.
// (this includes metric fns)
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());
let (test, result) = p.recv();
callback(TeResult(test, result));
@ -678,7 +683,7 @@ pub fn filter_tests(
filtered
} else {
let filter_str = match opts.filter {
Some(ref f) => copy *f,
Some(ref f) => (*f).clone(),
None => ~""
};
@ -752,7 +757,7 @@ pub fn run_test(force_ignore: bool,
let task_result = result_future.unwrap().recv();
let test_result = calc_result(&desc,
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.
pub fn load(p: &Path) -> MetricMap {
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());
MetricMap(Decodable::decode(&mut decoder))
}
/// Write MetricDiff to a file.
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());
}
@ -868,11 +873,11 @@ impl MetricMap {
}
}
};
diff.insert(copy *k, r);
diff.insert((*k).clone(), r);
}
for self.iter().advance |(k, _)| {
if !diff.contains_key(k) {
diff.insert(copy *k, MetricAdded);
diff.insert((*k).clone(), MetricAdded);
}
}
diff
@ -1153,7 +1158,7 @@ mod tests {
either::Left(o) => o,
_ => fail!("Malformed arg in first_free_arg_should_be_a_filter")
};
assert!("filter" == (copy opts.filter).get());
assert!("filter" == opts.filter.clone().get());
}
#[test]
@ -1236,11 +1241,11 @@ mod tests {
for names.iter().advance |name| {
let test = TestDescAndFn {
desc: TestDesc {
name: DynTestName(copy *name),
name: DynTestName((*name).clone()),
ignore: false,
should_fail: false
},
testfn: DynTestFn(copy testfn),
testfn: DynTestFn(testfn.clone()),
};
tests.push(test);
}

View File

@ -683,7 +683,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
tm_yday: tm.tm_yday,
tm_isdst: tm.tm_isdst,
tm_gmtoff: tm.tm_gmtoff,
tm_zone: copy tm.tm_zone,
tm_zone: tm.tm_zone.clone(),
tm_nsec: tm.tm_nsec,
})
} else { result }
@ -829,7 +829,7 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str {
//'x' {}
'Y' => int::to_str(tm.tm_year as int + 1900),
'y' => fmt!("%02d", (tm.tm_year as int + 1900) % 100),
'Z' => copy tm.tm_zone,
'Z' => tm.tm_zone.clone(),
'z' => {
let sign = if tm.tm_gmtoff > 0_i32 { '+' } else { '-' };
let mut m = num::abs(tm.tm_gmtoff) / 60_i32;

View File

@ -791,8 +791,8 @@ mod test_treemap {
let v1 = "baz".as_bytes();
let v2 = "foobar".as_bytes();
m.insert(copy k1, copy v1);
m.insert(copy k2, copy v2);
m.insert(k1.clone(), v1.clone());
m.insert(k2.clone(), v2.clone());
assert_eq!(m.find(&k2), Some(&v2));
assert_eq!(m.find(&k1), Some(&v1));

View File

@ -1476,7 +1476,7 @@ mod test {
let client_data = get_data_for_uv_handle(
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;
if request_str.contains(server_kill_msg) {
debug!(~"SERVER: client req contains kill_msg!");
@ -1726,12 +1726,12 @@ mod test {
let (continue_port, continue_chan) = stream::<bool>();
let continue_chan = SharedChan::new(continue_chan);
let kill_server_msg_copy = copy kill_server_msg;
let server_resp_msg_copy = copy server_resp_msg;
let kill_server_msg_copy = kill_server_msg.clone();
let server_resp_msg_copy = server_resp_msg.clone();
do task::spawn_sched(task::ManualThreads(1)) {
impl_uv_tcp_server(bind_ip, port,
copy kill_server_msg_copy,
copy server_resp_msg_copy,
kill_server_msg_copy.clone(),
server_resp_msg_copy.clone(),
server_chan.clone(),
continue_chan.clone());
};
@ -1741,7 +1741,7 @@ mod test {
continue_port.recv();
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)) {
impl_uv_tcp_request(request_ip, port,
kill_server_msg_copy,

View File

@ -97,7 +97,7 @@ use std::util::replace;
*
*/
#[deriving(Eq, Encodable, Decodable)]
#[deriving(Clone, Eq, Encodable, Decodable)]
struct WorkKey {
kind: ~str,
name: ~str
@ -138,6 +138,12 @@ impl WorkKey {
struct WorkMap(HashMap<WorkKey, ~str>);
impl Clone for WorkMap {
fn clone(&self) -> WorkMap {
WorkMap((**self).clone())
}
}
impl WorkMap {
fn new() -> WorkMap { WorkMap(HashMap::new()) }
}
@ -146,7 +152,7 @@ impl<S:Encoder> Encodable<S> for WorkMap {
fn encode(&self, s: &mut S) {
let mut d = ~[];
for self.iter().advance |(k, v)| {
d.push((copy *k, copy *v))
d.push(((*k).clone(), (*v).clone()))
}
sort::tim_sort(d);
d.encode(s)
@ -215,6 +221,7 @@ struct Context {
freshness: HashMap<~str,@fn(&str,&str)->bool>
}
#[deriving(Clone)]
struct Prep {
ctxt: @Context,
fn_name: ~str,
@ -341,7 +348,7 @@ impl TPrep for Prep {
&self.declared_inputs) &&
self.all_fresh("discovered input", disc_in) &&
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);
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 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; }");
}

View File

@ -118,7 +118,7 @@ static COMMANDS: &'static [Command<'static>] = &[
];
fn rustc_help() {
rustc::usage(copy os::args()[0])
rustc::usage(os::args()[0].clone())
}
fn find_cmd(command_string: &str) -> Option<Command> {
@ -148,7 +148,7 @@ fn cmd_help(args: &[~str]) -> ValidUsage {
}
match args {
[ref command_string] => print_usage(copy *command_string),
[ref command_string] => print_usage((*command_string).clone()),
_ => Invalid
}
}

View File

@ -39,7 +39,7 @@ use syntax::attr;
use syntax::print::pprust;
use syntax::parse::token;
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum output_type {
output_type_none,
output_type_bitcode,
@ -291,7 +291,7 @@ pub mod write {
}
let passes = if sess.opts.custom_passes.len() > 0 {
copy sess.opts.custom_passes
sess.opts.custom_passes.clone()
} else {
if sess.lint_llvm() {
mpm.add_pass_from_name("lint");
@ -817,7 +817,7 @@ pub fn link_binary(sess: Session,
// For win32, there is no cc command,
// so we add a condition to make it use gcc.
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 {
session::os_android =>
match &sess.opts.android_cross_path {
@ -845,7 +845,7 @@ pub fn link_binary(sess: Session,
out_filename.dir_path().push(long_libname)
} else {
/*bad*/copy *out_filename
out_filename.clone()
};
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);
out_filename.dir_path().push(long_libname)
} else {
/*bad*/copy *out_filename
out_filename.clone()
};
// The default library location, we need this to find the runtime.

View File

@ -185,7 +185,7 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
let mut minimized = ~[];
for rpaths.iter().advance |rpath| {
if set.insert(rpath.to_str()) {
minimized.push(copy *rpath);
minimized.push(rpath.clone());
}
}
minimized

View File

@ -109,10 +109,14 @@ pub fn build_configuration(sess: Session, argv0: @str, input: &input) ->
// Combine the configuration requested by the session (command line) with
// some default and generated configuration items
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
let user_cfg = if sess.opts.test { append_configuration(user_cfg, @"test") }
else { user_cfg };
let user_cfg = if sess.opts.test {
append_configuration(user_cfg, @"test")
} else {
user_cfg
};
// If the user requested GC, then add the GC cfg
let user_cfg = append_configuration(
user_cfg,
@ -202,7 +206,8 @@ pub fn compile_rest(sess: Session,
front::config::strip_unconfigured_items(crate));
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));
// 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));
}
if phases.to == cu_expand { return (Some(crate), None); }
if phases.to == cu_expand {
return (Some(crate), None);
}
assert!(phases.from != cu_no_trans);
@ -371,17 +378,28 @@ pub fn compile_rest(sess: Session,
return (None, None);
}
pub fn compile_upto(sess: Session, cfg: ast::crate_cfg,
input: &input, upto: compile_phase,
outputs: Option<@OutputFilenames>)
-> (Option<@ast::crate>, Option<ty::ctxt>) {
pub fn compile_upto(sess: Session,
cfg: ast::crate_cfg,
input: &input,
upto: compile_phase,
outputs: Option<@OutputFilenames>)
-> (Option<@ast::crate>, Option<ty::ctxt>) {
let time_passes = sess.time_passes();
let crate = time(time_passes, ~"parsing",
|| parse_input(sess, copy cfg, input) );
if upto == cu_parse { return (Some(crate), None); }
let crate = time(time_passes,
~"parsing",
|| 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 },
outputs, Some(crate))
compile_rest(sess,
cfg,
compile_upto {
from: cu_parse,
to: upto
},
outputs,
Some(crate))
}
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
// We want to toss everything after the final '.'
let dirpath = match *odir {
Some(ref d) => (/*bad*/copy *d),
Some(ref d) => (*d).clone(),
None => match *input {
str_input(_) => os::getcwd(),
file_input(ref ifile) => (*ifile).dir_path()
@ -914,9 +932,9 @@ pub fn build_output_filenames(input: &input,
}
Some(ref out_file) => {
out_path = (/*bad*/copy *out_file);
out_path = (*out_file).clone();
obj_path = if stop_after_codegen {
(/*bad*/copy *out_file)
(*out_file).clone()
} else {
(*out_file).with_filetype(obj_suffix)
};

View File

@ -33,7 +33,12 @@ use std::hashmap::HashMap;
#[deriving(Eq)]
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 {
os: os,
@ -118,7 +123,7 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
]
}
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum OptLevel {
No, // -O0
Less, // -O1
@ -126,6 +131,7 @@ pub enum OptLevel {
Aggressive // -O3
}
#[deriving(Clone)]
pub struct options {
// The crate config requested for the session, which may be combined
// 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
pub fn expect<T:Copy>(sess: Session,
opt: Option<T>,
msg: &fn() -> ~str)
-> T {
pub fn expect<T:Clone>(sess: Session, opt: Option<T>, msg: &fn() -> ~str)
-> T {
diagnostic::expect(sess.diagnostic(), opt, msg)
}

View File

@ -99,14 +99,14 @@ fn fold_item_underscore(cx: @Context, item: &ast::item_,
ast::item_impl(ref a, ref b, ref c, ref methods) => {
let methods = methods.iter().filter(|m| method_in_cfg(cx, **m))
.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) => {
let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) )
.transform(|x| /* bad */copy *x).collect();
ast::item_trait(/*bad*/copy *a, /*bad*/copy *b, methods)
.transform(|x| (*x).clone()).collect();
ast::item_trait((*a).clone(), (*b).clone(), methods)
}
ref item => /*bad*/ copy *item
ref item => (*item).clone(),
};
fold::noop_fold_item_underscore(&item, fld)
@ -151,11 +151,11 @@ fn fold_block(
}
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 {
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 {
@ -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 {
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 {
match *meth {
ast::required(ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs),
ast::provided(@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)(meth.attrs)
}
}

View File

@ -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 mut new_module = ast::_mod {
view_items: vis,
../*bad*/copy crate.module
..crate.module.clone()
};
if !no_prelude(crate.attrs) {
@ -76,7 +76,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
// FIXME #2543: Bad copy.
let new_crate = ast::crate_ {
module: new_module,
..copy *crate
..(*crate).clone()
};
(new_crate, span)
},
@ -115,7 +115,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
// FIXME #2543: Bad copy.
let new_module = ast::_mod {
view_items: vis,
..copy *module
..(*module).clone()
};
fold::noop_fold_mod(&new_module, fld)
},

View File

@ -66,7 +66,7 @@ fn generate_test_harness(sess: session::Session,
let cx: @mut TestCtxt = @mut TestCtxt {
sess: sess,
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: ~[],
testfns: ~[]
};
@ -109,26 +109,31 @@ fn fold_mod(cx: @mut TestCtxt,
fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item {
if !*cx.sess.building_library {
@ast::item{
@ast::item {
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(),
.. copy *item}
} else { item }
.. (*item).clone()
}
} else {
item
}
}
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(),
};
fold::noop_fold_mod(&mod_nomain, fld)
}
fn fold_crate(cx: @mut TestCtxt,
c: &ast::crate_,
fld: @fold::ast_fold)
-> ast::crate_ {
fn fold_crate(cx: @mut TestCtxt, c: &ast::crate_, fld: @fold::ast_fold)
-> ast::crate_ {
let folded = fold::noop_fold_crate(c, fld);
// 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> {
cx.path.push(i.ident);
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) {
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");
let test = Test {
span: i.span,
path: /*bad*/copy cx.path,
path: cx.path.clone(),
bench: is_bench_fn(i),
ignore: is_ignored(cx, 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))
.collect::<~[~[@ast::meta_item]]>()
.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 {
false
}
@ -248,8 +253,8 @@ fn should_fail(i: @ast::item) -> bool {
fn add_test_module(cx: &TestCtxt, m: &ast::_mod) -> ast::_mod {
let testmod = mk_test_module(cx);
ast::_mod {
items: vec::append_one(/*bad*/copy m.items, testmod),
.. /*bad*/ copy *m
items: vec::append_one(m.items.clone(), testmod),
..(*m).clone()
}
}
@ -333,7 +338,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item {
};
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;
}
@ -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 {
let span = test.span;
let path = /*bad*/copy test.path;
let path = test.path.clone();
let ext_cx = cx.ext_cx;

View File

@ -58,6 +58,7 @@ pub enum Linkage {
LinkerPrivateWeakLinkage = 16,
}
#[deriving(Clone)]
pub enum Attribute {
ZExtAttribute = 1,
SExtAttribute = 2,

View File

@ -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 othername = loader::crate_name_from_metas(
copy *entry.metas);
let othername = loader::crate_name_from_metas(*entry.metas);
if name == othername {
Left(entry)
} else {
@ -100,8 +99,8 @@ fn warn_if_multiple_versions(e: @mut Env,
for matches.iter().advance |match_| {
diag.span_note(match_.span, "used here");
let attrs = ~[
attr::mk_attr(attr::mk_list_item(
@"link", /*bad*/copy *match_.metas))
attr::mk_attr(attr::mk_list_item(@"link",
(*match_.metas).clone()))
];
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) => {
debug!("resolving extern mod stmt. ident: %?, meta: %?",
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);
}
_ => ()
@ -306,8 +309,8 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map {
let cmetas = metas_with(dep.vers, @"vers", ~[]);
debug!("resolving dep crate %s ver: %s hash: %s",
cname_str, dep.vers, dep.hash);
match existing_match(e, metas_with_ident(cname_str,
copy cmetas),
match existing_match(e,
metas_with_ident(cname_str, cmetas.clone()),
dep.hash) {
Some(local_cnum) => {
debug!("already have it");

View File

@ -91,12 +91,13 @@ pub fn iter_crate_data(cstore: &CStore,
pub fn add_used_crate_file(cstore: &mut CStore, lib: &Path) {
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] {
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 {
@ -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)
}
#[deriving(Clone)]
struct crate_hash {
name: @str,
vers: @str,
hash: @str,
}
// returns hashes of crates directly used by this crate. Hashes are sorted by
// (crate name, crate version, crate hash) in lexicographic order (not semver)
pub fn get_dep_hashes(cstore: &CStore) -> ~[@str] {
struct crate_hash { name: @str, vers: @str, hash: @str }
let mut result = ~[];
for cstore.extern_mod_crate_map.each_value |&cnum| {

View File

@ -714,7 +714,7 @@ pub fn maybe_get_item_ast(cdata: cmd, tcx: ty::ctxt,
let item_path = item_path(item_doc);
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),
None => {
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);
let name = item_name(intr, item);
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.
};
match variant_disr_val(item) {
@ -1149,6 +1149,7 @@ pub fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] {
return get_attributes(reader::Doc(data));
}
#[deriving(Clone)]
pub struct crate_dep {
cnum: ast::crate_num,
name: ast::ident,

View File

@ -128,6 +128,7 @@ fn encode_region_param(ecx: &EncodeContext,
}
}
#[deriving(Clone)]
struct entry<T> {
val: T,
pos: uint
@ -662,7 +663,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
-> ~[entry<int>] {
/* Each class has its own index, since different classes
may have fields with the same name */
let index = @mut ~[];
let mut index = ~[];
let tcx = ecx.tcx;
/* We encode both private and public fields -- need to include
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));
ebml_w.end_tag();
}
/*bad*/copy *index
index
}
// 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;
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| {
combined_ty_params.push(copy *x)
combined_ty_params.push((*x).clone())
}
let len = combined_ty_params.len();
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,
nitem: @foreign_item,
index: @mut ~[entry<int>],
path: ast_map::path,
path: &ast_map::path,
abi: AbiSet) {
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_name(ecx, ebml_w, nitem.ident);
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 {
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) => {
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_symbol(ecx, ebml_w, nitem.id);
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();
@ -1208,12 +1209,12 @@ fn encode_info_for_items(ecx: &EncodeContext,
visit::visit_crate(crate, ((), visit::mk_vt(@visit::Visitor {
visit_expr: |_e, (_cx, _v)| { },
visit_item: {
let ebml_w = copy *ebml_w;
let ebml_w = (*ebml_w).clone();
|i, (cx, v)| {
visit::visit_item(i, (cx, v));
match items.get_copy(&i.id) {
ast_map::node_item(_, pt) => {
let mut ebml_w = copy ebml_w;
let mut ebml_w = ebml_w.clone();
// See above
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
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: {
let ebml_w = copy *ebml_w;
let ebml_w = (*ebml_w).clone();
|ni, (cx, v)| {
visit::visit_foreign_item(ni, (cx, v));
match items.get_copy(&ni.id) {
@ -1234,14 +1235,14 @@ fn encode_info_for_items(ecx: &EncodeContext,
token::get_ident_interner()),
token::ident_to_str(&ni.ident));
let mut ebml_w = copy ebml_w;
let mut ebml_w = ebml_w.clone();
// See above
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
encode_info_for_foreign_item(ecx,
&mut ebml_w,
ni,
index,
/*bad*/copy *pt,
pt,
abi);
}
// case for separate item and foreign-item tables
@ -1252,24 +1253,24 @@ fn encode_info_for_items(ecx: &EncodeContext,
..*visit::default_visitor()
})));
ebml_w.end_tag();
return /*bad*/copy *index;
return /*bad*/(*index).clone();
}
// Path and definition ID indexing
fn create_index<T:Copy + Hash + IterBytes>(index: ~[entry<T>]) ->
~[@~[entry<T>]] {
fn create_index<T:Clone + Hash + IterBytes>(index: ~[entry<T>])
-> ~[@~[entry<T>]] {
let mut buckets: ~[@mut ~[entry<T>]] = ~[];
for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
for index.iter().advance |elt| {
let h = elt.val.hash() as uint;
buckets[h % 256].push(copy *elt);
buckets[h % 256].push((*elt).clone());
}
let mut buckets_frozen = ~[];
for buckets.iter().advance |bucket| {
buckets_frozen.push(@/*bad*/copy **bucket);
buckets_frozen.push(@/*bad*/(**bucket).clone());
}
return buckets_frozen;
}
@ -1401,7 +1402,7 @@ fn synthesize_crate_attrs(ecx: &EncodeContext,
match attr.node.value.node {
meta_list(_, ref l) => {
found_link_attr = true;;
synthesize_link_attr(ecx, /*bad*/copy *l)
synthesize_link_attr(ecx, (*l).clone())
}
_ => *attr
}

View File

@ -21,8 +21,11 @@ use std::str;
pub type pick<'self, T> = &'self fn(path: &Path) -> Option<T>;
pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
if path.file_path() == file { option::Some(copy *path) }
else { option::None }
if path.file_path() == file {
option::Some((*path).clone())
} else {
option::None
}
}
pub trait FileSearch {

View File

@ -55,11 +55,11 @@ pub struct Context {
pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) {
match find_library_crate(cx) {
Some(ref t) => return (/*bad*/copy *t),
Some(ref t) => return (/*bad*/(*t).clone()),
None => {
cx.diag.span_fatal(
cx.span, fmt!("can't find crate for `%s`",
token::ident_to_str(&cx.ident)));
cx.diag.span_fatal(cx.span,
fmt!("can't find crate for `%s`",
token::ident_to_str(&cx.ident)));
}
}
}

View File

@ -61,7 +61,7 @@ pub fn enc_ty(w: @io::Writer, cx: @ctxt, t: ty::t) {
Some(&s) => s,
None => {
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();
cx.tcx.short_names_cache.insert(t, s);
s
@ -75,7 +75,7 @@ pub fn enc_ty(w: @io::Writer, cx: @ctxt, t: ty::t) {
None => {}
}
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 len = end - pos;
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) {
match st {
fn enc_sty(w: @io::Writer, cx: @ctxt, st: &ty::sty) {
match *st {
ty::ty_nil => w.write_char('n'),
ty::ty_bot => w.write_char('z'),
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);
w.write_char(']');
}
ty::ty_tup(ts) => {
ty::ty_tup(ref ts) => {
w.write_str(&"T[");
for ts.iter().advance |t| { enc_ty(w, cx, *t); }
w.write_char(']');

View File

@ -106,7 +106,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
pub fn decode_inlined_item(cdata: @cstore::crate_metadata,
tcx: ty::ctxt,
maps: Maps,
path: ast_map::path,
path: &[ast_map::path_elt],
par_doc: ebml::Doc)
-> Option<ast::inlined_item> {
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()),
tcx.sess.str_of(ii.ident()));
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);
match ii {
ast::ii_item(i) => {
@ -618,7 +620,7 @@ fn encode_vtable_origin(ecx: &e::EncodeContext,
ebml_w.emit_def_id(def_id)
}
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| {
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,
ii: &ast::inlined_item) {
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
// 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
// it is mutable. But I believe it's harmless since we generate
// balanced EBML.
let mut new_ebml_w = copy new_ebml_w;
let mut new_ebml_w = new_ebml_w.clone();
// See above
let ecx : &e::EncodeContext = unsafe { cast::transmute(ecx_ptr) };
encode_side_tables_for_id(ecx, maps, &mut new_ebml_w, id)

View File

@ -49,6 +49,15 @@ pub mod gather_loans;
pub mod move_data;
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 fn check_crate(

View File

@ -71,6 +71,12 @@ pub struct FlowedMoveData {
#[deriving(Eq)]
pub struct MovePathIndex(uint);
impl Clone for MovePathIndex {
fn clone(&self) -> MovePathIndex {
MovePathIndex(**self)
}
}
static InvalidMovePathIndex: MovePathIndex =
MovePathIndex(uint::max_value);
@ -133,9 +139,27 @@ pub struct Assignment {
}
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 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>;
impl MoveData {

View File

@ -194,20 +194,21 @@ pub fn check_expr(sess: Session,
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
// FIXME: Should use the dependency graph when it's available (#1356)
pub fn check_item_recursion(sess: Session,
ast_map: ast_map::map,
def_map: resolve::DefMap,
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 {
root_it: it,
sess: sess,

View File

@ -14,6 +14,7 @@ use middle::ty;
use syntax::ast::*;
use syntax::visit;
#[deriving(Clone)]
pub struct Context {
in_loop: bool,
can_ret: bool

View File

@ -473,7 +473,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
left_ty: ty::t)
-> Option<~[@pat]> {
// 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 {
pat{id: pat_id, node: n, span: pat_span} =>
match n {

View File

@ -238,7 +238,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
capture_map: @mut HashMap::new()
};
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 {
item_static(_, ast::m_imm, const_expr) => Some(const_expr),
_ => None
@ -275,7 +275,7 @@ pub fn process_crate(crate: &ast::crate,
// FIXME (#33): this doesn't handle big integer/float literals correctly
// (nor does the rest of our literal handling).
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum const_val {
const_float(f64),
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_str(_)) => Err(~"Negate on string"),
Ok(const_bool(_)) => Err(~"Negate on boolean"),
ref err => (/*bad*/copy *err)
ref err => ((*err).clone())
}
}
expr_unary(_, not, inner) => {
@ -410,28 +410,34 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &expr)
expr_cast(base, _) => {
let ety = tcx.expr_ty(e);
let base = eval_const_expr_partial(tcx, base);
match /*bad*/copy base {
match base {
Err(_) => base,
Ok(val) => {
match ty::get(ety).sty {
ty::ty_float(_) => match val {
const_uint(u) => Ok(const_float(u as f64)),
const_int(i) => Ok(const_float(i as f64)),
const_float(_) => base,
_ => Err(~"Can't cast float to str"),
},
ty::ty_uint(_) => match val {
const_uint(_) => base,
const_int(i) => Ok(const_uint(i as u64)),
const_float(f) => Ok(const_uint(f as u64)),
_ => Err(~"Can't cast str to uint"),
},
ty::ty_int(_) | ty::ty_bool => match val {
const_uint(u) => Ok(const_int(u as i64)),
const_int(_) => base,
const_float(f) => Ok(const_int(f as i64)),
_ => Err(~"Can't cast str to int"),
},
ty::ty_float(_) => {
match val {
const_uint(u) => Ok(const_float(u as f64)),
const_int(i) => Ok(const_float(i as f64)),
const_float(f) => Ok(const_float(f)),
_ => Err(~"Can't cast float to str"),
}
}
ty::ty_uint(_) => {
match val {
const_uint(u) => Ok(const_uint(u)),
const_int(i) => Ok(const_uint(i as u64)),
const_float(f) => Ok(const_uint(f as u64)),
_ => Err(~"Can't cast str to uint"),
}
}
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")
}
}

View File

@ -30,6 +30,7 @@ use middle::ty;
use middle::typeck;
use util::ppaux::Repr;
#[deriving(Clone)]
pub struct DataFlowContext<O> {
priv tcx: ty::ctxt,
priv method_map: typeck::method_map,
@ -294,8 +295,8 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
}
}
impl<O:DataFlowOperator+Copy+'static> DataFlowContext<O> {
// ^^^^^^^^^^^^ only needed for pretty printing
impl<O:DataFlowOperator+Clone+'static> DataFlowContext<O> {
// ^^^^^^^^^^^^^ only needed for pretty printing
pub fn propagate(&mut self, blk: &ast::blk) {
//! Performs the data flow analysis.
@ -304,23 +305,25 @@ impl<O:DataFlowOperator+Copy+'static> DataFlowContext<O> {
return;
}
let mut propcx = PropagationContext {
dfcx: self,
changed: true
};
{
let mut propcx = PropagationContext {
dfcx: self,
changed: true
};
let mut temp = vec::from_elem(self.words_per_id, 0);
let mut loop_scopes = ~[];
let mut temp = vec::from_elem(self.words_per_id, 0u);
let mut loop_scopes = ~[];
while propcx.changed {
propcx.changed = false;
propcx.reset(temp);
propcx.walk_block(blk, temp, &mut loop_scopes);
while propcx.changed {
propcx.changed = false;
propcx.reset(temp);
propcx.walk_block(blk, temp, &mut loop_scopes);
}
}
debug!("Dataflow result:");
debug!("%s", {
let this = @copy *self;
let this = @(*self).clone();
this.pretty_print_to(io::stderr(), blk);
""
});
@ -897,7 +900,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
// statement.
let initial_state = reslice(in_out).to_owned();
for pats.iter().advance |&pat| {
let mut temp = copy initial_state;
let mut temp = initial_state.clone();
self.walk_pat(pat, temp, loop_scopes);
join_bits(&self.dfcx.oper, temp, in_out);
}

View File

@ -79,7 +79,7 @@ fn collect_freevars(def_map: resolve::DefMap, blk: &ast::blk)
visit_expr: walk_expr,
.. *visit::default_visitor()});
(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

View File

@ -53,6 +53,7 @@ use syntax::{visit, ast_util};
pub static try_adding: &'static str = "Try adding a move";
#[deriving(Clone)]
pub struct Context {
tcx: ty::ctxt,
method_map: typeck::method_map,

View File

@ -67,7 +67,7 @@ use syntax::{ast, visit, ast_util};
* item that's being warned about.
*/
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum lint {
ctypes,
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 {
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,
r: &ast::expr) -> bool {
fn check_limits(cx: &Context,
binop: ast::binop,
l: @ast::expr,
r: @ast::expr)
-> bool {
let (lit, expr, swap) = match (&l.node, &r.node) {
(&ast::expr_lit(_), _) => (l, r, true),
(_, &ast::expr_lit(_)) => (r, l, false),
@ -666,7 +669,7 @@ fn lint_type_limits() -> visit::vt<@mut Context> {
} else {
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) => {
let (min, max) = int_ty_range(int_ty);
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_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| {
match e.node {
ast::expr_binary(_, ref binop, @ref l, @ref r) => {
ast::expr_binary(_, ref binop, l, r) => {
if is_comparison(*binop)
&& !check_limits(cx, *binop, l, r) {
cx.span_lint(type_limits, e.span,

View File

@ -128,6 +128,12 @@ struct Variable(uint);
#[deriving(Eq)]
struct LiveNode(uint);
impl Clone for LiveNode {
fn clone(&self) -> LiveNode {
LiveNode(**self)
}
}
#[deriving(Eq)]
enum LiveNodeKind {
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
// the same basic propagation framework in all cases.
#[deriving(Clone)]
struct Users {
reader: LiveNode,
writer: LiveNode,

View File

@ -170,12 +170,14 @@ pub type MovesMap = @mut HashSet<node_id>;
pub type MovedVariablesSet = @mut HashSet<node_id>;
/** See the section Output on the module comment for explanation. */
#[deriving(Clone)]
pub struct MoveMaps {
moves_map: MovesMap,
moved_variables_set: MovedVariablesSet,
capture_map: CaptureMap
}
#[deriving(Clone)]
struct VisitContext {
tcx: ty::ctxt,
method_map: method_map,

View File

@ -376,7 +376,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
visit_item: |item, (method_map, visitor)| {
// Do not check privacy inside items with the resolve_unexported
// 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") {
visit::visit_item(item, (method_map, visitor));
}

View File

@ -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
// marked reachable. If we're in a private context, then only trait
// implementations are marked reachable.
#[deriving(Eq)]
#[deriving(Clone, Eq)]
enum PrivacyContext {
PublicContext,
PrivateContext,

View File

@ -60,6 +60,7 @@ pub struct RegionMaps {
priv cleanup_scopes: HashSet<ast::node_id>
}
#[deriving(Clone)]
pub struct Context {
sess: Session,
def_map: resolve::DefMap,

View File

@ -158,6 +158,7 @@ pub enum ImportDirectiveSubclass {
}
/// The context that we thread through while building the reduced graph.
#[deriving(Clone)]
pub enum ReducedGraphParent {
ModuleReducedGraphParent(@mut Module)
}
@ -1483,12 +1484,13 @@ impl Resolver {
for source_idents.iter().advance |source_ident| {
let name = source_ident.node.name;
let subclass = @SingleImport(name, name);
self.build_import_directive(privacy,
module_,
copy module_path,
subclass,
source_ident.span,
source_ident.node.id);
self.build_import_directive(
privacy,
module_,
module_path.clone(),
subclass,
source_ident.span,
source_ident.node.id);
}
}
view_path_glob(_, id) => {
@ -5165,13 +5167,13 @@ impl Resolver {
match self.method_map.find(&name) {
Some(candidate_traits) => loop {
// Look for the current trait.
match /*bad*/copy self.current_trait_refs {
Some(trait_def_ids) => {
match self.current_trait_refs {
Some(ref trait_def_ids) => {
for trait_def_ids.iter().advance |trait_def_id| {
if candidate_traits.contains(trait_def_id) {
self.add_trait_info(
&mut found_traits,
*trait_def_id, name);
self.add_trait_info(&mut found_traits,
*trait_def_id,
name);
}
}
}
@ -5428,10 +5430,9 @@ pub fn resolve_crate(session: Session,
-> CrateMap {
let resolver = @mut Resolver(session, lang_items, crate);
resolver.resolve();
let Resolver { def_map, export_map2, trait_map, _ } = copy *resolver;
CrateMap {
def_map: def_map,
exp_map2: export_map2,
trait_map: trait_map
def_map: resolver.def_map,
exp_map2: resolver.export_map2,
trait_map: resolver.trait_map.clone(),
}
}

View File

@ -76,7 +76,7 @@
*
* let a: A = ...;
* 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*`
* 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) => {
if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
// XXX: Must we clone?
match *subpats {
None => Some(vec::from_elem(variant_size, dummy)),
_ => copy *subpats
_ => (*subpats).clone(),
}
} else {
None
@ -597,7 +598,7 @@ pub fn enter_opt<'r>(bcx: block,
let n = before.len() + after.len();
let i = before.len();
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)
} else {
None
@ -606,7 +607,7 @@ pub fn enter_opt<'r>(bcx: block,
None => {
let n = before.len();
if opt_eq(tcx, &vec_len_eq(n), opt) {
Some(copy *before)
Some((*before).clone())
} else {
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()};
do enter_match(bcx, dm, m, col, val) |p| {
match p.node {
ast::pat_tup(ref elts) => {
Some(copy *elts)
}
ast::pat_tup(ref elts) => Some((*elts).clone()),
_ => {
assert_is_binding_or_wild(bcx, p);
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()};
do enter_match(bcx, dm, m, col, val) |p| {
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);
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,
val, test_val);
size = args.vals.len();
unpacked = /*bad*/copy args.vals;
unpacked = args.vals.clone();
opt_cx = args.bcx;
}
lit(_) | range(_, _) => ()
@ -1606,7 +1605,7 @@ pub fn compile_submatch(bcx: block,
pub fn trans_match(bcx: block,
match_expr: &ast::expr,
discr_expr: @ast::expr,
arms: ~[ast::arm],
arms: &[ast::arm],
dest: Dest) -> block {
let _icx = push_ctxt("match::trans_match");
do with_scope(bcx, match_expr.info(), "match") |bcx| {

View File

@ -191,9 +191,11 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
Some(ptrfield) => {
return NullablePointer {
nndiscr: discr,
nonnull: mk_struct(cx, cases[discr].tys, false),
nonnull: mk_struct(cx,
cases[discr].tys,
false),
ptrfield: ptrfield,
nullfields: copy cases[1 - discr].tys
nullfields: cases[1 - discr].tys.clone()
}
}
None => { }

View File

@ -112,7 +112,7 @@ impl Drop for _InsnCtxt {
fn drop(&self) {
do local_data::modify(task_local_insn_key) |c| {
do c.map_consume |ctx| {
let mut ctx = copy *ctx;
let mut ctx = (*ctx).clone();
ctx.pop();
@ctx
}
@ -124,7 +124,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
debug!("new InsnCtxt: %s", s);
do local_data::modify(task_local_insn_key) |c| {
do c.map_consume |ctx| {
let mut ctx = copy *ctx;
let mut ctx = (*ctx).clone();
ctx.push(s);
@ctx
}
@ -1413,7 +1413,7 @@ pub fn with_scope(bcx: block,
let scope = simple_block_scope(bcx.scope, opt_node_info);
bcx.scope = Some(scope);
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;
ret
}
@ -1427,7 +1427,9 @@ pub fn with_scope_result(bcx: block,
let scope = simple_block_scope(bcx.scope, opt_node_info);
bcx.scope = Some(scope);
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;
rslt(out_bcx, val)
@ -1932,7 +1934,7 @@ pub fn trans_fn(ccx: @mut CrateContext,
let _icx = push_ctxt("trans_fn");
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
trans_closure(ccx,
copy path,
path.clone(),
decl,
body,
llfndecl,
@ -2038,7 +2040,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
let fn_args = do args.map |varg| {
ast::arg {
is_mutbl: false,
ty: copy *varg.ty(),
ty: (*varg.ty()).clone(),
pat: ast_util::ident_to_pat(
ccx.tcx.sess.next_node_id(),
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 {
Some(ref substs) => { copy substs.tys }
None => ~[]
Some(ref substs) => {
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));
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 {
let llfndecl = get_item_val(ccx, item.id);
foreign::trans_foreign_fn(ccx,
vec::append(/*bad*/copy *path,
vec::append((*path).clone(),
[path_name(item.ident)]),
decl,
body,
@ -2139,7 +2150,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
} else if !generics.is_type_parameterized() {
let llfndecl = get_item_val(ccx, item.id);
trans_fn(ccx,
vec::append(/*bad*/copy *path, [path_name(item.ident)]),
vec::append((*path).clone(), [path_name(item.ident)]),
decl,
body,
llfndecl,
@ -2160,8 +2171,12 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
}
}
ast::item_impl(ref generics, _, _, ref ms) => {
meth::trans_impl(ccx, /*bad*/copy *path, item.ident, *ms,
generics, item.id);
meth::trans_impl(ccx,
(*path).clone(),
item.ident,
*ms,
generics,
item.id);
}
ast::item_mod(ref 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") {
path_elt_to_str(*path.last(), token::get_ident_interner())
} 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);
@ -2432,7 +2447,7 @@ pub fn item_path(ccx: &CrateContext, i: &ast::item) -> path {
// separate map for paths?
_ => 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 {
@ -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 val = match item {
ast_map::node_item(i, pth) => {
let my_path = vec::append(/*bad*/copy *pth,
[path_name(i.ident)]);
let my_path = vec::append((*pth).clone(), [path_name(i.ident)]);
match i.node {
ast::item_static(_, m, expr) => {
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 {
ast::foreign_item_fn(*) => {
register_fn(ccx, ni.span,
vec::append(/*bad*/copy *pth,
vec::append((*pth).clone(),
[path_name(ni.ident)]),
ni.id,
ni.attrs)
@ -2526,7 +2540,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
match v.node.kind {
ast::tuple_variant_kind(ref args) => {
assert!(args.len() != 0u);
let pth = vec::append(/*bad*/copy *pth,
let pth = vec::append((*pth).clone(),
[path_name(enm.ident),
path_name((*v).node.name)]);
llfn = match enm.node {
@ -2554,7 +2568,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
Some(ctor_id) => {
let llfn = register_fn(ccx,
struct_item.span,
/*bad*/copy *struct_path,
(*struct_path).clone(),
ctor_id,
struct_item.attrs);
set_inline_hint(llfn);
@ -2583,7 +2597,7 @@ pub fn register_method(ccx: @mut CrateContext,
m: @ast::method) -> ValueRef {
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(m.ident));
@ -2603,7 +2617,7 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
let mut i = 0;
let path = item_path(ccx, it);
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(special_idents::descrim)
]);

View File

@ -897,7 +897,7 @@ pub fn add_span_comment(bcx: block, sp: span, text: &str) {
let ccx = bcx.ccx();
if ccx.sess.asm_comments() {
let s = fmt!("%s (%s)", text, ccx.sess.codemap.span_to_str(sp));
debug!("%s", copy s);
debug!("%s", s);
add_comment(bcx, s);
}
}

View File

@ -22,6 +22,7 @@ pub trait ABIInfo {
fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType;
}
#[deriving(Clone)]
pub struct LLVMType {
cast: bool,
ty: Type

View File

@ -24,7 +24,7 @@ use std::option::Option;
use std::uint;
use std::vec;
#[deriving(Eq)]
#[deriving(Clone, Eq)]
enum RegClass {
NoClass,
Int,

View File

@ -221,7 +221,7 @@ fn resolve_default_method_vtables(bcx: block,
// Build up a param_substs that we are going to resolve the
// trait_vtables under.
let param_substs = Some(@param_substs {
tys: copy substs.tps,
tys: substs.tps.clone(),
self_ty: substs.self_ty,
vtables: impl_vtables,
self_vtable: None

View File

@ -423,11 +423,11 @@ pub fn trans_expr_fn(bcx: block,
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));
// XXX: Bad copy.
let s = mangle_internal_name_by_path_and_seq(ccx,
copy sub_path,
sub_path.clone(),
"expr_fn");
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);

View File

@ -287,7 +287,7 @@ pub enum heap {
heap_exchange_closure
}
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum cleantype {
normal_exit_only,
normal_exit_and_unwind
@ -298,8 +298,19 @@ pub enum cleanup {
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
// target: none means the path ends in an resume instruction
#[deriving(Clone)]
pub struct cleanup_path {
target: Option<BasicBlockRef>,
size: uint,
@ -441,7 +452,7 @@ pub fn revoke_clean(cx: block, val: ValueRef) {
pub fn block_cleanups(bcx: block) -> ~[cleanup] {
match bcx.scope {
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 {
@vts.iter().transform(|ds|
@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_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
// 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 {
resolve_vtable_under_param_substs(fcx.ccx.tcx,
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,
param_substs: Option<@param_substs>,
vt: typeck::vtable_origin)
-> typeck::vtable_origin {
match vt {
typeck::vtable_static(trait_id, tys, sub) => {
vt: &typeck::vtable_origin)
-> typeck::vtable_origin {
match *vt {
typeck::vtable_static(trait_id, ref tys, sub) => {
let tys = match param_substs {
Some(substs) => {
do tys.iter().transform |t| {
ty::subst_tps(tcx, substs.tys, substs.self_ty, *t)
}.collect()
}
_ => tys
_ => tys.to_owned()
};
typeck::vtable_static(
trait_id, tys,
@ -1085,7 +1098,7 @@ pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
match param_substs {
Some(@param_substs
{self_vtable: Some(ref self_vtable), _}) => {
copy *self_vtable
(*self_vtable).clone()
}
_ => {
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: &param_substs,
n_param: uint, n_bound: uint)
-> typeck::vtable_origin {
pub fn find_vtable(tcx: ty::ctxt,
ps: &param_substs,
n_param: uint,
n_bound: uint)
-> typeck::vtable_origin {
debug!("find_vtable(n_param=%u, n_bound=%u, ps=%s)",
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 {

View File

@ -816,8 +816,8 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
debug!("create_ty: %?", ty::get(t));
let sty = copy ty::get(t).sty;
let ty_md = match sty {
let sty = &ty::get(t).sty;
let ty_md = match *sty {
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_estr(ref vstore) => {

View File

@ -570,8 +570,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
return controlflow::trans_if(bcx, cond, thn, els, dest);
}
ast::expr_match(discr, ref arms) => {
return _match::trans_match(bcx, expr, discr, /*bad*/copy *arms,
dest);
return _match::trans_match(bcx, expr, discr, *arms, dest);
}
ast::expr_block(ref blk) => {
return do base::with_scope(bcx, blk.info(),

View File

@ -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 {
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")
};
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");
fn build_rust_fn(ccx: @mut CrateContext,
path: ast_map::path,
path: &ast_map::path,
decl: &ast::fn_decl,
body: &ast::blk,
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);
// XXX: Bad copy.
let ps = link::mangle_internal_name_by_path(
ccx, vec::append_one(copy path, ast_map::path_name(
special_idents::clownshoe_abi
)));
ccx,
vec::append_one((*path).clone(),
ast_map::path_name(
special_idents::clownshoe_abi)));
let llty = type_of_fn_from_ty(ccx, t);
let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty);
trans_fn(ccx,
path,
(*path).clone(),
decl,
body,
llfndecl,
@ -1318,7 +1319,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
let tys = shim_types(ccx, id);
// The internal Rust ABI function - runs on the Rust stack
// 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
let llshimfn = build_shim_fn(ccx, path, llrustfn, &tys);
// 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);
do tys.fn_ty.decl_fn |fnty| {
// XXX(pcwalton): We should not copy the path.
register_fn_fuller(ccx,
sp,
/*bad*/copy path,
path.clone(),
node_id,
attrs,
t,

View File

@ -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
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
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
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
let params = unsafe {

View File

@ -44,8 +44,7 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id)
csearch::maybe_get_item_ast(
ccx.tcx, fn_id,
|a,b,c,d| {
astencode::decode_inlined_item(a, b, ccx.maps,
/*bad*/ copy c, d)
astencode::decode_inlined_item(a, b, ccx.maps, c.clone(), d)
});
return match csearch_result {
csearch::not_found => {

View File

@ -60,7 +60,7 @@ pub fn trans_impl(ccx: @mut CrateContext,
for methods.iter().advance |method| {
if method.generics.ty_params.len() == 0u {
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));
trans_method(ccx,
@ -72,18 +72,17 @@ pub fn trans_impl(ccx: @mut CrateContext,
}
}
/**
Translates a (possibly monomorphized) method body.
# Parameters
- `path`: the path to the method
- `method`: the AST node for the method
- `param_substs`: if this is a generic method, the current values for
type parameters and so forth, else none
- `llfn`: the LLVM ValueRef for the method
- `impl_id`: the node ID of the impl this method is inside
*/
/// Translates a (possibly monomorphized) method body.
///
/// Parameters:
/// * `path`: the path to the method
/// * `method`: the AST node for the method
/// * `param_substs`: if this is a generic method, the current values for
/// type parameters and so forth, else none
/// * `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,
path: path,
method: &ast::method,
@ -226,9 +225,13 @@ pub fn trans_method_callee(bcx: block,
match bcx.fcx.param_substs {
Some(@param_substs
{self_vtable: Some(ref vtbl), _}) => {
trans_monomorphized_callee(bcx, callee_id, this, mentry,
trait_id, method_index,
copy *vtbl)
trans_monomorphized_callee(bcx,
callee_id,
this,
mentry,
trait_id,
method_index,
(*vtbl).clone())
}
_ => {
fail!("trans_method_callee: missing self_vtable")
@ -503,7 +506,7 @@ pub fn trans_trait_callee(bcx: block,
self_expr: @ast::expr,
store: ty::TraitStore,
explicit_self: ast::explicit_self_)
-> Callee {
-> Callee {
//!
//
// 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 {
&typeck::vtable_static(impl_id, ref substs, sub_vtables) => {
let psubsts = param_substs {
tys: copy *substs,
tys: (*substs).clone(),
vtables: Some(sub_vtables),
self_ty: None,
self_vtable: None
@ -733,7 +736,7 @@ pub fn make_impl_vtable(bcx: block,
let fty = ty::subst_tps(tcx,
substs,
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) {
debug!("(making impl vtable) method has self or type params: %s",
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));
// Store the vtable into the pair or triple.
let orig = /*bad*/copy ccx.maps.vtable_map.get(&id)[0][0];
let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig);
let orig = ccx.maps.vtable_map.get(&id)[0][0].clone();
let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, &orig);
let vtable = get_vtable(bcx, v_ty, orig);
Store(bcx, vtable, PointerCast(bcx,
GEPi(bcx, lldest, [0u, abi::trt_field_vtable]),

View File

@ -210,13 +210,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
ccx.monomorphizing.insert(fn_id, depth + 1);
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);
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);
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);
lldecl
};
@ -227,7 +227,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
_
}, _) => {
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,
pt,
decl,
@ -255,8 +255,13 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
set_inline_hint(d);
match v.node.kind {
ast::tuple_variant_kind(ref args) => {
trans_enum_variant(ccx, enum_item.id, v, /*bad*/copy *args,
this_tv.disr_val, Some(psubsts), d);
trans_enum_variant(ccx,
enum_item.id,
v,
(*args).clone(),
this_tv.disr_val,
Some(psubsts),
d);
}
ast::struct_variant_kind(_) =>
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, _, _) => {
// XXX: What should the self type be here?
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);
d
}
ast_map::node_trait_method(@ast::provided(mth), _, pt) => {
let d = mk_lldecl();
set_inline_hint_if_appr(/*bad*/copy mth.attrs, d);
meth::trans_method(ccx, /*bad*/copy *pt, mth, Some(psubsts), d);
set_inline_hint_if_appr(mth.attrs.clone(), d);
meth::trans_method(ccx, (*pt).clone(), mth, Some(psubsts), d);
d
}
ast_map::node_struct_ctor(struct_def, _, _) => {
let d = mk_lldecl();
set_inline_hint(d);
base::trans_tuple_struct(ccx,
/*bad*/copy struct_def.fields,
struct_def.fields,
struct_def.ctor_id.expect("ast-mapped tuple struct \
didn't have a ctor id"),
Some(psubsts),
@ -372,7 +377,7 @@ pub fn make_mono_id(ccx: @mut CrateContext,
Some(vts) => {
debug!("make_mono_id vtables=%s substs=%s",
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());
vts_iter.zip(substs_iter).transform(|(vtable, subst)| {
let v = vtable.map(|vt| meth::vtable_id(ccx, vt));

View File

@ -92,7 +92,7 @@ impl Reflector {
*self.visitor_methods).expect(fmt!("Couldn't find visit method \
for %s", ty_name));
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;
debug!("passing %u args:", args.len());
let mut bcx = self.bcx;

View File

@ -25,7 +25,7 @@ use std::cast;
use std::libc::{c_uint};
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub struct Type {
priv rf: TypeRef
}

View File

@ -83,7 +83,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
let cx = Context {
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
@ -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) {
Some(x) => (/*bad*/copy *x),
None => ccx.sess.bug(fmt!("type_uses_for: unbound item ID %?",
fn_id_loc))
Some(x) => {
(*x).clone()
}
None => {
ccx.sess.bug(fmt!("type_uses_for: unbound item ID %?",
fn_id_loc))
}
};
match map_node {
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(_, _, _) => {
for uint::range(0u, n_tps) |n| { cx.uses[n] |= use_repr;}
}
ast_map::node_foreign_item(i@@foreign_item { node: foreign_item_fn(*),
_ },
abi,
_,
_) => {
ast_map::node_foreign_item(i@@foreign_item {
node: foreign_item_fn(*),
_
},
abi,
_,
_) => {
if abi.is_intrinsic() {
let nm = cx.ccx.sess.str_of(i.ident);
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,
// 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")
}
};
@ -169,8 +177,8 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
}
}
ast_map::node_struct_ctor(*) => {
// Similarly to node_variant, this monomorphized function just uses
// the representations of all of its type parameters.
// Similarly to node_variant, this monomorphized function just
// uses the representations of all of its type parameters.
for uint::range(0, n_tps) |n| { cx.uses[n] |= use_repr; }
}
_ => {

View File

@ -96,13 +96,13 @@ impl Method {
}
}
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct mt {
ty: t,
mutbl: ast::mutability,
}
#[deriving(Eq, Encodable, Decodable, IterBytes)]
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum vstore {
vstore_fixed(uint),
vstore_uniq,
@ -110,7 +110,7 @@ pub enum vstore {
vstore_slice(Region)
}
#[deriving(Eq, IterBytes, Encodable, Decodable)]
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
pub enum TraitStore {
BoxTraitStore, // @Trait
UniqTraitStore, // ~Trait
@ -119,7 +119,7 @@ pub enum TraitStore {
// XXX: This should probably go away at some point. Maybe after destructors
// do?
#[deriving(Eq, Encodable, Decodable)]
#[deriving(Clone, Eq, Encodable, Decodable)]
pub enum SelfMode {
ByCopy,
ByRef,
@ -177,8 +177,12 @@ pub enum ast_ty_to_ty_cache_entry {
pub type opt_region_variance = Option<region_variance>;
#[deriving(Eq, Decodable, Encodable)]
pub enum region_variance { rv_covariant, rv_invariant, rv_contravariant }
#[deriving(Clone, Eq, Decodable, Encodable)]
pub enum region_variance {
rv_covariant,
rv_invariant,
rv_contravariant,
}
#[deriving(Decodable, Encodable)]
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 }
#[deriving(Eq,IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct BareFnTy {
purity: ast::purity,
abis: AbiSet,
sig: FnSig
}
#[deriving(Eq,IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct ClosureTy {
purity: ast::purity,
sigil: ast::Sigil,
@ -390,21 +394,21 @@ pub struct ClosureTy {
* - `lifetimes` is the list of region names bound in this fn.
* - `inputs` is the list of arguments and their modes.
* - `output` is the return type. */
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct FnSig {
bound_lifetime_names: OptVec<ast::ident>,
inputs: ~[t],
output: t
}
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct param_ty {
idx: uint,
def_id: def_id
}
/// Representation of regions:
#[deriving(Eq, IterBytes, Encodable, Decodable)]
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
pub enum Region {
/// Bound regions are found (primarily) in function types. They indicate
/// 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 {
scope_id: node_id,
bound_region: bound_region
}
#[deriving(Eq, IterBytes, Encodable, Decodable)]
#[deriving(Clone, Eq, IterBytes, Encodable, Decodable)]
pub enum bound_region {
/// The self region for structs, impls (&T in a type defn or &'self T)
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` type is rather funny in that it can only appear on traits and is
* always substituted away to the implementing type for a trait. */
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct substs {
self_r: opt_region,
self_ty: Option<ty::t>,
@ -557,7 +561,7 @@ mod primitives {
// NB: If you change this, you'll probably want to change the corresponding
// AST structure in libsyntax/ast.rs as well.
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub enum sty {
ty_nil,
ty_bot,
@ -600,22 +604,25 @@ pub struct TraitRef {
substs: substs
}
#[deriving(Eq)]
#[deriving(Clone, Eq)]
pub enum IntVarValue {
IntType(ast::int_ty),
UintType(ast::uint_ty),
}
#[deriving(Clone)]
pub enum terr_vstore_kind {
terr_vec, terr_str, terr_fn, terr_trait
}
#[deriving(Clone)]
pub struct expected_found<T> {
expected: T,
found: T
}
// Data structures used in type unification
#[deriving(Clone)]
pub enum type_err {
terr_mismatch,
terr_purity_mismatch(expected_found<purity>),
@ -657,7 +664,7 @@ pub struct ParamBounds {
pub type BuiltinBounds = EnumSet<BuiltinBound>;
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub enum BuiltinBound {
BoundCopy,
BoundStatic,
@ -689,28 +696,28 @@ impl CLike for BuiltinBound {
}
}
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct TyVid(uint);
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct IntVid(uint);
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub struct FloatVid(uint);
#[deriving(Eq, Encodable, Decodable, IterBytes)]
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub struct RegionVid {
id: uint
}
#[deriving(Eq, IterBytes)]
#[deriving(Clone, Eq, IterBytes)]
pub enum InferTy {
TyVar(TyVid),
IntVar(IntVid),
FloatVar(FloatVid)
}
#[deriving(Encodable, Decodable, IterBytes)]
#[deriving(Clone, Encodable, Decodable, IterBytes)]
pub enum InferRegion {
ReVar(RegionVid),
ReSkolemized(uint, bound_region)
@ -795,6 +802,7 @@ impl ToStr for IntVarValue {
}
}
#[deriving(Clone)]
pub struct TypeParameterDef {
ident: ast::ident,
def_id: ast::def_id,
@ -803,6 +811,7 @@ pub struct TypeParameterDef {
/// Information about the type/lifetime parametesr associated with an item.
/// Analogous to ast::Generics.
#[deriving(Clone)]
pub struct Generics {
type_param_defs: @~[TypeParameterDef],
region_param: Option<region_variance>,
@ -824,6 +833,7 @@ impl Generics {
///
/// - `ty`: the base type. May have reference to the (unsubstituted) bound
/// region `&self` or to (unsubstituted) ty_param types
#[deriving(Clone)]
pub struct ty_param_bounds_and_ty {
generics: Generics,
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));
FnSig {
bound_lifetime_names: copy sig.bound_lifetime_names,
bound_lifetime_names: sig.bound_lifetime_names.clone(),
inputs: args,
output: fldop(sig.output)
}
@ -1314,7 +1324,14 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
}
ty_closure(ref f) => {
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, 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_estr(_) | ty_type | ty_opaque_closure_ptr(_) | ty_err |
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_bare_fn(ref f) => {
ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt),
..copy *f})
ty::mk_bare_fn(cx, BareFnTy {
sig: fold_sig(&f.sig, fldfnt),
purity: f.purity,
abis: f.abis.clone(),
})
}
ty_closure(ref f) => {
ty::mk_closure(cx, ClosureTy {region: fldr(f.region),
sig: fold_sig(&f.sig, fldfnt),
..copy *f})
ty::mk_closure(cx, ClosureTy {
region: fldr(f.region),
sig: fold_sig(&f.sig, fldfnt),
purity: f.purity,
sigil: f.sigil,
onceness: f.onceness,
bounds: f.bounds,
})
}
ref sty => {
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) => {
let variants = enum_variants(cx, did);
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.
let tup_ty = mk_tup(cx, variant.args.clone());
let tup_ty = subst(cx, substs, tup_ty);
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] {
match cx.node_type_substs.find(&id) {
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 {
match get(fty).sty {
ty_bare_fn(ref f) => copy f.sig,
ty_closure(ref f) => copy f.sig,
ty_bare_fn(ref f) => f.sig.clone(),
ty_closure(ref f) => f.sig.clone(),
ref 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
pub fn ty_fn_args(fty: t) -> ~[t] {
match get(fty).sty {
ty_bare_fn(ref f) => copy f.sig.inputs,
ty_closure(ref f) => copy f.sig.inputs,
ty_bare_fn(ref f) => f.sig.inputs.clone(),
ty_closure(ref f) => f.sig.inputs.clone(),
ref 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 {
ty::ty_closure(ref fty) => {
ty::mk_closure(tcx, ClosureTy {
sig: FnSig {output: ret_type, ..copy fty.sig},
..copy *fty
sig: FnSig {output: ret_type, ..fty.sig.clone()},
..(*fty).clone()
})
}
_ => {
@ -2906,7 +2934,7 @@ pub fn adjust_ty(cx: ctxt,
onceness: ast::Many,
region: r,
bounds: ty::AllBuiltinBounds(),
sig: copy b.sig})
sig: b.sig.clone()})
}
ref b => {
cx.sess.bug(
@ -2990,7 +3018,7 @@ pub fn adjust_ty(cx: ctxt,
ty::mk_closure(cx, ClosureTy {
sigil: BorrowedSigil,
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);
}
pub fn method_call_type_param_defs(
tcx: ctxt,
method_map: typeck::method_map,
id: ast::node_id) -> Option<@~[TypeParameterDef]>
{
pub fn method_call_type_param_defs(tcx: ctxt,
method_map: typeck::method_map,
id: ast::node_id)
-> Option<@~[TypeParameterDef]> {
do method_map.find(&id).map |method| {
match method.origin {
typeck::method_static(did) => {
@ -3059,8 +3086,10 @@ pub fn method_call_type_param_defs(
let trait_type_param_defs =
ty::lookup_trait_def(tcx, trt_id).generics.type_param_defs;
@vec::append(
copy *trait_type_param_defs,
*ty::trait_method(tcx, trt_id, n_mth).generics.type_param_defs)
(*trait_type_param_defs).clone(),
*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))
}
fn lookup_locally_or_in_crate_store<V:Copy>(
fn lookup_locally_or_in_crate_store<V:Clone>(
descr: &str,
def_id: ast::def_id,
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) {
Some(&ref v) => { return copy *v; }
Some(&ref v) => { return (*v).clone(); }
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);
}
let v = load_external();
map.insert(def_id, copy v);
return copy v;
map.insert(def_id, v.clone());
v
}
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
#[deriving(Clone)]
pub struct VariantInfo_ {
args: ~[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);
@VariantInfo_{args: substd_args, ctor_ty: substd_ctor_ty,
../*bad*/copy **variant_info}
@VariantInfo_ {
args: substd_args,
ctor_ty: substd_ctor_ty,
..(**variant_info).clone()
}
}.collect()
}
@ -3770,21 +3803,21 @@ pub fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
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) => {
vec::append_one(/*bad*/copy *path,
vec::append_one((*path).clone(),
ast_map::path_name(nitem.ident))
}
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::node_trait_method(trait_method, _, path) => {
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))
}
@ -3794,7 +3827,7 @@ pub fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::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 => {
@ -4193,7 +4226,7 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
ty_closure(ref closure_ty) => {
mk_closure(cx, ClosureTy {
region: ty::re_static,
..copy *closure_ty
..(*closure_ty).clone()
})
}
@ -4205,7 +4238,7 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
substs {
self_r: Some(ty::re_static),
self_ty: None,
tps: /*bad*/copy (*r).tps
tps: (*r).tps.clone()
}),
None =>
t
@ -4217,7 +4250,7 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
// Ditto.
mk_struct(cx, did, substs {self_r: Some(ty::re_static),
self_ty: None,
tps: /*bad*/copy (*r).tps}),
tps: (*r).tps.clone()}),
None =>
t
},
@ -4403,6 +4436,10 @@ pub fn visitor_object_ty(tcx: ctxt) -> Result<(@TraitRef, t), ~str> {
let mut static_trait_bound = EmptyBuiltinBounds();
static_trait_bound.add(BoundStatic);
Ok((trait_ref,
mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs,
BoxTraitStore, ast::m_imm, static_trait_bound)))
mk_trait(tcx,
trait_ref.def_id,
trait_ref.substs.clone(),
BoxTraitStore,
ast::m_imm,
static_trait_bound)))
}

View File

@ -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,
rscope: &RS,
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)
}
fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
fn ast_path_substs<AC:AstConv,RS:region_scope + Clone + 'static>(
this: &AC,
rscope: &RS,
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}
}
pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
this: &AC,
rscope: &RS,
did: ast::def_id,
path: &ast::Path) -> ty_param_substs_and_ty
{
pub fn ast_path_to_substs_and_ty<AC:AstConv,
RS:region_scope + Clone + 'static>(
this: &AC,
rscope: &RS,
did: ast::def_id,
path: &ast::Path)
-> ty_param_substs_and_ty {
let tcx = this.tcx();
let ty::ty_param_bounds_and_ty {
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 }
}
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,
rscope: &RS,
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;
}
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,
rscope: &RS,
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
// internal notion of a type. `getter` is a function that returns the type
// 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 {
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 {
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.
// If a_seq_ty is a str or a vec, make it an estr/evec.
// 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,
rscope: &RS,
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);
return ty::mk_trait(tcx,
result.def_id,
copy result.substs,
result.substs.clone(),
trait_store,
a_seq_ty.mutbl,
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,
RS:region_scope + Copy + 'static>(
RS:region_scope + Clone + 'static>(
this: &AC,
rscope: &RS,
a: &ast::arg,
@ -570,7 +571,7 @@ struct SelfInfo {
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,
rscope: &RS,
purity: ast::purity,
@ -588,7 +589,7 @@ pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + 'static>(
(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,
rscope: &RS,
purity: ast::purity,
@ -601,7 +602,7 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
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,
rscope: &RS,
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
// that function type
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| {
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}
});
fn transform_self_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
fn transform_self_ty<AC:AstConv,RS:region_scope + Clone + 'static>(
this: &AC,
rscope: &RS,
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,
rscope: &RS,
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
// that function type
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 expected_arg_ty = do expected_sig.chain_ref |e| {

View File

@ -120,7 +120,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
// contains type variables.
// 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) => {
// Lookup the enum and variant def ids:
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);
fcx.write_error(pat.id);
kind_name = "[error]";
arg_types = (copy *subpats).get_or_default(~[]).map(|_|
ty::mk_err());
arg_types = (*subpats).clone()
.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);
fcx.write_error(pat.id);
kind_name = "[error]";
arg_types = (copy *subpats).get_or_default(~[]).map(|_|
ty::mk_err());
arg_types = (*subpats).clone()
.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.
let structure = structure_of(fcx, pat.span, expected);
let mut error_happened = false;
match structure {
match *structure {
ty::ty_struct(cid, ref substs) => {
check_struct_pat(pcx, pat.id, pat.span, expected, path,
*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.
if error_happened {
fcx.write_error(pat.id);
}
else {
} else {
fcx.write_ty(pat.id, expected);
}
}
ast::pat_tup(ref elts) => {
let s = structure_of(fcx, pat.span, expected);
let e_count = elts.len();
match s {
match *s {
ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => {
for elts.iter().enumerate().advance |(i, elt)| {
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());
}
// 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::terr_tuple_size(ty::expected_found{expected: ex_elts.len(),
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(
infer::PatternRegion(pat.span));
let (elt_type, region_var) = match structure_of(
fcx, pat.span, expected
) {
let (elt_type, region_var) = match *structure_of(fcx,
pat.span,
expected) {
ty::ty_evec(mt, vstore) => {
let region_var = match vstore {
ty::vstore_slice(r) => r,
@ -626,7 +627,7 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
check_pat(pcx, inner, e_inner.ty);
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 => {
check_inner(e_inner);
}

View File

@ -171,6 +171,7 @@ pub struct LookupContext<'self> {
* A potential method that might be called, assuming the receiver
* is of a suitable type.
*/
#[deriving(Clone)]
pub struct Candidate {
rcvr_ty: ty::t,
rcvr_substs: ty::substs,
@ -384,7 +385,7 @@ impl<'self> LookupContext<'self> {
let cand = Candidate {
rcvr_ty: rcvr_ty,
rcvr_substs: copy bound_trait_ref.substs,
rcvr_substs: bound_trait_ref.substs.clone(),
method_ty: method,
origin: method_param(
method_param {
@ -441,7 +442,7 @@ impl<'self> LookupContext<'self> {
// for Self.
let rcvr_substs = substs {
self_ty: Some(self_ty),
../*bad*/copy *substs
..(*substs).clone()
};
self.inherent_candidates.push(Candidate {
@ -506,7 +507,7 @@ impl<'self> LookupContext<'self> {
};
self.inherent_candidates.push(Candidate {
rcvr_ty: self_ty,
rcvr_substs: copy info.trait_ref.substs,
rcvr_substs: info.trait_ref.substs.clone(),
method_ty: info.method_ty,
origin: origin
});
@ -814,8 +815,9 @@ impl<'self> LookupContext<'self> {
rcvr_ty: ty::t,
candidates: &mut ~[Candidate])
-> Option<method_map_entry> {
// XXX(pcwalton): Do we need to clone here?
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();
let relevant_candidates = self.merge_candidates(relevant_candidates);
@ -840,7 +842,7 @@ impl<'self> LookupContext<'self> {
let mut merged = ~[];
let mut i = 0;
while i < candidates.len() {
let candidate_a = /*bad*/copy candidates[i];
let candidate_a = &candidates[i];
let mut skip = false;
@ -875,7 +877,7 @@ impl<'self> LookupContext<'self> {
// There are more than one of these and we need only one
loop;
} 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,
// which is equal to the class tps + the method tps.
let all_substs = substs {
tps: vec::append(/*bad*/copy candidate.rcvr_substs.tps,
m_substs),
../*bad*/copy candidate.rcvr_substs
tps: vec::append(candidate.rcvr_substs.tps.clone(), m_substs),
self_r: candidate.rcvr_substs.self_r,
self_ty: candidate.rcvr_substs.self_ty,
};
// 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
// signature with region variables
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 => {
tcx.sess.span_bug(
self.expr.span,
@ -979,7 +981,11 @@ impl<'self> LookupContext<'self> {
|br| self.fcx.infcx().next_region_var(
infer::BoundRegionInFnCall(self.expr.span, br)));
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));
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,
method_num: uint) -> ty::t {
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())
}
}

View File

@ -168,6 +168,7 @@ pub struct inherited {
vtable_map: vtable_map,
}
#[deriving(Clone)]
pub enum FnKind {
// This is a for-closure. The ty::t is the return type of the
// enclosing function.
@ -180,6 +181,7 @@ pub enum FnKind {
Vanilla
}
#[deriving(Clone)]
pub struct PurityState {
def: ast::node_id,
purity: ast::purity,
@ -219,6 +221,7 @@ enum AllowOverloadedOperatorsFlag {
DontAllowOverloadedOperators,
}
#[deriving(Clone)]
pub struct FnCtxt {
// Number of errors that had been reported when we started
// 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 {
match self.inh.node_type_substs.find(&id) {
Some(ts) => (/*bad*/copy *ts),
Some(ts) => (*ts).clone(),
None => {
self.tcx().sess.bug(
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);
// Some extra checks to detect weird cycles and so forth:
match sty {
match *sty {
ty::ty_box(inner) | ty::ty_uniq(inner) |
ty::ty_rptr(_, inner) => {
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:
match ty::deref_sty(fcx.ccx.tcx, &sty, false) {
match ty::deref_sty(fcx.ccx.tcx, sty, false) {
None => {
return (t1, autoderefs);
}
@ -1352,28 +1355,35 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
// Extract the function signature from `in_fty`.
let fn_sty = structure_of(fcx, f.span, fn_ty);
let fn_sig = match fn_sty {
ty::ty_bare_fn(ty::BareFnTy {sig: sig, _}) |
ty::ty_closure(ty::ClosureTy {sig: sig, _}) => sig,
// This is the "default" function signature, used in case of error.
// In that case, we check each argument against "error" in order to
// 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| {
fmt!("expected function but \
found `%s`", actual) }, fn_ty, None);
// 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()}
&error_fn_sig
}
};
// Replace any bound regions that appear in the function
// signature with region variables
let (_, _, fn_sig) =
replace_bound_regions_in_fn_sig(
fcx.tcx(), @Nil, None, &fn_sig,
|br| fcx.infcx().next_region_var(
replace_bound_regions_in_fn_sig(fcx.tcx(),
@Nil,
None,
fn_sig,
|br| fcx.infcx()
.next_region_var(
infer::BoundRegionInFnCall(call_expr.span, br)));
// 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
// block syntax lambdas; that is, lambdas without explicit
// 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 (expected_sig,
expected_purity,
@ -1761,10 +1773,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
output: ty::mk_err()
};
ty::mk_err()
}
else {
let fn_ty_copy = copy fn_ty;
fty_sig = copy fn_ty.sig;
} else {
let fn_ty_copy = fn_ty.clone();
fty_sig = fn_ty.sig.clone();
ty::mk_closure(tcx, fn_ty_copy)
};
@ -1795,7 +1806,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
fcx.expr_ty(base));
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) => {
// This is just for fields -- the same code handles
// 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
let tcx = fcx.tcx();
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 {
Some(ty::ty_closure(ref fty)) => {
match fcx.mk_subty(false, infer::Misc(expr.span),
fty.sig.output, ty::mk_bool()) {
result::Ok(_) => {
ty::mk_closure(tcx, ty::ClosureTy {
sig: FnSig {output: ty::mk_nil(),
..copy fty.sig},
..copy *fty
sig: FnSig {
output: ty::mk_nil(),
..fty.sig.clone()
},
..(*fty).clone()
})
}
result::Err(_) => {
@ -2361,13 +2376,13 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
}
ast::deref => {
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 {
Some(mt) => {
oprnd_t = mt.ty
}
None => {
match sty {
match *sty {
ty::ty_enum(*) => {
tcx.sess.span_err(
expr.span,
@ -2564,7 +2579,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
check_loop_body(fcx, expr, expected, loop_body);
}
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 {
Some(ty::ty_closure(_)) => expected.get(),
_ => match expected {
@ -2759,7 +2776,10 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
}
ast::expr_tup(ref elts) => {
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 err_field = false;
@ -2816,7 +2836,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
} else {
let (base_t, derefs) = do_autoderef(fcx, expr.span, raw_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) => {
require_integral(fcx, idx.span, idx_t);
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.
pub fn structure_of(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> ty::sty {
/*bad*/copy ty::get(structurally_resolved_type(fcx, sp, typ)).sty
pub fn structure_of<'a>(fcx: @mut FnCtxt, sp: span, typ: ty::t)
-> &'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 {

View File

@ -132,9 +132,12 @@ fn lookup_vtables(vcx: &VtableContext,
@result
}
fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
id: ast::def_id, substs: ty::substs,
is_early: bool) -> Option<ty::substs> {
fn fixup_substs(vcx: &VtableContext,
location_info: &LocationInfo,
id: ast::def_id,
substs: ty::substs,
is_early: bool)
-> Option<ty::substs> {
let tcx = vcx.tcx();
// use a dummy type just to package up the substs that need fixing up
let t = ty::mk_trait(tcx,
@ -144,7 +147,7 @@ fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
ty::EmptyBuiltinBounds());
do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
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")
}
}
@ -365,7 +368,7 @@ fn lookup_vtable(vcx: &VtableContext,
trait_ref.def_id,
substs,
is_early) {
Some(ref substs) => (/*bad*/copy *substs),
Some(ref substs) => (*substs).clone(),
None => {
assert!(is_early);
// Bail out with a bogus answer
@ -403,10 +406,9 @@ fn lookup_vtable(vcx: &VtableContext,
// the impl as well as the resolved list
// of type substitutions for the target
// trait.
found.push(
vtable_static(im.did,
/*bad*/copy substs_f.tps,
subres));
found.push(vtable_static(im.did,
substs_f.tps.clone(),
subres));
}
}
}
@ -414,14 +416,14 @@ fn lookup_vtable(vcx: &VtableContext,
match found.len() {
0 => { /* fallthrough */ }
1 => { return Some(/*bad*/copy found[0]); }
1 => return Some(found[0].clone()),
_ => {
if !is_early {
vcx.tcx().sess.span_err(
location_info.span,
"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 {
def_id: target_def_id,
substs: ty::substs {
tps: copy target_substs.tps,
tps: target_substs.tps.clone(),
self_r: target_substs.self_r,
self_ty: Some(mt.ty)
}

View File

@ -208,9 +208,10 @@ impl CoherenceChecker {
match item.node {
item_impl(_, ref opt_trait, _, _) => {
let opt_trait : ~[trait_ref] = opt_trait.iter()
.transform(|x| copy *x)
.collect();
let opt_trait : ~[trait_ref] =
opt_trait.iter()
.transform(|x| (*x).clone())
.collect();
self.check_implementation(item, opt_trait);
}
_ => {
@ -358,14 +359,14 @@ impl CoherenceChecker {
let new_generics = ty::Generics {
type_param_defs:
@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),
region_param:
impl_poly_type.generics.region_param
};
let new_polytype = ty::ty_param_bounds_and_ty {
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));
@ -901,7 +902,7 @@ impl CoherenceChecker {
// XXX(sully): We could probably avoid this copy if there are no
// default methods.
let mut methods = copy implementation.methods;
let mut methods = implementation.methods.clone();
self.add_provided_methods_to_impl(&mut methods,
&trait_ref.def_id,
&implementation.did);

View File

@ -86,7 +86,7 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) {
}
pub trait ToTy {
fn to_ty<RS:region_scope + Copy + 'static>(
fn to_ty<RS:region_scope + Clone + 'static>(
&self,
rs: &RS,
ast_ty: &ast::Ty)
@ -94,7 +94,7 @@ pub trait ToTy {
}
impl ToTy for CrateCtxt {
fn to_ty<RS:region_scope + Copy + 'static>(
fn to_ty<RS:region_scope + Clone + 'static>(
&self,
rs: &RS,
ast_ty: &ast::Ty)
@ -309,7 +309,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
// create the type of `foo`, applying the substitution above
let ty = ty::subst(tcx,
&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
// 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
let trait_fty =
ty::mk_bare_fn(
tcx,
ty::BareFnTy {purity: trait_m.fty.purity,
abis: trait_m.fty.abis,
sig: ty::FnSig {
bound_lifetime_names:
copy trait_m.fty.sig.bound_lifetime_names,
inputs: trait_fn_args,
output: trait_m.fty.sig.output
}});
ty::mk_bare_fn(tcx,
ty::BareFnTy {
purity: trait_m.fty.purity,
abis: trait_m.fty.abis,
sig: ty::FnSig {
bound_lifetime_names:
trait_m.fty
.sig
.bound_lifetime_names
.clone(),
inputs: trait_fn_args,
output: trait_m.fty.sig.output
}
});
let impl_fty =
ty::mk_bare_fn(
tcx,
ty::BareFnTy {purity: impl_m.fty.purity,
abis: impl_m.fty.abis,
sig: ty::FnSig {
bound_lifetime_names:
copy impl_m.fty.sig.bound_lifetime_names,
inputs: impl_fn_args,
output: impl_m.fty.sig.output
}});
ty::mk_bare_fn(tcx,
ty::BareFnTy {
purity: impl_m.fty.purity,
abis: impl_m.fty.abis,
sig: ty::FnSig {
bound_lifetime_names:
impl_m.fty
.sig
.bound_lifetime_names
.clone(),
inputs: impl_fn_args,
output: impl_m.fty.sig.output
}
});
// Perform substitutions so that the trait/impl methods are expressed
// in terms of the same set of type/region parameters:
@ -730,8 +738,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
untransformed_rcvr_ty,
rcvr_ast_generics, rcvr_visibility,
&m.generics);
let fty =
ty::mk_bare_fn(tcx, copy mty.fty);
let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
tcx.tcache.insert(
local_def(m.id),
@ -740,7 +747,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
ty_param_bounds_and_ty {
generics: ty::Generics {
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),
region_param: rcvr_ty_generics.region_param
},

View File

@ -275,8 +275,10 @@ impl Coerce {
b.inf_str(self.infcx));
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::OwnedSigil => copy *f,
ty::ty_closure(ref f) if f.sigil == ast::ManagedSigil ||
f.sigil == ast::OwnedSigil => {
(*f).clone()
}
ty::ty_bare_fn(ref f) => {
return self.coerce_from_bare_fn(a, f, b);
}
@ -331,16 +333,16 @@ impl Coerce {
}
let fn_ty_b = match *sty_b {
ty::ty_closure(ref f) => {copy *f}
_ => {
return self.subtype(a, b);
}
ty::ty_closure(ref f) => (*f).clone(),
_ => return self.subtype(a, b),
};
let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
let a_closure = ty::mk_closure(
self.infcx.tcx,
ty::ClosureTy {sig: copy fn_ty_a.sig, ..fn_ty_b});
let a_closure = ty::mk_closure(self.infcx.tcx,
ty::ClosureTy {
sig: fn_ty_a.sig.clone(),
..fn_ty_b
});
if_ok!(self.subtype(a_closure, b));
Ok(Some(adj))
}

View File

@ -241,13 +241,14 @@ pub fn super_substs<C:Combine>(
do this.tps(a.tps, b.tps).chain |tps| {
do this.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
do relate_region_param(this, generics,
a.self_r, b.self_r).chain |self_r|
{
do relate_region_param(this,
generics,
a.self_r,
b.self_r).chain |self_r| {
Ok(substs {
self_r: self_r,
self_ty: self_ty,
tps: /*bad*/copy tps
tps: tps.clone()
})
}
}
@ -425,7 +426,7 @@ pub fn super_fn_sigs<C:Combine>(
.chain |inputs| {
do this.tys(a_f.output, b_f.output).chain |output| {
Ok(FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
inputs: /*bad*/copy inputs,
inputs: inputs.clone(),
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.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
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))
}
}
}

View File

@ -71,39 +71,39 @@ impl LatticeValue for ty::t {
}
pub trait CombineFieldsLatticeMethods {
fn var_sub_var<T:Copy + InferStr + LatticeValue,
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(&self,
a_id: V,
b_id: V)
-> ures;
fn var_sub_var<T:Clone + InferStr + LatticeValue,
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(&self,
a_id: V,
b_id: V)
-> ures;
/// make variable a subtype of T
fn var_sub_t<T:Copy + InferStr + LatticeValue,
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
fn var_sub_t<T:Clone + InferStr + LatticeValue,
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
&self,
a_id: V,
b: T)
-> ures;
fn t_sub_var<T:Copy + InferStr + LatticeValue,
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
fn t_sub_var<T:Clone + InferStr + LatticeValue,
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
&self,
a: T,
b_id: V)
-> ures;
fn merge_bnd<T:Copy + InferStr + LatticeValue>(
fn merge_bnd<T:Clone + InferStr + LatticeValue>(
&self,
a: &Bound<T>,
b: &Bound<T>,
lattice_op: LatticeOp<T>)
-> cres<Bound<T>>;
fn set_var_to_merged_bounds<T:Copy + InferStr + LatticeValue,
V:Copy+Eq+ToStr+Vid+UnifyVid<Bounds<T>>>(
fn set_var_to_merged_bounds<T:Clone + InferStr + LatticeValue,
V:Clone+Eq+ToStr+Vid+UnifyVid<Bounds<T>>>(
&self,
v_id: V,
a: &Bounds<T>,
b: &Bounds<T>,
rank: uint)
-> ures;
fn bnds<T:Copy + InferStr + LatticeValue>(
fn bnds<T:Clone + InferStr + LatticeValue>(
&self,
a: &Bound<T>,
b: &Bound<T>)
@ -111,8 +111,8 @@ pub trait CombineFieldsLatticeMethods {
}
impl CombineFieldsLatticeMethods for CombineFields {
fn var_sub_var<T:Copy + InferStr + LatticeValue,
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
fn var_sub_var<T:Clone + InferStr + LatticeValue,
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
&self,
a_id: V,
b_id: V)
@ -126,10 +126,10 @@ impl CombineFieldsLatticeMethods for CombineFields {
// Need to make sub_id a subtype of sup_id.
let node_a = self.infcx.get(a_id);
let node_b = self.infcx.get(b_id);
let a_id = copy node_a.root;
let b_id = copy node_b.root;
let a_bounds = copy node_a.possible_types;
let b_bounds = copy node_b.possible_types;
let a_id = node_a.root.clone();
let b_id = node_b.root.clone();
let a_bounds = node_a.possible_types.clone();
let b_bounds = node_b.possible_types.clone();
debug!("vars(%s=%s <: %s=%s)",
a_id.to_str(), a_bounds.inf_str(self.infcx),
@ -164,8 +164,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
}
/// make variable a subtype of T
fn var_sub_t<T:Copy + InferStr + LatticeValue,
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
fn var_sub_t<T:Clone + InferStr + LatticeValue,
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
&self,
a_id: V,
b: T)
@ -175,9 +175,9 @@ impl CombineFieldsLatticeMethods for CombineFields {
* Make a variable (`a_id`) a subtype of the concrete type `b` */
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 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)",
a_id.to_str(),
@ -188,8 +188,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
a_id, a_bounds, b_bounds, node_a.rank)
}
fn t_sub_var<T:Copy + InferStr + LatticeValue,
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
fn t_sub_var<T:Clone + InferStr + LatticeValue,
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
&self,
a: T,
b_id: V)
@ -198,9 +198,9 @@ impl CombineFieldsLatticeMethods for CombineFields {
*
* 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 b_id = copy node_b.root;
let b_id = node_b.root.clone();
let b_bounds = &node_b.possible_types;
debug!("t_sub_var(%s <: %s=%s)",
@ -212,7 +212,7 @@ impl CombineFieldsLatticeMethods for CombineFields {
b_id, a_bounds, b_bounds, node_b.rank)
}
fn merge_bnd<T:Copy + InferStr + LatticeValue>(
fn merge_bnd<T:Clone + InferStr + LatticeValue>(
&self,
a: &Bound<T>,
b: &Bound<T>,
@ -229,8 +229,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
match (a, b) {
(&None, &None) => Ok(None),
(&Some(_), &None) => Ok(copy *a),
(&None, &Some(_)) => Ok(copy *b),
(&Some(_), &None) => Ok((*a).clone()),
(&None, &Some(_)) => Ok((*b).clone()),
(&Some(ref v_a), &Some(ref v_b)) => {
do lattice_op(self, v_a, v_b).chain |v| {
Ok(Some(v))
@ -239,8 +239,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
}
}
fn set_var_to_merged_bounds<T:Copy + InferStr + LatticeValue,
V:Copy+Eq+ToStr+Vid+UnifyVid<Bounds<T>>>(
fn set_var_to_merged_bounds<T:Clone + InferStr + LatticeValue,
V:Clone+Eq+ToStr+Vid+UnifyVid<Bounds<T>>>(
&self,
v_id: V,
a: &Bounds<T>,
@ -301,10 +301,10 @@ impl CombineFieldsLatticeMethods for CombineFields {
uok()
}
fn bnds<T:Copy + InferStr + LatticeValue>(&self,
a: &Bound<T>,
b: &Bound<T>)
-> ures {
fn bnds<T:Clone + InferStr + LatticeValue>(&self,
a: &Bound<T>,
b: &Bound<T>)
-> ures {
debug!("bnds(%s <: %s)", a.inf_str(self.infcx),
b.inf_str(self.infcx));
let _r = indenter();
@ -330,8 +330,8 @@ impl CombineFieldsLatticeMethods for CombineFields {
pub trait LatticeDir {
fn combine_fields(&self) -> CombineFields;
fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T>;
fn with_bnd<T:Copy>(&self, b: &Bounds<T>, t: T) -> Bounds<T>;
fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T>;
fn with_bnd<T:Clone>(&self, b: &Bounds<T>, t: T) -> Bounds<T>;
}
pub trait TyLatticeDir {
@ -340,9 +340,9 @@ pub trait TyLatticeDir {
impl LatticeDir for Lub {
fn combine_fields(&self) -> CombineFields { **self }
fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { copy b.ub }
fn with_bnd<T:Copy>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
Bounds { ub: Some(t), ..copy *b }
fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T> { b.ub.clone() }
fn with_bnd<T:Clone>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
Bounds { ub: Some(t), ..(*b).clone() }
}
}
@ -354,9 +354,9 @@ impl TyLatticeDir for Lub {
impl LatticeDir for Glb {
fn combine_fields(&self) -> CombineFields { **self }
fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { copy b.lb }
fn with_bnd<T:Copy>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
Bounds { lb: Some(t), ..copy *b }
fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T> { b.lb.clone() }
fn with_bnd<T:Clone>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
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>;
#[deriving(Clone)]
pub enum LatticeVarResult<V,T> {
VarResult(V),
ValueResult(T)
@ -433,8 +434,8 @@ pub enum LatticeVarResult<V,T> {
* result is a variable. This is indicated with a `VarResult`
* return. */
pub fn lattice_vars<L:LatticeDir + Combine,
T:Copy + InferStr + LatticeValue,
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
T:Clone + InferStr + LatticeValue,
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
this: &L, // defines whether we want LUB or GLB
a_vid: V, // first variable
b_vid: V, // second variable
@ -442,8 +443,8 @@ pub fn lattice_vars<L:LatticeDir + Combine,
-> cres<LatticeVarResult<V,T>> {
let nde_a = this.infcx().get(a_vid);
let nde_b = this.infcx().get(b_vid);
let a_vid = copy nde_a.root;
let b_vid = copy nde_b.root;
let a_vid = nde_a.root.clone();
let b_vid = nde_b.root.clone();
let a_bounds = &nde_a.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
// then use either variable as an upper bound:
let cf = this.combine_fields();
do cf.var_sub_var(copy a_vid, copy b_vid).then {
Ok(VarResult(copy a_vid))
do cf.var_sub_var(a_vid.clone(), b_vid.clone()).then {
Ok(VarResult(a_vid.clone()))
}
}
pub fn lattice_var_and_t<L:LatticeDir + Combine,
T:Copy + InferStr + LatticeValue,
V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
T:Clone + InferStr + LatticeValue,
V:Clone + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
this: &L,
a_id: V,
b: &T,
lattice_dir_op: LatticeDirOp<T>)
-> cres<T> {
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;
// 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
// and then return b.
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 {
this.infcx().set(copy a_id, Root(copy a_bounds, nde_a.rank));
Ok(copy *b)
this.infcx().set(a_id.clone(),
Root(a_bounds.clone(), nde_a.rank));
Ok((*b).clone())
}
}
}

View File

@ -62,6 +62,8 @@ pub mod coercion;
pub mod error_reporting;
pub type Bound<T> = Option<T>;
#[deriving(Clone)]
pub struct Bounds<T> {
lb: Bound<T>,
ub: Bound<T>
@ -96,6 +98,7 @@ pub struct InferCtxt {
/// Why did we require that the two types be related?
///
/// See `error_reporting.rs` for more details
#[deriving(Clone)]
pub enum TypeOrigin {
// Not yet categorized in a better way
Misc(span),
@ -120,6 +123,7 @@ pub enum TypeOrigin {
}
/// See `error_reporting.rs` for more details
#[deriving(Clone)]
pub enum ValuePairs {
Types(ty::expected_found<ty::t>),
TraitRefs(ty::expected_found<@ty::TraitRef>),
@ -129,6 +133,7 @@ pub enum ValuePairs {
/// encounter an error or subtyping constraint.
///
/// See `error_reporting.rs` for more details.
#[deriving(Clone)]
pub struct TypeTrace {
origin: TypeOrigin,
values: ValuePairs,
@ -137,6 +142,7 @@ pub struct TypeTrace {
/// The origin of a `r1 <= r2` constraint.
///
/// See `error_reporting.rs` for more details
#[deriving(Clone)]
pub enum SubregionOrigin {
// Arose from a subtyping relation
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 {
vals: SmallIntMap::new(),
bindings: ~[]
@ -439,12 +445,12 @@ pub fn resolve_region(cx: @mut InferCtxt, r: ty::Region, modes: uint)
}
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>;
}
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> {
self.chain(|_i| f())
}
@ -467,11 +473,11 @@ trait CresCompare<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> {
do (copy *self).chain |s| {
do (*self).clone().chain |s| {
if s == t {
copy *self
(*self).clone()
} else {
Err(f())
}
@ -483,10 +489,8 @@ pub fn uok() -> ures {
Ok(())
}
fn rollback_to<V:Copy + Vid,T:Copy>(
vb: &mut ValsAndBindings<V, T>,
len: uint)
{
fn rollback_to<V:Clone + Vid,T:Clone>(vb: &mut ValsAndBindings<V, T>,
len: uint) {
while vb.bindings.len() != len {
let (vid, old_v) = vb.bindings.pop();
vb.vals.insert(vid.to_uint(), old_v);
@ -588,10 +592,10 @@ impl InferCtxt {
}
}
fn next_simple_var<V:Copy,T:Copy>(
counter: &mut uint,
bindings: &mut ValsAndBindings<V,Option<T>>)
-> uint {
fn next_simple_var<V:Clone,T:Clone>(counter: &mut uint,
bindings: &mut ValsAndBindings<V,
Option<T>>)
-> uint {
let id = *counter;
*counter += 1;
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
let dummy0 = ty::mk_trait(self.tcx,
trait_ref.def_id,
copy trait_ref.substs,
trait_ref.substs.clone(),
ty::UniqTraitStore,
ast::m_imm,
ty::EmptyBuiltinBounds());
let dummy1 = self.resolve_type_vars_if_possible(dummy0);
match ty::get(dummy1).sty {
ty::ty_trait(ref def_id, ref substs, _, _, _) => {
ty::TraitRef {def_id: *def_id,
substs: copy *substs}
ty::TraitRef {
def_id: *def_id,
substs: (*substs).clone(),
}
}
_ => {
self.tcx.sess.bug(

View File

@ -18,6 +18,7 @@ use middle::typeck::infer::InferCtxt;
use middle::typeck::infer::to_str::InferStr;
use syntax::ast;
#[deriving(Clone)]
pub enum VarValue<V, T> {
Redirect(V),
Root(T, uint),
@ -40,18 +41,18 @@ pub trait UnifyVid<T> {
}
pub trait UnifyInferCtxtMethods {
fn get<T:Copy,
V:Copy + Eq + Vid + UnifyVid<T>>(
fn get<T:Clone,
V:Clone + Eq + Vid + UnifyVid<T>>(
&mut self,
vid: V)
-> Node<V, T>;
fn set<T:Copy + InferStr,
V:Copy + Vid + ToStr + UnifyVid<T>>(
fn set<T:Clone + InferStr,
V:Clone + Vid + ToStr + UnifyVid<T>>(
&mut self,
vid: V,
new_v: VarValue<V, T>);
fn unify<T:Copy + InferStr,
V:Copy + Vid + ToStr + UnifyVid<T>>(
fn unify<T:Clone + InferStr,
V:Clone + Vid + ToStr + UnifyVid<T>>(
&mut self,
node_a: &Node<V, T>,
node_b: &Node<V, T>)
@ -59,8 +60,8 @@ pub trait UnifyInferCtxtMethods {
}
impl UnifyInferCtxtMethods for InferCtxt {
fn get<T:Copy,
V:Copy + Eq + Vid + UnifyVid<T>>(
fn get<T:Clone,
V:Clone + Eq + Vid + UnifyVid<T>>(
&mut self,
vid: V)
-> Node<V, T> {
@ -75,14 +76,14 @@ impl UnifyInferCtxtMethods for InferCtxt {
let vb = UnifyVid::appropriate_vals_and_bindings(self);
return helper(tcx, vb, vid);
fn helper<T:Copy, V:Copy+Eq+Vid>(
fn helper<T:Clone, V:Clone+Eq+Vid>(
tcx: ty::ctxt,
vb: &mut ValsAndBindings<V,T>,
vid: V) -> Node<V, T>
{
let vid_u = vid.to_uint();
let var_val = match vb.vals.find(&vid_u) {
Some(&ref var_val) => copy *var_val,
Some(&ref var_val) => (*var_val).clone(),
None => {
tcx.sess.bug(fmt!(
"failed lookup of vid `%u`", vid_u));
@ -90,11 +91,11 @@ impl UnifyInferCtxtMethods for InferCtxt {
};
match var_val {
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 {
// Path compression
vb.vals.insert(vid.to_uint(),
Redirect(copy node.root));
Redirect(node.root.clone()));
}
node
}
@ -105,8 +106,8 @@ impl UnifyInferCtxtMethods for InferCtxt {
}
}
fn set<T:Copy + InferStr,
V:Copy + Vid + ToStr + UnifyVid<T>>(
fn set<T:Clone + InferStr,
V:Clone + Vid + ToStr + UnifyVid<T>>(
&mut self,
vid: V,
new_v: VarValue<V, T>) {
@ -119,13 +120,13 @@ impl UnifyInferCtxtMethods for InferCtxt {
vid.to_str(), new_v.inf_str(self));
let vb = UnifyVid::appropriate_vals_and_bindings(self);
let old_v = copy *vb.vals.get(&vid.to_uint());
vb.bindings.push((copy vid, old_v));
let old_v = (*vb.vals.get(&vid.to_uint())).clone();
vb.bindings.push((vid.clone(), old_v));
vb.vals.insert(vid.to_uint(), new_v);
}
fn unify<T:Copy + InferStr,
V:Copy + Vid + ToStr + UnifyVid<T>>(
fn unify<T:Clone + InferStr,
V:Clone + Vid + ToStr + UnifyVid<T>>(
&mut self,
node_a: &Node<V, T>,
node_b: &Node<V, T>)
@ -141,18 +142,18 @@ impl UnifyInferCtxtMethods for InferCtxt {
if node_a.rank > node_b.rank {
// a has greater rank, so a should become b's parent,
// i.e., b should redirect to a.
self.set(copy node_b.root, Redirect(copy node_a.root));
(copy node_a.root, node_a.rank)
self.set(node_b.root.clone(), Redirect(node_a.root.clone()));
(node_a.root.clone(), node_a.rank)
} else if node_a.rank < node_b.rank {
// b has greater rank, so a should redirect to b.
self.set(copy node_a.root, Redirect(copy node_b.root));
(copy node_b.root, node_b.rank)
self.set(node_a.root.clone(), Redirect(node_b.root.clone()));
(node_b.root.clone(), node_b.rank)
} else {
// If equal, redirect one to the other and increment the
// other's rank.
assert_eq!(node_a.rank, node_b.rank);
self.set(copy node_b.root, Redirect(copy node_a.root));
(copy node_a.root, node_a.rank + 1)
self.set(node_b.root.clone(), Redirect(node_a.root.clone()));
(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 {
fn simple_vars<T:Copy + Eq + InferStr + SimplyUnifiable,
V:Copy + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
fn simple_vars<T:Clone + Eq + InferStr + SimplyUnifiable,
V:Clone + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
&mut self,
a_is_expected: bool,
a_id: V,
b_id: V)
-> ures;
fn simple_var_t<T:Copy + Eq + InferStr + SimplyUnifiable,
V:Copy + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
fn simple_var_t<T:Clone + Eq + InferStr + SimplyUnifiable,
V:Clone + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
&mut self,
a_is_expected: bool,
a_id: V,
@ -196,8 +197,8 @@ pub trait InferCtxtMethods {
}
impl InferCtxtMethods for InferCtxt {
fn simple_vars<T:Copy + Eq + InferStr + SimplyUnifiable,
V:Copy + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
fn simple_vars<T:Clone + Eq + InferStr + SimplyUnifiable,
V:Clone + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
&mut self,
a_is_expected: bool,
a_id: V,
@ -212,20 +213,22 @@ impl InferCtxtMethods for InferCtxt {
let node_a = self.get(a_id);
let node_b = self.get(b_id);
let a_id = copy node_a.root;
let b_id = copy node_b.root;
let a_id = node_a.root.clone();
let b_id = node_b.root.clone();
if a_id == b_id { return uok(); }
let combined = match (&node_a.possible_types, &node_b.possible_types)
{
(&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)) => {
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();
}
fn simple_var_t<T:Copy + Eq + InferStr + SimplyUnifiable,
V:Copy + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
fn simple_var_t<T:Clone + Eq + InferStr + SimplyUnifiable,
V:Clone + Eq + Vid + ToStr + UnifyVid<Option<T>>>(
&mut self,
a_is_expected: bool,
a_id: V,
@ -249,7 +252,7 @@ impl InferCtxtMethods for InferCtxt {
* `b`. */
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 {
None => {
@ -261,7 +264,7 @@ impl InferCtxtMethods for InferCtxt {
if *a_t == b {
return uok();
} else {
return mk_err(a_is_expected, copy *a_t, b);
return mk_err(a_is_expected, (*a_t).clone(), b);
}
}
}

View File

@ -75,7 +75,7 @@ pub mod infer;
pub mod collect;
pub mod coherence;
#[deriving(Encodable, Decodable)]
#[deriving(Clone, Encodable, Decodable)]
pub enum method_origin {
// supertrait method invoked on "self" inside a default method
// 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
// with a bounded trait.
#[deriving(Encodable, Decodable)]
#[deriving(Clone, Encodable, Decodable)]
pub struct method_param {
// the trait containing the method to be invoked
trait_id: ast::def_id,
@ -115,6 +115,7 @@ pub struct method_param {
bound_num: uint,
}
#[deriving(Clone)]
pub struct method_map_entry {
// the type of the self parameter, which is not reflected in the fn type
// (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.
pub type vtable_res = @~[vtable_param_res];
#[deriving(Clone)]
pub enum vtable_origin {
/*
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) {
write_ty_to_tcx(tcx, node_id, tpt.ty);
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());
}
}

View File

@ -30,6 +30,7 @@ pub trait region_scope {
-> Result<ty::Region, RegionError>;
}
#[deriving(Clone)]
pub enum empty_rscope { empty_rscope }
impl region_scope for empty_rscope {
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>);
impl RegionParamNames {
@ -121,6 +123,7 @@ impl RegionParamNames {
}
}
#[deriving(Clone)]
struct RegionParameterization {
variance: ty::region_variance,
region_param_names: RegionParamNames,
@ -143,6 +146,7 @@ impl RegionParameterization {
}
}
#[deriving(Clone)]
pub struct MethodRscope {
explicit_self: ast::explicit_self_,
variance: Option<ty::region_variance>,
@ -166,7 +170,7 @@ impl MethodRscope {
}
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>);
impl type_rscope {
@ -268,11 +273,21 @@ pub struct binding_rscope {
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,
region_param_names: RegionParamNames)
-> binding_rscope {
let base = @copy *this;
let base = @(*this).clone();
let base = base as @region_scope;
binding_rscope {
base: base,

View File

@ -116,6 +116,7 @@ pub mod lib {
// macros.
/*
mod std {
pub use std::clone;
pub use std::cmp;
pub use std::os;
pub use std::str;
@ -184,9 +185,12 @@ Available lint options:
pub fn describe_debug_flags() {
io::println(fmt!("\nAvailable debug options:\n"));
let r = session::debugging_opts_map();
for r.iter().advance |pair| {
let (name, desc, _) = /*bad*/copy *pair;
io::println(fmt!(" -Z %-20s -- %s", name, desc));
for r.iter().advance |tuple| {
match *tuple {
(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.
::std::logging::console_off();
let mut args = /*bad*/copy *args;
let mut args = (*args).clone();
let binary = args.shift().to_managed();
if args.is_empty() { usage(binary); return; }

Some files were not shown because too many files have changed in this diff Show More