librustc: Make vectors no longer implicitly copyable in rustc. r=graydon

~20% perf win for trans on -O0, with other minor improvements across the board.
No effect on -O2.
This commit is contained in:
Patrick Walton 2013-01-07 14:16:52 -08:00
parent 09758f7072
commit 53f41f07ce
100 changed files with 1214 additions and 865 deletions

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back::rpath; use back::rpath;
use driver::session; use driver::session;
use lib::llvm::llvm; use lib::llvm::llvm;
@ -56,11 +57,13 @@ impl output_type : cmp::Eq {
pure fn ne(&self, other: &output_type) -> bool { !(*self).eq(other) } pure fn ne(&self, other: &output_type) -> bool { !(*self).eq(other) }
} }
fn llvm_err(sess: Session, msg: ~str) -> ! unsafe { fn llvm_err(sess: Session, +msg: ~str) -> ! unsafe {
let cstr = llvm::LLVMRustGetLastError(); let cstr = llvm::LLVMRustGetLastError();
if cstr == ptr::null() { if cstr == ptr::null() {
sess.fatal(msg); sess.fatal(msg);
} else { sess.fatal(msg + ~": " + str::raw::from_c_str(cstr)); } } else {
sess.fatal(msg + ~": " + str::raw::from_c_str(cstr));
}
} }
fn WriteOutputFile(sess: Session, fn WriteOutputFile(sess: Session,
@ -147,7 +150,7 @@ pub mod jit {
}; };
let func: fn(++argv: ~[~str]) = cast::transmute(move closure); let func: fn(++argv: ~[~str]) = cast::transmute(move closure);
func(~[sess.opts.binary]); func(~[/*bad*/copy sess.opts.binary]);
} }
} }
} }
@ -177,7 +180,7 @@ mod write {
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); } if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
let mut pm = mk_pass_manager(); let mut pm = mk_pass_manager();
let td = mk_target_data( let td = mk_target_data(
sess.targ_cfg.target_strs.data_layout); /*bad*/copy sess.targ_cfg.target_strs.data_layout);
llvm::LLVMAddTargetData(td.lltd, pm.llpm); llvm::LLVMAddTargetData(td.lltd, pm.llpm);
// FIXME (#2812): run the linter here also, once there are llvm-c // FIXME (#2812): run the linter here also, once there are llvm-c
// bindings for it. // bindings for it.
@ -438,17 +441,19 @@ fn build_link_meta(sess: Session, c: ast::crate, output: &Path,
let mut name: Option<~str> = None; let mut name: Option<~str> = None;
let mut vers: Option<~str> = None; let mut vers: Option<~str> = None;
let mut cmh_items: ~[@ast::meta_item] = ~[]; let mut cmh_items: ~[@ast::meta_item] = ~[];
let linkage_metas = attr::find_linkage_metas(c.node.attrs); let linkage_metas =
attr::require_unique_names(sess.diagnostic(), linkage_metas); attr::find_linkage_metas(/*bad*/copy c.node.attrs);
// XXX: Bad copy.
attr::require_unique_names(sess.diagnostic(), copy linkage_metas);
for linkage_metas.each |meta| { for linkage_metas.each |meta| {
if attr::get_meta_item_name(*meta) == ~"name" { if attr::get_meta_item_name(*meta) == ~"name" {
match attr::get_meta_item_value_str(*meta) { match attr::get_meta_item_value_str(*meta) {
Some(ref v) => { name = Some((*v)); } Some(ref v) => { name = Some((/*bad*/copy *v)); }
None => cmh_items.push(*meta) None => cmh_items.push(*meta)
} }
} else if attr::get_meta_item_name(*meta) == ~"vers" { } else if attr::get_meta_item_name(*meta) == ~"vers" {
match attr::get_meta_item_value_str(*meta) { match attr::get_meta_item_value_str(*meta) {
Some(ref v) => { vers = Some((*v)); } Some(ref v) => { vers = Some((/*bad*/copy *v)); }
None => cmh_items.push(*meta) None => cmh_items.push(*meta)
} }
} else { cmh_items.push(*meta); } } else { cmh_items.push(*meta); }
@ -469,7 +474,7 @@ fn build_link_meta(sess: Session, c: ast::crate, output: &Path,
return len_and_str(pprust::lit_to_str(@l)); return len_and_str(pprust::lit_to_str(@l));
} }
let cmh_items = attr::sort_meta_items(metas.cmh_items); let cmh_items = attr::sort_meta_items(/*bad*/copy metas.cmh_items);
symbol_hasher.reset(); symbol_hasher.reset();
for cmh_items.each |m| { for cmh_items.each |m| {
@ -504,15 +509,16 @@ fn build_link_meta(sess: Session, c: ast::crate, output: &Path,
fn crate_meta_name(sess: Session, _crate: ast::crate, fn crate_meta_name(sess: Session, _crate: ast::crate,
output: &Path, metas: provided_metas) -> ~str { output: &Path, metas: provided_metas) -> ~str {
return match metas.name { return match metas.name {
Some(ref v) => (*v), Some(ref v) => (/*bad*/copy *v),
None => { None => {
let name = match output.filestem() { let name = match output.filestem() {
None => sess.fatal(fmt!("output file name `%s` doesn't\ None => sess.fatal(fmt!("output file name `%s` doesn't\
appear to have a stem", appear to have a stem",
output.to_str())), output.to_str())),
Some(ref s) => (*s) Some(ref s) => (/*bad*/copy *s)
}; };
warn_missing(sess, ~"name", name); // XXX: Bad copy.
warn_missing(sess, ~"name", copy name);
name name
} }
}; };
@ -521,10 +527,11 @@ fn build_link_meta(sess: Session, c: ast::crate, output: &Path,
fn crate_meta_vers(sess: Session, _crate: ast::crate, fn crate_meta_vers(sess: Session, _crate: ast::crate,
metas: provided_metas) -> ~str { metas: provided_metas) -> ~str {
return match metas.vers { return match metas.vers {
Some(ref v) => (*v), Some(ref v) => (/*bad*/copy *v),
None => { None => {
let vers = ~"0.0"; let vers = ~"0.0";
warn_missing(sess, ~"vers", vers); // Bad copy.
warn_missing(sess, ~"vers", copy vers);
vers vers
} }
}; };
@ -565,10 +572,11 @@ fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t,
fn get_symbol_hash(ccx: @crate_ctxt, t: ty::t) -> ~str { fn get_symbol_hash(ccx: @crate_ctxt, t: ty::t) -> ~str {
match ccx.type_hashcodes.find(t) { match ccx.type_hashcodes.find(t) {
Some(ref h) => return (*h), Some(ref h) => return (/*bad*/copy *h),
None => { None => {
let hash = symbol_hash(ccx.tcx, ccx.symbol_hasher, t, ccx.link_meta); let hash = symbol_hash(ccx.tcx, ccx.symbol_hasher, t, ccx.link_meta);
ccx.type_hashcodes.insert(t, hash); // XXX: Bad copy. Prefer `@str`?
ccx.type_hashcodes.insert(t, copy hash);
return hash; return hash;
} }
} }
@ -625,21 +633,26 @@ fn mangle(sess: Session, ss: path) -> ~str {
n n
} }
fn exported_name(sess: Session, path: path, hash: ~str, vers: ~str) -> ~str { fn exported_name(sess: Session,
+path: path,
+hash: ~str,
+vers: ~str) -> ~str {
return mangle(sess, return mangle(sess,
vec::append_one( vec::append_one(
vec::append_one(path, path_name(sess.ident_of(hash))), vec::append_one(path, path_name(sess.ident_of(hash))),
path_name(sess.ident_of(vers)))); path_name(sess.ident_of(vers))));
} }
fn mangle_exported_name(ccx: @crate_ctxt, path: path, t: ty::t) -> ~str { fn mangle_exported_name(ccx: @crate_ctxt, +path: path, t: ty::t) -> ~str {
let hash = get_symbol_hash(ccx, t); let hash = get_symbol_hash(ccx, t);
return exported_name(ccx.sess, path, hash, ccx.link_meta.vers); return exported_name(ccx.sess, path,
hash,
/*bad*/copy ccx.link_meta.vers);
} }
fn mangle_internal_name_by_type_only(ccx: @crate_ctxt, fn mangle_internal_name_by_type_only(ccx: @crate_ctxt,
t: ty::t, name: ~str) -> t: ty::t,
~str { +name: ~str) -> ~str {
let s = ppaux::ty_to_short_str(ccx.tcx, t); let s = ppaux::ty_to_short_str(ccx.tcx, t);
let hash = get_symbol_hash(ccx, t); let hash = get_symbol_hash(ccx, t);
return mangle(ccx.sess, return mangle(ccx.sess,
@ -648,17 +661,18 @@ fn mangle_internal_name_by_type_only(ccx: @crate_ctxt,
path_name(ccx.sess.ident_of(hash))]); path_name(ccx.sess.ident_of(hash))]);
} }
fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt, path: path, fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt,
flav: ~str) -> ~str { +path: path,
+flav: ~str) -> ~str {
return mangle(ccx.sess, return mangle(ccx.sess,
vec::append_one(path, path_name((ccx.names)(flav)))); vec::append_one(path, path_name((ccx.names)(flav))));
} }
fn mangle_internal_name_by_path(ccx: @crate_ctxt, path: path) -> ~str { fn mangle_internal_name_by_path(ccx: @crate_ctxt, +path: path) -> ~str {
return mangle(ccx.sess, path); return mangle(ccx.sess, path);
} }
fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: ~str) -> ~str { fn mangle_internal_name_by_seq(ccx: @crate_ctxt, +flav: ~str) -> ~str {
return fmt!("%s_%u", flav, (ccx.names)(flav).repr); return fmt!("%s_%u", flav, (ccx.names)(flav).repr);
} }
@ -669,7 +683,7 @@ fn link_binary(sess: Session,
out_filename: &Path, out_filename: &Path,
lm: link_meta) { lm: link_meta) {
// Converts a library file-stem into a cc -l argument // Converts a library file-stem into a cc -l argument
fn unlib(config: @session::config, stem: ~str) -> ~str { fn unlib(config: @session::config, +stem: ~str) -> ~str {
if stem.starts_with("lib") && if stem.starts_with("lib") &&
config.os != session::os_win32 { config.os != session::os_win32 {
stem.slice(3, stem.len()) stem.slice(3, stem.len())
@ -689,7 +703,7 @@ fn link_binary(sess: Session,
out_filename.dir_path().push(long_libname) out_filename.dir_path().push(long_libname)
} else { } else {
*out_filename /*bad*/copy *out_filename
}; };
log(debug, ~"output: " + output.to_str()); log(debug, ~"output: " + output.to_str());
@ -736,7 +750,7 @@ fn link_binary(sess: Session,
} }
let ula = cstore::get_used_link_args(cstore); let ula = cstore::get_used_link_args(cstore);
for ula.each |arg| { cc_args.push(*arg); } for ula.each |arg| { cc_args.push(/*bad*/copy *arg); }
// # Extern library linking // # Extern library linking
@ -746,7 +760,7 @@ fn link_binary(sess: Session,
// to be found at compile time so it is still entirely up to outside // to be found at compile time so it is still entirely up to outside
// forces to make sure that library can be found at runtime. // forces to make sure that library can be found at runtime.
let addl_paths = sess.opts.addl_lib_search_paths; let addl_paths = /*bad*/copy sess.opts.addl_lib_search_paths;
for addl_paths.each |path| { cc_args.push(~"-L" + path.to_str()); } for addl_paths.each |path| { cc_args.push(~"-L" + path.to_str()); }
// The names of the extern libraries // The names of the extern libraries

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use driver::session; use driver::session;
use metadata::cstore; use metadata::cstore;
use metadata::filesearch; use metadata::filesearch;
@ -45,7 +46,7 @@ fn get_rpath_flags(sess: session::Session, out_filename: &Path) -> ~[~str] {
// where rustrt is and we know every rust program needs it // where rustrt is and we know every rust program needs it
let libs = vec::append_one(libs, get_sysroot_absolute_rt_lib(sess)); let libs = vec::append_one(libs, get_sysroot_absolute_rt_lib(sess));
let target_triple = sess.opts.target_triple; let target_triple = /*bad*/copy sess.opts.target_triple;
let rpaths = get_rpaths(os, &sysroot, output, libs, target_triple); let rpaths = get_rpaths(os, &sysroot, output, libs, target_triple);
rpaths_to_flags(rpaths) rpaths_to_flags(rpaths)
} }
@ -139,8 +140,8 @@ fn get_relative_to(abs1: &Path, abs2: &Path) -> Path {
let abs2 = abs2.normalize(); let abs2 = abs2.normalize();
debug!("finding relative path from %s to %s", debug!("finding relative path from %s to %s",
abs1.to_str(), abs2.to_str()); abs1.to_str(), abs2.to_str());
let split1 = abs1.components; let split1 = /*bad*/copy abs1.components;
let split2 = abs2.components; let split2 = /*bad*/copy abs2.components;
let len1 = vec::len(split1); let len1 = vec::len(split1);
let len2 = vec::len(split2); let len2 = vec::len(split2);
assert len1 > 0; assert len1 > 0;
@ -190,7 +191,7 @@ fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
for rpaths.each |rpath| { for rpaths.each |rpath| {
let s = rpath.to_str(); let s = rpath.to_str();
if !set.contains_key(s) { if !set.contains_key(s) {
minimized.push(*rpath); minimized.push(/*bad*/copy *rpath);
set.insert(s, ()); set.insert(s, ());
} }
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
type t = { type t = {
module_asm: ~str, module_asm: ~str,
meta_sect_name: ~str, meta_sect_name: ~str,

View File

@ -36,8 +36,10 @@ fn declare_upcalls(targ_cfg: @session::config,
fn nothrow(f: ValueRef) -> ValueRef { fn nothrow(f: ValueRef) -> ValueRef {
base::set_no_unwind(f); f base::set_no_unwind(f); f
} }
let d = |a,b,c| decl(llmod, ~"upcall_", a, b, c); let d: &fn(+a: ~str, +b: ~[TypeRef], +c: TypeRef) -> ValueRef =
let dv = |a,b| decl(llmod, ~"upcall_", a, b, T_void()); |a,b,c| decl(llmod, ~"upcall_", a, b, c);
let dv: &fn(+a: ~str, +b: ~[TypeRef]) -> ValueRef =
|a,b| decl(llmod, ~"upcall_", a, b, T_void());
let int_t = T_int(targ_cfg); let int_t = T_int(targ_cfg);

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back::target_strs; use back::target_strs;
use driver::session; use driver::session;
use metadata::loader::meta_section_name; use metadata::loader::meta_section_name;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back::target_strs; use back::target_strs;
use driver::session; use driver::session;
use metadata::loader::meta_section_name; use metadata::loader::meta_section_name;

View File

@ -9,6 +9,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back::link; use back::link;
use back::{x86, x86_64}; use back::{x86, x86_64};
use front; use front;
@ -66,7 +67,7 @@ fn source_name(input: input) -> ~str {
} }
} }
fn default_configuration(sess: Session, argv0: ~str, input: input) -> fn default_configuration(sess: Session, +argv0: ~str, input: input) ->
ast::crate_cfg { ast::crate_cfg {
let libc = match sess.targ_cfg.os { let libc = match sess.targ_cfg.os {
session::os_win32 => ~"msvcrt.dll", session::os_win32 => ~"msvcrt.dll",
@ -96,20 +97,21 @@ fn default_configuration(sess: Session, argv0: ~str, input: input) ->
mk(~"build_input", source_name(input))]; mk(~"build_input", source_name(input))];
} }
fn append_configuration(cfg: ast::crate_cfg, name: ~str) -> ast::crate_cfg { fn append_configuration(+cfg: ast::crate_cfg, +name: ~str) -> ast::crate_cfg {
if attr::contains_name(cfg, name) { // XXX: Bad copy.
if attr::contains_name(copy cfg, copy name) {
return cfg; return cfg;
} else { } else {
return vec::append_one(cfg, attr::mk_word_item(name)); return vec::append_one(cfg, attr::mk_word_item(name));
} }
} }
fn build_configuration(sess: Session, argv0: ~str, input: input) -> fn build_configuration(sess: Session, +argv0: ~str, input: input) ->
ast::crate_cfg { ast::crate_cfg {
// Combine the configuration requested by the session (command line) with // Combine the configuration requested by the session (command line) with
// some default and generated configuration items // some default and generated configuration items
let default_cfg = default_configuration(sess, argv0, input); let default_cfg = default_configuration(sess, argv0, input);
let user_cfg = sess.opts.cfg; let user_cfg = /*bad*/copy sess.opts.cfg;
// If the user wants a test runner, then add the test cfg // If the user wants a test runner, then add the test cfg
let user_cfg = append_configuration( let user_cfg = append_configuration(
user_cfg, user_cfg,
@ -128,7 +130,7 @@ fn parse_cfgspecs(cfgspecs: ~[~str]) -> ast::crate_cfg {
// meta_word variant. // meta_word variant.
let mut words = ~[]; let mut words = ~[];
for cfgspecs.each |s| { for cfgspecs.each |s| {
words.push(attr::mk_word_item(*s)); words.push(attr::mk_word_item(/*bad*/copy *s));
} }
return words; return words;
} }
@ -140,7 +142,7 @@ enum input {
str_input(~str) str_input(~str)
} }
fn parse_input(sess: Session, cfg: ast::crate_cfg, input: input) fn parse_input(sess: Session, +cfg: ast::crate_cfg, input: input)
-> @ast::crate { -> @ast::crate {
match input { match input {
file_input(ref file) => { file_input(ref file) => {
@ -149,7 +151,7 @@ fn parse_input(sess: Session, cfg: ast::crate_cfg, input: input)
str_input(ref src) => { str_input(ref src) => {
// FIXME (#2319): Don't really want to box the source string // FIXME (#2319): Don't really want to box the source string
parse::parse_crate_from_source_str( parse::parse_crate_from_source_str(
anon_src(), @(*src), cfg, sess.parse_sess) anon_src(), @(/*bad*/copy *src), cfg, sess.parse_sess)
} }
} }
} }
@ -326,7 +328,7 @@ fn compile_upto(sess: Session, cfg: ast::crate_cfg,
return {crate: crate, tcx: None}; return {crate: crate, tcx: None};
} }
fn compile_input(sess: Session, cfg: ast::crate_cfg, input: input, fn compile_input(sess: Session, +cfg: ast::crate_cfg, input: input,
outdir: &Option<Path>, output: &Option<Path>) { outdir: &Option<Path>, output: &Option<Path>) {
let upto = if sess.opts.parse_only { cu_parse } let upto = if sess.opts.parse_only { cu_parse }
@ -336,7 +338,7 @@ fn compile_input(sess: Session, cfg: ast::crate_cfg, input: input,
compile_upto(sess, cfg, input, upto, Some(outputs)); compile_upto(sess, cfg, input, upto, Some(outputs));
} }
fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: input, fn pretty_print_input(sess: Session, +cfg: ast::crate_cfg, input: input,
ppm: pp_mode) { ppm: pp_mode) {
fn ann_paren_for_expr(node: pprust::ann_node) { fn ann_paren_for_expr(node: pprust::ann_node) {
match node { match node {
@ -482,7 +484,7 @@ fn host_triple() -> ~str {
}; };
} }
fn build_session_options(binary: ~str, fn build_session_options(+binary: ~str,
matches: &getopts::Matches, matches: &getopts::Matches,
demitter: diagnostic::emitter) -> @session::options { demitter: diagnostic::emitter) -> @session::options {
let crate_type = if opt_present(matches, ~"lib") { let crate_type = if opt_present(matches, ~"lib") {
@ -527,7 +529,7 @@ fn build_session_options(binary: ~str,
for debug_flags.each |debug_flag| { for debug_flags.each |debug_flag| {
let mut this_bit = 0u; let mut this_bit = 0u;
for debug_map.each |pair| { for debug_map.each |pair| {
let (name, _, bit) = *pair; let (name, _, bit) = /*bad*/copy *pair;
if name == *debug_flag { this_bit = bit; break; } if name == *debug_flag { this_bit = bit; break; }
} }
if this_bit == 0u { if this_bit == 0u {
@ -588,7 +590,7 @@ fn build_session_options(binary: ~str,
let target = let target =
match target_opt { match target_opt {
None => host_triple(), None => host_triple(),
Some(ref s) => (*s) Some(ref s) => (/*bad*/copy *s)
}; };
let addl_lib_search_paths = let addl_lib_search_paths =
@ -641,7 +643,7 @@ fn build_session_(sopts: @session::options,
let filesearch = filesearch::mk_filesearch( let filesearch = filesearch::mk_filesearch(
sopts.maybe_sysroot, sopts.maybe_sysroot,
sopts.target_triple, sopts.target_triple,
sopts.addl_lib_search_paths); /*bad*/copy sopts.addl_lib_search_paths);
let lint_settings = lint::mk_lint_settings(); let lint_settings = lint::mk_lint_settings();
Session_(@{targ_cfg: target_cfg, Session_(@{targ_cfg: target_cfg,
opts: sopts, opts: sopts,
@ -768,7 +770,7 @@ fn build_output_filenames(input: input,
// have to make up a name // have to make up a name
// We want to toss everything after the final '.' // We want to toss everything after the final '.'
let dirpath = match *odir { let dirpath = match *odir {
Some(ref d) => (*d), Some(ref d) => (/*bad*/copy *d),
None => match input { None => match input {
str_input(_) => os::getcwd(), str_input(_) => os::getcwd(),
file_input(ref ifile) => (*ifile).dir_path() file_input(ref ifile) => (*ifile).dir_path()
@ -790,9 +792,9 @@ fn build_output_filenames(input: input,
} }
Some(ref out_file) => { Some(ref out_file) => {
out_path = (*out_file); out_path = (/*bad*/copy *out_file);
obj_path = if stop_after_codegen { obj_path = if stop_after_codegen {
(*out_file) (/*bad*/copy *out_file)
} else { } else {
(*out_file).with_filetype(obj_suffix) (*out_file).with_filetype(obj_suffix)
}; };

View File

@ -208,8 +208,7 @@ impl Session {
fn unimpl(msg: ~str) -> ! { fn unimpl(msg: ~str) -> ! {
self.span_diagnostic.handler().unimpl(msg) self.span_diagnostic.handler().unimpl(msg)
} }
fn span_lint_level(level: lint::level, fn span_lint_level(level: lint::level, sp: span, +msg: ~str) {
sp: span, msg: ~str) {
match level { match level {
lint::allow => { }, lint::allow => { },
lint::warn => self.span_warn(sp, msg), lint::warn => self.span_warn(sp, msg),
@ -219,8 +218,10 @@ impl Session {
} }
} }
fn span_lint(lint_mode: lint::lint, fn span_lint(lint_mode: lint::lint,
expr_id: ast::node_id, item_id: ast::node_id, expr_id: ast::node_id,
span: span, msg: ~str) { item_id: ast::node_id,
span: span,
+msg: ~str) {
let level = lint::get_lint_settings_level( let level = lint::get_lint_settings_level(
self.lint_settings, lint_mode, expr_id, item_id); self.lint_settings, lint_mode, expr_id, item_id);
self.span_lint_level(level, span, msg); self.span_lint_level(level, span, msg);
@ -258,9 +259,9 @@ impl Session {
} }
fn str_of(id: ast::ident) -> ~str { fn str_of(id: ast::ident) -> ~str {
*self.parse_sess.interner.get(id) /*bad*/copy *self.parse_sess.interner.get(id)
} }
fn ident_of(st: ~str) -> ast::ident { fn ident_of(+st: ~str) -> ast::ident {
self.parse_sess.interner.intern(@st) self.parse_sess.interner.intern(@st)
} }
fn intr() -> @syntax::parse::token::ident_interner { fn intr() -> @syntax::parse::token::ident_interner {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use syntax::{ast, fold, attr}; use syntax::{ast, fold, attr};
use core::option; use core::option;
@ -17,7 +18,7 @@ export strip_unconfigured_items;
export metas_in_cfg; export metas_in_cfg;
export strip_items; export strip_items;
type in_cfg_pred = fn@(~[ast::attribute]) -> bool; type in_cfg_pred = fn@(+attrs: ~[ast::attribute]) -> bool;
type ctxt = @{ type ctxt = @{
in_cfg: in_cfg_pred in_cfg: in_cfg_pred
@ -27,7 +28,7 @@ type ctxt = @{
// any items that do not belong in the current configuration // any items that do not belong in the current configuration
fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate { fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
do strip_items(crate) |attrs| { do strip_items(crate) |attrs| {
in_cfg(crate.node.config, attrs) in_cfg(/*bad*/copy crate.node.config, attrs)
} }
} }
@ -40,7 +41,10 @@ fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred)
@{fold_mod: |a,b| fold_mod(ctxt, a, b), @{fold_mod: |a,b| fold_mod(ctxt, a, b),
fold_block: fold::wrap(|a,b| fold_block(ctxt, a, b) ), fold_block: fold::wrap(|a,b| fold_block(ctxt, a, b) ),
fold_foreign_mod: |a,b| fold_foreign_mod(ctxt, a, b), fold_foreign_mod: |a,b| fold_foreign_mod(ctxt, a, b),
fold_item_underscore: |a,b| fold_item_underscore(ctxt, a, b), fold_item_underscore: |a,b| {
// Bad copy.
fold_item_underscore(ctxt, copy a, b)
},
.. *fold::default_ast_fold()}; .. *fold::default_ast_fold()};
let fold = fold::make_fold(precursor); let fold = fold::make_fold(precursor);
@ -94,18 +98,18 @@ fn fold_foreign_mod(cx: ctxt, nm: ast::foreign_mod,
}; };
} }
fn fold_item_underscore(cx: ctxt, item: ast::item_, fn fold_item_underscore(cx: ctxt, +item: ast::item_,
fld: fold::ast_fold) -> ast::item_ { fld: fold::ast_fold) -> ast::item_ {
let item = match item { let item = match item {
ast::item_impl(a, b, c, methods) => { ast::item_impl(a, b, c, methods) => {
let methods = methods.filter(|m| method_in_cfg(cx, *m) ); let methods = methods.filter(|m| method_in_cfg(cx, *m) );
ast::item_impl(a, b, c, methods) ast::item_impl(a, b, c, methods)
} }
ast::item_trait(a, b, ref methods) => { ast::item_trait(ref a, ref b, ref methods) => {
let methods = methods.filter(|m| trait_method_in_cfg(cx, m) ); let methods = methods.filter(|m| trait_method_in_cfg(cx, m) );
ast::item_trait(a, b, methods) ast::item_trait(/*bad*/copy *a, /*bad*/copy *b, methods)
} }
_ => item item => item
}; };
fold::noop_fold_item_underscore(item, fld) fold::noop_fold_item_underscore(item, fld)
@ -131,7 +135,7 @@ fn filter_stmt(cx: ctxt, &&stmt: @ast::stmt) ->
fn fold_block(cx: ctxt, b: ast::blk_, fld: fold::ast_fold) -> fn fold_block(cx: ctxt, b: ast::blk_, fld: fold::ast_fold) ->
ast::blk_ { ast::blk_ {
let filtered_stmts = vec::filter_map(b.stmts, |a| filter_stmt(cx, *a)); let filtered_stmts = vec::filter_map(b.stmts, |a| filter_stmt(cx, *a));
return {view_items: b.view_items, return {view_items: /*bad*/copy b.view_items,
stmts: vec::map(filtered_stmts, |x| fld.fold_stmt(*x)), stmts: vec::map(filtered_stmts, |x| fld.fold_stmt(*x)),
expr: option::map(&b.expr, |x| fld.fold_expr(*x)), expr: option::map(&b.expr, |x| fld.fold_expr(*x)),
id: b.id, id: b.id,
@ -139,36 +143,35 @@ fn fold_block(cx: ctxt, b: ast::blk_, fld: fold::ast_fold) ->
} }
fn item_in_cfg(cx: ctxt, item: @ast::item) -> bool { fn item_in_cfg(cx: ctxt, item: @ast::item) -> bool {
return (cx.in_cfg)(item.attrs); return (cx.in_cfg)(/*bad*/copy item.attrs);
} }
fn foreign_item_in_cfg(cx: ctxt, item: @ast::foreign_item) -> bool { fn foreign_item_in_cfg(cx: ctxt, item: @ast::foreign_item) -> bool {
return (cx.in_cfg)(item.attrs); return (cx.in_cfg)(/*bad*/copy item.attrs);
} }
fn view_item_in_cfg(cx: ctxt, item: @ast::view_item) -> bool { fn view_item_in_cfg(cx: ctxt, item: @ast::view_item) -> bool {
return (cx.in_cfg)(item.attrs); return (cx.in_cfg)(/*bad*/copy item.attrs);
} }
fn method_in_cfg(cx: ctxt, meth: @ast::method) -> bool { fn method_in_cfg(cx: ctxt, meth: @ast::method) -> bool {
return (cx.in_cfg)(meth.attrs); return (cx.in_cfg)(/*bad*/copy meth.attrs);
} }
fn trait_method_in_cfg(cx: ctxt, meth: &ast::trait_method) -> bool { fn trait_method_in_cfg(cx: ctxt, meth: &ast::trait_method) -> bool {
match *meth { match *meth {
ast::required(ref meth) => (cx.in_cfg)(meth.attrs), ast::required(ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs),
ast::provided(@ref meth) => (cx.in_cfg)(meth.attrs) ast::provided(@ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs)
} }
} }
// Determine if an item should be translated in the current crate // Determine if an item should be translated in the current crate
// configuration based on the item's attributes // configuration based on the item's attributes
fn in_cfg(cfg: ast::crate_cfg, attrs: ~[ast::attribute]) -> bool { fn in_cfg(+cfg: ast::crate_cfg, +attrs: ~[ast::attribute]) -> bool {
metas_in_cfg(cfg, attr::attr_metas(attrs)) metas_in_cfg(cfg, attr::attr_metas(attrs))
} }
fn metas_in_cfg(cfg: ast::crate_cfg, metas: ~[@ast::meta_item]) -> bool { fn metas_in_cfg(cfg: ast::crate_cfg, +metas: ~[@ast::meta_item]) -> bool {
// The "cfg" attributes on the item // The "cfg" attributes on the item
let cfg_metas = attr::find_meta_items_by_name(metas, ~"cfg"); let cfg_metas = attr::find_meta_items_by_name(metas, ~"cfg");
@ -182,7 +185,7 @@ fn metas_in_cfg(cfg: ast::crate_cfg, metas: ~[@ast::meta_item]) -> bool {
if !has_cfg_metas { return true; } if !has_cfg_metas { return true; }
for cfg_metas.each |cfg_mi| { for cfg_metas.each |cfg_mi| {
if attr::contains(cfg, *cfg_mi) { return true; } if attr::contains(/*bad*/copy cfg, *cfg_mi) { return true; }
} }
return false; return false;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use driver::session::Session; use driver::session::Session;
use core::vec; use core::vec;
@ -61,10 +62,14 @@ fn inject_libcore_ref(sess: Session,
span: dummy_sp()}; span: dummy_sp()};
let vis = vec::append(~[vi1], crate.module.view_items); let vis = vec::append(~[vi1], crate.module.view_items);
let mut new_module = { view_items: vis, ..crate.module }; let mut new_module = {
view_items: vis,
../*bad*/copy crate.module
};
new_module = fld.fold_mod(new_module); new_module = fld.fold_mod(new_module);
let new_crate = { module: new_module, ..crate }; // XXX: Bad copy.
let new_crate = { module: new_module, ..copy crate };
(new_crate, span) (new_crate, span)
}, },
fold_mod: |module, fld| { fold_mod: |module, fld| {
@ -80,7 +85,9 @@ fn inject_libcore_ref(sess: Session,
span: dummy_sp()}; span: dummy_sp()};
let vis = vec::append(~[vi2], module.view_items); let vis = vec::append(~[vi2], module.view_items);
let new_module = { view_items: vis, ..module };
// XXX: Bad copy.
let new_module = { view_items: vis, ..copy module };
fold::noop_fold_mod(new_module, fld) fold::noop_fold_mod(new_module, fld)
}, },
..*fold::default_ast_fold() ..*fold::default_ast_fold()

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use driver::session::Session; use driver::session::Session;
use syntax::parse; use syntax::parse;
use syntax::ast; use syntax::ast;
@ -21,7 +22,7 @@ fn inject_intrinsic(sess: Session, crate: @ast::crate) -> @ast::crate {
let item = parse::parse_item_from_source_str(~"<intrinsic>", let item = parse::parse_item_from_source_str(~"<intrinsic>",
intrinsic_module, intrinsic_module,
sess.opts.cfg, /*bad*/copy sess.opts.cfg,
~[], ~[],
sess.parse_sess); sess.parse_sess);
let item = let item =
@ -34,6 +35,6 @@ fn inject_intrinsic(sess: Session, crate: @ast::crate) -> @ast::crate {
let items = vec::append(~[item], crate.node.module.items); let items = vec::append(~[item], crate.node.module.items);
return @{node: {module: { items: items ,.. crate.node.module } return @{node: {module: { items: items ,.. /*bad*/copy crate.node.module }
,.. crate.node} ,.. *crate } ,.. /*bad*/copy crate.node} ,.. /*bad*/copy *crate }
} }

View File

@ -10,6 +10,7 @@
// Code that generates a test runner to run all the tests in a crate // Code that generates a test runner to run all the tests in a crate
use driver::session; use driver::session;
use front::config; use front::config;
use session::Session; use session::Session;
@ -45,7 +46,7 @@ fn modify_for_testing(sess: session::Session,
// We generate the test harness when building in the 'test' // We generate the test harness when building in the 'test'
// configuration, either with the '--test' or '--cfg test' // configuration, either with the '--test' or '--cfg test'
// command line options. // command line options.
let should_test = attr::contains(crate.node.config, let should_test = attr::contains(/*bad*/copy crate.node.config,
attr::mk_word_item(~"test")); attr::mk_word_item(~"test"));
if should_test { if should_test {
@ -101,7 +102,7 @@ fn fold_mod(cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod {
} }
let mod_nomain = let mod_nomain =
{view_items: m.view_items, {view_items: /*bad*/copy m.view_items,
items: vec::filter_map(m.items, |i| nomain(cx, *i))}; items: vec::filter_map(m.items, |i| nomain(cx, *i))};
return fold::noop_fold_mod(mod_nomain, fld); return fold::noop_fold_mod(mod_nomain, fld);
} }
@ -112,7 +113,7 @@ fn fold_crate(cx: test_ctxt, c: ast::crate_, fld: fold::ast_fold) ->
// Add a special __test module to the crate that will contain code // Add a special __test module to the crate that will contain code
// generated for the test harness // generated for the test harness
return {module: add_test_module(cx, folded.module),.. folded}; return {module: add_test_module(cx, /*bad*/copy folded.module),.. folded};
} }
@ -133,7 +134,7 @@ fn fold_item(cx: test_ctxt, &&i: @ast::item, fld: fold::ast_fold) ->
_ => { _ => {
debug!("this is a test function"); debug!("this is a test function");
let test = {span: i.span, let test = {span: i.span,
path: cx.path, ignore: is_ignored(cx, i), path: /*bad*/copy cx.path, ignore: is_ignored(cx, i),
should_fail: should_fail(i)}; should_fail: should_fail(i)};
cx.testfns.push(test); cx.testfns.push(test);
debug!("have %u test functions", cx.testfns.len()); debug!("have %u test functions", cx.testfns.len());
@ -151,7 +152,7 @@ fn is_test_fn(i: @ast::item) -> bool {
vec::len(attr::find_attrs_by_name(i.attrs, ~"test")) > 0u; vec::len(attr::find_attrs_by_name(i.attrs, ~"test")) > 0u;
fn has_test_signature(i: @ast::item) -> bool { fn has_test_signature(i: @ast::item) -> bool {
match i.node { match /*bad*/copy i.node {
ast::item_fn(decl, _, tps, _) => { ast::item_fn(decl, _, tps, _) => {
let input_cnt = vec::len(decl.inputs); let input_cnt = vec::len(decl.inputs);
let no_output = match decl.output.node { let no_output = match decl.output.node {
@ -169,12 +170,13 @@ fn is_test_fn(i: @ast::item) -> bool {
} }
fn is_ignored(cx: test_ctxt, i: @ast::item) -> bool { fn is_ignored(cx: test_ctxt, i: @ast::item) -> bool {
let ignoreattrs = attr::find_attrs_by_name(i.attrs, ~"ignore"); let ignoreattrs = attr::find_attrs_by_name(/*bad*/copy i.attrs,
~"ignore");
let ignoreitems = attr::attr_metas(ignoreattrs); let ignoreitems = attr::attr_metas(ignoreattrs);
let cfg_metas = vec::concat(vec::filter_map(ignoreitems, let cfg_metas = vec::concat(vec::filter_map(ignoreitems,
|i| attr::get_meta_item_list(*i))); |i| attr::get_meta_item_list(*i)));
return if vec::is_not_empty(ignoreitems) { return if vec::is_not_empty(ignoreitems) {
config::metas_in_cfg(cx.crate.node.config, cfg_metas) config::metas_in_cfg(/*bad*/copy cx.crate.node.config, cfg_metas)
} else { } else {
false false
} }
@ -184,9 +186,9 @@ fn should_fail(i: @ast::item) -> bool {
vec::len(attr::find_attrs_by_name(i.attrs, ~"should_fail")) > 0u vec::len(attr::find_attrs_by_name(i.attrs, ~"should_fail")) > 0u
} }
fn add_test_module(cx: test_ctxt, m: ast::_mod) -> ast::_mod { fn add_test_module(cx: test_ctxt, +m: ast::_mod) -> ast::_mod {
let testmod = mk_test_module(cx); let testmod = mk_test_module(cx);
return {items: vec::append_one(m.items, testmod),.. m}; return {items: vec::append_one(/*bad*/copy m.items, testmod),.. m};
} }
/* /*
@ -228,7 +230,7 @@ fn mk_test_module(cx: test_ctxt) -> @ast::item {
span: dummy_sp()}; span: dummy_sp()};
debug!("Synthetic test module:\n%s\n", debug!("Synthetic test module:\n%s\n",
pprust::item_to_str(@item, cx.sess.intr())); pprust::item_to_str(@copy item, cx.sess.intr()));
return @item; return @item;
} }
@ -237,11 +239,11 @@ fn nospan<T: Copy>(t: T) -> ast::spanned<T> {
return {node: t, span: dummy_sp()}; return {node: t, span: dummy_sp()};
} }
fn path_node(ids: ~[ast::ident]) -> @ast::path { fn path_node(+ids: ~[ast::ident]) -> @ast::path {
@{span: dummy_sp(), global: false, idents: ids, rp: None, types: ~[]} @{span: dummy_sp(), global: false, idents: ids, rp: None, types: ~[]}
} }
fn path_node_global(ids: ~[ast::ident]) -> @ast::path { fn path_node_global(+ids: ~[ast::ident]) -> @ast::path {
@{span: dummy_sp(), global: true, idents: ids, rp: None, types: ~[]} @{span: dummy_sp(), global: true, idents: ids, rp: None, types: ~[]}
} }
@ -271,11 +273,11 @@ fn mk_tests(cx: test_ctxt) -> @ast::item {
return @item; return @item;
} }
fn mk_path(cx: test_ctxt, path: ~[ast::ident]) -> ~[ast::ident] { fn mk_path(cx: test_ctxt, +path: ~[ast::ident]) -> ~[ast::ident] {
// For tests that are inside of std we don't want to prefix // For tests that are inside of std we don't want to prefix
// the paths with std:: // the paths with std::
let is_std = { let is_std = {
let items = attr::find_linkage_metas(cx.crate.node.attrs); let items = attr::find_linkage_metas(/*bad*/copy cx.crate.node.attrs);
match attr::last_meta_item_value_str_by_name(items, ~"name") { match attr::last_meta_item_value_str_by_name(items, ~"name") {
Some(~"std") => true, Some(~"std") => true,
_ => false _ => false
@ -325,14 +327,15 @@ fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr {
fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr { fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
let span = test.span; let span = test.span;
let path = test.path; let path = /*bad*/copy test.path;
debug!("encoding %s", ast_util::path_name_i(path, debug!("encoding %s", ast_util::path_name_i(path,
cx.sess.parse_sess.interner)); cx.sess.parse_sess.interner));
// XXX: Bad copy of `path`.
let name_lit: ast::lit = let name_lit: ast::lit =
nospan(ast::lit_str(@ast_util::path_name_i(path, cx.sess.parse_sess nospan(ast::lit_str(@ast_util::path_name_i(
.interner))); copy path, cx.sess.parse_sess.interner)));
let name_expr_inner: @ast::expr = let name_expr_inner: @ast::expr =
@{id: cx.sess.next_node_id(), @{id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
@ -401,7 +404,7 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
// FIXME (#1281): This can go away once fn is the type of bare function. // FIXME (#1281): This can go away once fn is the type of bare function.
fn mk_test_wrapper(cx: test_ctxt, fn mk_test_wrapper(cx: test_ctxt,
fn_path_expr: ast::expr, +fn_path_expr: ast::expr,
span: span) -> @ast::expr { span: span) -> @ast::expr {
let call_expr: ast::expr = { let call_expr: ast::expr = {
id: cx.sess.next_node_id(), id: cx.sess.next_node_id(),

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use core::cast; use core::cast;
use core::cmp; use core::cmp;
use core::int; use core::int;
@ -1070,8 +1071,9 @@ fn SetLinkage(Global: ValueRef, Link: Linkage) {
type type_names = @{type_names: HashMap<TypeRef, ~str>, type type_names = @{type_names: HashMap<TypeRef, ~str>,
named_types: HashMap<~str, TypeRef>}; named_types: HashMap<~str, TypeRef>};
fn associate_type(tn: type_names, s: ~str, t: TypeRef) { fn associate_type(tn: type_names, +s: ~str, t: TypeRef) {
assert tn.type_names.insert(t, s); // XXX: Bad copy, use @str instead?
assert tn.type_names.insert(t, copy s);
assert tn.named_types.insert(s, t); assert tn.named_types.insert(s, t);
} }
@ -1079,7 +1081,7 @@ fn type_has_name(tn: type_names, t: TypeRef) -> Option<~str> {
return tn.type_names.find(t); return tn.type_names.find(t);
} }
fn name_has_type(tn: type_names, s: ~str) -> Option<TypeRef> { fn name_has_type(tn: type_names, +s: ~str) -> Option<TypeRef> {
return tn.named_types.find(s); return tn.named_types.find(s);
} }
@ -1092,14 +1094,15 @@ fn type_to_str(names: type_names, ty: TypeRef) -> ~str {
return type_to_str_inner(names, ~[], ty); return type_to_str_inner(names, ~[], ty);
} }
fn type_to_str_inner(names: type_names, outer0: ~[TypeRef], ty: TypeRef) -> fn type_to_str_inner(names: type_names, +outer0: ~[TypeRef], ty: TypeRef) ->
~str { ~str {
match type_has_name(names, ty) { match type_has_name(names, ty) {
option::Some(ref n) => return (*n), option::Some(ref n) => return (/*bad*/copy *n),
_ => {} _ => {}
} }
let outer = vec::append_one(outer0, ty); // XXX: Bad copy.
let outer = vec::append_one(copy outer0, ty);
let kind = llvm::LLVMGetTypeKind(ty); let kind = llvm::LLVMGetTypeKind(ty);

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// EBML enum definitions and utils shared by the encoder and decoder // EBML enum definitions and utils shared by the encoder and decoder
const tag_items: uint = 0x02u; const tag_items: uint = 0x02u;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//! Validates all used crates and extern libraries and loads their metadata //! Validates all used crates and extern libraries and loads their metadata
use metadata::cstore; use metadata::cstore;
@ -79,7 +80,8 @@ fn warn_if_multiple_versions(e: env, diag: span_handler,
use either::*; use either::*;
if crate_cache.len() != 0u { if crate_cache.len() != 0u {
let name = loader::crate_name_from_metas(*crate_cache.last().metas); let name = loader::crate_name_from_metas(
/*bad*/copy *crate_cache.last().metas);
let (matches, non_matches) = let (matches, non_matches) =
partition(crate_cache.map_to_vec(|&entry| { partition(crate_cache.map_to_vec(|&entry| {
let othername = loader::crate_name_from_metas(*entry.metas); let othername = loader::crate_name_from_metas(*entry.metas);
@ -98,7 +100,8 @@ fn warn_if_multiple_versions(e: env, diag: span_handler,
for matches.each |match_| { for matches.each |match_| {
diag.span_note(match_.span, ~"used here"); diag.span_note(match_.span, ~"used here");
let attrs = ~[ let attrs = ~[
attr::mk_attr(attr::mk_list_item(~"link", *match_.metas)) attr::mk_attr(attr::mk_list_item(
~"link", /*bad*/copy *match_.metas))
]; ];
loader::note_linkage_attrs(e.intr, diag, attrs); loader::note_linkage_attrs(e.intr, diag, attrs);
} }
@ -118,7 +121,7 @@ type env = @{diag: span_handler,
intr: @ident_interner}; intr: @ident_interner};
fn visit_view_item(e: env, i: @ast::view_item) { fn visit_view_item(e: env, i: @ast::view_item) {
match i.node { match /*bad*/copy i.node {
ast::view_item_use(ident, meta_items, id) => { ast::view_item_use(ident, meta_items, id) => {
debug!("resolving use stmt. ident: %?, meta: %?", ident, meta_items); debug!("resolving use stmt. ident: %?, meta: %?", ident, meta_items);
let cnum = resolve_crate(e, ident, meta_items, ~"", i.span); let cnum = resolve_crate(e, ident, meta_items, ~"", i.span);
@ -129,7 +132,7 @@ fn visit_view_item(e: env, i: @ast::view_item) {
} }
fn visit_item(e: env, i: @ast::item) { fn visit_item(e: env, i: @ast::item) {
match i.node { match /*bad*/copy i.node {
ast::item_foreign_mod(fm) => { ast::item_foreign_mod(fm) => {
match attr::foreign_abi(i.attrs) { match attr::foreign_abi(i.attrs) {
either::Right(abi) => { either::Right(abi) => {
@ -141,7 +144,8 @@ fn visit_item(e: env, i: @ast::item) {
let cstore = e.cstore; let cstore = e.cstore;
let mut already_added = false; let mut already_added = false;
let link_args = attr::find_attrs_by_name(i.attrs, ~"link_args"); let link_args = attr::find_attrs_by_name(/*bad*/copy i.attrs,
~"link_args");
match fm.sort { match fm.sort {
ast::named => { ast::named => {
@ -154,9 +158,9 @@ fn visit_item(e: env, i: @ast::item) {
i.span, i.span,
~"empty #[link_name] not allowed; use #[nolink]."); ~"empty #[link_name] not allowed; use #[nolink].");
} }
(*nn) (/*bad*/copy *nn)
} }
None => *e.intr.get(i.ident) None => /*bad*/copy *e.intr.get(i.ident)
}; };
if attr::find_attrs_by_name(i.attrs, ~"nolink").is_empty() { if attr::find_attrs_by_name(i.attrs, ~"nolink").is_empty() {
already_added = !cstore::add_used_library(cstore, already_added = !cstore::add_used_library(cstore,
@ -173,7 +177,7 @@ fn visit_item(e: env, i: @ast::item) {
for link_args.each |a| { for link_args.each |a| {
match attr::get_meta_item_value_str(attr::attr_meta(*a)) { match attr::get_meta_item_value_str(attr::attr_meta(*a)) {
Some(ref linkarg) => { Some(ref linkarg) => {
cstore::add_used_link_args(cstore, (*linkarg)); cstore::add_used_link_args(cstore, (/*bad*/copy *linkarg));
} }
None => {/* fallthrough */ } None => {/* fallthrough */ }
} }
@ -183,9 +187,10 @@ fn visit_item(e: env, i: @ast::item) {
} }
} }
fn metas_with(ident: ~str, key: ~str, metas: ~[@ast::meta_item]) fn metas_with(+ident: ~str, +key: ~str, +metas: ~[@ast::meta_item])
-> ~[@ast::meta_item] { -> ~[@ast::meta_item] {
let name_items = attr::find_meta_items_by_name(metas, key); // XXX: Bad copies.
let name_items = attr::find_meta_items_by_name(copy metas, copy key);
if name_items.is_empty() { if name_items.is_empty() {
vec::append_one(metas, attr::mk_name_value_item_str(key, ident)) vec::append_one(metas, attr::mk_name_value_item_str(key, ident))
} else { } else {
@ -193,7 +198,7 @@ fn metas_with(ident: ~str, key: ~str, metas: ~[@ast::meta_item])
} }
} }
fn metas_with_ident(ident: ~str, metas: ~[@ast::meta_item]) fn metas_with_ident(+ident: ~str, +metas: ~[@ast::meta_item])
-> ~[@ast::meta_item] { -> ~[@ast::meta_item] {
metas_with(ident, ~"name", metas) metas_with(ident, ~"name", metas)
} }
@ -210,9 +215,9 @@ fn existing_match(e: env, metas: ~[@ast::meta_item], hash: ~str) ->
return None; return None;
} }
fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item], fn resolve_crate(e: env, ident: ast::ident, +metas: ~[@ast::meta_item],
hash: ~str, span: span) -> ast::crate_num { +hash: ~str, span: span) -> ast::crate_num {
let metas = metas_with_ident(*e.intr.get(ident), metas); let metas = metas_with_ident(/*bad*/copy *e.intr.get(ident), metas);
match existing_match(e, metas, hash) { match existing_match(e, metas, hash) {
None => { None => {
@ -221,7 +226,7 @@ fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item],
filesearch: e.filesearch, filesearch: e.filesearch,
span: span, span: span,
ident: ident, ident: ident,
metas: metas, metas: copy metas, // XXX: Bad copy.
hash: hash, hash: hash,
os: e.os, os: e.os,
static: e.static, static: e.static,
@ -247,8 +252,8 @@ fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item],
let cname = let cname =
match attr::last_meta_item_value_str_by_name(metas, ~"name") { match attr::last_meta_item_value_str_by_name(metas, ~"name") {
option::Some(ref v) => (*v), option::Some(ref v) => (/*bad*/copy *v),
option::None => *e.intr.get(ident) option::None => /*bad*/copy *e.intr.get(ident)
}; };
let cmeta = @{name: cname, data: cdata, let cmeta = @{name: cname, data: cdata,
cnum_map: cnum_map, cnum: cnum}; cnum_map: cnum_map, cnum: cnum};
@ -273,7 +278,7 @@ fn resolve_crate_deps(e: env, cdata: @~[u8]) -> cstore::cnum_map {
for decoder::get_crate_deps(e.intr, cdata).each |dep| { for decoder::get_crate_deps(e.intr, cdata).each |dep| {
let extrn_cnum = dep.cnum; let extrn_cnum = dep.cnum;
let cname = dep.name; let cname = dep.name;
let cmetas = metas_with(dep.vers, ~"vers", ~[]); let cmetas = metas_with(/*bad*/copy dep.vers, ~"vers", ~[]);
debug!("resolving dep crate %s ver: %s hash: %s", debug!("resolving dep crate %s ver: %s hash: %s",
*e.intr.get(dep.name), dep.vers, dep.hash); *e.intr.get(dep.name), dep.vers, dep.hash);
match existing_match(e, metas_with_ident(*e.intr.get(cname), cmetas), match existing_match(e, metas_with_ident(*e.intr.get(cname), cmetas),
@ -289,8 +294,8 @@ fn resolve_crate_deps(e: env, cdata: @~[u8]) -> cstore::cnum_map {
// FIXME (#2404): Need better error reporting than just a bogus // FIXME (#2404): Need better error reporting than just a bogus
// span. // span.
let fake_span = ast_util::dummy_sp(); let fake_span = ast_util::dummy_sp();
let local_cnum = resolve_crate(e, cname, cmetas, dep.hash, let local_cnum = resolve_crate(e, cname, cmetas,
fake_span); /*bad*/copy dep.hash, fake_span);
cnum_map.insert(extrn_cnum, local_cnum); cnum_map.insert(extrn_cnum, local_cnum);
} }
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// Searching for information from the cstore // Searching for information from the cstore
use metadata::common::*; use metadata::common::*;
@ -100,7 +101,8 @@ fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {
// FIXME #1920: This path is not always correct if the crate is not linked // FIXME #1920: This path is not always correct if the crate is not linked
// into the root namespace. // into the root namespace.
vec::append(~[ast_map::path_mod(tcx.sess.ident_of(cdata.name))], path) vec::append(~[ast_map::path_mod(tcx.sess.ident_of(
/*bad*/copy cdata.name))], path)
} }
enum found_ast { enum found_ast {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// The crate store - a central repo for information collected about external // The crate store - a central repo for information collected about external
// crates and libraries // crates and libraries
@ -125,10 +126,10 @@ fn add_used_crate_file(cstore: CStore, lib: &Path) {
} }
fn get_used_crate_files(cstore: CStore) -> ~[Path] { fn get_used_crate_files(cstore: CStore) -> ~[Path] {
return p(cstore).used_crate_files; return /*bad*/copy p(cstore).used_crate_files;
} }
fn add_used_library(cstore: CStore, lib: ~str) -> bool { fn add_used_library(cstore: CStore, +lib: ~str) -> bool {
assert lib != ~""; assert lib != ~"";
if vec::contains(p(cstore).used_libraries, &lib) { return false; } if vec::contains(p(cstore).used_libraries, &lib) { return false; }
@ -137,7 +138,7 @@ fn add_used_library(cstore: CStore, lib: ~str) -> bool {
} }
fn get_used_libraries(cstore: CStore) -> ~[~str] { fn get_used_libraries(cstore: CStore) -> ~[~str] {
return p(cstore).used_libraries; return /*bad*/copy p(cstore).used_libraries;
} }
fn add_used_link_args(cstore: CStore, args: ~str) { fn add_used_link_args(cstore: CStore, args: ~str) {
@ -145,7 +146,7 @@ fn add_used_link_args(cstore: CStore, args: ~str) {
} }
fn get_used_link_args(cstore: CStore) -> ~[~str] { fn get_used_link_args(cstore: CStore) -> ~[~str] {
return p(cstore).used_link_args; return /*bad*/copy p(cstore).used_link_args;
} }
fn add_use_stmt_cnum(cstore: CStore, use_id: ast::node_id, fn add_use_stmt_cnum(cstore: CStore, use_id: ast::node_id,
@ -168,7 +169,7 @@ fn get_dep_hashes(cstore: CStore) -> ~[~str] {
let cdata = cstore::get_crate_data(cstore, cnum); let cdata = cstore::get_crate_data(cstore, cnum);
let hash = decoder::get_crate_hash(cdata.data); let hash = decoder::get_crate_hash(cdata.data);
debug!("Add hash[%s]: %s", cdata.name, hash); debug!("Add hash[%s]: %s", cdata.name, hash);
result.push({name: cdata.name, hash: hash}); result.push({name: /*bad*/copy cdata.name, hash: hash});
}; };
pure fn lteq(a: &crate_hash, b: &crate_hash) -> bool {a.name <= b.name} pure fn lteq(a: &crate_hash, b: &crate_hash) -> bool {a.name <= b.name}
let sorted = std::sort::merge_sort(result, lteq); let sorted = std::sort::merge_sort(result, lteq);
@ -176,7 +177,7 @@ fn get_dep_hashes(cstore: CStore) -> ~[~str] {
for sorted.each |x| { for sorted.each |x| {
debug!(" hash[%s]: %s", x.name, x.hash); debug!(" hash[%s]: %s", x.name, x.hash);
} }
fn mapper(ch: &crate_hash) -> ~str { return ch.hash; } fn mapper(ch: &crate_hash) -> ~str { return /*bad*/copy ch.hash; }
return vec::map(sorted, mapper); return vec::map(sorted, mapper);
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// Decoding metadata from a single crate's metadata // Decoding metadata from a single crate's metadata
use cmd = metadata::cstore::crate_metadata; use cmd = metadata::cstore::crate_metadata;
@ -472,7 +473,7 @@ struct path_entry {
def_like: def_like, def_like: def_like,
} }
fn path_entry(path_string: ~str, def_like: def_like) -> path_entry { fn path_entry(+path_string: ~str, def_like: def_like) -> path_entry {
path_entry { path_entry {
path_string: path_string, path_string: path_string,
def_like: def_like def_like: def_like
@ -520,7 +521,8 @@ fn each_path(intr: @ident_interner, cdata: cmd,
let def_like = item_to_def_like(item_doc, def_id, cdata.cnum); let def_like = item_to_def_like(item_doc, def_id, cdata.cnum);
// Hand the information off to the iteratee. // Hand the information off to the iteratee.
let this_path_entry = path_entry(path, def_like); // XXX: Bad copy.
let this_path_entry = path_entry(copy path, def_like);
if !f(this_path_entry) { if !f(this_path_entry) {
broken = true; // XXX: This is awful. broken = true; // XXX: This is awful.
} }
@ -608,7 +610,7 @@ fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt,
let item_doc = lookup_item(id, cdata.data); let item_doc = lookup_item(id, cdata.data);
let path = vec::init(item_path(intr, item_doc)); let path = vec::init(item_path(intr, item_doc));
match decode_inlined_item(cdata, tcx, path, item_doc) { match decode_inlined_item(cdata, tcx, path, item_doc) {
Some(ref ii) => csearch::found((*ii)), Some(ref ii) => csearch::found((/*bad*/copy *ii)),
None => { None => {
match item_parent_item(item_doc) { match item_parent_item(item_doc) {
Some(did) => { Some(did) => {
@ -616,7 +618,7 @@ fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt,
let parent_item = lookup_item(did.node, cdata.data); let parent_item = lookup_item(did.node, cdata.data);
match decode_inlined_item(cdata, tcx, path, match decode_inlined_item(cdata, tcx, path,
parent_item) { parent_item) {
Some(ref ii) => csearch::found_parent(did, (*ii)), Some(ref ii) => csearch::found_parent(did, (/*bad*/copy *ii)),
None => csearch::not_found None => csearch::not_found
} }
} }
@ -755,7 +757,7 @@ fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id,
let ty = doc_type(mth, tcx, cdata); let ty = doc_type(mth, tcx, cdata);
let def_id = item_def_id(mth, cdata); let def_id = item_def_id(mth, cdata);
let fty = match ty::get(ty).sty { let fty = match ty::get(ty).sty {
ty::ty_fn(ref f) => (*f), ty::ty_fn(ref f) => (/*bad*/copy *f),
_ => { _ => {
tcx.diag.handler().bug( tcx.diag.handler().bug(
~"get_trait_methods: id has non-function type"); ~"get_trait_methods: id has non-function type");
@ -786,7 +788,7 @@ fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
let fty; let fty;
match ty::get(ty).sty { match ty::get(ty).sty {
ty::ty_fn(ref f) => fty = (*f), ty::ty_fn(ref f) => fty = (/*bad*/copy *f),
_ => { _ => {
tcx.diag.handler().bug(~"get_provided_trait_methods(): id \ tcx.diag.handler().bug(~"get_provided_trait_methods(): id \
has non-function type"); has non-function type");
@ -1027,7 +1029,7 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] {
assert (vec::len(meta_items) == 1u); assert (vec::len(meta_items) == 1u);
let meta_item = meta_items[0]; let meta_item = meta_items[0];
attrs.push( attrs.push(
{node: {style: ast::attr_outer, value: *meta_item, {node: {style: ast::attr_outer, value: /*bad*/copy *meta_item,
is_sugared_doc: false}, is_sugared_doc: false},
span: ast_util::dummy_sp()}); span: ast_util::dummy_sp()});
}; };
@ -1102,19 +1104,20 @@ fn get_crate_vers(data: @~[u8]) -> ~str {
let attrs = decoder::get_crate_attributes(data); let attrs = decoder::get_crate_attributes(data);
return match attr::last_meta_item_value_str_by_name( return match attr::last_meta_item_value_str_by_name(
attr::find_linkage_metas(attrs), ~"vers") { attr::find_linkage_metas(attrs), ~"vers") {
Some(ref ver) => (*ver), Some(ref ver) => (/*bad*/copy *ver),
None => ~"0.0" None => ~"0.0"
}; };
} }
fn iter_crate_items(intr: @ident_interner, cdata: cmd, fn iter_crate_items(intr: @ident_interner, cdata: cmd,
get_crate_data: GetCrateDataCb, get_crate_data: GetCrateDataCb,
proc: fn(~str, ast::def_id)) { proc: fn(+path: ~str, ast::def_id)) {
for each_path(intr, cdata, get_crate_data) |path_entry| { for each_path(intr, cdata, get_crate_data) |path_entry| {
match path_entry.def_like { match path_entry.def_like {
dl_impl(*) | dl_field => {} dl_impl(*) | dl_field => {}
dl_def(def) => { dl_def(def) => {
proc(path_entry.path_string, ast_util::def_id_of_def(def)) proc(/*bad*/copy path_entry.path_string,
ast_util::def_id_of_def(def))
} }
} }
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// Metadata encoding // Metadata encoding
use metadata::common::*; use metadata::common::*;
@ -233,7 +234,7 @@ fn encode_type(ecx: @encode_ctxt, ebml_w: writer::Encoder, typ: ty::t) {
fn encode_symbol(ecx: @encode_ctxt, ebml_w: writer::Encoder, id: node_id) { fn encode_symbol(ecx: @encode_ctxt, ebml_w: writer::Encoder, id: node_id) {
ebml_w.start_tag(tag_items_data_item_symbol); ebml_w.start_tag(tag_items_data_item_symbol);
let sym = match ecx.item_symbols.find(id) { let sym = match ecx.item_symbols.find(id) {
Some(ref x) => (*x), Some(ref x) => (/*bad*/copy *x),
None => { None => {
ecx.diag.handler().bug( ecx.diag.handler().bug(
fmt!("encode_symbol: id not found %d", id)); fmt!("encode_symbol: id not found %d", id));
@ -280,7 +281,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: writer::Encoder,
encode_type(ecx, ebml_w, encode_type(ecx, ebml_w,
node_id_to_type(ecx.tcx, variant.node.id)); node_id_to_type(ecx.tcx, variant.node.id));
match variant.node.kind { match variant.node.kind {
ast::tuple_variant_kind(args) ast::tuple_variant_kind(ref args)
if args.len() > 0 && ty_params.len() == 0 => { if args.len() > 0 && ty_params.len() == 0 => {
encode_symbol(ecx, ebml_w, variant.node.id); encode_symbol(ecx, ebml_w, variant.node.id);
} }
@ -292,8 +293,9 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: writer::Encoder,
encode_disr_val(ecx, ebml_w, vi[i].disr_val); encode_disr_val(ecx, ebml_w, vi[i].disr_val);
disr_val = vi[i].disr_val; disr_val = vi[i].disr_val;
} }
encode_type_param_bounds(ebml_w, ecx, ty_params); encode_type_param_bounds(ebml_w, ecx, /*bad*/copy ty_params);
encode_path(ecx, ebml_w, path, ast_map::path_name(variant.node.name)); encode_path(ecx, ebml_w, /*bad*/copy path,
ast_map::path_name(variant.node.name));
ebml_w.end_tag(); ebml_w.end_tag();
disr_val += 1; disr_val += 1;
i += 1; i += 1;
@ -322,7 +324,7 @@ fn encode_path(ecx: @encode_ctxt, ebml_w: writer::Encoder,
} }
fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: writer::Encoder, fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: writer::Encoder,
md: _mod, id: node_id, path: ast_map::path, md: _mod, id: node_id, +path: ast_map::path,
name: ident) { name: ident) {
ebml_w.start_tag(tag_items_data_item); ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(id)); encode_def_id(ebml_w, local_def(id));
@ -449,7 +451,8 @@ fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder,
tcx.sess.str_of(nm), id); tcx.sess.str_of(nm), id);
encode_visibility(ebml_w, vis); encode_visibility(ebml_w, vis);
encode_name(ecx, ebml_w, nm); encode_name(ecx, ebml_w, nm);
encode_path(ecx, ebml_w, path, ast_map::path_name(nm)); encode_path(ecx, ebml_w, /*bad*/copy path,
ast_map::path_name(nm));
encode_type(ecx, ebml_w, node_id_to_type(tcx, id)); encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
encode_mutability(ebml_w, mt); encode_mutability(ebml_w, mt);
encode_def_id(ebml_w, local_def(id)); encode_def_id(ebml_w, local_def(id));
@ -458,13 +461,13 @@ fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder,
unnamed_field => {} unnamed_field => {}
} }
} }
*index /*bad*/copy *index
} }
// This is for encoding info for ctors and dtors // This is for encoding info for ctors and dtors
fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder, fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder,
id: node_id, ident: ident, path: ast_map::path, id: node_id, ident: ident, +path: ast_map::path,
item: Option<inlined_item>, tps: ~[ty_param]) { item: Option<inlined_item>, +tps: ~[ty_param]) {
ebml_w.start_tag(tag_items_data_item); ebml_w.start_tag(tag_items_data_item);
encode_name(ecx, ebml_w, ident); encode_name(ecx, ebml_w, ident);
encode_def_id(ebml_w, local_def(id)); encode_def_id(ebml_w, local_def(id));
@ -475,7 +478,8 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder,
ecx.tcx.sess.str_of(ident), ecx.tcx.sess.str_of(ident),
ty_to_str(ecx.tcx, its_ty), id); ty_to_str(ecx.tcx, its_ty), id);
encode_type(ecx, ebml_w, its_ty); encode_type(ecx, ebml_w, its_ty);
encode_path(ecx, ebml_w, path, ast_map::path_name(ident)); // XXX: Bad copy.
encode_path(ecx, ebml_w, copy path, ast_map::path_name(ident));
match item { match item {
Some(ref it) => { Some(ref it) => {
(ecx.encode_inlined_item)(ecx, ebml_w, path, (*it)); (ecx.encode_inlined_item)(ecx, ebml_w, path, (*it));
@ -487,10 +491,13 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder,
ebml_w.end_tag(); ebml_w.end_tag();
} }
fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: writer::Encoder, fn encode_info_for_method(ecx: @encode_ctxt,
impl_path: ast_map::path, should_inline: bool, ebml_w: writer::Encoder,
+impl_path: ast_map::path,
should_inline: bool,
parent_id: node_id, parent_id: node_id,
m: @method, all_tps: ~[ty_param]) { m: @method,
+all_tps: ~[ty_param]) {
debug!("encode_info_for_method: %d %s %u", m.id, debug!("encode_info_for_method: %d %s %u", m.id,
ecx.tcx.sess.str_of(m.ident), all_tps.len()); ecx.tcx.sess.str_of(m.ident), all_tps.len());
ebml_w.start_tag(tag_items_data_item); ebml_w.start_tag(tag_items_data_item);
@ -501,12 +508,14 @@ fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: writer::Encoder,
} }
_ => encode_family(ebml_w, purity_fn_family(m.purity)) _ => encode_family(ebml_w, purity_fn_family(m.purity))
} }
let len = all_tps.len();
encode_type_param_bounds(ebml_w, ecx, all_tps); encode_type_param_bounds(ebml_w, ecx, all_tps);
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id)); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
encode_name(ecx, ebml_w, m.ident); encode_name(ecx, ebml_w, m.ident);
encode_path(ecx, ebml_w, impl_path, ast_map::path_name(m.ident)); // XXX: Bad copy.
encode_path(ecx, ebml_w, copy impl_path, ast_map::path_name(m.ident));
encode_self_type(ebml_w, m.self_ty.node); encode_self_type(ebml_w, m.self_ty.node);
if all_tps.len() > 0u || should_inline { if len > 0u || should_inline {
(ecx.encode_inlined_item)( (ecx.encode_inlined_item)(
ecx, ebml_w, impl_path, ecx, ebml_w, impl_path,
ii_method(local_def(parent_id), m)); ii_method(local_def(parent_id), m));
@ -544,7 +553,7 @@ fn should_inline(attrs: ~[attribute]) -> bool {
fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
item: @item, index: @mut ~[entry<int>], item: @item, index: @mut ~[entry<int>],
path: ast_map::path) { +path: ast_map::path) {
let tcx = ecx.tcx; let tcx = ecx.tcx;
let must_write = let must_write =
@ -564,7 +573,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
debug!("encoding info for item at %s", debug!("encoding info for item at %s",
ecx.tcx.sess.codemap.span_to_str(item.span)); ecx.tcx.sess.codemap.span_to_str(item.span));
match item.node { match /*bad*/copy item.node {
item_const(_, _) => { item_const(_, _) => {
add_to_index(); add_to_index();
ebml_w.start_tag(tag_items_data_item); ebml_w.start_tag(tag_items_data_item);
@ -580,11 +589,13 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
ebml_w.start_tag(tag_items_data_item); ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id)); encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, purity_fn_family(purity)); encode_family(ebml_w, purity_fn_family(purity));
let tps_len = tps.len();
encode_type_param_bounds(ebml_w, ecx, tps); encode_type_param_bounds(ebml_w, ecx, tps);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); // XXX: Bad copy.
encode_attributes(ebml_w, item.attrs); encode_path(ecx, ebml_w, copy path, ast_map::path_name(item.ident));
if tps.len() > 0u || should_inline(item.attrs) { encode_attributes(ebml_w, /*bad*/copy item.attrs);
if tps_len > 0u || should_inline(item.attrs) {
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item)); (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
} else { } else {
encode_symbol(ecx, ebml_w, item.id); encode_symbol(ecx, ebml_w, item.id);
@ -616,36 +627,39 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
encode_region_param(ecx, ebml_w, item); encode_region_param(ecx, ebml_w, item);
ebml_w.end_tag(); ebml_w.end_tag();
} }
item_enum(ref enum_definition, tps) => { item_enum(ref enum_definition, ref tps) => {
add_to_index(); add_to_index();
do ebml_w.wr_tag(tag_items_data_item) { do ebml_w.wr_tag(tag_items_data_item) {
encode_def_id(ebml_w, local_def(item.id)); encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 't'); encode_family(ebml_w, 't');
encode_type_param_bounds(ebml_w, ecx, tps); encode_type_param_bounds(ebml_w, ecx, /*bad*/copy *tps);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ecx, ebml_w, item.ident); encode_name(ecx, ebml_w, item.ident);
for (*enum_definition).variants.each |v| { for (*enum_definition).variants.each |v| {
encode_variant_id(ebml_w, local_def(v.node.id)); encode_variant_id(ebml_w, local_def(v.node.id));
} }
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item)); (ecx.encode_inlined_item)(ecx, ebml_w, /*bad*/copy path,
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); ii_item(item));
encode_path(ecx, ebml_w, /*bad*/copy path,
ast_map::path_name(item.ident));
encode_region_param(ecx, ebml_w, item); encode_region_param(ecx, ebml_w, item);
} }
encode_enum_variant_info(ecx, encode_enum_variant_info(ecx,
ebml_w, ebml_w,
item.id, item.id,
(*enum_definition).variants, /*bad*/copy (*enum_definition).variants,
path, path,
index, index,
tps); /*bad*/copy *tps);
} }
item_struct(struct_def, tps) => { item_struct(struct_def, tps) => {
/* First, encode the fields /* First, encode the fields
These come first because we need to write them to make These come first because we need to write them to make
the index, and the index needs to be in the item for the the index, and the index needs to be in the item for the
class itself */ class itself */
let idx = encode_info_for_struct(ecx, ebml_w, path, // XXX: Bad copy of `path`.
struct_def.fields, index); let idx = encode_info_for_struct(ecx, ebml_w, copy path,
/*bad*/copy struct_def.fields, index);
/* Encode the dtor */ /* Encode the dtor */
do struct_def.dtor.iter |dtor| { do struct_def.dtor.iter |dtor| {
index.push({val: dtor.node.id, pos: ebml_w.writer.tell()}); index.push({val: dtor.node.id, pos: ebml_w.writer.tell()});
@ -653,10 +667,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
ecx.tcx.sess.ident_of( ecx.tcx.sess.ident_of(
ecx.tcx.sess.str_of(item.ident) + ecx.tcx.sess.str_of(item.ident) +
~"_dtor"), ~"_dtor"),
path, if tps.len() > 0u { /*bad*/copy path, if tps.len() > 0u {
Some(ii_dtor(*dtor, item.ident, tps, Some(ii_dtor(*dtor, item.ident, tps,
local_def(item.id))) } local_def(item.id))) }
else { None }, tps); else { None }, /*bad*/copy tps);
} }
/* Index the class*/ /* Index the class*/
@ -705,10 +719,11 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
encode_def_id(ebml_w, local_def(item.id)); encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'i'); encode_family(ebml_w, 'i');
encode_region_param(ecx, ebml_w, item); encode_region_param(ecx, ebml_w, item);
encode_type_param_bounds(ebml_w, ecx, tps); // XXX: Bad copy.
encode_type_param_bounds(ebml_w, ecx, copy tps);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ecx, ebml_w, item.ident); encode_name(ecx, ebml_w, item.ident);
encode_attributes(ebml_w, item.attrs); encode_attributes(ebml_w, /*bad*/copy item.attrs);
match ty.node { match ty.node {
ast::ty_path(path, _) if path.idents.len() == 1 => { ast::ty_path(path, _) if path.idents.len() == 1 => {
encode_impl_type_basename(ecx, ebml_w, encode_impl_type_basename(ecx, ebml_w,
@ -725,19 +740,21 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
do opt_trait.iter() |associated_trait| { do opt_trait.iter() |associated_trait| {
encode_trait_ref(ebml_w, ecx, *associated_trait); encode_trait_ref(ebml_w, ecx, *associated_trait);
} }
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); // XXX: Bad copy.
encode_path(ecx, ebml_w, copy path, ast_map::path_name(item.ident));
ebml_w.end_tag(); ebml_w.end_tag();
let impl_path = vec::append_one(path, let impl_path = vec::append_one(path,
ast_map::path_name(item.ident)); ast_map::path_name(item.ident));
for methods.each |m| { for methods.each |m| {
index.push({val: m.id, pos: ebml_w.writer.tell()}); index.push({val: m.id, pos: ebml_w.writer.tell()});
encode_info_for_method(ecx, ebml_w, impl_path, encode_info_for_method(ecx, ebml_w, /*bad*/copy impl_path,
should_inline(m.attrs), item.id, *m, should_inline(/*bad*/copy m.attrs),
vec::append(tps, m.tps)); item.id, *m,
vec::append(/*bad*/copy tps, m.tps));
} }
} }
item_trait(tps, traits, ref ms) => { item_trait(ref tps, ref traits, ref ms) => {
let provided_methods = dvec::DVec(); let provided_methods = dvec::DVec();
add_to_index(); add_to_index();
@ -745,10 +762,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
encode_def_id(ebml_w, local_def(item.id)); encode_def_id(ebml_w, local_def(item.id));
encode_family(ebml_w, 'I'); encode_family(ebml_w, 'I');
encode_region_param(ecx, ebml_w, item); encode_region_param(ecx, ebml_w, item);
encode_type_param_bounds(ebml_w, ecx, tps); encode_type_param_bounds(ebml_w, ecx, /*bad*/copy *tps);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ecx, ebml_w, item.ident); encode_name(ecx, ebml_w, item.ident);
encode_attributes(ebml_w, item.attrs); encode_attributes(ebml_w, /*bad*/copy item.attrs);
let mut i = 0u; let mut i = 0u;
for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| { for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| {
match (*ms)[i] { match (*ms)[i] {
@ -756,8 +773,9 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
ebml_w.start_tag(tag_item_trait_method); ebml_w.start_tag(tag_item_trait_method);
encode_def_id(ebml_w, local_def((*ty_m).id)); encode_def_id(ebml_w, local_def((*ty_m).id));
encode_name(ecx, ebml_w, mty.ident); encode_name(ecx, ebml_w, mty.ident);
encode_type_param_bounds(ebml_w, ecx, (*ty_m).tps); encode_type_param_bounds(ebml_w, ecx,
encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty)); /*bad*/copy (*ty_m).tps);
encode_type(ecx, ebml_w, ty::mk_fn(tcx, /*bad*/copy mty.fty));
encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity)); encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity));
encode_self_type(ebml_w, mty.self_ty); encode_self_type(ebml_w, mty.self_ty);
encode_method_sort(ebml_w, 'r'); encode_method_sort(ebml_w, 'r');
@ -769,8 +787,8 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
ebml_w.start_tag(tag_item_trait_method); ebml_w.start_tag(tag_item_trait_method);
encode_def_id(ebml_w, local_def(m.id)); encode_def_id(ebml_w, local_def(m.id));
encode_name(ecx, ebml_w, mty.ident); encode_name(ecx, ebml_w, mty.ident);
encode_type_param_bounds(ebml_w, ecx, m.tps); encode_type_param_bounds(ebml_w, ecx, /*bad*/copy m.tps);
encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty)); encode_type(ecx, ebml_w, ty::mk_fn(tcx, /*bad*/copy mty.fty));
encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity)); encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity));
encode_self_type(ebml_w, mty.self_ty); encode_self_type(ebml_w, mty.self_ty);
encode_method_sort(ebml_w, 'p'); encode_method_sort(ebml_w, 'p');
@ -779,7 +797,8 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
} }
i += 1u; i += 1u;
} }
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); // XXX: Bad copy.
encode_path(ecx, ebml_w, copy path, ast_map::path_name(item.ident));
for traits.each |associated_trait| { for traits.each |associated_trait| {
encode_trait_ref(ebml_w, ecx, *associated_trait) encode_trait_ref(ebml_w, ecx, *associated_trait)
} }
@ -805,7 +824,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
let polyty = ecx.tcx.tcache.get(local_def(ty_m.id)); let polyty = ecx.tcx.tcache.get(local_def(ty_m.id));
encode_ty_type_param_bounds(ebml_w, ecx, polyty.bounds); encode_ty_type_param_bounds(ebml_w, ecx, polyty.bounds);
encode_type(ecx, ebml_w, polyty.ty); encode_type(ecx, ebml_w, polyty.ty);
let m_path = vec::append_one(path, let m_path = vec::append_one(/*bad*/copy path,
ast_map::path_name(item.ident)); ast_map::path_name(item.ident));
encode_path(ecx, ebml_w, m_path, ast_map::path_name(ty_m.ident)); encode_path(ecx, ebml_w, m_path, ast_map::path_name(ty_m.ident));
ebml_w.end_tag(); ebml_w.end_tag();
@ -814,30 +833,33 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
// Finally, output all the provided methods as items. // Finally, output all the provided methods as items.
for provided_methods.each |m| { for provided_methods.each |m| {
index.push({val: m.id, pos: ebml_w.writer.tell()}); index.push({val: m.id, pos: ebml_w.writer.tell()});
encode_info_for_method(ecx, ebml_w, path, true, item.id, *m, encode_info_for_method(ecx, ebml_w, /*bad*/copy path,
m.tps); true, item.id, *m, /*bad*/copy m.tps);
} }
} }
item_mac(*) => fail ~"item macros unimplemented" item_mac(*) => fail ~"item macros unimplemented"
} }
} }
fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: writer::Encoder, fn encode_info_for_foreign_item(ecx: @encode_ctxt,
ebml_w: writer::Encoder,
nitem: @foreign_item, nitem: @foreign_item,
index: @mut ~[entry<int>], index: @mut ~[entry<int>],
path: ast_map::path, abi: foreign_abi) { +path: ast_map::path,
abi: foreign_abi) {
if !reachable(ecx, nitem.id) { return; } if !reachable(ecx, nitem.id) { return; }
index.push({val: nitem.id, pos: ebml_w.writer.tell()}); index.push({val: nitem.id, pos: ebml_w.writer.tell()});
ebml_w.start_tag(tag_items_data_item); ebml_w.start_tag(tag_items_data_item);
match nitem.node { match /*bad*/copy nitem.node {
foreign_item_fn(_, purity, tps) => { foreign_item_fn(_, purity, tps) => {
encode_def_id(ebml_w, local_def(nitem.id)); encode_def_id(ebml_w, local_def(nitem.id));
encode_family(ebml_w, purity_fn_family(purity)); encode_family(ebml_w, purity_fn_family(purity));
encode_type_param_bounds(ebml_w, ecx, tps); encode_type_param_bounds(ebml_w, ecx, tps);
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id)); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
if abi == foreign_abi_rust_intrinsic { if abi == foreign_abi_rust_intrinsic {
(ecx.encode_inlined_item)(ecx, ebml_w, path, // XXX: Bad copy of `path`.
(ecx.encode_inlined_item)(ecx, ebml_w, copy path,
ii_foreign(nitem)); ii_foreign(nitem));
} else { } else {
encode_symbol(ecx, ebml_w, nitem.id); encode_symbol(ecx, ebml_w, nitem.id);
@ -869,7 +891,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
visit::visit_item(i, cx, v); visit::visit_item(i, cx, v);
match ecx.tcx.items.get(i.id) { match ecx.tcx.items.get(i.id) {
ast_map::node_item(_, pt) => { ast_map::node_item(_, pt) => {
encode_info_for_item(ecx, ebml_w, i, index, *pt); encode_info_for_item(ecx, ebml_w, i, index, /*bad*/copy *pt);
} }
_ => fail ~"bad item" _ => fail ~"bad item"
} }
@ -879,7 +901,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
match ecx.tcx.items.get(ni.id) { match ecx.tcx.items.get(ni.id) {
ast_map::node_foreign_item(_, abi, pt) => { ast_map::node_foreign_item(_, abi, pt) => {
encode_info_for_foreign_item(ecx, ebml_w, ni, encode_info_for_foreign_item(ecx, ebml_w, ni,
index, *pt, abi); index, /*bad*/copy *pt, abi);
} }
// case for separate item and foreign-item tables // case for separate item and foreign-item tables
_ => fail ~"bad foreign item" _ => fail ~"bad foreign item"
@ -888,7 +910,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
,.. *visit::default_visitor() ,.. *visit::default_visitor()
})); }));
ebml_w.end_tag(); ebml_w.end_tag();
return *index; return /*bad*/copy *index;
} }
@ -905,7 +927,7 @@ fn create_index<T: Copy Hash IterBytes>(index: ~[entry<T>]) ->
let mut buckets_frozen = ~[]; let mut buckets_frozen = ~[];
for buckets.each |bucket| { for buckets.each |bucket| {
buckets_frozen.push(@**bucket); buckets_frozen.push(@/*bad*/copy **bucket);
} }
return buckets_frozen; return buckets_frozen;
} }
@ -969,7 +991,7 @@ fn encode_meta_item(ebml_w: writer::Encoder, mi: meta_item) {
_ => {/* FIXME (#623): encode other variants */ } _ => {/* FIXME (#623): encode other variants */ }
} }
} }
meta_list(ref name, items) => { meta_list(ref name, ref items) => {
ebml_w.start_tag(tag_meta_item_list); ebml_w.start_tag(tag_meta_item_list);
ebml_w.start_tag(tag_meta_item_name); ebml_w.start_tag(tag_meta_item_name);
ebml_w.writer.write(str::to_bytes((*name))); ebml_w.writer.write(str::to_bytes((*name)));
@ -998,16 +1020,18 @@ fn encode_attributes(ebml_w: writer::Encoder, attrs: ~[attribute]) {
// them in anyway with default values. // them in anyway with default values.
fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] { fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] {
fn synthesize_link_attr(ecx: @encode_ctxt, items: ~[@meta_item]) -> fn synthesize_link_attr(ecx: @encode_ctxt, +items: ~[@meta_item]) ->
attribute { attribute {
assert (ecx.link_meta.name != ~""); assert (ecx.link_meta.name != ~"");
assert (ecx.link_meta.vers != ~""); assert (ecx.link_meta.vers != ~"");
let name_item = let name_item =
attr::mk_name_value_item_str(~"name", ecx.link_meta.name); attr::mk_name_value_item_str(~"name",
/*bad*/copy ecx.link_meta.name);
let vers_item = let vers_item =
attr::mk_name_value_item_str(~"vers", ecx.link_meta.vers); attr::mk_name_value_item_str(~"vers",
/*bad*/copy ecx.link_meta.vers);
let other_items = let other_items =
{ {
@ -1026,14 +1050,14 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] {
for crate.node.attrs.each |attr| { for crate.node.attrs.each |attr| {
attrs.push( attrs.push(
if attr::get_attr_name(*attr) != ~"link" { if attr::get_attr_name(*attr) != ~"link" {
*attr /*bad*/copy *attr
} else { } else {
match attr.node.value.node { match /*bad*/copy attr.node.value.node {
meta_list(_, l) => { meta_list(_, l) => {
found_link_attr = true;; found_link_attr = true;;
synthesize_link_attr(ecx, l) synthesize_link_attr(ecx, l)
} }
_ => *attr _ => /*bad*/copy *attr
} }
}); });
} }
@ -1055,7 +1079,8 @@ fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: writer::Encoder,
// Pull the cnums and name,vers,hash out of cstore // Pull the cnums and name,vers,hash out of cstore
let mut deps: ~[numdep] = ~[]; let mut deps: ~[numdep] = ~[];
do cstore::iter_crate_data(cstore) |key, val| { do cstore::iter_crate_data(cstore) |key, val| {
let dep = {cnum: key, name: ecx.tcx.sess.ident_of(val.name), let dep = {cnum: key,
name: ecx.tcx.sess.ident_of(/*bad*/copy val.name),
vers: decoder::get_crate_vers(val.data), vers: decoder::get_crate_vers(val.data),
hash: decoder::get_crate_hash(val.data)}; hash: decoder::get_crate_hash(val.data)};
deps.push(dep); deps.push(dep);
@ -1161,7 +1186,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
reexports2: parms.reexports2, reexports2: parms.reexports2,
item_symbols: parms.item_symbols, item_symbols: parms.item_symbols,
discrim_symbols: parms.discrim_symbols, discrim_symbols: parms.discrim_symbols,
link_meta: parms.link_meta, link_meta: /*bad*/copy parms.link_meta,
cstore: parms.cstore, cstore: parms.cstore,
encode_inlined_item: parms.encode_inlined_item, encode_inlined_item: parms.encode_inlined_item,
type_abbrevs: ty::new_ty_hash() type_abbrevs: ty::new_ty_hash()
@ -1169,7 +1194,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
let ebml_w = writer::Encoder(wr as io::Writer); let ebml_w = writer::Encoder(wr as io::Writer);
encode_hash(ebml_w, ecx.link_meta.extras_hash); encode_hash(ebml_w, /*bad*/copy ecx.link_meta.extras_hash);
let mut i = wr.pos; let mut i = wr.pos;
let crate_attrs = synthesize_crate_attrs(ecx, crate); let crate_attrs = synthesize_crate_attrs(ecx, crate);

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// A module for searching for libraries // A module for searching for libraries
// FIXME (#2658): I'm not happy how this module turned out. Should // FIXME (#2658): I'm not happy how this module turned out. Should
// probably just be folded into cstore. // probably just be folded into cstore.
@ -45,24 +46,24 @@ trait FileSearch {
fn mk_filesearch(maybe_sysroot: Option<Path>, fn mk_filesearch(maybe_sysroot: Option<Path>,
target_triple: &str, target_triple: &str,
addl_lib_search_paths: ~[Path]) -> FileSearch { +addl_lib_search_paths: ~[Path]) -> FileSearch {
type filesearch_impl = {sysroot: Path, type filesearch_impl = {sysroot: Path,
addl_lib_search_paths: ~[Path], addl_lib_search_paths: ~[Path],
target_triple: ~str}; target_triple: ~str};
impl filesearch_impl: FileSearch { impl filesearch_impl: FileSearch {
fn sysroot() -> Path { self.sysroot } fn sysroot() -> Path { /*bad*/copy self.sysroot }
fn lib_search_paths() -> ~[Path] { fn lib_search_paths() -> ~[Path] {
let mut paths = self.addl_lib_search_paths; let mut paths = /*bad*/copy self.addl_lib_search_paths;
paths.push( paths.push(
make_target_lib_path(&self.sysroot, make_target_lib_path(&self.sysroot,
self.target_triple)); self.target_triple));
match get_cargo_lib_path_nearest() { match get_cargo_lib_path_nearest() {
result::Ok(ref p) => paths.push((*p)), result::Ok(ref p) => paths.push((/*bad*/copy *p)),
result::Err(_) => () result::Err(_) => ()
} }
match get_cargo_lib_path() { match get_cargo_lib_path() {
result::Ok(ref p) => paths.push((*p)), result::Ok(ref p) => paths.push((/*bad*/copy *p)),
result::Err(_) => () result::Err(_) => ()
} }
paths paths
@ -122,7 +123,7 @@ fn get_or_default_sysroot() -> Path {
fn get_sysroot(maybe_sysroot: Option<Path>) -> Path { fn get_sysroot(maybe_sysroot: Option<Path>) -> Path {
match maybe_sysroot { match maybe_sysroot {
option::Some(ref sr) => (*sr), option::Some(ref sr) => (/*bad*/copy *sr),
option::None => get_or_default_sysroot() option::None => get_or_default_sysroot()
} }
} }
@ -146,7 +147,7 @@ fn get_cargo_root_nearest() -> Result<Path, ~str> {
let cwd = os::getcwd(); let cwd = os::getcwd();
let cwd_cargo = cwd.push(".cargo"); let cwd_cargo = cwd.push(".cargo");
let mut par_cargo = cwd.pop().push(".cargo"); let mut par_cargo = cwd.pop().push(".cargo");
let mut rslt = result::Ok(cwd_cargo); let mut rslt = result::Ok(copy cwd_cargo); // XXX: Bad copy.
if !os::path_is_dir(&cwd_cargo) && cwd_cargo != p { if !os::path_is_dir(&cwd_cargo) && cwd_cargo != p {
while par_cargo != p { while par_cargo != p {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//! Finds crate binaries and loads their metadata //! Finds crate binaries and loads their metadata
use lib::llvm::{False, llvm, mk_object_file, mk_section_iter}; use lib::llvm::{False, llvm, mk_object_file, mk_section_iter};
@ -62,7 +63,7 @@ type ctxt = {
fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} { fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} {
match find_library_crate(cx) { match find_library_crate(cx) {
Some(ref t) => return (*t), Some(ref t) => return (/*bad*/copy *t),
None => { None => {
cx.diag.span_fatal( cx.diag.span_fatal(
cx.span, fmt!("can't find crate for `%s`", cx.span, fmt!("can't find crate for `%s`",
@ -72,7 +73,7 @@ fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} {
} }
fn find_library_crate(cx: ctxt) -> Option<{ident: ~str, data: @~[u8]}> { fn find_library_crate(cx: ctxt) -> Option<{ident: ~str, data: @~[u8]}> {
attr::require_unique_names(cx.diag, cx.metas); attr::require_unique_names(cx.diag, /*bad*/copy cx.metas);
find_library_crate_aux(cx, libname(cx), cx.filesearch) find_library_crate_aux(cx, libname(cx), cx.filesearch)
} }
@ -90,9 +91,9 @@ fn find_library_crate_aux(cx: ctxt,
nn: {prefix: ~str, suffix: ~str}, nn: {prefix: ~str, suffix: ~str},
filesearch: filesearch::FileSearch) -> filesearch: filesearch::FileSearch) ->
Option<{ident: ~str, data: @~[u8]}> { Option<{ident: ~str, data: @~[u8]}> {
let crate_name = crate_name_from_metas(cx.metas); let crate_name = crate_name_from_metas(/*bad*/copy cx.metas);
let prefix: ~str = nn.prefix + crate_name + ~"-"; let prefix: ~str = nn.prefix + crate_name + ~"-";
let suffix: ~str = nn.suffix; let suffix: ~str = /*bad*/copy nn.suffix;
let mut matches = ~[]; let mut matches = ~[];
filesearch::search(filesearch, |path| { filesearch::search(filesearch, |path| {
@ -127,7 +128,7 @@ fn find_library_crate_aux(cx: ctxt,
if matches.is_empty() { if matches.is_empty() {
None None
} else if matches.len() == 1u { } else if matches.len() == 1u {
Some(matches[0]) Some(/*bad*/copy matches[0])
} else { } else {
cx.diag.span_err( cx.diag.span_err(
cx.span, fmt!("multiple matching crates for `%s`", crate_name)); cx.span, fmt!("multiple matching crates for `%s`", crate_name));
@ -142,12 +143,12 @@ fn find_library_crate_aux(cx: ctxt,
} }
} }
fn crate_name_from_metas(metas: ~[@ast::meta_item]) -> ~str { fn crate_name_from_metas(+metas: ~[@ast::meta_item]) -> ~str {
let name_items = attr::find_meta_items_by_name(metas, ~"name"); let name_items = attr::find_meta_items_by_name(metas, ~"name");
match vec::last_opt(name_items) { match vec::last_opt(name_items) {
Some(i) => { Some(i) => {
match attr::get_meta_item_value_str(i) { match attr::get_meta_item_value_str(i) {
Some(ref n) => (*n), Some(ref n) => (/*bad*/copy *n),
// FIXME (#2406): Probably want a warning here since the user // FIXME (#2406): Probably want a warning here since the user
// is using the wrong type of meta item. // is using the wrong type of meta item.
_ => fail _ => fail
@ -165,7 +166,7 @@ fn note_linkage_attrs(intr: @ident_interner, diag: span_handler,
} }
} }
fn crate_matches(crate_data: @~[u8], metas: ~[@ast::meta_item], fn crate_matches(crate_data: @~[u8], +metas: ~[@ast::meta_item],
hash: ~str) -> bool { hash: ~str) -> bool {
let attrs = decoder::get_crate_attributes(crate_data); let attrs = decoder::get_crate_attributes(crate_data);
let linkage_metas = attr::find_linkage_metas(attrs); let linkage_metas = attr::find_linkage_metas(attrs);

View File

@ -9,6 +9,7 @@
// except according to those terms. // except according to those terms.
#[legacy_exports]; #[legacy_exports];
export encoder; export encoder;
export creader; export creader;
export cstore; export cstore;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// Type decoding // Type decoding
// tjc note: Would be great to have a `match check` macro equivalent // tjc note: Would be great to have a `match check` macro equivalent

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// Type encoding // Type encoding
use middle::ty; use middle::ty;
@ -60,12 +61,12 @@ fn enc_ty(w: io::Writer, cx: @ctxt, t: ty::t) {
match cx.abbrevs { match cx.abbrevs {
ac_no_abbrevs => { ac_no_abbrevs => {
let result_str = match cx.tcx.short_names_cache.find(t) { let result_str = match cx.tcx.short_names_cache.find(t) {
Some(s) => *s, Some(s) => /*bad*/copy *s,
None => { None => {
let s = do io::with_str_writer |wr| { let s = do io::with_str_writer |wr| {
enc_sty(wr, cx, ty::get(t).sty); enc_sty(wr, cx, /*bad*/copy ty::get(t).sty);
}; };
cx.tcx.short_names_cache.insert(t, @s); cx.tcx.short_names_cache.insert(t, @copy s);
s s
} }
}; };
@ -89,7 +90,7 @@ fn enc_ty(w: io::Writer, cx: @ctxt, t: ty::t) {
} }
_ => {} _ => {}
} }
enc_sty(w, cx, ty::get(t).sty); enc_sty(w, cx, /*bad*/copy ty::get(t).sty);
let end = w.tell(); let end = w.tell();
let len = end - pos; let len = end - pos;
fn estimate_sz(u: uint) -> uint { fn estimate_sz(u: uint) -> uint {
@ -210,7 +211,7 @@ fn enc_vstore(w: io::Writer, cx: @ctxt, v: ty::vstore) {
} }
} }
fn enc_sty(w: io::Writer, cx: @ctxt, st: ty::sty) { fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
match st { match st {
ty::ty_nil => w.write_char('n'), ty::ty_nil => w.write_char('n'),
ty::ty_bot => w.write_char('z'), ty::ty_bot => w.write_char('z'),

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use c = metadata::common; use c = metadata::common;
use cstore = metadata::cstore; use cstore = metadata::cstore;
use driver::session::Session; use driver::session::Session;
@ -113,7 +114,7 @@ fn encode_inlined_item(ecx: @e::encode_ctxt,
fn decode_inlined_item(cdata: cstore::crate_metadata, fn decode_inlined_item(cdata: cstore::crate_metadata,
tcx: ty::ctxt, tcx: ty::ctxt,
maps: maps, maps: maps,
path: ast_map::path, +path: ast_map::path,
par_doc: ebml::Doc) -> Option<ast::inlined_item> { par_doc: ebml::Doc) -> Option<ast::inlined_item> {
let dcx = @{cdata: cdata, tcx: tcx, maps: maps}; let dcx = @{cdata: cdata, tcx: tcx, maps: maps};
match par_doc.opt_child(c::tag_ast) { match par_doc.opt_child(c::tag_ast) {
@ -129,8 +130,9 @@ fn decode_inlined_item(cdata: cstore::crate_metadata,
to_id_range: to_id_range}); to_id_range: to_id_range});
let raw_ii = decode_ast(ast_doc); let raw_ii = decode_ast(ast_doc);
let ii = renumber_ast(xcx, raw_ii); let ii = renumber_ast(xcx, raw_ii);
// XXX: Bad copy of `path`.
ast_map::map_decoded_item(tcx.sess.diagnostic(), ast_map::map_decoded_item(tcx.sess.diagnostic(),
dcx.tcx.items, path, ii); dcx.tcx.items, copy path, ii);
debug!("Fn named: %s", tcx.sess.str_of(ii.ident())); debug!("Fn named: %s", tcx.sess.str_of(ii.ident()));
decode_side_tables(xcx, ast_doc); decode_side_tables(xcx, ast_doc);
debug!("< Decoded inlined fn: %s::%s", debug!("< Decoded inlined fn: %s::%s",
@ -261,7 +263,8 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
ast::stmt_mac(*) => fail ~"unexpanded macro in astencode" ast::stmt_mac(*) => fail ~"unexpanded macro in astencode"
} }
}; };
let blk_sans_items = { stmts: stmts_sans_items,.. blk }; // XXX: Bad copy.
let blk_sans_items = { stmts: stmts_sans_items,.. copy blk };
fold::noop_fold_block(blk_sans_items, fld) fold::noop_fold_block(blk_sans_items, fld)
} }
@ -280,11 +283,11 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
ast::ii_foreign(i) => { ast::ii_foreign(i) => {
ast::ii_foreign(fld.fold_foreign_item(i)) ast::ii_foreign(fld.fold_foreign_item(i))
} }
ast::ii_dtor(ref dtor, nm, tps, parent_id) => { ast::ii_dtor(ref dtor, nm, ref tps, parent_id) => {
let dtor_body = fld.fold_block((*dtor).node.body); let dtor_body = fld.fold_block((*dtor).node.body);
ast::ii_dtor({node: {body: dtor_body, ast::ii_dtor({node: {body: dtor_body,
.. (*dtor).node}, .. /*bad*/copy (*dtor).node},
.. (*dtor)}, nm, tps, parent_id) .. (/*bad*/copy *dtor)}, nm, /*bad*/copy *tps, parent_id)
} }
} }
} }
@ -313,16 +316,16 @@ fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item)
ast::ii_foreign(i) => { ast::ii_foreign(i) => {
ast::ii_foreign(fld.fold_foreign_item(i)) ast::ii_foreign(fld.fold_foreign_item(i))
} }
ast::ii_dtor(ref dtor, nm, tps, parent_id) => { ast::ii_dtor(ref dtor, nm, ref tps, parent_id) => {
let dtor_body = fld.fold_block((*dtor).node.body); let dtor_body = fld.fold_block((*dtor).node.body);
let dtor_attrs = fld.fold_attributes((*dtor).node.attrs); let dtor_attrs = fld.fold_attributes(/*bad*/copy (*dtor).node.attrs);
let new_params = fold::fold_ty_params(tps, fld); let new_params = fold::fold_ty_params(/*bad*/copy *tps, fld);
let dtor_id = fld.new_id((*dtor).node.id); let dtor_id = fld.new_id((*dtor).node.id);
let new_parent = xcx.tr_def_id(parent_id); let new_parent = xcx.tr_def_id(parent_id);
let new_self = fld.new_id((*dtor).node.self_id); let new_self = fld.new_id((*dtor).node.self_id);
ast::ii_dtor({node: {id: dtor_id, attrs: dtor_attrs, ast::ii_dtor({node: {id: dtor_id, attrs: dtor_attrs,
self_id: new_self, body: dtor_body}, self_id: new_self, body: dtor_body},
.. (*dtor)}, .. (/*bad*/copy *dtor)},
nm, new_params, new_parent) nm, new_params, new_parent)
} }
} }
@ -520,7 +523,7 @@ fn encode_vtable_res(ecx: @e::encode_ctxt,
// ty::t doesn't work, and there is no way (atm) to have // ty::t doesn't work, and there is no way (atm) to have
// hand-written encoding routines combine with auto-generated // hand-written encoding routines combine with auto-generated
// ones. perhaps we should fix this. // ones. perhaps we should fix this.
do ebml_w.emit_from_vec(*dr) |vtable_origin| { do ebml_w.emit_from_vec(/*bad*/copy *dr) |vtable_origin| {
encode_vtable_origin(ecx, ebml_w, *vtable_origin) encode_vtable_origin(ecx, ebml_w, *vtable_origin)
} }
} }
@ -529,14 +532,14 @@ fn encode_vtable_origin(ecx: @e::encode_ctxt,
ebml_w: writer::Encoder, ebml_w: writer::Encoder,
vtable_origin: typeck::vtable_origin) { vtable_origin: typeck::vtable_origin) {
do ebml_w.emit_enum(~"vtable_origin") { do ebml_w.emit_enum(~"vtable_origin") {
match vtable_origin { match /*bad*/copy vtable_origin {
typeck::vtable_static(def_id, tys, vtable_res) => { typeck::vtable_static(def_id, tys, vtable_res) => {
do ebml_w.emit_enum_variant(~"vtable_static", 0u, 3u) { do ebml_w.emit_enum_variant(~"vtable_static", 0u, 3u) {
do ebml_w.emit_enum_variant_arg(0u) { do ebml_w.emit_enum_variant_arg(0u) {
ebml_w.emit_def_id(def_id) ebml_w.emit_def_id(def_id)
} }
do ebml_w.emit_enum_variant_arg(1u) { do ebml_w.emit_enum_variant_arg(1u) {
ebml_w.emit_tys(ecx, tys); ebml_w.emit_tys(ecx, /*bad*/copy tys);
} }
do ebml_w.emit_enum_variant_arg(2u) { do ebml_w.emit_enum_variant_arg(2u) {
encode_vtable_res(ecx, ebml_w, vtable_res); encode_vtable_res(ecx, ebml_w, vtable_res);
@ -559,7 +562,7 @@ fn encode_vtable_origin(ecx: @e::encode_ctxt,
ebml_w.emit_def_id(def_id) ebml_w.emit_def_id(def_id)
} }
do ebml_w.emit_enum_variant_arg(1u) { do ebml_w.emit_enum_variant_arg(1u) {
ebml_w.emit_tys(ecx, tys); ebml_w.emit_tys(ecx, /*bad*/copy tys);
} }
} }
} }
@ -670,7 +673,8 @@ impl writer::Encoder: ebml_writer_helpers {
} }
fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]) { fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]) {
do self.emit_from_vec(tys) |ty| { // XXX: Bad copy.
do self.emit_from_vec(copy tys) |ty| {
self.emit_ty(ecx, *ty) self.emit_ty(ecx, *ty)
} }
} }
@ -684,7 +688,7 @@ impl writer::Encoder: ebml_writer_helpers {
fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty) { fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty) {
do self.emit_rec { do self.emit_rec {
do self.emit_field(~"bounds", 0u) { do self.emit_field(~"bounds", 0u) {
do self.emit_from_vec(*tpbt.bounds) |bs| { do self.emit_from_vec(/*bad*/copy *tpbt.bounds) |bs| {
self.emit_bounds(ecx, *bs); self.emit_bounds(ecx, *bs);
} }
} }
@ -758,7 +762,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
do ebml_w.tag(c::tag_table_node_type_subst) { do ebml_w.tag(c::tag_table_node_type_subst) {
ebml_w.id(id); ebml_w.id(id);
do ebml_w.tag(c::tag_table_val) { do ebml_w.tag(c::tag_table_val) {
ebml_w.emit_tys(ecx, *tys) ebml_w.emit_tys(ecx, /*bad*/copy *tys)
} }
} }
} }
@ -767,7 +771,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
do ebml_w.tag(c::tag_table_freevars) { do ebml_w.tag(c::tag_table_freevars) {
ebml_w.id(id); ebml_w.id(id);
do ebml_w.tag(c::tag_table_val) { do ebml_w.tag(c::tag_table_val) {
do ebml_w.emit_from_vec(**fv) |fv_entry| { do ebml_w.emit_from_vec(/*bad*/copy **fv) |fv_entry| {
encode_freevar_entry(ebml_w, *fv_entry) encode_freevar_entry(ebml_w, *fv_entry)
} }
} }

View File

@ -17,6 +17,7 @@
// 3. assignments do not affect things loaned out as immutable // 3. assignments do not affect things loaned out as immutable
// 4. moves to dnot affect things loaned out in any way // 4. moves to dnot affect things loaned out in any way
use middle::ty::{CopyValue, MoveValue, ReadValue}; use middle::ty::{CopyValue, MoveValue, ReadValue};
use middle::ty; use middle::ty;
@ -631,7 +632,7 @@ fn check_loans_in_expr(expr: @ast::expr,
Some(ReadValue) | Some(CopyValue) | None => {} Some(ReadValue) | Some(CopyValue) | None => {}
} }
match expr.node { match /*bad*/copy expr.node {
ast::expr_path(*) if self.bccx.last_use_map.contains_key(expr.id) => { ast::expr_path(*) if self.bccx.last_use_map.contains_key(expr.id) => {
self.check_last_use(expr); self.check_last_use(expr);
} }

View File

@ -16,6 +16,7 @@
// their associated scopes. In phase two, checking loans, we will then make // their associated scopes. In phase two, checking loans, we will then make
// sure that all of these loans are honored. // sure that all of these loans are honored.
use middle::borrowck::preserve::{preserve_condition, pc_ok, pc_if_pure}; use middle::borrowck::preserve::{preserve_condition, pc_ok, pc_if_pure};
use middle::mem_categorization::{mem_categorization_ctxt, opt_deref_kind}; use middle::mem_categorization::{mem_categorization_ctxt, opt_deref_kind};
use middle::pat_util; use middle::pat_util;
@ -122,7 +123,7 @@ fn req_loans_in_expr(ex: @ast::expr,
} }
// Special checks for various kinds of expressions: // Special checks for various kinds of expressions:
match ex.node { match /*bad*/copy ex.node {
ast::expr_addr_of(mutbl, base) => { ast::expr_addr_of(mutbl, base) => {
let base_cmt = self.bccx.cat_expr(base); let base_cmt = self.bccx.cat_expr(base);

View File

@ -12,6 +12,7 @@
// Loan(Ex, M, S) = Ls holds if ToAddr(Ex) will remain valid for the entirety // Loan(Ex, M, S) = Ls holds if ToAddr(Ex) will remain valid for the entirety
// of the scope S, presuming that the returned set of loans `Ls` are honored. // of the scope S, presuming that the returned set of loans `Ls` are honored.
use middle::ty; use middle::ty;
use core::result::{Result, Ok, Err}; use core::result::{Result, Ok, Err};

View File

@ -519,11 +519,11 @@ impl borrowck_ctxt {
self.note_and_explain_bckerr(err); self.note_and_explain_bckerr(err);
} }
fn span_err(s: span, m: ~str) { fn span_err(s: span, +m: ~str) {
self.tcx.sess.span_err(s, m); self.tcx.sess.span_err(s, m);
} }
fn span_note(s: span, m: ~str) { fn span_note(s: span, +m: ~str) {
self.tcx.sess.span_note(s, m); self.tcx.sess.span_note(s, m);
} }

View File

@ -13,6 +13,7 @@
// the scope S. // the scope S.
// //
use middle::ty; use middle::ty;
use syntax::ast; use syntax::ast;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::freevars; use middle::freevars;
use middle::ty; use middle::ty;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::const_eval::{compare_const_vals, lookup_const_by_id}; use middle::const_eval::{compare_const_vals, lookup_const_by_id};
use middle::const_eval::{eval_const_expr, const_val, const_int, const_bool}; use middle::const_eval::{eval_const_expr, const_val, const_int, const_bool};
use middle::pat_util::*; use middle::pat_util::*;
@ -73,7 +74,7 @@ fn check_expr(cx: @AltCheckCtxt, ex: @expr, &&s: (), v: visit::vt<()>) {
arm.pats); arm.pats);
} }
check_arms(cx, (*arms)); check_arms(cx, (/*bad*/copy *arms));
/* Check for exhaustiveness */ /* Check for exhaustiveness */
// Check for empty enum, because is_useful only works on inhabited // Check for empty enum, because is_useful only works on inhabited
// types. // types.
@ -215,7 +216,7 @@ impl ctor : cmp::Eq {
// Note: is_useful doesn't work on empty types, as the paper notes. // Note: is_useful doesn't work on empty types, as the paper notes.
// So it assumes that v is non-empty. // So it assumes that v is non-empty.
fn is_useful(cx: @AltCheckCtxt, m: matrix, v: ~[@pat]) -> useful { fn is_useful(cx: @AltCheckCtxt, +m: matrix, +v: ~[@pat]) -> useful {
if m.len() == 0u { return useful_; } if m.len() == 0u { return useful_; }
if m[0].len() == 0u { return not_useful; } if m[0].len() == 0u { return not_useful; }
let real_pat = match vec::find(m, |r| r[0].id != 0) { let real_pat = match vec::find(m, |r| r[0].id != 0) {
@ -238,7 +239,7 @@ fn is_useful(cx: @AltCheckCtxt, m: matrix, v: ~[@pat]) -> useful {
val(const_bool(false)), val(const_bool(false)),
0u, left_ty) 0u, left_ty)
} }
ref u => (*u) ref u => (/*bad*/copy *u)
} }
} }
ty::ty_enum(eid, _) => { ty::ty_enum(eid, _) => {
@ -246,14 +247,14 @@ fn is_useful(cx: @AltCheckCtxt, m: matrix, v: ~[@pat]) -> useful {
match is_useful_specialized(cx, m, v, variant(va.id), match is_useful_specialized(cx, m, v, variant(va.id),
va.args.len(), left_ty) { va.args.len(), left_ty) {
not_useful => (), not_useful => (),
ref u => return (*u) ref u => return (/*bad*/copy *u)
} }
} }
not_useful not_useful
} }
ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
let max_len = do m.foldr(0) |r, max_len| { let max_len = do m.foldr(0) |r, max_len| {
match r[0].node { match /*bad*/copy r[0].node {
pat_vec(elems, _) => uint::max(elems.len(), max_len), pat_vec(elems, _) => uint::max(elems.len(), max_len),
_ => max_len _ => max_len
} }
@ -261,7 +262,7 @@ fn is_useful(cx: @AltCheckCtxt, m: matrix, v: ~[@pat]) -> useful {
for uint::range(0, max_len + 1) |n| { for uint::range(0, max_len + 1) |n| {
match is_useful_specialized(cx, m, v, vec(n), n, left_ty) { match is_useful_specialized(cx, m, v, vec(n), n, left_ty) {
not_useful => (), not_useful => (),
ref u => return (*u) ref u => return (/*bad*/copy *u)
} }
} }
not_useful not_useful
@ -275,33 +276,33 @@ fn is_useful(cx: @AltCheckCtxt, m: matrix, v: ~[@pat]) -> useful {
Some(ref ctor) => { Some(ref ctor) => {
match is_useful(cx, vec::filter_map(m, |r| default(cx, *r)), match is_useful(cx, vec::filter_map(m, |r| default(cx, *r)),
vec::tail(v)) { vec::tail(v)) {
useful_ => useful(left_ty, (*ctor)), useful_ => useful(left_ty, (/*bad*/copy *ctor)),
ref u => (*u) ref u => (/*bad*/copy *u)
} }
} }
} }
} }
Some(ref v0_ctor) => { Some(ref v0_ctor) => {
let arity = ctor_arity(cx, (*v0_ctor), left_ty); let arity = ctor_arity(cx, (*v0_ctor), left_ty);
is_useful_specialized(cx, m, v, (*v0_ctor), arity, left_ty) is_useful_specialized(cx, m, v, /*bad*/copy *v0_ctor, arity, left_ty)
} }
} }
} }
fn is_useful_specialized(cx: @AltCheckCtxt, m: matrix, v: ~[@pat], ctor: ctor, fn is_useful_specialized(cx: @AltCheckCtxt, m: matrix, +v: ~[@pat],
arity: uint, lty: ty::t) -> useful { +ctor: ctor, arity: uint, lty: ty::t) -> useful {
let ms = vec::filter_map(m, |r| specialize(cx, *r, ctor, arity, lty)); let ms = vec::filter_map(m, |r| specialize(cx, *r, ctor, arity, lty));
let could_be_useful = is_useful( let could_be_useful = is_useful(
cx, ms, specialize(cx, v, ctor, arity, lty).get()); cx, ms, specialize(cx, v, ctor, arity, lty).get());
match could_be_useful { match could_be_useful {
useful_ => useful(lty, ctor), useful_ => useful(lty, ctor),
ref u => (*u) ref u => (/*bad*/copy *u)
} }
} }
fn pat_ctor_id(cx: @AltCheckCtxt, p: @pat) -> Option<ctor> { fn pat_ctor_id(cx: @AltCheckCtxt, p: @pat) -> Option<ctor> {
let pat = raw_pat(p); let pat = raw_pat(p);
match pat.node { match /*bad*/copy pat.node {
pat_wild => { None } pat_wild => { None }
pat_ident(_, _, _) | pat_enum(_, _) => { pat_ident(_, _, _) | pat_enum(_, _) => {
match cx.tcx.def_map.find(pat.id) { match cx.tcx.def_map.find(pat.id) {
@ -367,7 +368,7 @@ fn missing_ctor(cx: @AltCheckCtxt,
for m.each |r| { for m.each |r| {
do option::iter(&pat_ctor_id(cx, r[0])) |id| { do option::iter(&pat_ctor_id(cx, r[0])) |id| {
if !vec::contains(found, id) { if !vec::contains(found, id) {
found.push(*id); found.push(/*bad*/copy *id);
} }
} }
} }
@ -400,7 +401,7 @@ fn missing_ctor(cx: @AltCheckCtxt,
// Find the lengths and tails of all vector patterns. // Find the lengths and tails of all vector patterns.
let vec_pat_lens = do m.filter_map |r| { let vec_pat_lens = do m.filter_map |r| {
match r[0].node { match /*bad*/copy r[0].node {
pat_vec(elems, tail) => { pat_vec(elems, tail) => {
Some((elems.len(), tail.is_some())) Some((elems.len(), tail.is_some()))
} }
@ -451,7 +452,7 @@ fn missing_ctor(cx: @AltCheckCtxt,
} }
fn ctor_arity(cx: @AltCheckCtxt, ctor: ctor, ty: ty::t) -> uint { fn ctor_arity(cx: @AltCheckCtxt, ctor: ctor, ty: ty::t) -> uint {
match ty::get(ty).sty { match /*bad*/copy ty::get(ty).sty {
ty::ty_tup(fs) => fs.len(), ty::ty_tup(fs) => fs.len(),
ty::ty_rec(fs) => fs.len(), ty::ty_rec(fs) => fs.len(),
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) => 1u, ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) => 1u,
@ -481,7 +482,7 @@ fn wild() -> @pat {
fn specialize(cx: @AltCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint, fn specialize(cx: @AltCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint,
left_ty: ty::t) -> Option<~[@pat]> { left_ty: ty::t) -> Option<~[@pat]> {
let r0 = raw_pat(r[0]); let r0 = raw_pat(r[0]);
match r0.node { match /*bad*/copy r0.node {
pat_wild => Some(vec::append(vec::from_elem(arity, wild()), pat_wild => Some(vec::append(vec::from_elem(arity, wild()),
vec::tail(r))), vec::tail(r))),
pat_ident(_, _, _) => { pat_ident(_, _, _) => {
@ -530,7 +531,7 @@ fn specialize(cx: @AltCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint,
} }
} }
pat_rec(flds, _) => { pat_rec(flds, _) => {
let ty_flds = match ty::get(left_ty).sty { let ty_flds = match /*bad*/copy ty::get(left_ty).sty {
ty::ty_rec(flds) => flds, ty::ty_rec(flds) => flds,
_ => fail ~"bad type for pat_rec" _ => fail ~"bad type for pat_rec"
}; };
@ -602,8 +603,8 @@ fn specialize(cx: @AltCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint,
} }
pat_range(lo, hi) => { pat_range(lo, hi) => {
let (c_lo, c_hi) = match ctor_id { let (c_lo, c_hi) = match ctor_id {
val(ref v) => ((*v), (*v)), val(ref v) => ((/*bad*/copy *v), (/*bad*/copy *v)),
range(ref lo, ref hi) => ((*lo), (*hi)), range(ref lo, ref hi) => ((/*bad*/copy *lo), (/*bad*/copy *hi)),
single => return Some(vec::tail(r)), single => return Some(vec::tail(r)),
_ => fail ~"type error" _ => fail ~"type error"
}; };
@ -617,8 +618,9 @@ fn specialize(cx: @AltCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint,
match ctor_id { match ctor_id {
vec(_) => { vec(_) => {
if elems.len() < arity && tail.is_some() { if elems.len() < arity && tail.is_some() {
// XXX: Bad copy.
Some(vec::append( Some(vec::append(
vec::append(elems, vec::from_elem( vec::append(copy elems, vec::from_elem(
arity - elems.len(), wild() arity - elems.len(), wild()
)), )),
vec::tail(r) vec::tail(r)
@ -683,7 +685,7 @@ fn is_refutable(cx: @AltCheckCtxt, pat: &pat) -> bool {
_ => () _ => ()
} }
match pat.node { match /*bad*/copy pat.node {
pat_box(sub) | pat_uniq(sub) | pat_region(sub) | pat_box(sub) | pat_uniq(sub) | pat_region(sub) |
pat_ident(_, _, Some(sub)) => { pat_ident(_, _, Some(sub)) => {
is_refutable(cx, sub) is_refutable(cx, sub)

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use driver::session::Session; use driver::session::Session;
use middle::resolve; use middle::resolve;
use middle::ty; use middle::ty;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use syntax::ast::*; use syntax::ast::*;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::resolve; use middle::resolve;
use middle::ty; use middle::ty;
use middle; use middle;
@ -79,7 +80,7 @@ fn classify(e: @expr,
Some(x) => x, Some(x) => x,
None => { None => {
let cn = let cn =
match e.node { match /*bad*/copy e.node {
ast::expr_lit(lit) => { ast::expr_lit(lit) => {
match lit.node { match lit.node {
ast::lit_str(*) | ast::lit_str(*) |
@ -241,8 +242,8 @@ impl const_val : cmp::Eq {
fn eval_const_expr(tcx: middle::ty::ctxt, e: @expr) -> const_val { fn eval_const_expr(tcx: middle::ty::ctxt, e: @expr) -> const_val {
match eval_const_expr_partial(tcx, e) { match eval_const_expr_partial(tcx, e) {
Ok(ref r) => (*r), Ok(ref r) => (/*bad*/copy *r),
Err(ref s) => fail (*s) Err(ref s) => fail (/*bad*/copy *s)
} }
} }
@ -258,7 +259,7 @@ fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: @expr)
Ok(const_uint(i)) => Ok(const_uint(-i)), Ok(const_uint(i)) => Ok(const_uint(-i)),
Ok(const_str(_)) => Err(~"Negate on string"), Ok(const_str(_)) => Err(~"Negate on string"),
Ok(const_bool(_)) => Err(~"Negate on boolean"), Ok(const_bool(_)) => Err(~"Negate on boolean"),
ref err => (*err) ref err => (/*bad*/copy *err)
} }
} }
expr_unary(not, inner) => { expr_unary(not, inner) => {
@ -405,7 +406,7 @@ fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: @expr)
fn lit_to_const(lit: @lit) -> const_val { fn lit_to_const(lit: @lit) -> const_val {
match lit.node { match lit.node {
lit_str(s) => const_str(*s), lit_str(s) => const_str(/*bad*/copy *s),
lit_int(n, _) => const_int(n), lit_int(n, _) => const_int(n),
lit_uint(n, _) => const_uint(n), lit_uint(n, _) => const_uint(n),
lit_int_unsuffixed(n) => const_int(n), lit_int_unsuffixed(n) => const_int(n),

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// A pass that annotates for each loops and functions with the free // A pass that annotates for each loops and functions with the free
// variables that they contain. // variables that they contain.
@ -92,7 +93,7 @@ fn collect_freevars(def_map: resolve::DefMap, blk: ast::blk)
let v = visit::mk_vt(@{visit_item: ignore_item, visit_expr: walk_expr, let v = visit::mk_vt(@{visit_item: ignore_item, visit_expr: walk_expr,
.. *visit::default_visitor()}); .. *visit::default_visitor()});
(v.visit_block)(blk, 1, v); (v.visit_block)(blk, 1, v);
return @*refs; return @/*bad*/copy *refs;
} }
// Build a map from every function and for-each body to a set of the // Build a map from every function and for-each body to a set of the

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::freevars::freevar_entry; use middle::freevars::freevar_entry;
use middle::freevars; use middle::freevars;
use middle::lint::{non_implicitly_copyable_typarams, implicit_copies}; use middle::lint::{non_implicitly_copyable_typarams, implicit_copies};
@ -296,7 +297,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
} }
} }
match e.node { match /*bad*/copy e.node {
expr_assign(_, ex) | expr_assign(_, ex) |
expr_unary(box(_), ex) | expr_unary(uniq(_), ex) | expr_unary(box(_), ex) | expr_unary(uniq(_), ex) |
expr_ret(Some(ex)) => { expr_ret(Some(ex)) => {
@ -329,7 +330,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
Some(ex) => { Some(ex) => {
// All noncopyable fields must be overridden // All noncopyable fields must be overridden
let t = ty::expr_ty(cx.tcx, ex); let t = ty::expr_ty(cx.tcx, ex);
let ty_fields = match ty::get(t).sty { let ty_fields = match /*bad*/copy ty::get(t).sty {
ty::ty_rec(f) => f, ty::ty_rec(f) => f,
ty::ty_struct(did, ref substs) => ty::ty_struct(did, ref substs) =>
ty::struct_fields(cx.tcx, did, &(*substs)), ty::struct_fields(cx.tcx, did, &(*substs)),
@ -407,7 +408,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
fn check_stmt(stmt: @stmt, cx: ctx, v: visit::vt<ctx>) { fn check_stmt(stmt: @stmt, cx: ctx, v: visit::vt<ctx>) {
match stmt.node { match stmt.node {
stmt_decl(@{node: decl_local(locals), _}, _) => { stmt_decl(@{node: decl_local(ref locals), _}, _) => {
for locals.each |local| { for locals.each |local| {
match local.node.init { match local.node.init {
Some(expr) => Some(expr) =>
@ -614,7 +615,7 @@ fn check_cast_for_escaping_regions(
// worries. // worries.
let target_ty = ty::expr_ty(cx.tcx, target); let target_ty = ty::expr_ty(cx.tcx, target);
let target_substs = match ty::get(target_ty).sty { let target_substs = match ty::get(target_ty).sty {
ty::ty_trait(_, ref substs, _) => {(*substs)} ty::ty_trait(_, ref substs, _) => {(/*bad*/copy *substs)}
_ => { return; /* not a cast to a trait */ } _ => { return; /* not a cast to a trait */ }
}; };

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// Detecting language items. // Detecting language items.
// //
// Language items are items that represent concepts intrinsic to the language // Language items are items that represent concepts intrinsic to the language
@ -287,8 +288,8 @@ impl LanguageItemCollector {
match literal.node { match literal.node {
lit_str(value) => { lit_str(value) => {
self.match_and_collect_item(item_def_id, self.match_and_collect_item(item_def_id,
(*key), (/*bad*/copy *key),
*value); /*bad*/copy *value);
} }
_ => {} // Skip. _ => {} // Skip.
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use driver::session::Session; use driver::session::Session;
use driver::session; use driver::session;
use middle::pat_util::{pat_bindings}; use middle::pat_util::{pat_bindings};
@ -310,7 +311,7 @@ impl ctxt {
} }
} }
fn span_lint(level: level, span: span, msg: ~str) { fn span_lint(level: level, span: span, +msg: ~str) {
self.sess.span_lint_level(level, span, msg); self.sess.span_lint_level(level, span, msg);
} }
@ -327,15 +328,17 @@ impl ctxt {
for [allow, warn, deny, forbid].each |level| { for [allow, warn, deny, forbid].each |level| {
let level_name = level_to_str(*level); let level_name = level_to_str(*level);
let metas = let metas =
attr::attr_metas(attr::find_attrs_by_name(attrs, attr::attr_metas(attr::find_attrs_by_name(/*bad*/copy attrs,
level_name)); level_name));
for metas.each |meta| { for metas.each |meta| {
match meta.node { match /*bad*/copy meta.node {
ast::meta_list(_, metas) => { ast::meta_list(_, metas) => {
for metas.each |meta| { for metas.each |meta| {
match meta.node { match meta.node {
ast::meta_word(ref lintname) => { ast::meta_word(ref lintname) => {
triples.push((*meta, *level, *lintname)); triples.push((*meta,
*level,
/*bad*/copy *lintname));
} }
_ => { _ => {
self.sess.span_err( self.sess.span_err(
@ -354,7 +357,7 @@ impl ctxt {
} }
for triples.each |pair| { for triples.each |pair| {
let (meta, level, lintname) = *pair; let (meta, level, lintname) = /*bad*/copy *pair;
match self.dict.find(lintname) { match self.dict.find(lintname) {
None => { None => {
self.span_lint( self.span_lint(
@ -394,7 +397,7 @@ impl ctxt {
fn build_settings_item(i: @ast::item, &&cx: ctxt, v: visit::vt<ctxt>) { fn build_settings_item(i: @ast::item, &&cx: ctxt, v: visit::vt<ctxt>) {
do cx.with_lint_attrs(i.attrs) |cx| { do cx.with_lint_attrs(/*bad*/copy i.attrs) |cx| {
if !cx.is_default { if !cx.is_default {
cx.sess.lint_settings.settings_map.insert(i.id, cx.curr); cx.sess.lint_settings.settings_map.insert(i.id, cx.curr);
} }
@ -418,7 +421,7 @@ fn build_settings_crate(sess: session::Session, crate: @ast::crate) {
cx.set_level(lint, level); cx.set_level(lint, level);
} }
do cx.with_lint_attrs(crate.node.attrs) |cx| { do cx.with_lint_attrs(/*bad*/copy crate.node.attrs) |cx| {
// Copy out the default settings // Copy out the default settings
for cx.curr.each |k, v| { for cx.curr.each |k, v| {
sess.lint_settings.default_settings.insert(k, v); sess.lint_settings.default_settings.insert(k, v);
@ -538,7 +541,7 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) {
} else { } else {
binop binop
}; };
match ty::get(ty::expr_ty(cx, @*expr)).sty { match ty::get(ty::expr_ty(cx, @/*bad*/copy *expr)).sty {
ty::ty_int(int_ty) => { ty::ty_int(int_ty) => {
let (min, max) = int_ty_range(int_ty); let (min, max) = int_ty_range(int_ty);
let lit_val: i64 = match lit.node { let lit_val: i64 = match lit.node {
@ -597,7 +600,7 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) {
} }
fn check_item_default_methods(cx: ty::ctxt, item: @ast::item) { fn check_item_default_methods(cx: ty::ctxt, item: @ast::item) {
match item.node { match /*bad*/copy item.node {
ast::item_trait(_, _, methods) => { ast::item_trait(_, _, methods) => {
for methods.each |method| { for methods.each |method| {
match *method { match *method {
@ -630,10 +633,10 @@ fn check_item_deprecated_self(cx: ty::ctxt, item: @ast::item) {
parameter or mark the method as static"); parameter or mark the method as static");
} }
match item.node { match /*bad*/copy item.node {
ast::item_trait(_, _, methods) => { ast::item_trait(_, _, methods) => {
for methods.each |method| { for methods.each |method| {
match *method { match /*bad*/copy *method {
ast::required(ty_method) => { ast::required(ty_method) => {
maybe_warn(cx, item, ty_method.self_ty); maybe_warn(cx, item, ty_method.self_ty);
} }
@ -701,10 +704,11 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
} }
match it.node { match it.node {
ast::item_foreign_mod(nmod) if attr::foreign_abi(it.attrs) != ast::item_foreign_mod(ref nmod)
either::Right(ast::foreign_abi_rust_intrinsic) => { if attr::foreign_abi(it.attrs) !=
either::Right(ast::foreign_abi_rust_intrinsic) => {
for nmod.items.each |ni| { for nmod.items.each |ni| {
match ni.node { match /*bad*/copy ni.node {
ast::foreign_item_fn(decl, _, _) => { ast::foreign_item_fn(decl, _, _) => {
check_foreign_fn(cx, it.id, decl); check_foreign_fn(cx, it.id, decl);
} }
@ -812,14 +816,14 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) {
!ident.contains_char('_') !ident.contains_char('_')
} }
fn ident_without_trailing_underscores(ident: ~str) -> ~str { fn ident_without_trailing_underscores(+ident: ~str) -> ~str {
match str::rfind(ident, |c| c != '_') { match str::rfind(ident, |c| c != '_') {
Some(idx) => (ident).slice(0, idx + 1), Some(idx) => (ident).slice(0, idx + 1),
None => { ident } // all underscores None => { ident } // all underscores
} }
} }
fn ident_without_leading_underscores(ident: ~str) -> ~str { fn ident_without_leading_underscores(+ident: ~str) -> ~str {
match str::find(ident, |c| c != '_') { match str::find(ident, |c| c != '_') {
Some(idx) => ident.slice(idx, ident.len()), Some(idx) => ident.slice(idx, ident.len()),
None => { None => {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
/*! /*!
* A classic liveness analysis based on dataflow over the AST. Computes, * A classic liveness analysis based on dataflow over the AST. Computes,
* for each local variable in a function, whether that variable is live * for each local variable in a function, whether that variable is live
@ -1032,7 +1033,7 @@ impl Liveness {
} }
fn propagate_through_decl(decl: @decl, succ: LiveNode) -> LiveNode { fn propagate_through_decl(decl: @decl, succ: LiveNode) -> LiveNode {
match decl.node { match /*bad*/copy decl.node {
decl_local(locals) => { decl_local(locals) => {
do locals.foldr(succ) |local, succ| { do locals.foldr(succ) |local, succ| {
self.propagate_through_local(*local, succ) self.propagate_through_local(*local, succ)
@ -1081,7 +1082,7 @@ impl Liveness {
debug!("propagate_through_expr: %s", debug!("propagate_through_expr: %s",
expr_to_str(expr, self.tcx.sess.intr())); expr_to_str(expr, self.tcx.sess.intr()));
match expr.node { match /*bad*/copy expr.node {
// Interesting cases with control flow or which gen/kill // Interesting cases with control flow or which gen/kill
expr_path(_) => { expr_path(_) => {
@ -1562,7 +1563,7 @@ fn check_call(args: &[@expr],
} }
fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) { fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
match expr.node { match /*bad*/copy expr.node {
expr_path(_) => { expr_path(_) => {
for self.variable_from_def_map(expr.id, expr.span).each |var| { for self.variable_from_def_map(expr.id, expr.span).each |var| {
let ln = self.live_node(expr.id, expr.span); let ln = self.live_node(expr.id, expr.span);

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
/*! /*!
* # Categorization * # Categorization
* *
@ -913,7 +914,7 @@ impl &mem_categorization_ctxt {
pat.id, pprust::pat_to_str(pat, tcx.sess.intr()), pat.id, pprust::pat_to_str(pat, tcx.sess.intr()),
self.cmt_to_repr(cmt)); self.cmt_to_repr(cmt));
match pat.node { match /*bad*/copy pat.node {
ast::pat_wild => { ast::pat_wild => {
// _ // _
} }
@ -1117,7 +1118,7 @@ fn field_mutbl(tcx: ty::ctxt,
f_name: ast::ident, f_name: ast::ident,
node_id: ast::node_id) -> Option<ast::mutability> { node_id: ast::node_id) -> Option<ast::mutability> {
// Need to refactor so that records/class fields can be treated uniformly. // Need to refactor so that records/class fields can be treated uniformly.
match ty::get(base_ty).sty { match /*bad*/copy ty::get(base_ty).sty {
ty::ty_rec(fields) => { ty::ty_rec(fields) => {
for fields.each |f| { for fields.each |f| {
if f.ident == f_name { if f.ident == f_name {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::pat_util; use middle::pat_util;
use middle::ty; use middle::ty;
use middle::ty::{CopyValue, MoveValue, ReadValue, ValueMode, ctxt}; use middle::ty::{CopyValue, MoveValue, ReadValue, ValueMode, ctxt};
@ -89,7 +90,7 @@ fn compute_modes_for_expr(expr: @expr,
} }
}; };
match expr.node { match /*bad*/copy expr.node {
expr_call(callee, args, is_block) => { expr_call(callee, args, is_block) => {
let callee_cx = VisitContext { mode: ReadValue, ..cx }; let callee_cx = VisitContext { mode: ReadValue, ..cx };
compute_modes_for_expr(callee, callee_cx, v); compute_modes_for_expr(callee, callee_cx, v);

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::resolve; use middle::resolve;
use middle::ty::{CopyValue, MoveValue, ReadValue}; use middle::ty::{CopyValue, MoveValue, ReadValue};
use middle::ty; use middle::ty;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// A pass that checks to make sure private fields and methods aren't used // A pass that checks to make sure private fields and methods aren't used
// outside their scopes. // outside their scopes.
@ -311,7 +312,7 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
visit::visit_expr(expr, method_map, visitor); visit::visit_expr(expr, method_map, visitor);
}, },
visit_pat: |pattern, method_map, visitor| { visit_pat: |pattern, method_map, visitor| {
match pattern.node { match /*bad*/copy pattern.node {
pat_struct(_, fields, _) => { pat_struct(_, fields, _) => {
match ty::get(ty::pat_ty(tcx, pattern)).sty { match ty::get(ty::pat_ty(tcx, pattern)).sty {
ty_struct(id, _) => { ty_struct(id, _) => {

View File

@ -17,6 +17,7 @@ region parameterized.
*/ */
use driver::session::Session; use driver::session::Session;
use metadata::csearch; use metadata::csearch;
use middle::resolve; use middle::resolve;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use driver::session::Session; use driver::session::Session;
use metadata::csearch::{each_path, get_method_names_if_trait}; use metadata::csearch::{each_path, get_method_names_if_trait};
use metadata::csearch::{get_static_methods_if_impl, get_type_name_if_impl}; use metadata::csearch::{get_static_methods_if_impl, get_type_name_if_impl};
@ -1126,7 +1127,7 @@ impl Resolver {
}; };
let privacy = visibility_to_privacy(item.vis, legacy); let privacy = visibility_to_privacy(item.vis, legacy);
match item.node { match /*bad*/copy item.node {
item_mod(module_) => { item_mod(module_) => {
let legacy = has_legacy_export_attr(item.attrs); let legacy = has_legacy_export_attr(item.attrs);
let (name_bindings, new_parent) = let (name_bindings, new_parent) =
@ -1458,7 +1459,7 @@ impl Resolver {
ModuleReducedGraphParent(m) => m.legacy_exports ModuleReducedGraphParent(m) => m.legacy_exports
}; };
let privacy = visibility_to_privacy(view_item.vis, legacy); let privacy = visibility_to_privacy(view_item.vis, legacy);
match view_item.node { match /*bad*/copy view_item.node {
view_item_import(view_paths) => { view_item_import(view_paths) => {
for view_paths.each |view_path| { for view_paths.each |view_path| {
// Extract and intern the module part of the path. For // Extract and intern the module part of the path. For
@ -1626,7 +1627,7 @@ impl Resolver {
self.add_child(name, parent, ForbidDuplicateValues, self.add_child(name, parent, ForbidDuplicateValues,
foreign_item.span); foreign_item.span);
match foreign_item.node { match /*bad*/copy foreign_item.node {
foreign_item_fn(_, purity, type_parameters) => { foreign_item_fn(_, purity, type_parameters) => {
let def = def_fn(local_def(foreign_item.id), purity); let def = def_fn(local_def(foreign_item.id), purity);
(*name_bindings).define_value(Public, def, foreign_item.span); (*name_bindings).define_value(Public, def, foreign_item.span);
@ -1809,7 +1810,7 @@ impl Resolver {
let mut current_module = root; let mut current_module = root;
for pieces.each |ident_str| { for pieces.each |ident_str| {
let ident = self.session.ident_of(*ident_str); let ident = self.session.ident_of(/*bad*/copy *ident_str);
// Create or reuse a graph node for the child. // Create or reuse a graph node for the child.
let (child_name_bindings, new_parent) = let (child_name_bindings, new_parent) =
self.add_child(ident, self.add_child(ident,
@ -1869,9 +1870,6 @@ impl Resolver {
} }
dl_impl(def) => { dl_impl(def) => {
// We only process static methods of impls here. // We only process static methods of impls here.
debug!("(building reduced graph for external crate) \
processing impl %s", final_ident_str);
match get_type_name_if_impl(self.session.cstore, def) { match get_type_name_if_impl(self.session.cstore, def) {
None => {} None => {}
Some(final_ident) => { Some(final_ident) => {
@ -1879,7 +1877,7 @@ impl Resolver {
get_static_methods_if_impl( get_static_methods_if_impl(
self.session.cstore, def); self.session.cstore, def);
match static_methods_opt { match static_methods_opt {
Some(static_methods) if Some(ref static_methods) if
static_methods.len() >= 1 => { static_methods.len() >= 1 => {
debug!("(building reduced graph for \ debug!("(building reduced graph for \
external crate) processing \ external crate) processing \
@ -1955,7 +1953,7 @@ impl Resolver {
} }
dl_field => { dl_field => {
debug!("(building reduced graph for external crate) \ debug!("(building reduced graph for external crate) \
ignoring field %s", final_ident_str); ignoring field");
} }
} }
} }
@ -3816,15 +3814,16 @@ impl Resolver {
// Items with the !resolve_unexported attribute are X-ray contexts. // Items with the !resolve_unexported attribute are X-ray contexts.
// This is used to allow the test runner to run unexported tests. // This is used to allow the test runner to run unexported tests.
let orig_xray_flag = self.xray_context; let orig_xray_flag = self.xray_context;
if contains_name(attr_metas(item.attrs), ~"!resolve_unexported") { if contains_name(attr_metas(/*bad*/copy item.attrs),
~"!resolve_unexported") {
self.xray_context = Xray; self.xray_context = Xray;
} }
match item.node { match /*bad*/copy item.node {
// enum item: resolve all the variants' discrs, // enum item: resolve all the variants' discrs,
// then resolve the ty params // then resolve the ty params
item_enum(ref enum_def, type_parameters) => { item_enum(ref enum_def, ref type_parameters) => {
for (*enum_def).variants.each() |variant| { for (*enum_def).variants.each() |variant| {
do variant.node.disr_expr.iter() |dis_expr| { do variant.node.disr_expr.iter() |dis_expr| {
@ -3839,11 +3838,9 @@ impl Resolver {
// n.b. the discr expr gets visted twice. // n.b. the discr expr gets visted twice.
// but maybe it's okay since the first time will signal an // but maybe it's okay since the first time will signal an
// error if there is one? -- tjc // error if there is one? -- tjc
do self.with_type_parameter_rib do self.with_type_parameter_rib(
(HasTypeParameters(&type_parameters, item.id, 0, HasTypeParameters(
NormalRibKind)) type_parameters, item.id, 0, NormalRibKind)) {
|| {
visit_item(item, (), visitor); visit_item(item, (), visitor);
} }
} }
@ -3871,7 +3868,7 @@ impl Resolver {
visitor); visitor);
} }
item_trait(type_parameters, traits, ref methods) => { item_trait(ref type_parameters, ref traits, ref methods) => {
// Create a new rib for the self type. // Create a new rib for the self type.
let self_type_rib = @Rib(NormalRibKind); let self_type_rib = @Rib(NormalRibKind);
(*self.type_ribs).push(self_type_rib); (*self.type_ribs).push(self_type_rib);
@ -3880,10 +3877,11 @@ impl Resolver {
// Create a new rib for the trait-wide type parameters. // Create a new rib for the trait-wide type parameters.
do self.with_type_parameter_rib do self.with_type_parameter_rib
(HasTypeParameters(&type_parameters, item.id, 0, (HasTypeParameters(type_parameters, item.id, 0,
NormalRibKind)) { NormalRibKind)) {
self.resolve_type_parameters(type_parameters, visitor); self.resolve_type_parameters(/*bad*/copy *type_parameters,
visitor);
// Resolve derived traits. // Resolve derived traits.
for traits.each |trt| { for traits.each |trt| {
@ -3922,8 +3920,9 @@ impl Resolver {
// Resolve the method-specific type // Resolve the method-specific type
// parameters. // parameters.
self.resolve_type_parameters((*ty_m).tps, self.resolve_type_parameters(
visitor); /*bad*/copy (*ty_m).tps,
visitor);
for (*ty_m).decl.inputs.each |argument| { for (*ty_m).decl.inputs.each |argument| {
self.resolve_type(argument.ty, visitor); self.resolve_type(argument.ty, visitor);
@ -3949,7 +3948,7 @@ impl Resolver {
item_struct(struct_def, ty_params) => { item_struct(struct_def, ty_params) => {
self.resolve_struct(item.id, self.resolve_struct(item.id,
@copy ty_params, @copy ty_params,
struct_def.fields, /*bad*/copy struct_def.fields,
struct_def.dtor, struct_def.dtor,
visitor); visitor);
} }
@ -3964,7 +3963,7 @@ impl Resolver {
item_foreign_mod(foreign_module) => { item_foreign_mod(foreign_module) => {
do self.with_scope(Some(item.ident)) { do self.with_scope(Some(item.ident)) {
for foreign_module.items.each |foreign_item| { for foreign_module.items.each |foreign_item| {
match foreign_item.node { match /*bad*/copy foreign_item.node {
foreign_item_fn(_, _, type_parameters) => { foreign_item_fn(_, _, type_parameters) => {
do self.with_type_parameter_rib do self.with_type_parameter_rib
(HasTypeParameters(&type_parameters, (HasTypeParameters(&type_parameters,
@ -3986,7 +3985,7 @@ impl Resolver {
} }
} }
item_fn(fn_decl, _, ty_params, ref block) => { item_fn(ref fn_decl, _, ref ty_params, ref block) => {
// If this is the main function, we must record it in the // If this is the main function, we must record it in the
// session. // session.
// //
@ -4001,9 +4000,9 @@ impl Resolver {
} }
self.resolve_function(OpaqueFunctionRibKind, self.resolve_function(OpaqueFunctionRibKind,
Some(@fn_decl), Some(@/*bad*/copy *fn_decl),
HasTypeParameters HasTypeParameters
(&ty_params, (ty_params,
item.id, item.id,
0, 0,
OpaqueFunctionRibKind), OpaqueFunctionRibKind),
@ -4128,7 +4127,8 @@ impl Resolver {
// Continue. // Continue.
} }
HasTypeParameters(type_parameters, _, _, _) => { HasTypeParameters(type_parameters, _, _, _) => {
self.resolve_type_parameters(*type_parameters, visitor); self.resolve_type_parameters(/*bad*/copy *type_parameters,
visitor);
} }
} }
@ -4200,7 +4200,8 @@ impl Resolver {
OpaqueFunctionRibKind)) { OpaqueFunctionRibKind)) {
// Resolve the type parameters. // Resolve the type parameters.
self.resolve_type_parameters(*type_parameters, visitor); self.resolve_type_parameters(/*bad*/copy *type_parameters,
visitor);
// Resolve fields. // Resolve fields.
for fields.each |field| { for fields.each |field| {
@ -4247,7 +4248,7 @@ impl Resolver {
}; };
self.resolve_function(rib_kind, self.resolve_function(rib_kind,
Some(@method.decl), Some(@/*bad*/copy method.decl),
type_parameters, type_parameters,
method.body, method.body,
self_binding, self_binding,
@ -4269,7 +4270,8 @@ impl Resolver {
(borrowed_type_parameters, id, 0, (borrowed_type_parameters, id, 0,
NormalRibKind)) { NormalRibKind)) {
// Resolve the type parameters. // Resolve the type parameters.
self.resolve_type_parameters(type_parameters, visitor); self.resolve_type_parameters(/*bad*/copy type_parameters,
visitor);
// Resolve the trait reference, if necessary. // Resolve the trait reference, if necessary.
let original_trait_refs = self.current_trait_refs; let original_trait_refs = self.current_trait_refs;
@ -5114,7 +5116,8 @@ impl Resolver {
self.record_def(expr.id, def); self.record_def(expr.id, def);
} }
None => { None => {
let wrong_name = self.idents_to_str(path.idents); let wrong_name = self.idents_to_str(
/*bad*/copy path.idents);
if self.name_exists_in_scope_struct(wrong_name) { if self.name_exists_in_scope_struct(wrong_name) {
self.session.span_err(expr.span, self.session.span_err(expr.span,
fmt!("unresolved name: `%s`. \ fmt!("unresolved name: `%s`. \
@ -5133,10 +5136,10 @@ impl Resolver {
visit_expr(expr, (), visitor); visit_expr(expr, (), visitor);
} }
expr_fn(_, fn_decl, ref block, capture_clause) | expr_fn(_, ref fn_decl, ref block, capture_clause) |
expr_fn_block(fn_decl, ref block, capture_clause) => { expr_fn_block(ref fn_decl, ref block, capture_clause) => {
self.resolve_function(FunctionRibKind(expr.id, block.node.id), self.resolve_function(FunctionRibKind(expr.id, block.node.id),
Some(@fn_decl), Some(@/*bad*/copy *fn_decl),
NoTypeParameters, NoTypeParameters,
(*block), (*block),
NoSelfBinding, NoSelfBinding,

View File

@ -142,6 +142,7 @@
* *
*/ */
use back::abi; use back::abi;
use lib::llvm::llvm; use lib::llvm::llvm;
use lib::llvm::{ValueRef, BasicBlockRef}; use lib::llvm::{ValueRef, BasicBlockRef};
@ -499,7 +500,7 @@ fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
let tcx = bcx.tcx(); let tcx = bcx.tcx();
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()}; let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
do enter_match(bcx, tcx.def_map, m, col, val) |p| { do enter_match(bcx, tcx.def_map, m, col, val) |p| {
match p.node { match /*bad*/copy p.node {
ast::pat_enum(_, subpats) => { ast::pat_enum(_, subpats) => {
if opt_eq(tcx, &variant_opt(tcx, p.id), opt) { if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
Some(option::get_or_default(subpats, Some(option::get_or_default(subpats,
@ -600,7 +601,7 @@ fn enter_rec_or_struct(bcx: block, dm: DefMap, m: &[@Match/&r], col: uint,
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()}; let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
do enter_match(bcx, dm, m, col, val) |p| { do enter_match(bcx, dm, m, col, val) |p| {
match p.node { match /*bad*/copy p.node {
ast::pat_rec(fpats, _) | ast::pat_struct(_, fpats, _) => { ast::pat_rec(fpats, _) | ast::pat_struct(_, fpats, _) => {
let mut pats = ~[]; let mut pats = ~[];
for vec::each(fields) |fname| { for vec::each(fields) |fname| {
@ -632,7 +633,7 @@ fn enter_tup(bcx: block, dm: DefMap, m: &[@Match/&r],
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()}; let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
do enter_match(bcx, dm, m, col, val) |p| { do enter_match(bcx, dm, m, col, val) |p| {
match p.node { match /*bad*/copy p.node {
ast::pat_tup(elts) => { ast::pat_tup(elts) => {
Some(elts) Some(elts)
} }
@ -657,7 +658,7 @@ fn enter_tuple_struct(bcx: block, dm: DefMap, m: &[@Match/&r], col: uint,
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()}; let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
do enter_match(bcx, dm, m, col, val) |p| { do enter_match(bcx, dm, m, col, val) |p| {
match p.node { match /*bad*/copy p.node {
ast::pat_enum(_, Some(elts)) => Some(elts), ast::pat_enum(_, Some(elts)) => Some(elts),
_ => { _ => {
assert_is_binding_or_wild(bcx, p); assert_is_binding_or_wild(bcx, p);
@ -754,7 +755,7 @@ fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] {
let found = DVec(); let found = DVec();
for vec::each(m) |br| { for vec::each(m) |br| {
let cur = br.pats[col]; let cur = br.pats[col];
match cur.node { match /*bad*/copy cur.node {
ast::pat_lit(l) => { ast::pat_lit(l) => {
add_to_set(ccx.tcx, &found, lit(ExprLit(l))); add_to_set(ccx.tcx, &found, lit(ExprLit(l)));
} }
@ -812,7 +813,10 @@ fn extract_variant_args(bcx: block, pat_id: ast::node_id,
let _icx = bcx.insn_ctxt("alt::extract_variant_args"); let _icx = bcx.insn_ctxt("alt::extract_variant_args");
let ccx = bcx.fcx.ccx; let ccx = bcx.fcx.ccx;
let enum_ty_substs = match ty::get(node_id_type(bcx, pat_id)).sty { let enum_ty_substs = match ty::get(node_id_type(bcx, pat_id)).sty {
ty::ty_enum(id, ref substs) => { assert id == vdefs.enm; (*substs).tps } ty::ty_enum(id, ref substs) => {
assert id == vdefs.enm;
/*bad*/copy (*substs).tps
}
_ => bcx.sess().bug(~"extract_variant_args: pattern has non-enum type") _ => bcx.sess().bug(~"extract_variant_args: pattern has non-enum type")
}; };
let mut blobptr = val; let mut blobptr = val;
@ -828,7 +832,7 @@ fn extract_variant_args(bcx: block, pat_id: ast::node_id,
let vdefs_var = vdefs.var; let vdefs_var = vdefs.var;
let args = do vec::from_fn(size) |i| { let args = do vec::from_fn(size) |i| {
GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var, GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
enum_ty_substs, i) /*bad*/copy enum_ty_substs, i)
}; };
return {vals: args, bcx: bcx}; return {vals: args, bcx: bcx};
} }
@ -873,7 +877,7 @@ fn collect_record_or_struct_fields(bcx: block, m: &[@Match], col: uint) ->
~[ast::ident] { ~[ast::ident] {
let mut fields: ~[ast::ident] = ~[]; let mut fields: ~[ast::ident] = ~[];
for vec::each(m) |br| { for vec::each(m) |br| {
match br.pats[col].node { match /*bad*/copy br.pats[col].node {
ast::pat_rec(fs, _) => extend(&mut fields, fs), ast::pat_rec(fs, _) => extend(&mut fields, fs),
ast::pat_struct(_, fs, _) => { ast::pat_struct(_, fs, _) => {
match ty::get(node_id_type(bcx, br.pats[col].id)).sty { match ty::get(node_id_type(bcx, br.pats[col].id)).sty {
@ -1259,7 +1263,7 @@ fn compile_submatch(bcx: block,
if any_tup_pat(m, col) { if any_tup_pat(m, col) {
let tup_ty = node_id_type(bcx, pat_id); let tup_ty = node_id_type(bcx, pat_id);
let n_tup_elts = match ty::get(tup_ty).sty { let n_tup_elts = match /*bad*/copy ty::get(tup_ty).sty {
ty::ty_tup(elts) => elts.len(), ty::ty_tup(elts) => elts.len(),
_ => ccx.sess.bug(~"non-tuple type in tuple pattern") _ => ccx.sess.bug(~"non-tuple type in tuple pattern")
}; };
@ -1485,7 +1489,7 @@ fn compile_submatch(bcx: block,
var(_, vdef) => { var(_, vdef) => {
let args = extract_variant_args(opt_cx, pat_id, vdef, val); let args = extract_variant_args(opt_cx, pat_id, vdef, val);
size = args.vals.len(); size = args.vals.len();
unpacked = args.vals; unpacked = /*bad*/copy args.vals;
opt_cx = args.bcx; opt_cx = args.bcx;
} }
vec_len_eq(n) | vec_len_ge(n) => { vec_len_eq(n) | vec_len_ge(n) => {
@ -1495,7 +1499,7 @@ fn compile_submatch(bcx: block,
}; };
let args = extract_vec_elems(opt_cx, pat_id, n, tail, val); let args = extract_vec_elems(opt_cx, pat_id, n, tail, val);
size = args.vals.len(); size = args.vals.len();
unpacked = args.vals; unpacked = /*bad*/copy args.vals;
opt_cx = args.bcx; opt_cx = args.bcx;
} }
lit(_) | range(_, _) => () lit(_) | range(_, _) => ()
@ -1634,7 +1638,7 @@ fn trans_alt_inner(scope_cx: block,
return controlflow::join_blocks(scope_cx, dvec::unwrap(move arm_cxs)); return controlflow::join_blocks(scope_cx, dvec::unwrap(move arm_cxs));
fn mk_fail(bcx: block, sp: span, msg: ~str, fn mk_fail(bcx: block, sp: span, +msg: ~str,
finished: @mut Option<BasicBlockRef>) -> BasicBlockRef { finished: @mut Option<BasicBlockRef>) -> BasicBlockRef {
match *finished { Some(bb) => return bb, _ => () } match *finished { Some(bb) => return bb, _ => () }
let fail_cx = sub_block(bcx, ~"case_fallthrough"); let fail_cx = sub_block(bcx, ~"case_fallthrough");
@ -1663,7 +1667,7 @@ fn bind_irrefutable_pat(bcx: block,
let mut bcx = bcx; let mut bcx = bcx;
// Necessary since bind_irrefutable_pat is called outside trans_alt // Necessary since bind_irrefutable_pat is called outside trans_alt
match pat.node { match /*bad*/copy pat.node {
ast::pat_ident(_, _,inner) => { ast::pat_ident(_, _,inner) => {
if pat_is_variant_or_struct(bcx.tcx().def_map, pat) { if pat_is_variant_or_struct(bcx.tcx().def_map, pat) {
return bcx; return bcx;

View File

@ -23,6 +23,7 @@
// but many TypeRefs correspond to one ty::t; for instance, tup(int, int, // but many TypeRefs correspond to one ty::t; for instance, tup(int, int,
// int) and rec(x=int, y=int, z=int) will have the same TypeRef. // int) and rec(x=int, y=int, z=int) will have the same TypeRef.
use back::link::{mangle_exported_name}; use back::link::{mangle_exported_name};
use back::link::{mangle_internal_name_by_path_and_seq}; use back::link::{mangle_internal_name_by_path_and_seq};
use back::link::{mangle_internal_name_by_path}; use back::link::{mangle_internal_name_by_path};
@ -126,7 +127,7 @@ impl fn_ctxt: get_insn_ctxt {
} }
} }
fn log_fn_time(ccx: @crate_ctxt, name: ~str, start: time::Timespec, fn log_fn_time(ccx: @crate_ctxt, +name: ~str, start: time::Timespec,
end: time::Timespec) { end: time::Timespec) {
let elapsed = 1000 * ((end.sec - start.sec) as int) + let elapsed = 1000 * ((end.sec - start.sec) as int) +
((end.nsec as int) - (start.nsec as int)) / 1000000; ((end.nsec as int) - (start.nsec as int)) / 1000000;
@ -142,13 +143,13 @@ fn decl_fn(llmod: ModuleRef, name: ~str, cc: lib::llvm::CallConv,
return llfn; return llfn;
} }
fn decl_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) -> ValueRef { fn decl_cdecl_fn(llmod: ModuleRef, +name: ~str, llty: TypeRef) -> ValueRef {
return decl_fn(llmod, name, lib::llvm::CCallConv, llty); return decl_fn(llmod, name, lib::llvm::CCallConv, llty);
} }
// Only use this if you are going to actually define the function. It's // Only use this if you are going to actually define the function. It's
// not valid to simply declare a function as internal. // not valid to simply declare a function as internal.
fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) -> fn decl_internal_cdecl_fn(llmod: ModuleRef, +name: ~str, llty: TypeRef) ->
ValueRef { ValueRef {
let llfn = decl_cdecl_fn(llmod, name, llty); let llfn = decl_cdecl_fn(llmod, name, llty);
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
@ -156,17 +157,22 @@ fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) ->
} }
fn get_extern_fn(externs: HashMap<~str, ValueRef>, fn get_extern_fn(externs: HashMap<~str, ValueRef>,
llmod: ModuleRef, name: ~str, llmod: ModuleRef,
cc: lib::llvm::CallConv, ty: TypeRef) -> ValueRef { +name: ~str,
if externs.contains_key(name) { return externs.get(name); } cc: lib::llvm::CallConv,
let f = decl_fn(llmod, name, cc, ty); ty: TypeRef) -> ValueRef {
// XXX: Bad copy.
if externs.contains_key(copy name) { return externs.get(name); }
// XXX: Bad copy.
let f = decl_fn(llmod, copy name, cc, ty);
externs.insert(name, f); externs.insert(name, f);
return f; return f;
} }
fn get_extern_const(externs: HashMap<~str, ValueRef>, llmod: ModuleRef, fn get_extern_const(externs: HashMap<~str, ValueRef>, llmod: ModuleRef,
name: ~str, ty: TypeRef) -> ValueRef { +name: ~str, ty: TypeRef) -> ValueRef {
if externs.contains_key(name) { return externs.get(name); } // XXX: Bad copy.
if externs.contains_key(copy name) { return externs.get(name); }
let c = str::as_c_str(name, |buf| llvm::LLVMAddGlobal(llmod, ty, buf)); let c = str::as_c_str(name, |buf| llvm::LLVMAddGlobal(llmod, ty, buf));
externs.insert(name, c); externs.insert(name, c);
return c; return c;
@ -175,7 +181,8 @@ fn get_extern_const(externs: HashMap<~str, ValueRef>, llmod: ModuleRef,
fn get_simple_extern_fn(cx: block, fn get_simple_extern_fn(cx: block,
externs: HashMap<~str, ValueRef>, externs: HashMap<~str, ValueRef>,
llmod: ModuleRef, llmod: ModuleRef,
name: ~str, n_args: int) -> ValueRef { +name: ~str,
n_args: int) -> ValueRef {
let _icx = cx.insn_ctxt("get_simple_extern_fn"); let _icx = cx.insn_ctxt("get_simple_extern_fn");
let ccx = cx.fcx.ccx; let ccx = cx.fcx.ccx;
let inputs = vec::from_elem(n_args as uint, ccx.int_type); let inputs = vec::from_elem(n_args as uint, ccx.int_type);
@ -185,7 +192,7 @@ fn get_simple_extern_fn(cx: block,
} }
fn trans_foreign_call(cx: block, externs: HashMap<~str, ValueRef>, fn trans_foreign_call(cx: block, externs: HashMap<~str, ValueRef>,
llmod: ModuleRef, name: ~str, args: ~[ValueRef]) -> llmod: ModuleRef, +name: ~str, args: ~[ValueRef]) ->
ValueRef { ValueRef {
let _icx = cx.insn_ctxt("trans_foreign_call"); let _icx = cx.insn_ctxt("trans_foreign_call");
let n = args.len() as int; let n = args.len() as int;
@ -413,8 +420,9 @@ fn set_glue_inlining(f: ValueRef, t: ty::t) {
// Double-check that we never ask LLVM to declare the same symbol twice. It // Double-check that we never ask LLVM to declare the same symbol twice. It
// silently mangles such symbols, breaking our linkage model. // silently mangles such symbols, breaking our linkage model.
fn note_unique_llvm_symbol(ccx: @crate_ctxt, sym: ~str) { fn note_unique_llvm_symbol(ccx: @crate_ctxt, +sym: ~str) {
if ccx.all_llvm_symbols.contains_key(sym) { // XXX: Bad copy.
if ccx.all_llvm_symbols.contains_key(copy sym) {
ccx.sess.bug(~"duplicate LLVM symbol: " + sym); ccx.sess.bug(~"duplicate LLVM symbol: " + sym);
} }
ccx.all_llvm_symbols.insert(sym, ()); ccx.all_llvm_symbols.insert(sym, ());
@ -570,7 +578,8 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
let mut j = 0u; let mut j = 0u;
let v_id = variant.id; let v_id = variant.id;
for vec::each(fn_ty.sig.inputs) |a| { for vec::each(fn_ty.sig.inputs) |a| {
let llfldp_a = GEP_enum(cx, a_tup, tid, v_id, tps, j); let llfldp_a = GEP_enum(cx, a_tup, tid, v_id,
/*bad*/copy tps, j);
// XXX: Is "None" right here? // XXX: Is "None" right here?
let ty_subst = ty::subst_tps(ccx.tcx, tps, None, a.ty); let ty_subst = ty::subst_tps(ccx.tcx, tps, None, a.ty);
cx = f(cx, llfldp_a, ty_subst); cx = f(cx, llfldp_a, ty_subst);
@ -585,11 +594,8 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
return cx; return cx;
} }
/*
Typestate constraint that shows the unimpl case doesn't happen?
*/
let mut cx = cx; let mut cx = cx;
match ty::get(t).sty { match /*bad*/copy ty::get(t).sty {
ty::ty_rec(*) | ty::ty_struct(*) => { ty::ty_rec(*) | ty::ty_struct(*) => {
do expr::with_field_tys(cx.tcx(), t, None) |_has_dtor, field_tys| { do expr::with_field_tys(cx.tcx(), t, None) |_has_dtor, field_tys| {
for vec::eachi(field_tys) |i, field_ty| { for vec::eachi(field_tys) |i, field_ty| {
@ -615,8 +621,12 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
// Cast the enums to types we can GEP into. // Cast the enums to types we can GEP into.
if n_variants == 1u { if n_variants == 1u {
return iter_variant(cx, av, variants[0], return iter_variant(cx,
(*substs).tps, tid, f); av,
variants[0],
/*bad*/copy substs.tps,
tid,
f);
} }
let ccx = cx.ccx(); let ccx = cx.ccx();
@ -641,7 +651,7 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
AddCase(llswitch, C_int(ccx, variant.disr_val), variant_cx.llbb); AddCase(llswitch, C_int(ccx, variant.disr_val), variant_cx.llbb);
let variant_cx = let variant_cx =
iter_variant(variant_cx, llunion_a_ptr, *variant, iter_variant(variant_cx, llunion_a_ptr, *variant,
(*substs).tps, tid, f); /*bad*/copy (*substs).tps, tid, f);
Br(variant_cx, next_cx.llbb); Br(variant_cx, next_cx.llbb);
} }
return next_cx; return next_cx;
@ -711,7 +721,7 @@ fn fail_if_zero(cx: block, span: span, divmod: ast::binop,
} }
}; };
do with_cond(cx, is_zero) |bcx| { do with_cond(cx, is_zero) |bcx| {
controlflow::trans_fail(bcx, Some(span), text) controlflow::trans_fail(bcx, Some(span), /*bad*/copy text)
} }
} }
@ -754,7 +764,7 @@ fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef {
} }
} }
fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) -> block { fn invoke(bcx: block, llfn: ValueRef, +llargs: ~[ValueRef]) -> block {
let _icx = bcx.insn_ctxt("invoke_"); let _icx = bcx.insn_ctxt("invoke_");
if bcx.unreachable { return bcx; } if bcx.unreachable { return bcx; }
if need_invoke(bcx) { if need_invoke(bcx) {
@ -954,16 +964,17 @@ fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef {
return v; return v;
} }
fn trans_trace(bcx: block, sp_opt: Option<span>, trace_str: ~str) { fn trans_trace(bcx: block, sp_opt: Option<span>, +trace_str: ~str) {
if !bcx.sess().trace() { return; } if !bcx.sess().trace() { return; }
let _icx = bcx.insn_ctxt("trans_trace"); let _icx = bcx.insn_ctxt("trans_trace");
add_comment(bcx, trace_str); // XXX: Bad copy.
add_comment(bcx, copy trace_str);
let V_trace_str = C_cstr(bcx.ccx(), trace_str); let V_trace_str = C_cstr(bcx.ccx(), trace_str);
let {V_filename, V_line} = match sp_opt { let {V_filename, V_line} = match sp_opt {
Some(sp) => { Some(sp) => {
let sess = bcx.sess(); let sess = bcx.sess();
let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo); let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo);
{V_filename: C_cstr(bcx.ccx(), loc.file.name), {V_filename: C_cstr(bcx.ccx(), /*bad*/copy loc.file.name),
V_line: loc.line as int} V_line: loc.line as int}
} }
None => { None => {
@ -1057,7 +1068,7 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
bcx = expr::trans_into(cx, e, expr::Ignore); bcx = expr::trans_into(cx, e, expr::Ignore);
} }
ast::stmt_decl(d, _) => { ast::stmt_decl(d, _) => {
match d.node { match /*bad*/copy d.node {
ast::decl_local(locals) => { ast::decl_local(locals) => {
for vec::each(locals) |local| { for vec::each(locals) |local| {
bcx = init_local(bcx, *local); bcx = init_local(bcx, *local);
@ -1078,7 +1089,7 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
// You probably don't want to use this one. See the // You probably don't want to use this one. See the
// next three functions instead. // next three functions instead.
fn new_block(cx: fn_ctxt, parent: Option<block>, +kind: block_kind, fn new_block(cx: fn_ctxt, parent: Option<block>, +kind: block_kind,
is_lpad: bool, name: ~str, opt_node_info: Option<node_info>) is_lpad: bool, +name: ~str, opt_node_info: Option<node_info>)
-> block { -> block {
let s = if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo { let s = if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo {
@ -1112,13 +1123,13 @@ fn top_scope_block(fcx: fn_ctxt, opt_node_info: Option<node_info>) -> block {
fn scope_block(bcx: block, fn scope_block(bcx: block,
opt_node_info: Option<node_info>, opt_node_info: Option<node_info>,
n: ~str) -> block { +n: ~str) -> block {
return new_block(bcx.fcx, Some(bcx), simple_block_scope(), bcx.is_lpad, return new_block(bcx.fcx, Some(bcx), simple_block_scope(), bcx.is_lpad,
n, opt_node_info); n, opt_node_info);
} }
fn loop_scope_block(bcx: block, loop_break: block, loop_label: Option<ident>, fn loop_scope_block(bcx: block, loop_break: block, loop_label: Option<ident>,
n: ~str, opt_node_info: Option<node_info>) -> block { +n: ~str, opt_node_info: Option<node_info>) -> block {
return new_block(bcx.fcx, Some(bcx), block_scope(scope_info { return new_block(bcx.fcx, Some(bcx), block_scope(scope_info {
loop_break: Some(loop_break), loop_break: Some(loop_break),
loop_label: loop_label, loop_label: loop_label,
@ -1129,12 +1140,12 @@ fn loop_scope_block(bcx: block, loop_break: block, loop_label: Option<ident>,
} }
// Use this when creating a block for the inside of a landing pad. // Use this when creating a block for the inside of a landing pad.
fn lpad_block(bcx: block, n: ~str) -> block { fn lpad_block(bcx: block, +n: ~str) -> block {
new_block(bcx.fcx, Some(bcx), block_non_scope, true, n, None) new_block(bcx.fcx, Some(bcx), block_non_scope, true, n, None)
} }
// Use this when you're making a general CFG BB within a scope. // Use this when you're making a general CFG BB within a scope.
fn sub_block(bcx: block, n: ~str) -> block { fn sub_block(bcx: block, +n: ~str) -> block {
new_block(bcx.fcx, Some(bcx), block_non_scope, bcx.is_lpad, n, None) new_block(bcx.fcx, Some(bcx), block_non_scope, bcx.is_lpad, n, None)
} }
@ -1240,7 +1251,7 @@ fn leave_block(bcx: block, out_of: block) -> block {
} }
fn with_scope(bcx: block, opt_node_info: Option<node_info>, fn with_scope(bcx: block, opt_node_info: Option<node_info>,
name: ~str, f: fn(block) -> block) -> block { +name: ~str, f: fn(block) -> block) -> block {
let _icx = bcx.insn_ctxt("with_scope"); let _icx = bcx.insn_ctxt("with_scope");
debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)", debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)",
@ -1252,10 +1263,11 @@ fn with_scope(bcx: block, opt_node_info: Option<node_info>,
leave_block(f(scope_cx), scope_cx) leave_block(f(scope_cx), scope_cx)
} }
fn with_scope_result(bcx: block, opt_node_info: Option<node_info>, fn with_scope_result(bcx: block,
name: ~str, f: fn(block) -> Result) opt_node_info: Option<node_info>,
-> Result +name: ~str,
{ f: fn(block) -> Result)
-> Result {
let _icx = bcx.insn_ctxt("with_scope_result"); let _icx = bcx.insn_ctxt("with_scope_result");
let scope_cx = scope_block(bcx, opt_node_info, name); let scope_cx = scope_block(bcx, opt_node_info, name);
Br(bcx, scope_cx.llbb); Br(bcx, scope_cx.llbb);
@ -1264,7 +1276,7 @@ fn with_scope_result(bcx: block, opt_node_info: Option<node_info>,
} }
fn with_scope_datumblock(bcx: block, opt_node_info: Option<node_info>, fn with_scope_datumblock(bcx: block, opt_node_info: Option<node_info>,
name: ~str, f: fn(block) -> datum::DatumBlock) +name: ~str, f: fn(block) -> datum::DatumBlock)
-> datum::DatumBlock -> datum::DatumBlock
{ {
use middle::trans::datum::DatumBlock; use middle::trans::datum::DatumBlock;
@ -1280,7 +1292,7 @@ fn block_locals(b: ast::blk, it: fn(@ast::local)) {
for vec::each(b.node.stmts) |s| { for vec::each(b.node.stmts) |s| {
match s.node { match s.node {
ast::stmt_decl(d, _) => { ast::stmt_decl(d, _) => {
match d.node { match /*bad*/copy d.node {
ast::decl_local(locals) => { ast::decl_local(locals) => {
for vec::each(locals) |local| { for vec::each(locals) |local| {
it(*local); it(*local);
@ -1443,11 +1455,11 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
// - new_fn_ctxt // - new_fn_ctxt
// - trans_args // - trans_args
fn new_fn_ctxt_w_id(ccx: @crate_ctxt, fn new_fn_ctxt_w_id(ccx: @crate_ctxt,
path: path, +path: path,
llfndecl: ValueRef, llfndecl: ValueRef,
id: ast::node_id, id: ast::node_id,
impl_id: Option<ast::def_id>, impl_id: Option<ast::def_id>,
param_substs: Option<param_substs>, +param_substs: Option<param_substs>,
sp: Option<span>) -> fn_ctxt { sp: Option<span>) -> fn_ctxt {
let llbbs = mk_standard_basic_blocks(llfndecl); let llbbs = mk_standard_basic_blocks(llfndecl);
return @fn_ctxt_ { return @fn_ctxt_ {
@ -1472,8 +1484,11 @@ fn new_fn_ctxt_w_id(ccx: @crate_ctxt,
}; };
} }
fn new_fn_ctxt(ccx: @crate_ctxt, path: path, llfndecl: ValueRef, fn new_fn_ctxt(ccx: @crate_ctxt,
sp: Option<span>) -> fn_ctxt { +path: path,
llfndecl: ValueRef,
sp: Option<span>)
-> fn_ctxt {
return new_fn_ctxt_w_id(ccx, path, llfndecl, -1, None, None, sp); return new_fn_ctxt_w_id(ccx, path, llfndecl, -1, None, None, sp);
} }
@ -1625,10 +1640,13 @@ enum self_arg { impl_self(ty::t), impl_owned_self(ty::t), no_self, }
// trans_closure: Builds an LLVM function out of a source function. // trans_closure: Builds an LLVM function out of a source function.
// If the function closes over its environment a closure will be // If the function closes over its environment a closure will be
// returned. // returned.
fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl, fn trans_closure(ccx: @crate_ctxt,
body: ast::blk, llfndecl: ValueRef, +path: path,
decl: ast::fn_decl,
body: ast::blk,
llfndecl: ValueRef,
ty_self: self_arg, ty_self: self_arg,
param_substs: Option<param_substs>, +param_substs: Option<param_substs>,
id: ast::node_id, id: ast::node_id,
impl_id: Option<ast::def_id>, impl_id: Option<ast::def_id>,
maybe_load_env: fn(fn_ctxt), maybe_load_env: fn(fn_ctxt),
@ -1640,7 +1658,8 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
// Set up arguments to the function. // Set up arguments to the function.
let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, id, impl_id, param_substs, let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, id, impl_id, param_substs,
Some(body.span)); Some(body.span));
let raw_llargs = create_llargs_for_fn_args(fcx, ty_self, decl.inputs); let raw_llargs = create_llargs_for_fn_args(fcx, ty_self,
/*bad*/copy decl.inputs);
// Set GC for function. // Set GC for function.
if ccx.sess.opts.gc { if ccx.sess.opts.gc {
@ -1684,12 +1703,12 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
// trans_fn: creates an LLVM function corresponding to a source language // trans_fn: creates an LLVM function corresponding to a source language
// function. // function.
fn trans_fn(ccx: @crate_ctxt, fn trans_fn(ccx: @crate_ctxt,
path: path, +path: path,
decl: ast::fn_decl, decl: ast::fn_decl,
body: ast::blk, body: ast::blk,
llfndecl: ValueRef, llfndecl: ValueRef,
ty_self: self_arg, ty_self: self_arg,
param_substs: Option<param_substs>, +param_substs: Option<param_substs>,
id: ast::node_id, id: ast::node_id,
impl_id: Option<ast::def_id>) { impl_id: Option<ast::def_id>) {
let do_time = ccx.sess.trans_stats(); let do_time = ccx.sess.trans_stats();
@ -1698,7 +1717,8 @@ fn trans_fn(ccx: @crate_ctxt,
debug!("trans_fn(ty_self=%?)", ty_self); debug!("trans_fn(ty_self=%?)", ty_self);
let _icx = ccx.insn_ctxt("trans_fn"); let _icx = ccx.insn_ctxt("trans_fn");
ccx.stats.n_fns += 1; ccx.stats.n_fns += 1;
trans_closure(ccx, path, decl, body, llfndecl, ty_self, // XXX: Bad copy of `path`.
trans_closure(ccx, copy path, decl, body, llfndecl, ty_self,
param_substs, id, impl_id, param_substs, id, impl_id,
|fcx| { |fcx| {
if ccx.sess.opts.extra_debuginfo { if ccx.sess.opts.extra_debuginfo {
@ -1718,7 +1738,7 @@ fn trans_enum_variant(ccx: @crate_ctxt,
args: ~[ast::variant_arg], args: ~[ast::variant_arg],
disr: int, disr: int,
is_degen: bool, is_degen: bool,
param_substs: Option<param_substs>, +param_substs: Option<param_substs>,
llfndecl: ValueRef) { llfndecl: ValueRef) {
let _icx = ccx.insn_ctxt("trans_enum_variant"); let _icx = ccx.insn_ctxt("trans_enum_variant");
// Translate variant arguments to function arguments. // Translate variant arguments to function arguments.
@ -1729,11 +1749,13 @@ fn trans_enum_variant(ccx: @crate_ctxt,
ast_util::dummy_sp(), ast_util::dummy_sp(),
special_idents::arg), special_idents::arg),
id: varg.id}); id: varg.id});
// XXX: Bad copy of `param_substs`.
let fcx = new_fn_ctxt_w_id(ccx, ~[], llfndecl, variant.node.id, None, let fcx = new_fn_ctxt_w_id(ccx, ~[], llfndecl, variant.node.id, None,
param_substs, None); copy param_substs, None);
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args); // XXX: Bad copy.
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, copy fn_args);
let ty_param_substs = match param_substs { let ty_param_substs = match param_substs {
Some(substs) => substs.tys, Some(ref substs) => /*bad*/copy substs.tys,
None => ~[] None => ~[]
}; };
let bcx = top_scope_block(fcx, None), lltop = bcx.llbb; let bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
@ -1754,7 +1776,7 @@ fn trans_enum_variant(ccx: @crate_ctxt,
let v_id = local_def(variant.node.id); let v_id = local_def(variant.node.id);
for vec::eachi(args) |i, va| { for vec::eachi(args) |i, va| {
let lldestptr = GEP_enum(bcx, llblobptr, t_id, v_id, let lldestptr = GEP_enum(bcx, llblobptr, t_id, v_id,
ty_param_substs, i); /*bad*/copy ty_param_substs, i);
// If this argument to this function is a enum, it'll have come in to // If this argument to this function is a enum, it'll have come in to
// this function as an opaque blob due to the way that type_of() // this function as an opaque blob due to the way that type_of()
// works. So we have to cast to the destination's view of the type. // works. So we have to cast to the destination's view of the type.
@ -1774,7 +1796,7 @@ fn trans_enum_variant(ccx: @crate_ctxt,
fn trans_tuple_struct(ccx: @crate_ctxt, fn trans_tuple_struct(ccx: @crate_ctxt,
fields: ~[@ast::struct_field], fields: ~[@ast::struct_field],
ctor_id: ast::node_id, ctor_id: ast::node_id,
param_substs: Option<param_substs>, +param_substs: Option<param_substs>,
llfndecl: ValueRef) { llfndecl: ValueRef) {
let _icx = ccx.insn_ctxt("trans_tuple_struct"); let _icx = ccx.insn_ctxt("trans_tuple_struct");
@ -1792,7 +1814,9 @@ fn trans_tuple_struct(ccx: @crate_ctxt,
let fcx = new_fn_ctxt_w_id(ccx, ~[], llfndecl, ctor_id, None, let fcx = new_fn_ctxt_w_id(ccx, ~[], llfndecl, ctor_id, None,
param_substs, None); param_substs, None);
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
// XXX: Bad copy.
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, copy fn_args);
let bcx = top_scope_block(fcx, None); let bcx = top_scope_block(fcx, None);
let lltop = bcx.llbb; let lltop = bcx.llbb;
@ -1816,11 +1840,14 @@ fn trans_tuple_struct(ccx: @crate_ctxt,
finish_fn(fcx, lltop); finish_fn(fcx, lltop);
} }
fn trans_struct_dtor(ccx: @crate_ctxt, path: path, fn trans_struct_dtor(ccx: @crate_ctxt,
body: ast::blk, dtor_id: ast::node_id, +path: path,
psubsts: Option<param_substs>, body: ast::blk,
hash_id: Option<mono_id>, parent_id: ast::def_id) dtor_id: ast::node_id,
-> ValueRef { +psubsts: Option<param_substs>,
hash_id: Option<mono_id>,
parent_id: ast::def_id)
-> ValueRef {
let tcx = ccx.tcx; let tcx = ccx.tcx;
/* Look up the parent class's def_id */ /* Look up the parent class's def_id */
let mut class_ty = ty::lookup_item_type(tcx, parent_id).ty; let mut class_ty = ty::lookup_item_type(tcx, parent_id).ty;
@ -1833,7 +1860,8 @@ fn trans_struct_dtor(ccx: @crate_ctxt, path: path,
and returns () */ and returns () */
let lldty = type_of_dtor(ccx, class_ty); let lldty = type_of_dtor(ccx, class_ty);
let s = get_dtor_symbol(ccx, path, dtor_id, psubsts); // XXX: Bad copies.
let s = get_dtor_symbol(ccx, copy path, dtor_id, copy psubsts);
/* Register the dtor as a function. It has external linkage */ /* Register the dtor as a function. It has external linkage */
let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, lldty); let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, lldty);
@ -1859,23 +1887,23 @@ fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def,
*i += 1; *i += 1;
match variant.node.kind { match variant.node.kind {
ast::tuple_variant_kind(args) if args.len() > 0 => { ast::tuple_variant_kind(ref args) if args.len() > 0 => {
let llfn = get_item_val(ccx, variant.node.id); let llfn = get_item_val(ccx, variant.node.id);
trans_enum_variant(ccx, id, *variant, args, disr_val, trans_enum_variant(ccx, id, *variant, /*bad*/copy *args,
degen, None, llfn); disr_val, degen, None, llfn);
} }
ast::tuple_variant_kind(_) => { ast::tuple_variant_kind(_) => {
// Nothing to do. // Nothing to do.
} }
ast::struct_variant_kind(struct_def) => { ast::struct_variant_kind(struct_def) => {
trans_struct_def(ccx, struct_def, tps, path, trans_struct_def(ccx, struct_def, /*bad*/copy tps, path,
variant.node.id); variant.node.id);
} }
ast::enum_variant_kind(ref enum_definition) => { ast::enum_variant_kind(ref enum_definition) => {
trans_enum_def(ccx, trans_enum_def(ccx,
*enum_definition, *enum_definition,
id, id,
tps, /*bad*/copy tps,
degen, degen,
path, path,
vi, vi,
@ -1892,19 +1920,20 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
// tjc: ? // tjc: ?
_ => fail ~"trans_item", _ => fail ~"trans_item",
}; };
match item.node { match /*bad*/copy item.node {
ast::item_fn(decl, purity, tps, ref body) => { // XXX: Bad copies.
ast::item_fn(copy decl, purity, copy tps, ref body) => {
if purity == ast::extern_fn { if purity == ast::extern_fn {
let llfndecl = get_item_val(ccx, item.id); let llfndecl = get_item_val(ccx, item.id);
foreign::trans_foreign_fn(ccx, foreign::trans_foreign_fn(ccx,
vec::append( vec::append(
*path, /*bad*/copy *path,
~[path_name(item.ident)]), ~[path_name(item.ident)]),
decl, (*body), llfndecl, item.id); decl, (*body), llfndecl, item.id);
} else if tps.is_empty() { } else if tps.is_empty() {
let llfndecl = get_item_val(ccx, item.id); let llfndecl = get_item_val(ccx, item.id);
trans_fn(ccx, trans_fn(ccx,
vec::append(*path, ~[path_name(item.ident)]), vec::append(/*bad*/copy *path, ~[path_name(item.ident)]),
decl, (*body), llfndecl, no_self, None, item.id, None); decl, (*body), llfndecl, no_self, None, item.id, None);
} else { } else {
for vec::each((*body).node.stmts) |stmt| { for vec::each((*body).node.stmts) |stmt| {
@ -1918,26 +1947,27 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
} }
} }
ast::item_impl(tps, _, _, ms) => { ast::item_impl(tps, _, _, ms) => {
meth::trans_impl(ccx, *path, item.ident, ms, tps, None, meth::trans_impl(ccx, /*bad*/copy *path, item.ident, ms, tps, None,
item.id); item.id);
} }
ast::item_mod(m) => { ast::item_mod(m) => {
trans_mod(ccx, m); trans_mod(ccx, m);
} }
ast::item_enum(ref enum_definition, tps) => { ast::item_enum(ref enum_definition, ref tps) => {
if tps.len() == 0u { if tps.len() == 0u {
let degen = (*enum_definition).variants.len() == 1u; let degen = (*enum_definition).variants.len() == 1u;
let vi = ty::enum_variants(ccx.tcx, local_def(item.id)); let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
let mut i = 0; let mut i = 0;
trans_enum_def(ccx, (*enum_definition), item.id, tps, degen, path, trans_enum_def(ccx, (*enum_definition), item.id, /*bad*/copy *tps,
vi, &mut i); degen, path, vi, &mut i);
} }
} }
ast::item_const(_, expr) => consts::trans_const(ccx, expr, item.id), ast::item_const(_, expr) => consts::trans_const(ccx, expr, item.id),
ast::item_foreign_mod(foreign_mod) => { ast::item_foreign_mod(foreign_mod) => {
let abi = match attr::foreign_abi(item.attrs) { let abi = match attr::foreign_abi(item.attrs) {
either::Right(abi_) => abi_, either::Right(abi_) => abi_,
either::Left(ref msg) => ccx.sess.span_fatal(item.span, (*msg)) either::Left(ref msg) => ccx.sess.span_fatal(item.span,
/*bad*/copy *msg)
}; };
foreign::trans_foreign_mod(ccx, foreign_mod, abi); foreign::trans_foreign_mod(ccx, foreign_mod, abi);
} }
@ -1956,7 +1986,7 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
if tps.len() == 0u { if tps.len() == 0u {
// Translate the destructor. // Translate the destructor.
do option::iter(&struct_def.dtor) |dtor| { do option::iter(&struct_def.dtor) |dtor| {
trans_struct_dtor(ccx, *path, dtor.node.body, trans_struct_dtor(ccx, /*bad*/copy *path, dtor.node.body,
dtor.node.id, None, None, local_def(id)); dtor.node.id, None, None, local_def(id));
}; };
@ -1966,8 +1996,8 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
// otherwise this is a unit-like struct. // otherwise this is a unit-like struct.
Some(ctor_id) if struct_def.fields.len() > 0 => { Some(ctor_id) if struct_def.fields.len() > 0 => {
let llfndecl = get_item_val(ccx, ctor_id); let llfndecl = get_item_val(ccx, ctor_id);
trans_tuple_struct(ccx, struct_def.fields, ctor_id, None, trans_tuple_struct(ccx, /*bad*/copy struct_def.fields,
llfndecl); ctor_id, None, llfndecl);
} }
Some(_) | None => {} Some(_) | None => {}
} }
@ -1991,30 +2021,35 @@ fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
return struct_elt(llpairty, 0u); return struct_elt(llpairty, 0u);
} }
fn register_fn(ccx: @crate_ctxt, sp: span, path: path, fn register_fn(ccx: @crate_ctxt,
node_id: ast::node_id) -> ValueRef { sp: span,
+path: path,
node_id: ast::node_id)
-> ValueRef {
let t = ty::node_id_to_type(ccx.tcx, node_id); let t = ty::node_id_to_type(ccx.tcx, node_id);
register_fn_full(ccx, sp, path, node_id, t) register_fn_full(ccx, sp, path, node_id, t)
} }
fn register_fn_full(ccx: @crate_ctxt, sp: span, path: path, fn register_fn_full(ccx: @crate_ctxt, sp: span, +path: path,
node_id: ast::node_id, node_type: ty::t) -> ValueRef { node_id: ast::node_id, node_type: ty::t) -> ValueRef {
let llfty = type_of_fn_from_ty(ccx, node_type); let llfty = type_of_fn_from_ty(ccx, node_type);
register_fn_fuller(ccx, sp, path, node_id, node_type, register_fn_fuller(ccx, sp, path, node_id, node_type,
lib::llvm::CCallConv, llfty) lib::llvm::CCallConv, llfty)
} }
fn register_fn_fuller(ccx: @crate_ctxt, sp: span, path: path, fn register_fn_fuller(ccx: @crate_ctxt, sp: span, +path: path,
node_id: ast::node_id, node_type: ty::t, node_id: ast::node_id, node_type: ty::t,
cc: lib::llvm::CallConv, llfty: TypeRef) -> ValueRef { cc: lib::llvm::CallConv, llfty: TypeRef) -> ValueRef {
let ps: ~str = mangle_exported_name(ccx, path, node_type); debug!("register_fn_fuller creating fn for item %d with path %s",
let llfn: ValueRef = decl_fn(ccx.llmod, ps, cc, llfty); node_id,
ccx.item_symbols.insert(node_id, ps);
debug!("register_fn_fuller created fn %s for item %d with path %s",
val_str(ccx.tn, llfn), node_id,
ast_map::path_to_str(path, ccx.sess.parse_sess.interner)); ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
// XXX: Bad copy.
let ps: ~str = mangle_exported_name(ccx, copy path, node_type);
// XXX: Bad copy.
let llfn: ValueRef = decl_fn(ccx.llmod, copy ps, cc, llfty);
ccx.item_symbols.insert(node_id, ps);
let is_main = is_main_name(path) && !ccx.sess.building_library; let is_main = is_main_name(path) && !ccx.sess.building_library;
if is_main { create_main_wrapper(ccx, sp, llfn); } if is_main { create_main_wrapper(ccx, sp, llfn); }
llfn llfn
@ -2098,7 +2133,7 @@ fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef,
fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path { fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path {
vec::append( vec::append(
*match ccx.tcx.items.get(i.id) { /*bad*/copy *match ccx.tcx.items.get(i.id) {
ast_map::node_item(_, p) => p, ast_map::node_item(_, p) => p,
// separate map for paths? // separate map for paths?
_ => fail ~"item_path" _ => fail ~"item_path"
@ -2108,17 +2143,21 @@ fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path {
/* If there's already a symbol for the dtor with <id> and substs <substs>, /* If there's already a symbol for the dtor with <id> and substs <substs>,
return it; otherwise, create one and register it, returning it as well */ return it; otherwise, create one and register it, returning it as well */
fn get_dtor_symbol(ccx: @crate_ctxt, path: path, id: ast::node_id, fn get_dtor_symbol(ccx: @crate_ctxt,
substs: Option<param_substs>) -> ~str { +path: path,
id: ast::node_id,
+substs: Option<param_substs>)
-> ~str {
let t = ty::node_id_to_type(ccx.tcx, id); let t = ty::node_id_to_type(ccx.tcx, id);
match ccx.item_symbols.find(id) { match ccx.item_symbols.find(id) {
Some(ref s) => (*s), Some(ref s) => (/*bad*/copy *s),
None if substs.is_none() => { None if substs.is_none() => {
let s = mangle_exported_name( let s = mangle_exported_name(
ccx, ccx,
vec::append(path, ~[path_name((ccx.names)(~"dtor"))]), vec::append(path, ~[path_name((ccx.names)(~"dtor"))]),
t); t);
ccx.item_symbols.insert(id, s); // XXX: Bad copy, use `@str`?
ccx.item_symbols.insert(id, copy s);
s s
} }
None => { None => {
@ -2152,7 +2191,8 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
let mut exprt = false; let mut exprt = false;
let val = match ccx.tcx.items.get(id) { let val = match ccx.tcx.items.get(id) {
ast_map::node_item(i, pth) => { ast_map::node_item(i, pth) => {
let my_path = vec::append(*pth, ~[path_name(i.ident)]); let my_path = vec::append(/*bad*/copy *pth,
~[path_name(i.ident)]);
match i.node { match i.node {
ast::item_const(_, _) => { ast::item_const(_, _) => {
let typ = ty::node_id_to_type(ccx.tcx, i.id); let typ = ty::node_id_to_type(ccx.tcx, i.id);
@ -2169,7 +2209,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
} else { } else {
foreign::register_foreign_fn(ccx, i.span, my_path, i.id) foreign::register_foreign_fn(ccx, i.span, my_path, i.id)
}; };
set_inline_hint_if_appr(i.attrs, llfn); set_inline_hint_if_appr(/*bad*/copy i.attrs, llfn);
llfn llfn
} }
_ => fail ~"get_item_val: weird result in table" _ => fail ~"get_item_val: weird result in table"
@ -2197,7 +2237,8 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
match ni.node { match ni.node {
ast::foreign_item_fn(*) => { ast::foreign_item_fn(*) => {
register_fn(ccx, ni.span, register_fn(ccx, ni.span,
vec::append(*pth, ~[path_name(ni.ident)]), vec::append(/*bad*/copy *pth,
~[path_name(ni.ident)]),
ni.id) ni.id)
} }
ast::foreign_item_const(*) => { ast::foreign_item_const(*) => {
@ -2223,7 +2264,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
let lldty = T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(tcx))), let lldty = T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(tcx))),
T_ptr(type_of(ccx, class_ty))], T_ptr(type_of(ccx, class_ty))],
llvm::LLVMVoidType()); llvm::LLVMVoidType());
let s = get_dtor_symbol(ccx, *pt, dt.node.id, None); let s = get_dtor_symbol(ccx, /*bad*/copy *pt, dt.node.id, None);
/* Make the declaration for the dtor */ /* Make the declaration for the dtor */
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, lldty); let llfn = decl_internal_cdecl_fn(ccx.llmod, s, lldty);
@ -2233,10 +2274,10 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
ast_map::node_variant(ref v, enm, pth) => { ast_map::node_variant(ref v, enm, pth) => {
let llfn; let llfn;
match (*v).node.kind { match /*bad*/copy (*v).node.kind {
ast::tuple_variant_kind(args) => { ast::tuple_variant_kind(args) => {
assert args.len() != 0u; assert args.len() != 0u;
let pth = vec::append(*pth, let pth = vec::append(/*bad*/copy *pth,
~[path_name(enm.ident), ~[path_name(enm.ident),
path_name((*v).node.name)]); path_name((*v).node.name)]);
llfn = match enm.node { llfn = match enm.node {
@ -2266,7 +2307,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
} }
Some(ctor_id) => { Some(ctor_id) => {
let llfn = register_fn(ccx, struct_item.span, let llfn = register_fn(ccx, struct_item.span,
*struct_path, ctor_id); /*bad*/copy *struct_path, ctor_id);
set_inline_hint(llfn); set_inline_hint(llfn);
llfn llfn
} }
@ -2289,10 +2330,10 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
fn register_method(ccx: @crate_ctxt, id: ast::node_id, pth: @ast_map::path, fn register_method(ccx: @crate_ctxt, id: ast::node_id, pth: @ast_map::path,
m: @ast::method) -> ValueRef { m: @ast::method) -> ValueRef {
let mty = ty::node_id_to_type(ccx.tcx, id); let mty = ty::node_id_to_type(ccx.tcx, id);
let pth = vec::append(*pth, ~[path_name((ccx.names)(~"meth")), let pth = vec::append(/*bad*/copy *pth, ~[path_name((ccx.names)(~"meth")),
path_name(m.ident)]); path_name(m.ident)]);
let llfn = register_fn_full(ccx, m.span, pth, id, mty); let llfn = register_fn_full(ccx, m.span, pth, id, mty);
set_inline_hint_if_appr(m.attrs, llfn); set_inline_hint_if_appr(/*bad*/copy m.attrs, llfn);
llfn llfn
} }
@ -2306,11 +2347,14 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
let mut i = 0; let mut i = 0;
let path = item_path(ccx, it); let path = item_path(ccx, it);
for vec::each((*enum_definition).variants) |variant| { for vec::each((*enum_definition).variants) |variant| {
let p = vec::append(path, ~[path_name(variant.node.name), let p = vec::append(/*bad*/copy path, ~[
path_name(special_idents::descrim)]); path_name(variant.node.name),
path_name(special_idents::descrim)
]);
let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx)); let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx));
let disr_val = vi[i].disr_val; let disr_val = vi[i].disr_val;
note_unique_llvm_symbol(ccx, s); // XXX: Bad copy.
note_unique_llvm_symbol(ccx, copy s);
let discrim_gvar = str::as_c_str(s, |buf| { let discrim_gvar = str::as_c_str(s, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
}); });
@ -2639,11 +2683,10 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
C_array(ccx.int_type, subcrates)])); C_array(ccx.int_type, subcrates)]));
} }
fn crate_ctxt_to_encode_parms(cx: @crate_ctxt) fn crate_ctxt_to_encode_parms(cx: @crate_ctxt) -> encoder::encode_parms {
-> encoder::encode_parms { // XXX: Bad copy of `c`, whatever it is.
let encode_inlined_item = let encode_inlined_item =
|a,b,c,d| astencode::encode_inlined_item(a, b, c, d, cx.maps); |a,b,c,d| astencode::encode_inlined_item(a, b, copy c, d, cx.maps);
return { return {
diag: cx.sess.diagnostic(), diag: cx.sess.diagnostic(),
@ -2652,7 +2695,7 @@ fn crate_ctxt_to_encode_parms(cx: @crate_ctxt)
reexports2: cx.exp_map2, reexports2: cx.exp_map2,
item_symbols: cx.item_symbols, item_symbols: cx.item_symbols,
discrim_symbols: cx.discrim_symbols, discrim_symbols: cx.discrim_symbols,
link_meta: cx.link_meta, link_meta: /*bad*/copy cx.link_meta,
cstore: cx.sess.cstore, cstore: cx.sess.cstore,
encode_inlined_item: encode_inlined_item encode_inlined_item: encode_inlined_item
}; };
@ -2715,8 +2758,8 @@ fn trans_crate(sess: session::Session,
llvm::LLVMModuleCreateWithNameInContext llvm::LLVMModuleCreateWithNameInContext
(buf, llvm::LLVMGetGlobalContext()) (buf, llvm::LLVMGetGlobalContext())
}); });
let data_layout = sess.targ_cfg.target_strs.data_layout; let data_layout = /*bad*/copy sess.targ_cfg.target_strs.data_layout;
let targ_triple = sess.targ_cfg.target_strs.target_triple; let targ_triple = /*bad*/copy sess.targ_cfg.target_strs.target_triple;
let _: () = let _: () =
str::as_c_str(data_layout, str::as_c_str(data_layout,
|buf| llvm::LLVMSetDataLayout(llmod, buf)); |buf| llvm::LLVMSetDataLayout(llmod, buf));
@ -2724,7 +2767,8 @@ fn trans_crate(sess: session::Session,
str::as_c_str(targ_triple, str::as_c_str(targ_triple,
|buf| llvm::LLVMSetTarget(llmod, buf)); |buf| llvm::LLVMSetTarget(llmod, buf));
let targ_cfg = sess.targ_cfg; let targ_cfg = sess.targ_cfg;
let td = mk_target_data(sess.targ_cfg.target_strs.data_layout); let td = mk_target_data(
/*bad*/copy sess.targ_cfg.target_strs.data_layout);
let tn = mk_type_names(); let tn = mk_type_names();
let intrinsics = declare_intrinsics(llmod); let intrinsics = declare_intrinsics(llmod);
if sess.opts.extra_debuginfo { if sess.opts.extra_debuginfo {
@ -2739,9 +2783,9 @@ fn trans_crate(sess: session::Session,
lib::llvm::associate_type(tn, ~"tydesc", tydesc_type); lib::llvm::associate_type(tn, ~"tydesc", tydesc_type);
let crate_map = decl_crate_map(sess, link_meta, llmod); let crate_map = decl_crate_map(sess, link_meta, llmod);
let dbg_cx = if sess.opts.debuginfo { let dbg_cx = if sess.opts.debuginfo {
option::Some(debuginfo::mk_ctxt(llmod_id, sess.parse_sess.interner)) Some(debuginfo::mk_ctxt(copy llmod_id, sess.parse_sess.interner))
} else { } else {
option::None None
}; };
let ccx = @crate_ctxt { let ccx = @crate_ctxt {
@ -2756,7 +2800,7 @@ fn trans_crate(sess: session::Session,
reachable: reachable, reachable: reachable,
item_symbols: HashMap(), item_symbols: HashMap(),
mut main_fn: None::<ValueRef>, mut main_fn: None::<ValueRef>,
link_meta: link_meta, link_meta: copy link_meta, // XXX: Bad copy.
enum_sizes: ty::new_ty_hash(), enum_sizes: ty::new_ty_hash(),
discrims: HashMap(), discrims: HashMap(),
discrim_symbols: HashMap(), discrim_symbols: HashMap(),

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use codemap::span; use codemap::span;
use lib::llvm::llvm; use lib::llvm::llvm;
use lib::llvm::{CallConv, TypeKind, AtomicBinOp, AtomicOrdering}; use lib::llvm::{CallConv, TypeKind, AtomicBinOp, AtomicOrdering};
@ -53,8 +54,8 @@ fn count_insn(cx: block, category: &str) {
let mut s = ~"."; let mut s = ~".";
i = 0u; i = 0u;
while i < len { while i < len {
let e = v[i]; let e = /*bad*/copy v[i];
i = mm.get(e); i = mm.get(/*bad*/ copy e);
s += ~"/"; s += ~"/";
s += e; s += e;
i += 1u; i += 1u;
@ -662,7 +663,7 @@ fn add_span_comment(bcx: block, sp: span, text: ~str) {
if !ccx.sess.no_asm_comments() { if !ccx.sess.no_asm_comments() {
let s = text + ~" (" + ccx.sess.codemap.span_to_str(sp) let s = text + ~" (" + ccx.sess.codemap.span_to_str(sp)
+ ~")"; + ~")";
log(debug, s); log(debug, copy s);
add_comment(bcx, s); add_comment(bcx, s);
} }
} }

View File

@ -16,6 +16,7 @@
// and methods are represented as just a fn ptr and not a full // and methods are represented as just a fn ptr and not a full
// closure. // closure.
use lib::llvm::ValueRef; use lib::llvm::ValueRef;
use middle::trans::base::{get_item_val, trans_external_path}; use middle::trans::base::{get_item_val, trans_external_path};
use middle::trans::build::*; use middle::trans::build::*;
@ -159,7 +160,7 @@ fn trans_fn_ref(bcx: block,
fn trans_fn_ref_with_vtables_to_callee(bcx: block, fn trans_fn_ref_with_vtables_to_callee(bcx: block,
def_id: ast::def_id, def_id: ast::def_id,
ref_id: ast::node_id, ref_id: ast::node_id,
type_params: ~[ty::t], +type_params: ~[ty::t],
vtables: Option<typeck::vtable_res>) vtables: Option<typeck::vtable_res>)
-> Callee -> Callee
{ {
@ -172,7 +173,7 @@ fn trans_fn_ref_with_vtables(
bcx: block, // bcx: block, //
def_id: ast::def_id, // def id of fn def_id: ast::def_id, // def id of fn
ref_id: ast::node_id, // node id of use of fn; may be zero if N/A ref_id: ast::node_id, // node id of use of fn; may be zero if N/A
type_params: ~[ty::t], // values for fn's ty params +type_params: ~[ty::t], // values for fn's ty params
vtables: Option<typeck::vtable_res>) vtables: Option<typeck::vtable_res>)
-> FnData -> FnData
{ {
@ -415,7 +416,7 @@ fn trans_call_inner(
autoref_arg: AutorefArg) -> block autoref_arg: AutorefArg) -> block
{ {
do base::with_scope(in_cx, call_info, ~"call") |cx| { do base::with_scope(in_cx, call_info, ~"call") |cx| {
let ret_in_loop = match args { let ret_in_loop = match /*bad*/copy args {
ArgExprs(args) => { ArgExprs(args) => {
args.len() > 0u && match vec::last(args).node { args.len() > 0u && match vec::last(args).node {
ast::expr_loop_body(@{ ast::expr_loop_body(@{
@ -459,10 +460,10 @@ fn trans_call_inner(
} }
}; };
let args_res = trans_args(bcx, llenv, args, fn_expr_ty, let args_res = trans_args(bcx, llenv, /*bad*/copy args, fn_expr_ty,
dest, ret_flag, autoref_arg); dest, ret_flag, autoref_arg);
bcx = args_res.bcx; bcx = args_res.bcx;
let mut llargs = args_res.args; let mut llargs = /*bad*/copy args_res.args;
let llretslot = args_res.retslot; let llretslot = args_res.retslot;
@ -519,8 +520,12 @@ enum CallArgs {
ArgVals(~[ValueRef]) ArgVals(~[ValueRef])
} }
fn trans_args(cx: block, llenv: ValueRef, args: CallArgs, fn_ty: ty::t, fn trans_args(cx: block,
dest: expr::Dest, ret_flag: Option<ValueRef>, llenv: ValueRef,
+args: CallArgs,
fn_ty: ty::t,
dest: expr::Dest,
ret_flag: Option<ValueRef>,
+autoref_arg: AutorefArg) +autoref_arg: AutorefArg)
-> {bcx: block, args: ~[ValueRef], retslot: ValueRef} -> {bcx: block, args: ~[ValueRef], retslot: ValueRef}
{ {
@ -614,14 +619,18 @@ fn trans_arg_expr(bcx: block,
Some(_) => { Some(_) => {
match arg_expr.node { match arg_expr.node {
ast::expr_loop_body( ast::expr_loop_body(
blk@@{node:ast::expr_fn_block(decl, ref body, cap), _}) => // XXX: Bad copy.
blk@@{
node: ast::expr_fn_block(copy decl, ref body, cap),
_
}) =>
{ {
let scratch_ty = expr_ty(bcx, blk); let scratch_ty = expr_ty(bcx, blk);
let scratch = alloc_ty(bcx, scratch_ty); let scratch = alloc_ty(bcx, scratch_ty);
let arg_ty = expr_ty(bcx, arg_expr); let arg_ty = expr_ty(bcx, arg_expr);
let proto = ty::ty_fn_proto(arg_ty); let proto = ty::ty_fn_proto(arg_ty);
let bcx = closure::trans_expr_fn( let bcx = closure::trans_expr_fn(
bcx, proto, decl, (*body), blk.id, cap, bcx, proto, decl, /*bad*/copy *body, blk.id, cap,
Some(ret_flag), expr::SaveIn(scratch)); Some(ret_flag), expr::SaveIn(scratch));
DatumBlock {bcx: bcx, DatumBlock {bcx: bcx,
datum: Datum {val: scratch, datum: Datum {val: scratch,

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back::abi; use back::abi;
use back::link::{mangle_internal_name_by_path_and_seq}; use back::link::{mangle_internal_name_by_path_and_seq};
use back::link::{mangle_internal_name_by_path}; use back::link::{mangle_internal_name_by_path};
@ -211,7 +212,8 @@ fn store_environment(bcx: block,
let ccx = bcx.ccx(), tcx = ccx.tcx; let ccx = bcx.ccx(), tcx = ccx.tcx;
// compute the shape of the closure // compute the shape of the closure
let cdata_ty = mk_closure_tys(tcx, bound_values); // XXX: Bad copy.
let cdata_ty = mk_closure_tys(tcx, copy bound_values);
// allocate closure in the heap // allocate closure in the heap
let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, proto, cdata_ty); let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, proto, cdata_ty);
@ -374,8 +376,8 @@ fn load_environment(fcx: fn_ctxt,
fn trans_expr_fn(bcx: block, fn trans_expr_fn(bcx: block,
proto: ast::Proto, proto: ast::Proto,
decl: ast::fn_decl, +decl: ast::fn_decl,
body: ast::blk, +body: ast::blk,
id: ast::node_id, id: ast::node_id,
cap_clause: ast::capture_clause, cap_clause: ast::capture_clause,
is_loop_body: Option<Option<ValueRef>>, is_loop_body: Option<Option<ValueRef>>,
@ -392,19 +394,24 @@ fn trans_expr_fn(bcx: block,
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let fty = node_id_type(bcx, id); let fty = node_id_type(bcx, id);
let llfnty = type_of_fn_from_ty(ccx, fty); let llfnty = type_of_fn_from_ty(ccx, fty);
let sub_path = vec::append_one(bcx.fcx.path, let sub_path = vec::append_one(/*bad*/copy bcx.fcx.path,
path_name(special_idents::anon)); path_name(special_idents::anon));
let s = mangle_internal_name_by_path_and_seq(ccx, sub_path, ~"expr_fn"); // XXX: Bad copy.
let s = mangle_internal_name_by_path_and_seq(ccx,
copy sub_path,
~"expr_fn");
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty); let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
let trans_closure_env = fn@(proto: ast::Proto) -> Result { // XXX: Bad copies.
let trans_closure_env = |proto, copy body, copy sub_path, copy decl| {
let cap_vars = capture::compute_capture_vars(ccx.tcx, id, proto, let cap_vars = capture::compute_capture_vars(ccx.tcx, id, proto,
cap_clause); cap_clause);
let ret_handle = match is_loop_body { Some(x) => x, None => None }; let ret_handle = match is_loop_body { Some(x) => x, None => None };
let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, proto, // XXX: Bad copy.
let {llbox, cdata_ty, bcx} = build_closure(bcx, copy cap_vars, proto,
ret_handle); ret_handle);
trans_closure(ccx, sub_path, decl, body, llfn, no_self, trans_closure(ccx, /*bad*/copy sub_path, decl, body, llfn, no_self,
bcx.fcx.param_substs, id, None, |fcx| { /*bad*/copy bcx.fcx.param_substs, id, None, |fcx| {
load_environment(fcx, cdata_ty, cap_vars, load_environment(fcx, cdata_ty, cap_vars,
ret_handle.is_some(), proto); ret_handle.is_some(), proto);
}, |bcx| { }, |bcx| {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
/** /**
Code that is useful in various trans modules. Code that is useful in various trans modules.
@ -59,7 +60,10 @@ use syntax::{ast, ast_map};
type namegen = fn@(~str) -> ident; type namegen = fn@(~str) -> ident;
fn new_namegen(intr: @ident_interner) -> namegen { fn new_namegen(intr: @ident_interner) -> namegen {
return fn@(prefix: ~str) -> ident { return fn@(prefix: ~str) -> ident {
return intr.gensym(@fmt!("%s_%u", prefix, intr.gensym(@prefix).repr)) // XXX: Bad copies.
return intr.gensym(@fmt!("%s_%u",
prefix,
intr.gensym(@copy prefix).repr))
}; };
} }
@ -470,7 +474,7 @@ fn revoke_clean(cx: block, val: ValueRef) {
fn block_cleanups(bcx: block) -> ~[cleanup] { fn block_cleanups(bcx: block) -> ~[cleanup] {
match bcx.kind { match bcx.kind {
block_non_scope => ~[], block_non_scope => ~[],
block_scope(ref inf) => (*inf).cleanups block_scope(ref inf) => /*bad*/copy inf.cleanups
} }
} }
@ -1077,7 +1081,7 @@ fn C_u8(i: uint) -> ValueRef { return C_integral(T_i8(), i as u64, False); }
// This is a 'c-like' raw string, which differs from // This is a 'c-like' raw string, which differs from
// our boxed-and-length-annotated strings. // our boxed-and-length-annotated strings.
fn C_cstr(cx: @crate_ctxt, s: ~str) -> ValueRef { fn C_cstr(cx: @crate_ctxt, +s: ~str) -> ValueRef {
match cx.const_cstr_cache.find(s) { match cx.const_cstr_cache.find(s) {
Some(llval) => return llval, Some(llval) => return llval,
None => () None => ()
@ -1100,9 +1104,10 @@ fn C_cstr(cx: @crate_ctxt, s: ~str) -> ValueRef {
// NB: Do not use `do_spill_noroot` to make this into a constant string, or // NB: Do not use `do_spill_noroot` to make this into a constant string, or
// you will be kicked off fast isel. See issue #4352 for an example of this. // you will be kicked off fast isel. See issue #4352 for an example of this.
fn C_estr_slice(cx: @crate_ctxt, s: ~str) -> ValueRef { fn C_estr_slice(cx: @crate_ctxt, +s: ~str) -> ValueRef {
let len = str::len(s);
let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8())); let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8()));
C_struct(~[cs, C_uint(cx, str::len(s) + 1u /* +1 for null */)]) C_struct(~[cs, C_uint(cx, len + 1u /* +1 for null */)])
} }
// Returns a Plain Old LLVM String: // Returns a Plain Old LLVM String:
@ -1149,7 +1154,7 @@ fn C_bytes_plus_null(bytes: ~[u8]) -> ValueRef unsafe {
bytes.len() as c_uint, False); bytes.len() as c_uint, False);
} }
fn C_shape(ccx: @crate_ctxt, bytes: ~[u8]) -> ValueRef { fn C_shape(ccx: @crate_ctxt, +bytes: ~[u8]) -> ValueRef {
let llshape = C_bytes_plus_null(bytes); let llshape = C_bytes_plus_null(bytes);
let name = fmt!("shape%u", (ccx.names)(~"shape").repr); let name = fmt!("shape%u", (ccx.names)(~"shape").repr);
let llglobal = str::as_c_str(name, |buf| { let llglobal = str::as_c_str(name, |buf| {
@ -1185,19 +1190,20 @@ type mono_id = @mono_id_;
impl mono_param_id : cmp::Eq { impl mono_param_id : cmp::Eq {
pure fn eq(&self, other: &mono_param_id) -> bool { pure fn eq(&self, other: &mono_param_id) -> bool {
match ((*self), (*other)) { match (self, other) {
(mono_precise(ty_a, ids_a), mono_precise(ty_b, ids_b)) => { (&mono_precise(ty_a, ref ids_a),
&mono_precise(ty_b, ref ids_b)) => {
ty_a == ty_b && ids_a == ids_b ty_a == ty_b && ids_a == ids_b
} }
(mono_any, mono_any) => true, (&mono_any, &mono_any) => true,
(mono_repr(size_a, align_a, is_float_a, mode_a), (&mono_repr(size_a, align_a, is_float_a, mode_a),
mono_repr(size_b, align_b, is_float_b, mode_b)) => { &mono_repr(size_b, align_b, is_float_b, mode_b)) => {
size_a == size_b && align_a == align_b && size_a == size_b && align_a == align_b &&
is_float_a == is_float_b && mode_a == mode_b is_float_a == is_float_b && mode_a == mode_b
} }
(mono_precise(*), _) => false, (&mono_precise(*), _) => false,
(mono_any, _) => false, (&mono_any, _) => false,
(mono_repr(*), _) => false (&mono_repr(*), _) => false
} }
} }
pure fn ne(&self, other: &mono_param_id) -> bool { !(*self).eq(other) } pure fn ne(&self, other: &mono_param_id) -> bool { !(*self).eq(other) }
@ -1212,7 +1218,7 @@ impl mono_id_ : cmp::Eq {
impl mono_param_id : to_bytes::IterBytes { impl mono_param_id : to_bytes::IterBytes {
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
match *self { match /*bad*/copy *self {
mono_precise(t, mids) => mono_precise(t, mids) =>
to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), &mids, lsb0, f), to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), &mids, lsb0, f),
@ -1261,7 +1267,7 @@ fn path_str(sess: session::Session, p: path) -> ~str {
} }
fn monomorphize_type(bcx: block, t: ty::t) -> ty::t { fn monomorphize_type(bcx: block, t: ty::t) -> ty::t {
match bcx.fcx.param_substs { match /*bad*/copy bcx.fcx.param_substs {
Some(substs) => { Some(substs) => {
ty::subst_tps(bcx.tcx(), substs.tys, substs.self_ty, t) ty::subst_tps(bcx.tcx(), substs.tys, substs.self_ty, t)
} }
@ -1282,7 +1288,7 @@ fn expr_ty(bcx: block, ex: @ast::expr) -> ty::t {
fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] { fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] {
let tcx = bcx.tcx(); let tcx = bcx.tcx();
let params = ty::node_id_to_type_params(tcx, id); let params = ty::node_id_to_type_params(tcx, id);
match bcx.fcx.param_substs { match /*bad*/copy bcx.fcx.param_substs {
Some(substs) => { Some(substs) => {
do vec::map(params) |t| { do vec::map(params) |t| {
ty::subst_tps(tcx, substs.tys, substs.self_ty, *t) ty::subst_tps(tcx, substs.tys, substs.self_ty, *t)
@ -1306,13 +1312,13 @@ fn resolve_vtables_in_fn_ctxt(fcx: fn_ctxt, vts: typeck::vtable_res)
// Apply the typaram substitutions in the fn_ctxt to a vtable. This should // Apply the typaram substitutions in the fn_ctxt to a vtable. This should
// eliminate any vtable_params. // eliminate any vtable_params.
fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin) fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, +vt: typeck::vtable_origin)
-> typeck::vtable_origin -> typeck::vtable_origin
{ {
let tcx = fcx.ccx.tcx; let tcx = fcx.ccx.tcx;
match vt { match vt {
typeck::vtable_static(trait_id, tys, sub) => { typeck::vtable_static(trait_id, tys, sub) => {
let tys = match fcx.param_substs { let tys = match /*bad*/copy fcx.param_substs {
Some(substs) => { Some(substs) => {
do vec::map(tys) |t| { do vec::map(tys) |t| {
ty::subst_tps(tcx, substs.tys, substs.self_ty, *t) ty::subst_tps(tcx, substs.tys, substs.self_ty, *t)
@ -1330,12 +1336,12 @@ fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin)
} }
_ => { _ => {
tcx.sess.bug(fmt!( tcx.sess.bug(fmt!(
"resolve_vtable_in_fn_ctxt: asked to lookup %? but \ "resolve_vtable_in_fn_ctxt: asked to lookup but \
no vtables in the fn_ctxt!", vt)) no vtables in the fn_ctxt!"))
} }
} }
} }
_ => vt vt => vt
} }
} }
@ -1352,10 +1358,10 @@ fn find_vtable(tcx: ty::ctxt, ps: &param_substs,
let vtables_to_skip = let vtables_to_skip =
ty::count_traits_and_supertraits(tcx, first_n_bounds); ty::count_traits_and_supertraits(tcx, first_n_bounds);
let vtable_off = vtables_to_skip + n_bound; let vtable_off = vtables_to_skip + n_bound;
ps.vtables.get()[vtable_off] /*bad*/ copy ps.vtables.get()[vtable_off]
} }
fn dummy_substs(tps: ~[ty::t]) -> ty::substs { fn dummy_substs(+tps: ~[ty::t]) -> ty::substs {
{self_r: Some(ty::re_bound(ty::br_self)), {self_r: Some(ty::re_bound(ty::br_self)),
self_ty: None, self_ty: None,
tps: tps} tps: tps}

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::const_eval; use middle::const_eval;
use middle::trans::base::get_insn_ctxt; use middle::trans::base::get_insn_ctxt;
use middle::trans::common::*; use middle::trans::common::*;
@ -36,12 +37,12 @@ fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
~"integer literal doesn't have a type") ~"integer literal doesn't have a type")
} }
} }
ast::lit_float(fs, t) => C_floating(*fs, T_float_ty(cx, t)), ast::lit_float(fs, t) => C_floating(/*bad*/copy *fs, T_float_ty(cx, t)),
ast::lit_float_unsuffixed(fs) => { ast::lit_float_unsuffixed(fs) => {
let lit_float_ty = ty::node_id_to_type(cx.tcx, e.id); let lit_float_ty = ty::node_id_to_type(cx.tcx, e.id);
match ty::get(lit_float_ty).sty { match ty::get(lit_float_ty).sty {
ty::ty_float(t) => { ty::ty_float(t) => {
C_floating(*fs, T_float_ty(cx, t)) C_floating(/*bad*/copy *fs, T_float_ty(cx, t))
} }
_ => { _ => {
cx.sess.span_bug(lit.span, cx.sess.span_bug(lit.span,
@ -52,7 +53,7 @@ fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
} }
ast::lit_bool(b) => C_bool(b), ast::lit_bool(b) => C_bool(b),
ast::lit_nil => C_nil(), ast::lit_nil => C_nil(),
ast::lit_str(s) => C_estr_slice(cx, *s) ast::lit_str(s) => C_estr_slice(cx, /*bad*/copy *s)
} }
} }
@ -129,7 +130,7 @@ fn get_const_val(cx: @crate_ctxt, def_id: ast::def_id) -> ValueRef {
fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
let _icx = cx.insn_ctxt("const_expr"); let _icx = cx.insn_ctxt("const_expr");
return match e.node { return match /*bad*/copy e.node {
ast::expr_lit(lit) => consts::const_lit(cx, e, *lit), ast::expr_lit(lit) => consts::const_lit(cx, e, *lit),
ast::expr_binary(b, e1, e2) => { ast::expr_binary(b, e1, e2) => {
let te1 = const_expr(cx, e1); let te1 = const_expr(cx, e1);
@ -358,7 +359,7 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
const_expr(cx, e) const_expr(cx, e)
} }
ast::expr_vstore(sub, ast::expr_vstore_slice) => { ast::expr_vstore(sub, ast::expr_vstore_slice) => {
match sub.node { match /*bad*/copy sub.node {
ast::expr_lit(lit) => { ast::expr_lit(lit) => {
match lit.node { match lit.node {
ast::lit_str(*) => { const_expr(cx, sub) } ast::lit_str(*) => { const_expr(cx, sub) }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use lib::llvm::ValueRef; use lib::llvm::ValueRef;
use middle::trans::base::*; use middle::trans::base::*;
use middle::trans::callee; use middle::trans::callee;
@ -171,13 +172,15 @@ fn trans_log(log_ex: @ast::expr,
} }
let modpath = vec::append( let modpath = vec::append(
~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))], ~[path_mod(ccx.sess.ident_of(/*bad*/copy ccx.link_meta.name))],
vec::filter(bcx.fcx.path, |e| vec::filter(bcx.fcx.path, |e|
match *e { path_mod(_) => true, _ => false } match *e { path_mod(_) => true, _ => false }
)); ));
let modname = path_str(ccx.sess, modpath); // XXX: Bad copy.
let modname = path_str(ccx.sess, copy modpath);
let global = if ccx.module_data.contains_key(modname) { // XXX: Bad copy.
let global = if ccx.module_data.contains_key(copy modname) {
ccx.module_data.get(modname) ccx.module_data.get(modname)
} else { } else {
let s = link::mangle_internal_name_by_path_and_seq( let s = link::mangle_internal_name_by_path_and_seq(
@ -310,7 +313,7 @@ fn trans_check_expr(bcx: block, chk_expr: @ast::expr,
} }
}; };
do with_cond(bcx, Not(bcx, val)) |bcx| { do with_cond(bcx, Not(bcx, val)) |bcx| {
trans_fail(bcx, Some(pred_expr.span), expr_str) trans_fail(bcx, Some(pred_expr.span), /*bad*/copy expr_str)
} }
} }
@ -340,7 +343,7 @@ fn trans_fail_expr(bcx: block,
} }
} }
fn trans_fail(bcx: block, sp_opt: Option<span>, fail_str: ~str) fn trans_fail(bcx: block, sp_opt: Option<span>, +fail_str: ~str)
-> block -> block
{ {
let _icx = bcx.insn_ctxt("trans_fail"); let _icx = bcx.insn_ctxt("trans_fail");
@ -357,7 +360,7 @@ fn trans_fail_value(bcx: block, sp_opt: Option<span>, V_fail_str: ValueRef)
Some(sp) => { Some(sp) => {
let sess = bcx.sess(); let sess = bcx.sess();
let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo); let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo);
{V_filename: C_cstr(bcx.ccx(), loc.file.name), {V_filename: C_cstr(bcx.ccx(), /*bad*/copy loc.file.name),
V_line: loc.line as int} V_line: loc.line as int}
} }
None => { None => {
@ -381,7 +384,7 @@ fn trans_fail_bounds_check(bcx: block, sp: span,
let loc = bcx.sess().parse_sess.cm.lookup_char_pos(sp.lo); let loc = bcx.sess().parse_sess.cm.lookup_char_pos(sp.lo);
let line = C_int(ccx, loc.line as int); let line = C_int(ccx, loc.line as int);
let filename_cstr = C_cstr(bcx.ccx(), loc.file.name); let filename_cstr = C_cstr(bcx.ccx(), /*bad*/copy loc.file.name);
let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8())); let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8()));
let args = ~[filename, line, index, len]; let args = ~[filename, line, index, len];

View File

@ -95,6 +95,7 @@
* methods themselves. Most are only suitable for some types of * methods themselves. Most are only suitable for some types of
* values. */ * values. */
use lib::llvm::ValueRef; use lib::llvm::ValueRef;
use middle::trans::base::*; use middle::trans::base::*;
use middle::trans::build::*; use middle::trans::build::*;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use driver::session; use driver::session;
use lib::llvm::ValueRef; use lib::llvm::ValueRef;
use lib::llvm::llvm; use lib::llvm::llvm;
@ -107,7 +108,7 @@ type debug_ctxt = {
crate_file: ~str crate_file: ~str
}; };
fn mk_ctxt(crate: ~str, intr: @ident_interner) -> debug_ctxt { fn mk_ctxt(+crate: ~str, intr: @ident_interner) -> debug_ctxt {
{llmetadata: map::HashMap(), {llmetadata: map::HashMap(),
names: new_namegen(intr), names: new_namegen(intr),
crate_file: crate} crate_file: crate}
@ -181,7 +182,7 @@ fn cached_metadata<T: Copy>(cache: metadata_cache, mdtag: int,
fn create_compile_unit(cx: @crate_ctxt) fn create_compile_unit(cx: @crate_ctxt)
-> @metadata<compile_unit_md> unsafe { -> @metadata<compile_unit_md> unsafe {
let cache = get_cache(cx); let cache = get_cache(cx);
let crate_name = cx.dbg_cx.get().crate_file; let crate_name = /*bad*/copy (/*bad*/copy cx.dbg_cx).get().crate_file;
let tg = CompileUnitTag; let tg = CompileUnitTag;
match cached_metadata::<@metadata<compile_unit_md>>(cache, tg, match cached_metadata::<@metadata<compile_unit_md>>(cache, tg,
|md| md.data.name == crate_name) { |md| md.data.name == crate_name) {
@ -194,7 +195,7 @@ fn create_compile_unit(cx: @crate_ctxt)
let unit_metadata = ~[lltag(tg), let unit_metadata = ~[lltag(tg),
llunused(), llunused(),
lli32(DW_LANG_RUST), lli32(DW_LANG_RUST),
llstr(crate_name), llstr(copy crate_name),
llstr(work_dir), llstr(work_dir),
llstr(env!("CFG_VERSION")), llstr(env!("CFG_VERSION")),
lli1(true), // deprecated: main compile unit lli1(true), // deprecated: main compile unit
@ -211,7 +212,7 @@ fn create_compile_unit(cx: @crate_ctxt)
} }
fn get_cache(cx: @crate_ctxt) -> metadata_cache { fn get_cache(cx: @crate_ctxt) -> metadata_cache {
cx.dbg_cx.get().llmetadata (/*bad*/copy cx.dbg_cx).get().llmetadata
} }
fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) {
@ -223,7 +224,7 @@ fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) {
}, str::from_slice(work_dir)) }, str::from_slice(work_dir))
} }
fn create_file(cx: @crate_ctxt, full_path: ~str) -> @metadata<file_md> { fn create_file(cx: @crate_ctxt, +full_path: ~str) -> @metadata<file_md> {
let cache = get_cache(cx);; let cache = get_cache(cx);;
let tg = FileDescriptorTag; let tg = FileDescriptorTag;
match cached_metadata::<@metadata<file_md>>( match cached_metadata::<@metadata<file_md>>(
@ -262,7 +263,7 @@ fn create_block(cx: block) -> @metadata<block_md> {
let sp = cx.node_info.get().span; let sp = cx.node_info.get().span;
let start = cx.sess().codemap.lookup_char_pos(sp.lo); let start = cx.sess().codemap.lookup_char_pos(sp.lo);
let fname = start.file.name; let fname = /*bad*/copy start.file.name;
let end = cx.sess().codemap.lookup_char_pos(sp.hi); let end = cx.sess().codemap.lookup_char_pos(sp.hi);
let tg = LexicalBlockTag; let tg = LexicalBlockTag;
/*alt cached_metadata::<@metadata<block_md>>( /*alt cached_metadata::<@metadata<block_md>>(
@ -365,12 +366,18 @@ type struct_ctxt = {
}; };
fn finish_structure(cx: @struct_ctxt) -> ValueRef { fn finish_structure(cx: @struct_ctxt) -> ValueRef {
return create_composite_type(StructureTypeTag, cx.name, cx.file, cx.line, return create_composite_type(StructureTypeTag,
cx.total_size, cx.align, 0, option::None, /*bad*/copy cx.name,
option::Some(cx.members)); cx.file,
cx.line,
cx.total_size,
cx.align,
0,
option::None,
option::Some(/*bad*/copy cx.members));
} }
fn create_structure(file: @metadata<file_md>, name: ~str, line: int) fn create_structure(file: @metadata<file_md>, +name: ~str, line: int)
-> @struct_ctxt { -> @struct_ctxt {
let cx = @{file: file.node, let cx = @{file: file.node,
name: name, name: name,
@ -382,7 +389,7 @@ fn create_structure(file: @metadata<file_md>, name: ~str, line: int)
return cx; return cx;
} }
fn create_derived_type(type_tag: int, file: ValueRef, name: ~str, line: int, fn create_derived_type(type_tag: int, file: ValueRef, +name: ~str, line: int,
size: int, align: int, offset: int, ty: ValueRef) size: int, align: int, offset: int, ty: ValueRef)
-> ValueRef { -> ValueRef {
let lldata = ~[lltag(type_tag), let lldata = ~[lltag(type_tag),
@ -398,7 +405,7 @@ fn create_derived_type(type_tag: int, file: ValueRef, name: ~str, line: int,
return llmdnode(lldata); return llmdnode(lldata);
} }
fn add_member(cx: @struct_ctxt, name: ~str, line: int, size: int, align: int, fn add_member(cx: @struct_ctxt, +name: ~str, line: int, size: int, align: int,
ty: ValueRef) { ty: ValueRef) {
cx.members.push(create_derived_type(MemberTag, cx.file, name, line, cx.members.push(create_derived_type(MemberTag, cx.file, name, line,
size * 8, align * 8, cx.total_size, size * 8, align * 8, cx.total_size,
@ -412,7 +419,8 @@ fn create_record(cx: @crate_ctxt, t: ty::t, fields: ~[ast::ty_field],
let file_node = create_file(cx, fname); let file_node = create_file(cx, fname);
let scx = create_structure(file_node, let scx = create_structure(file_node,
cx.sess.str_of( cx.sess.str_of(
(cx.dbg_cx.get().names)(~"rec")), ((/*bad*/copy cx.dbg_cx).get().names)
(~"rec")),
line_from_span(cx.sess.codemap, line_from_span(cx.sess.codemap,
span) as int); span) as int);
for fields.each |field| { for fields.each |field| {
@ -455,10 +463,10 @@ fn create_boxed_type(cx: @crate_ctxt, outer: ty::t, _inner: ty::t,
return mdval; return mdval;
} }
fn create_composite_type(type_tag: int, name: ~str, file: ValueRef, line: int, fn create_composite_type(type_tag: int, +name: ~str, file: ValueRef,
size: int, align: int, offset: int, line: int, size: int, align: int, offset: int,
derived: Option<ValueRef>, derived: Option<ValueRef>,
members: Option<~[ValueRef]>) +members: Option<~[ValueRef]>)
-> ValueRef { -> ValueRef {
let lldata = ~[lltag(type_tag), let lldata = ~[lltag(type_tag),
file, file,
@ -614,10 +622,10 @@ fn create_ty(_cx: @crate_ctxt, _t: ty::t, _ty: @ast::Ty)
} }
fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> ~str { fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> ~str {
cx.sess.codemap.lookup_char_pos(sp.lo).file.name /*bad*/copy cx.sess.codemap.lookup_char_pos(sp.lo).file.name
} }
fn create_var(type_tag: int, context: ValueRef, name: ~str, file: ValueRef, fn create_var(type_tag: int, context: ValueRef, +name: ~str, file: ValueRef,
line: int, ret_ty: ValueRef) -> ValueRef { line: int, ret_ty: ValueRef) -> ValueRef {
let lldata = ~[lltag(type_tag), let lldata = ~[lltag(type_tag),
context, context,
@ -649,7 +657,7 @@ fn create_local_var(bcx: block, local: @ast::local)
let loc = cx.sess.codemap.lookup_char_pos(local.span.lo); let loc = cx.sess.codemap.lookup_char_pos(local.span.lo);
let ty = node_id_type(bcx, local.node.id); let ty = node_id_type(bcx, local.node.id);
let tymd = create_ty(cx, ty, local.node.ty); let tymd = create_ty(cx, ty, local.node.ty);
let filemd = create_file(cx, loc.file.name); let filemd = create_file(cx, /*bad*/copy loc.file.name);
let context = match bcx.parent { let context = match bcx.parent {
None => create_function(bcx.fcx).node, None => create_function(bcx.fcx).node,
Some(_) => create_block(bcx).node Some(_) => create_block(bcx).node
@ -693,7 +701,7 @@ fn create_arg(bcx: block, arg: ast::arg, sp: span)
let loc = cx.sess.codemap.lookup_char_pos(sp.lo); let loc = cx.sess.codemap.lookup_char_pos(sp.lo);
let ty = node_id_type(bcx, arg.id); let ty = node_id_type(bcx, arg.id);
let tymd = create_ty(cx, ty, arg.ty); let tymd = create_ty(cx, ty, arg.ty);
let filemd = create_file(cx, loc.file.name); let filemd = create_file(cx, /*bad*/copy loc.file.name);
let context = create_function(bcx.fcx); let context = create_function(bcx.fcx);
match arg.pat.node { match arg.pat.node {
@ -740,7 +748,7 @@ fn update_source_pos(cx: block, s: span) {
fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> { fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
let cx = fcx.ccx; let cx = fcx.ccx;
let dbg_cx = cx.dbg_cx.get(); let dbg_cx = (/*bad*/copy cx.dbg_cx).get();
debug!("~~"); debug!("~~");
log(debug, fcx.id); log(debug, fcx.id);
@ -750,7 +758,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
let (ident, ret_ty, id) = match cx.tcx.items.get(fcx.id) { let (ident, ret_ty, id) = match cx.tcx.items.get(fcx.id) {
ast_map::node_item(item, _) => { ast_map::node_item(item, _) => {
match item.node { match /*bad*/copy item.node {
ast::item_fn(decl, _, _, _) => { ast::item_fn(decl, _, _, _) => {
(item.ident, decl.output, item.id) (item.ident, decl.output, item.id)
} }
@ -762,7 +770,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
(method.ident, method.decl.output, method.id) (method.ident, method.decl.output, method.id)
} }
ast_map::node_expr(expr) => { ast_map::node_expr(expr) => {
match expr.node { match /*bad*/copy expr.node {
ast::expr_fn(_, decl, _, _) => { ast::expr_fn(_, decl, _, _) => {
((dbg_cx.names)(~"fn"), decl.output, expr.id) ((dbg_cx.names)(~"fn"), decl.output, expr.id)
} }

View File

@ -111,6 +111,7 @@ lvalues are *never* stored by value.
*/ */
use lib::llvm::ValueRef; use lib::llvm::ValueRef;
use middle::resolve; use middle::resolve;
use middle::trans::base::*; use middle::trans::base::*;
@ -514,7 +515,8 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
match expr.node { // XXX: This copy is really bad.
match /*bad*/copy expr.node {
ast::expr_paren(e) => { ast::expr_paren(e) => {
return trans_rvalue_dps_unadjusted(bcx, e, dest); return trans_rvalue_dps_unadjusted(bcx, e, dest);
} }
@ -526,7 +528,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
return controlflow::trans_if(bcx, cond, (*thn), els, dest); return controlflow::trans_if(bcx, cond, (*thn), els, dest);
} }
ast::expr_match(discr, ref arms) => { ast::expr_match(discr, ref arms) => {
return alt::trans_alt(bcx, expr, discr, (*arms), dest); return alt::trans_alt(bcx, expr, discr, /*bad*/copy *arms, dest);
} }
ast::expr_block(ref blk) => { ast::expr_block(ref blk) => {
return do base::with_scope(bcx, (*blk).info(), return do base::with_scope(bcx, (*blk).info(),
@ -554,13 +556,14 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
ast::expr_vec(*) | ast::expr_repeat(*) => { ast::expr_vec(*) | ast::expr_repeat(*) => {
return tvec::trans_fixed_vstore(bcx, expr, expr, dest); return tvec::trans_fixed_vstore(bcx, expr, expr, dest);
} }
ast::expr_fn(proto, decl, ref body, cap_clause) => { // XXX: Bad copy.
ast::expr_fn(proto, copy decl, ref body, cap_clause) => {
// Don't use this function for anything real. Use the one in // Don't use this function for anything real. Use the one in
// astconv instead. // astconv instead.
return closure::trans_expr_fn(bcx, proto, decl, *body, expr.id, return closure::trans_expr_fn(bcx, proto, decl, /*bad*/copy *body,
cap_clause, None, dest); expr.id, cap_clause, None, dest);
} }
ast::expr_fn_block(decl, ref body, cap_clause) => { ast::expr_fn_block(ref decl, ref body, cap_clause) => {
let expr_ty = expr_ty(bcx, expr); let expr_ty = expr_ty(bcx, expr);
match ty::get(expr_ty).sty { match ty::get(expr_ty).sty {
ty::ty_fn(ref fn_ty) => { ty::ty_fn(ref fn_ty) => {
@ -568,7 +571,8 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
expr_to_str(expr, tcx.sess.intr()), expr_to_str(expr, tcx.sess.intr()),
ty_to_str(tcx, expr_ty)); ty_to_str(tcx, expr_ty));
return closure::trans_expr_fn( return closure::trans_expr_fn(
bcx, fn_ty.meta.proto, decl, *body, expr.id, bcx, fn_ty.meta.proto, /*bad*/copy *decl,
/*bad*/copy *body, expr.id,
cap_clause, None, dest); cap_clause, None, dest);
} }
_ => { _ => {
@ -581,10 +585,16 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
match ty::get(expr_ty(bcx, expr)).sty { match ty::get(expr_ty(bcx, expr)).sty {
ty::ty_fn(ref fn_ty) => { ty::ty_fn(ref fn_ty) => {
match blk.node { match blk.node {
ast::expr_fn_block(decl, ref body, cap) => { ast::expr_fn_block(copy decl, ref body, cap) => {
return closure::trans_expr_fn( return closure::trans_expr_fn(
bcx, fn_ty.meta.proto, decl, *body, blk.id, bcx,
cap, Some(None), dest); fn_ty.meta.proto,
decl,
/*bad*/copy *body,
blk.id,
cap,
Some(None),
dest);
} }
_ => { _ => {
bcx.sess().impossible_case( bcx.sess().impossible_case(

View File

@ -11,6 +11,7 @@
// The classification code for the x86_64 ABI is taken from the clay language // The classification code for the x86_64 ABI is taken from the clay language
// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
use back::{link, abi}; use back::{link, abi};
use driver::session::arch_x86_64; use driver::session::arch_x86_64;
use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg}; use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
@ -441,7 +442,7 @@ fn decl_x86_64_fn(tys: x86_64_tys,
fn link_name(ccx: @crate_ctxt, i: @ast::foreign_item) -> ~str { fn link_name(ccx: @crate_ctxt, i: @ast::foreign_item) -> ~str {
match attr::first_attr_value_str_by_name(i.attrs, ~"link_name") { match attr::first_attr_value_str_by_name(i.attrs, ~"link_name") {
None => ccx.sess.str_of(i.ident), None => ccx.sess.str_of(i.ident),
option::Some(ref ln) => (*ln) option::Some(ref ln) => (/*bad*/copy *ln)
} }
} }
@ -458,7 +459,9 @@ fn c_arg_and_ret_lltys(ccx: @crate_ctxt,
id: ast::node_id) -> (~[TypeRef], TypeRef, ty::t) { id: ast::node_id) -> (~[TypeRef], TypeRef, ty::t) {
match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty { match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty {
ty::ty_fn(ref fn_ty) => { ty::ty_fn(ref fn_ty) => {
let llargtys = type_of_explicit_args(ccx, fn_ty.sig.inputs); let llargtys = type_of_explicit_args(
ccx,
/*bad*/copy fn_ty.sig.inputs);
let llretty = type_of::type_of(ccx, fn_ty.sig.output); let llretty = type_of::type_of(ccx, fn_ty.sig.output);
(llargtys, llretty, fn_ty.sig.output) (llargtys, llretty, fn_ty.sig.output)
} }
@ -469,7 +472,8 @@ fn c_arg_and_ret_lltys(ccx: @crate_ctxt,
fn c_stack_tys(ccx: @crate_ctxt, fn c_stack_tys(ccx: @crate_ctxt,
id: ast::node_id) -> @c_stack_tys { id: ast::node_id) -> @c_stack_tys {
let (llargtys, llretty, ret_ty) = c_arg_and_ret_lltys(ccx, id); let (llargtys, llretty, ret_ty) = c_arg_and_ret_lltys(ccx, id);
let bundle_ty = T_struct(vec::append_one(llargtys, T_ptr(llretty))); // XXX: Bad copy.
let bundle_ty = T_struct(vec::append_one(copy llargtys, T_ptr(llretty)));
let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty); let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
let x86_64 = if ccx.sess.targ_cfg.arch == arch_x86_64 { let x86_64 = if ccx.sess.targ_cfg.arch == arch_x86_64 {
option::Some(x86_64_tys(llargtys, llretty, ret_def)) option::Some(x86_64_tys(llargtys, llretty, ret_def))
@ -493,7 +497,7 @@ type shim_ret_builder = fn(bcx: block, tys: @c_stack_tys,
llargbundle: ValueRef, llretval: ValueRef); llargbundle: ValueRef, llretval: ValueRef);
fn build_shim_fn_(ccx: @crate_ctxt, fn build_shim_fn_(ccx: @crate_ctxt,
shim_name: ~str, +shim_name: ~str,
llbasefn: ValueRef, llbasefn: ValueRef,
tys: @c_stack_tys, tys: @c_stack_tys,
cc: lib::llvm::CallConv, cc: lib::llvm::CallConv,
@ -615,8 +619,8 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
match tys.x86_64_tys { match tys.x86_64_tys {
Some(ref x86_64) => { Some(ref x86_64) => {
let mut atys = (*x86_64).arg_tys; let mut atys = /*bad*/copy (*x86_64).arg_tys;
let mut attrs = (*x86_64).attrs; let mut attrs = /*bad*/copy (*x86_64).attrs;
if (*x86_64).sret { if (*x86_64).sret {
let llretptr = GEPi(bcx, llargbundle, [0u, n]); let llretptr = GEPi(bcx, llargbundle, [0u, n]);
let llretloc = Load(bcx, llretptr); let llretloc = Load(bcx, llretptr);
@ -696,24 +700,24 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
} }
let lname = link_name(ccx, foreign_item); let lname = link_name(ccx, foreign_item);
let llbasefn = base_fn(ccx, lname, tys, cc); let llbasefn = base_fn(ccx, copy lname, tys, cc);
// Name the shim function // Name the shim function
let shim_name = lname + ~"__c_stack_shim"; let shim_name = lname + ~"__c_stack_shim";
return build_shim_fn_(ccx, shim_name, llbasefn, tys, cc, return build_shim_fn_(ccx, shim_name, llbasefn, tys, cc,
build_args, build_ret); build_args, build_ret);
} }
fn base_fn(ccx: @crate_ctxt, lname: ~str, tys: @c_stack_tys, fn base_fn(ccx: @crate_ctxt, +lname: ~str, tys: @c_stack_tys,
cc: lib::llvm::CallConv) -> ValueRef { cc: lib::llvm::CallConv) -> ValueRef {
// Declare the "prototype" for the base function F: // Declare the "prototype" for the base function F:
match tys.x86_64_tys { match tys.x86_64_tys {
Some(ref x86_64) => { Some(ref x86_64) => {
do decl_x86_64_fn((*x86_64)) |fnty| { do decl_x86_64_fn((*x86_64)) |fnty| {
decl_fn(ccx.llmod, lname, cc, fnty) decl_fn(ccx.llmod, /*bad*/copy lname, cc, fnty)
} }
} }
_ => { _ => {
let llbasefnty = T_fn(tys.arg_tys, tys.ret_ty); let llbasefnty = T_fn(/*bad*/copy tys.arg_tys, tys.ret_ty);
decl_fn(ccx.llmod, lname, cc, llbasefnty) decl_fn(ccx.llmod, lname, cc, llbasefnty)
} }
} }
@ -786,7 +790,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
if abi != ast::foreign_abi_rust_intrinsic { if abi != ast::foreign_abi_rust_intrinsic {
let llwrapfn = get_item_val(ccx, id); let llwrapfn = get_item_val(ccx, id);
let tys = c_stack_tys(ccx, id); let tys = c_stack_tys(ccx, id);
if attr::attrs_contains_name(foreign_item.attrs, if attr::attrs_contains_name(/*bad*/copy foreign_item.attrs,
~"rust_stack") { ~"rust_stack") {
build_direct_fn(ccx, llwrapfn, *foreign_item, tys, cc); build_direct_fn(ccx, llwrapfn, *foreign_item, tys, cc);
} else { } else {
@ -806,13 +810,14 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
} }
fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item, fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
path: ast_map::path, substs: param_substs, +path: ast_map::path, +substs: param_substs,
ref_id: Option<ast::node_id>) ref_id: Option<ast::node_id>)
{ {
debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident)); debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident));
// XXX: Bad copy.
let fcx = new_fn_ctxt_w_id(ccx, path, decl, item.id, None, let fcx = new_fn_ctxt_w_id(ccx, path, decl, item.id, None,
Some(substs), Some(item.span)); Some(copy substs), Some(item.span));
let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb; let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
match ccx.sess.str_of(item.ident) { match ccx.sess.str_of(item.ident) {
~"atomic_cxchg" => { ~"atomic_cxchg" => {
@ -1292,18 +1297,19 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
finish_fn(fcx, lltop); finish_fn(fcx, lltop);
} }
fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl, fn trans_foreign_fn(ccx: @crate_ctxt, +path: ast_map::path,
body: ast::blk, llwrapfn: ValueRef, id: ast::node_id) { decl: ast::fn_decl, body: ast::blk, llwrapfn: ValueRef,
id: ast::node_id) {
let _icx = ccx.insn_ctxt("foreign::build_foreign_fn"); let _icx = ccx.insn_ctxt("foreign::build_foreign_fn");
fn build_rust_fn(ccx: @crate_ctxt, path: ast_map::path, fn build_rust_fn(ccx: @crate_ctxt, +path: ast_map::path,
decl: ast::fn_decl, body: ast::blk, decl: ast::fn_decl, body: ast::blk,
id: ast::node_id) -> ValueRef { id: ast::node_id) -> ValueRef {
let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn"); let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn");
let t = ty::node_id_to_type(ccx.tcx, id); let t = ty::node_id_to_type(ccx.tcx, id);
// XXX: Bad copy.
let ps = link::mangle_internal_name_by_path( let ps = link::mangle_internal_name_by_path(
ccx, vec::append_one(path, ast_map::path_name( ccx, vec::append_one(copy path, ast_map::path_name(
special_idents::clownshoe_abi special_idents::clownshoe_abi
))); )));
let llty = type_of_fn_from_ty(ccx, t); let llty = type_of_fn_from_ty(ccx, t);
@ -1312,9 +1318,8 @@ fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
return llfndecl; return llfndecl;
} }
fn build_shim_fn(ccx: @crate_ctxt, path: ast_map::path, fn build_shim_fn(ccx: @crate_ctxt, +path: ast_map::path,
llrustfn: ValueRef, tys: @c_stack_tys) -> ValueRef { llrustfn: ValueRef, tys: @c_stack_tys) -> ValueRef {
let _icx = ccx.insn_ctxt("foreign::foreign::build_shim_fn"); let _icx = ccx.insn_ctxt("foreign::foreign::build_shim_fn");
fn build_args(bcx: block, tys: @c_stack_tys, fn build_args(bcx: block, tys: @c_stack_tys,
@ -1360,8 +1365,8 @@ fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_args"); let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_args");
match tys.x86_64_tys { match tys.x86_64_tys {
option::Some(ref x86_64) => { option::Some(ref x86_64) => {
let mut atys = (*x86_64).arg_tys; let mut atys = /*bad*/copy (*x86_64).arg_tys;
let mut attrs = (*x86_64).attrs; let mut attrs = /*bad*/copy (*x86_64).attrs;
let mut j = 0u; let mut j = 0u;
let llretptr = if (*x86_64).sret { let llretptr = if (*x86_64).sret {
atys = vec::tail(atys); atys = vec::tail(atys);
@ -1445,16 +1450,19 @@ fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
let tys = c_stack_tys(ccx, id); let tys = c_stack_tys(ccx, id);
// The internal Rust ABI function - runs on the Rust stack // The internal Rust ABI function - runs on the Rust stack
let llrustfn = build_rust_fn(ccx, path, decl, body, id); // XXX: Bad copy.
let llrustfn = build_rust_fn(ccx, copy path, decl, body, id);
// The internal shim function - runs on the Rust stack // The internal shim function - runs on the Rust stack
let llshimfn = build_shim_fn(ccx, path, llrustfn, tys); let llshimfn = build_shim_fn(ccx, path, llrustfn, tys);
// The foreign C function - runs on the C stack // The foreign C function - runs on the C stack
build_wrap_fn(ccx, llshimfn, llwrapfn, tys) build_wrap_fn(ccx, llshimfn, llwrapfn, tys)
} }
fn register_foreign_fn(ccx: @crate_ctxt, sp: span, fn register_foreign_fn(ccx: @crate_ctxt,
path: ast_map::path, node_id: ast::node_id) sp: span,
-> ValueRef { +path: ast_map::path,
node_id: ast::node_id)
-> ValueRef {
let _icx = ccx.insn_ctxt("foreign::register_foreign_fn"); let _icx = ccx.insn_ctxt("foreign::register_foreign_fn");
let t = ty::node_id_to_type(ccx.tcx, node_id); let t = ty::node_id_to_type(ccx.tcx, node_id);
let (llargtys, llretty, ret_ty) = c_arg_and_ret_lltys(ccx, node_id); let (llargtys, llretty, ret_ty) = c_arg_and_ret_lltys(ccx, node_id);
@ -1462,7 +1470,7 @@ fn register_foreign_fn(ccx: @crate_ctxt, sp: span,
let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty); let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
let x86_64 = x86_64_tys(llargtys, llretty, ret_def); let x86_64 = x86_64_tys(llargtys, llretty, ret_def);
do decl_x86_64_fn(x86_64) |fnty| { do decl_x86_64_fn(x86_64) |fnty| {
register_fn_fuller(ccx, sp, path, node_id, register_fn_fuller(ccx, sp, /*bad*/copy path, node_id,
t, lib::llvm::CCallConv, fnty) t, lib::llvm::CCallConv, fnty)
} }
} else { } else {
@ -1482,7 +1490,9 @@ fn abi_of_foreign_fn(ccx: @crate_ctxt, i: @ast::foreign_item)
}, },
Some(_) => match attr::foreign_abi(i.attrs) { Some(_) => match attr::foreign_abi(i.attrs) {
either::Right(abi) => abi, either::Right(abi) => abi,
either::Left(ref msg) => ccx.sess.span_fatal(i.span, (*msg)) either::Left(ref msg) => {
ccx.sess.span_fatal(i.span, (/*bad*/copy *msg))
}
} }
} }
} }

View File

@ -12,6 +12,7 @@
// //
// Code relating to taking, dropping, etc as well as type descriptors. // Code relating to taking, dropping, etc as well as type descriptors.
use lib::llvm::{ValueRef, TypeRef}; use lib::llvm::{ValueRef, TypeRef};
use middle::trans::base::*; use middle::trans::base::*;
use middle::trans::callee; use middle::trans::callee;
@ -447,7 +448,7 @@ fn trans_struct_drop(bcx: block,
// Find and call the actual destructor // Find and call the actual destructor
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did,
class_did, substs.tps); class_did, /*bad*/copy substs.tps);
// The second argument is the "self" argument for drop // The second argument is the "self" argument for drop
let params = lib::llvm::fn_ty_param_tys( let params = lib::llvm::fn_ty_param_tys(
@ -656,7 +657,8 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
} else { } else {
mangle_internal_name_by_seq(ccx, ~"tydesc") mangle_internal_name_by_seq(ccx, ~"tydesc")
}; };
note_unique_llvm_symbol(ccx, name); // XXX: Bad copy.
note_unique_llvm_symbol(ccx, copy name);
log(debug, fmt!("+++ declare_tydesc %s %s", ty_to_str(ccx.tcx, t), name)); log(debug, fmt!("+++ declare_tydesc %s %s", ty_to_str(ccx.tcx, t), name));
let gvar = str::as_c_str(name, |buf| { let gvar = str::as_c_str(name, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf) llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
@ -678,7 +680,7 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
type glue_helper = fn@(block, ValueRef, ty::t); type glue_helper = fn@(block, ValueRef, ty::t);
fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef, fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
name: ~str) -> ValueRef { +name: ~str) -> ValueRef {
let _icx = ccx.insn_ctxt("declare_generic_glue"); let _icx = ccx.insn_ctxt("declare_generic_glue");
let name = name; let name = name;
let mut fn_nm; let mut fn_nm;
@ -689,7 +691,8 @@ fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
fn_nm = mangle_internal_name_by_seq(ccx, (~"glue_" + name)); fn_nm = mangle_internal_name_by_seq(ccx, (~"glue_" + name));
} }
debug!("%s is for type %s", fn_nm, ty_to_str(ccx.tcx, t)); debug!("%s is for type %s", fn_nm, ty_to_str(ccx.tcx, t));
note_unique_llvm_symbol(ccx, fn_nm); // XXX: Bad copy.
note_unique_llvm_symbol(ccx, copy fn_nm);
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty); let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
set_glue_inlining(llfn, t); set_glue_inlining(llfn, t);
return llfn; return llfn;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::astencode; use middle::astencode;
use middle::trans::base::{get_insn_ctxt}; use middle::trans::base::{get_insn_ctxt};
use middle::trans::base::{impl_owned_self, impl_self, no_self}; use middle::trans::base::{impl_owned_self, impl_self, no_self};

View File

@ -10,6 +10,7 @@
// Information concerning the machine representation of various types. // Information concerning the machine representation of various types.
use middle::trans::common::*; use middle::trans::common::*;
use middle::trans::type_of; use middle::trans::type_of;
use middle::ty; use middle::ty;
@ -152,8 +153,9 @@ pub fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint {
let mut max_size = 0u; let mut max_size = 0u;
let variants = ty::enum_variants(cx.tcx, tid); let variants = ty::enum_variants(cx.tcx, tid);
for vec::each(*variants) |variant| { for vec::each(*variants) |variant| {
let tup_ty = simplify_type(cx.tcx, let tup_ty = simplify_type(
ty::mk_tup(cx.tcx, variant.args)); cx.tcx,
ty::mk_tup(cx.tcx, /*bad*/copy variant.args));
// Perform any type parameter substitutions. // Perform any type parameter substitutions.
let tup_ty = ty::subst(cx.tcx, substs, tup_ty); let tup_ty = ty::subst(cx.tcx, substs, tup_ty);
// Here we possibly do a recursive call. // Here we possibly do a recursive call.

View File

@ -52,4 +52,4 @@ macro_rules! trace(
) )
); );
} }

View File

@ -44,7 +44,7 @@ for non-monomorphized methods only. Other methods will
be generated once they are invoked with specific type parameters, be generated once they are invoked with specific type parameters,
see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`. see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
*/ */
fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident, fn trans_impl(ccx: @crate_ctxt, +path: path, name: ast::ident,
methods: ~[@ast::method], tps: ~[ast::ty_param], methods: ~[@ast::method], tps: ~[ast::ty_param],
self_ty: Option<ty::t>, id: ast::node_id) { self_ty: Option<ty::t>, id: ast::node_id) {
let _icx = ccx.insn_ctxt("impl::trans_impl"); let _icx = ccx.insn_ctxt("impl::trans_impl");
@ -53,7 +53,8 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
for vec::each(methods) |method| { for vec::each(methods) |method| {
if method.tps.len() == 0u { if method.tps.len() == 0u {
let llfn = get_item_val(ccx, method.id); let llfn = get_item_val(ccx, method.id);
let path = vec::append_one(sub_path, path_name(method.ident)); let path = vec::append_one(/*bad*/copy sub_path,
path_name(method.ident));
let param_substs_opt; let param_substs_opt;
match self_ty { match self_ty {
@ -90,13 +91,12 @@ Translates a (possibly monomorphized) method body.
- `impl_id`: the node ID of the impl this method is inside - `impl_id`: the node ID of the impl this method is inside
*/ */
fn trans_method(ccx: @crate_ctxt, fn trans_method(ccx: @crate_ctxt,
path: path, +path: path,
method: &ast::method, method: &ast::method,
param_substs: Option<param_substs>, +param_substs: Option<param_substs>,
base_self_ty: Option<ty::t>, base_self_ty: Option<ty::t>,
llfn: ValueRef, llfn: ValueRef,
impl_id: ast::def_id) { impl_id: ast::def_id) {
// figure out how self is being passed // figure out how self is being passed
let self_arg = match method.self_ty.node { let self_arg = match method.self_ty.node {
ast::sty_static => { ast::sty_static => {
@ -289,7 +289,7 @@ fn trans_static_method_callee(bcx: block,
let vtbls = resolve_vtables_in_fn_ctxt( let vtbls = resolve_vtables_in_fn_ctxt(
bcx.fcx, ccx.maps.vtable_map.get(callee_id)); bcx.fcx, ccx.maps.vtable_map.get(callee_id));
match vtbls[bound_index] { match /*bad*/copy vtbls[bound_index] {
typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => { typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => {
let mth_id = method_with_name(bcx.ccx(), impl_did, mname); let mth_id = method_with_name(bcx.ccx(), impl_did, mname);
@ -325,8 +325,11 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id,
name: ast::ident) -> ast::def_id { name: ast::ident) -> ast::def_id {
if impl_id.crate == ast::local_crate { if impl_id.crate == ast::local_crate {
match ccx.tcx.items.get(impl_id.node) { match ccx.tcx.items.get(impl_id.node) {
ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) => { ast_map::node_item(@{
method_from_methods(ms, name).get() node: ast::item_impl(_, _, _, ref ms),
_
}, _) => {
method_from_methods(/*bad*/copy *ms, name).get()
} }
_ => fail ~"method_with_name" _ => fail ~"method_with_name"
} }
@ -339,8 +342,10 @@ fn method_with_name_or_default(ccx: @crate_ctxt, impl_id: ast::def_id,
name: ast::ident) -> ast::def_id { name: ast::ident) -> ast::def_id {
if impl_id.crate == ast::local_crate { if impl_id.crate == ast::local_crate {
match ccx.tcx.items.get(impl_id.node) { match ccx.tcx.items.get(impl_id.node) {
ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) => { ast_map::node_item(@{
let did = method_from_methods(ms, name); node: ast::item_impl(_, _, _, ref ms), _
}, _) => {
let did = method_from_methods(/*bad*/copy *ms, name);
if did.is_some() { if did.is_some() {
return did.get(); return did.get();
} else { } else {
@ -400,7 +405,7 @@ fn trans_monomorphized_callee(bcx: block,
mentry: typeck::method_map_entry, mentry: typeck::method_map_entry,
trait_id: ast::def_id, trait_id: ast::def_id,
n_method: uint, n_method: uint,
vtbl: typeck::vtable_origin) +vtbl: typeck::vtable_origin)
-> Callee -> Callee
{ {
let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee"); let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee");
@ -462,7 +467,7 @@ fn combine_impl_and_methods_tps(bcx: block,
mth_did: ast::def_id, mth_did: ast::def_id,
impl_did: ast::def_id, impl_did: ast::def_id,
callee_id: ast::node_id, callee_id: ast::node_id,
rcvr_substs: ~[ty::t]) +rcvr_substs: ~[ty::t])
-> ~[ty::t] -> ~[ty::t]
{ {
/*! /*!
@ -485,12 +490,12 @@ fn combine_impl_and_methods_tps(bcx: block,
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let n_m_tps = method_ty_param_count(ccx, mth_did, impl_did); let n_m_tps = method_ty_param_count(ccx, mth_did, impl_did);
let node_substs = node_id_type_params(bcx, callee_id); let node_substs = node_id_type_params(bcx, callee_id);
debug!("rcvr_substs=%?", rcvr_substs.map(|t| bcx.ty_to_str(*t)));
let ty_substs let ty_substs
= vec::append(rcvr_substs, = vec::append(rcvr_substs,
vec::tailn(node_substs, vec::tailn(node_substs,
node_substs.len() - n_m_tps)); node_substs.len() - n_m_tps));
debug!("n_m_tps=%?", n_m_tps); debug!("n_m_tps=%?", n_m_tps);
debug!("rcvr_substs=%?", rcvr_substs.map(|t| bcx.ty_to_str(*t)));
debug!("node_substs=%?", node_substs.map(|t| bcx.ty_to_str(*t))); debug!("node_substs=%?", node_substs.map(|t| bcx.ty_to_str(*t)));
debug!("ty_substs=%?", ty_substs.map(|t| bcx.ty_to_str(*t))); debug!("ty_substs=%?", ty_substs.map(|t| bcx.ty_to_str(*t)));
@ -535,7 +540,7 @@ fn combine_impl_and_methods_origins(bcx: block,
let m_origins = vec::tailn(*r_m_origins, r_m_origins.len() - m_vtables); let m_origins = vec::tailn(*r_m_origins, r_m_origins.len() - m_vtables);
// Combine rcvr + method to find the final result: // Combine rcvr + method to find the final result:
@vec::append(*rcvr_origins, m_origins) @vec::append(/*bad*/copy *rcvr_origins, m_origins)
} }
@ -706,7 +711,7 @@ fn trans_trait_callee_from_llval(bcx: block,
}; };
} }
fn vtable_id(ccx: @crate_ctxt, origin: typeck::vtable_origin) -> mono_id { fn vtable_id(ccx: @crate_ctxt, +origin: typeck::vtable_origin) -> mono_id {
match origin { match origin {
typeck::vtable_static(impl_id, substs, sub_vtables) => { typeck::vtable_static(impl_id, substs, sub_vtables) => {
monomorphize::make_mono_id( monomorphize::make_mono_id(
@ -733,9 +738,9 @@ fn vtable_id(ccx: @crate_ctxt, origin: typeck::vtable_origin) -> mono_id {
} }
} }
fn get_vtable(ccx: @crate_ctxt, origin: typeck::vtable_origin) fn get_vtable(ccx: @crate_ctxt, +origin: typeck::vtable_origin) -> ValueRef {
-> ValueRef { // XXX: Bad copy.
let hash_id = vtable_id(ccx, origin); let hash_id = vtable_id(ccx, copy origin);
match ccx.vtables.find(hash_id) { match ccx.vtables.find(hash_id) {
Some(val) => val, Some(val) => val,
None => match origin { None => match origin {
@ -868,7 +873,7 @@ fn trans_trait_cast(bcx: block,
} }
// Store the vtable into the pair or triple. // Store the vtable into the pair or triple.
let orig = ccx.maps.vtable_map.get(id)[0]; let orig = /*bad*/copy ccx.maps.vtable_map.get(id)[0];
let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig); let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig);
let vtable = get_vtable(bcx.ccx(), orig); let vtable = get_vtable(bcx.ccx(), orig);
Store(bcx, vtable, PointerCast(bcx, Store(bcx, vtable, PointerCast(bcx,

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back::link::mangle_exported_name; use back::link::mangle_exported_name;
use middle::trans::base::{get_insn_ctxt}; use middle::trans::base::{get_insn_ctxt};
use middle::trans::base::{set_inline_hint_if_appr, set_inline_hint}; use middle::trans::base::{set_inline_hint_if_appr, set_inline_hint};
@ -53,7 +54,8 @@ fn monomorphic_fn(ccx: @crate_ctxt,
for real_substs.each() |s| { assert !ty::type_has_params(*s); } for real_substs.each() |s| { assert !ty::type_has_params(*s); }
for substs.each() |s| { assert !ty::type_has_params(*s); } for substs.each() |s| { assert !ty::type_has_params(*s); }
let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len()); let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len());
let hash_id = make_mono_id(ccx, fn_id, substs, vtables, impl_did_opt, // XXX: Bad copy.
let hash_id = make_mono_id(ccx, fn_id, copy substs, vtables, impl_did_opt,
Some(param_uses)); Some(param_uses));
if vec::any(hash_id.params, if vec::any(hash_id.params,
|p| match *p { mono_precise(_, _) => false, _ => true }) { |p| match *p { mono_precise(_, _) => false, _ => true }) {
@ -146,12 +148,12 @@ fn monomorphic_fn(ccx: @crate_ctxt,
} }
ccx.monomorphizing.insert(fn_id, depth + 1); ccx.monomorphizing.insert(fn_id, depth + 1);
let pt = vec::append(*pt, let pt = vec::append(/*bad*/copy *pt,
~[path_name((ccx.names)(ccx.sess.str_of(name)))]); ~[path_name((ccx.names)(ccx.sess.str_of(name)))]);
let s = mangle_exported_name(ccx, pt, mono_ty); let s = mangle_exported_name(ccx, /*bad*/copy pt, mono_ty);
let mk_lldecl = || { let mk_lldecl = |/*bad*/copy s| {
let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, llfty); let lldecl = decl_internal_cdecl_fn(ccx.llmod, /*bad*/copy s, llfty);
ccx.monomorphized.insert(hash_id, lldecl); ccx.monomorphized.insert(hash_id, lldecl);
lldecl lldecl
}; };
@ -165,11 +167,12 @@ fn monomorphic_fn(ccx: @crate_ctxt,
let lldecl = match map_node { let lldecl = match map_node {
ast_map::node_item(i@@{ ast_map::node_item(i@@{
node: ast::item_fn(decl, _, _, ref body), // XXX: Bad copy.
node: ast::item_fn(copy decl, _, _, ref body),
_ _
}, _) => { }, _) => {
let d = mk_lldecl(); let d = mk_lldecl();
set_inline_hint_if_appr(i.attrs, d); set_inline_hint_if_appr(/*bad*/copy i.attrs, d);
trans_fn(ccx, pt, decl, *body, d, no_self, psubsts, fn_id.node, None); trans_fn(ccx, pt, decl, *body, d, no_self, psubsts, fn_id.node, None);
d d
} }
@ -189,9 +192,9 @@ fn monomorphic_fn(ccx: @crate_ctxt,
let d = mk_lldecl(); let d = mk_lldecl();
set_inline_hint(d); set_inline_hint(d);
match (*v).node.kind { match (*v).node.kind {
ast::tuple_variant_kind(args) => { ast::tuple_variant_kind(ref args) => {
trans_enum_variant(ccx, enum_item.id, (*v), args, trans_enum_variant(ccx, enum_item.id, *v, /*bad*/copy *args,
this_tv.disr_val, (*tvs).len() == 1u, this_tv.disr_val, tvs.len() == 1u,
psubsts, d); psubsts, d);
} }
ast::struct_variant_kind(_) => ast::struct_variant_kind(_) =>
@ -204,7 +207,7 @@ fn monomorphic_fn(ccx: @crate_ctxt,
ast_map::node_method(mth, supplied_impl_did, _) => { ast_map::node_method(mth, supplied_impl_did, _) => {
// XXX: What should the self type be here? // XXX: What should the self type be here?
let d = mk_lldecl(); let d = mk_lldecl();
set_inline_hint_if_appr(mth.attrs, d); set_inline_hint_if_appr(/*bad*/copy mth.attrs, d);
// Override the impl def ID if necessary. // Override the impl def ID if necessary.
let impl_did; let impl_did;
@ -223,14 +226,14 @@ fn monomorphic_fn(ccx: @crate_ctxt,
None => ccx.sess.span_bug(dtor.span, ~"Bad self ty in \ None => ccx.sess.span_bug(dtor.span, ~"Bad self ty in \
dtor") dtor")
}; };
trans_struct_dtor(ccx, *pt, dtor.node.body, trans_struct_dtor(ccx, /*bad*/copy *pt, dtor.node.body,
dtor.node.id, psubsts, Some(hash_id), parent_id) dtor.node.id, psubsts, Some(hash_id), parent_id)
} }
ast_map::node_trait_method(@ast::provided(mth), _, pt) => { ast_map::node_trait_method(@ast::provided(mth), _, pt) => {
let d = mk_lldecl(); let d = mk_lldecl();
set_inline_hint_if_appr(mth.attrs, d); set_inline_hint_if_appr(/*bad*/copy mth.attrs, d);
debug!("monomorphic_fn impl_did_opt is %?", impl_did_opt); debug!("monomorphic_fn impl_did_opt is %?", impl_did_opt);
meth::trans_method(ccx, *pt, mth, psubsts, None, d, meth::trans_method(ccx, /*bad*/copy *pt, mth, psubsts, None, d,
impl_did_opt.get()); impl_did_opt.get());
d d
} }
@ -238,7 +241,7 @@ fn monomorphic_fn(ccx: @crate_ctxt,
let d = mk_lldecl(); let d = mk_lldecl();
set_inline_hint(d); set_inline_hint(d);
base::trans_tuple_struct(ccx, base::trans_tuple_struct(ccx,
struct_def.fields, /*bad*/copy struct_def.fields,
option::expect(struct_def.ctor_id, option::expect(struct_def.ctor_id,
~"ast-mapped tuple struct \ ~"ast-mapped tuple struct \
didn't have a ctor id"), didn't have a ctor id"),
@ -316,7 +319,7 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t],
for bounds.each |bound| { for bounds.each |bound| {
match *bound { match *bound {
ty::bound_trait(_) => { ty::bound_trait(_) => {
v.push(meth::vtable_id(ccx, vts[i])); v.push(meth::vtable_id(ccx, /*bad*/copy vts[i]));
i += 1u; i += 1u;
} }
_ => () _ => ()
@ -330,15 +333,16 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t],
} }
}; };
let param_ids = match param_uses { let param_ids = match param_uses {
Some(uses) => { Some(ref uses) => {
vec::map2(precise_param_ids, uses, |id, uses| { vec::map2(precise_param_ids, *uses, |id, uses| {
if ccx.sess.no_monomorphic_collapse() { if ccx.sess.no_monomorphic_collapse() {
match *id { match *id {
(a, b) => mono_precise(a, b) (a, b) => mono_precise(a, b)
} }
} else { } else {
match *id { match *id {
(a, b@Some(_)) => mono_precise(a, b), // XXX: Bad copy.
(a, copy b@Some(_)) => mono_precise(a, b),
(subst, None) => { (subst, None) => {
if *uses == 0u { if *uses == 0u {
mono_any mono_any

View File

@ -15,6 +15,7 @@
// makes all other generics or inline functions that it references // makes all other generics or inline functions that it references
// reachable as well. // reachable as well.
use driver::session::*; use driver::session::*;
use middle::resolve; use middle::resolve;
use middle::ty; use middle::ty;
@ -71,7 +72,7 @@ fn traverse_def_id(cx: ctx, did: def_id) {
if did.crate != local_crate { return; } if did.crate != local_crate { return; }
let n = match cx.tcx.items.find(did.node) { let n = match cx.tcx.items.find(did.node) {
None => return, // This can happen for self, for example None => return, // This can happen for self, for example
Some(ref n) => (*n) Some(ref n) => (/*bad*/copy *n)
}; };
match n { match n {
ast_map::node_item(item, _) => traverse_public_item(cx, item), ast_map::node_item(item, _) => traverse_public_item(cx, item),
@ -98,7 +99,7 @@ fn traverse_public_mod(cx: ctx, mod_id: node_id, m: _mod) {
fn traverse_public_item(cx: ctx, item: @item) { fn traverse_public_item(cx: ctx, item: @item) {
if cx.rmap.contains_key(item.id) { return; } if cx.rmap.contains_key(item.id) { return; }
cx.rmap.insert(item.id, ()); cx.rmap.insert(item.id, ());
match item.node { match /*bad*/copy item.node {
item_mod(m) => traverse_public_mod(cx, item.id, m), item_mod(m) => traverse_public_mod(cx, item.id, m),
item_foreign_mod(nm) => { item_foreign_mod(nm) => {
if !traverse_exports(cx, item.id) { if !traverse_exports(cx, item.id) {
@ -107,7 +108,7 @@ fn traverse_public_item(cx: ctx, item: @item) {
} }
} }
} }
item_fn(_, _, tps, ref blk) => { item_fn(_, _, ref tps, ref blk) => {
if tps.len() > 0u || if tps.len() > 0u ||
attr::find_inline_attr(item.attrs) != attr::ia_none { attr::find_inline_attr(item.attrs) != attr::ia_none {
traverse_inline_body(cx, (*blk)); traverse_inline_body(cx, (*blk));

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back::abi; use back::abi;
use lib::llvm::{TypeRef, ValueRef}; use lib::llvm::{TypeRef, ValueRef};
use middle::trans::base::*; use middle::trans::base::*;
@ -45,16 +46,16 @@ impl reflector {
C_int(self.bcx.ccx(), i) C_int(self.bcx.ccx(), i)
} }
fn c_slice(s: ~str) -> ValueRef { fn c_slice(+s: ~str) -> ValueRef {
// We're careful to not use first class aggregates here because that // We're careful to not use first class aggregates here because that
// will kick us off fast isel. (Issue #4352.) // will kick us off fast isel. (Issue #4352.)
let bcx = self.bcx; let bcx = self.bcx;
let str_vstore = ty::vstore_slice(ty::re_static); let str_vstore = ty::vstore_slice(ty::re_static);
let str_ty = ty::mk_estr(bcx.tcx(), str_vstore); let str_ty = ty::mk_estr(bcx.tcx(), str_vstore);
let scratch = scratch_datum(bcx, str_ty, false); let scratch = scratch_datum(bcx, str_ty, false);
let len = C_uint(bcx.ccx(), s.len() + 1);
let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), T_ptr(T_i8())); let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), T_ptr(T_i8()));
Store(bcx, c_str, GEPi(bcx, scratch.val, [ 0, 0 ])); Store(bcx, c_str, GEPi(bcx, scratch.val, [ 0, 0 ]));
let len = C_uint(bcx.ccx(), s.len() + 1);
Store(bcx, len, GEPi(bcx, scratch.val, [ 0, 1 ])); Store(bcx, len, GEPi(bcx, scratch.val, [ 0, 1 ]));
scratch.val scratch.val
} }
@ -85,7 +86,9 @@ impl reflector {
tcx.sess.ident_of(~"visit_" + ty_name), tcx.sess.ident_of(~"visit_" + ty_name),
*self.visitor_methods).expect(fmt!("Couldn't find visit method \ *self.visitor_methods).expect(fmt!("Couldn't find visit method \
for %s", ty_name)); for %s", ty_name));
let mth_ty = ty::mk_fn(tcx, self.visitor_methods[mth_idx].fty); let mth_ty = ty::mk_fn(
tcx,
/*bad*/copy self.visitor_methods[mth_idx].fty);
let v = self.visitor_val; let v = self.visitor_val;
debug!("passing %u args:", vec::len(args)); debug!("passing %u args:", vec::len(args));
let bcx = self.bcx; let bcx = self.bcx;
@ -110,16 +113,17 @@ impl reflector {
self.bcx = next_bcx self.bcx = next_bcx
} }
fn bracketed(bracket_name: ~str, extra: ~[ValueRef], fn bracketed(bracket_name: ~str, +extra: ~[ValueRef],
inner: fn()) { inner: fn()) {
self.visit(~"enter_" + bracket_name, extra); // XXX: Bad copy.
self.visit(~"enter_" + bracket_name, copy extra);
inner(); inner();
self.visit(~"leave_" + bracket_name, extra); self.visit(~"leave_" + bracket_name, extra);
} }
fn vstore_name_and_extra(t: ty::t, fn vstore_name_and_extra(t: ty::t,
vstore: ty::vstore, vstore: ty::vstore,
f: fn(~str,~[ValueRef])) { f: fn(+s: ~str,+v: ~[ValueRef])) {
match vstore { match vstore {
ty::vstore_fixed(n) => { ty::vstore_fixed(n) => {
let extra = vec::append(~[self.c_uint(n)], let extra = vec::append(~[self.c_uint(n)],
@ -132,7 +136,7 @@ impl reflector {
} }
} }
fn leaf(name: ~str) { fn leaf(+name: ~str) {
self.visit(name, ~[]); self.visit(name, ~[]);
} }
@ -143,7 +147,7 @@ impl reflector {
debug!("reflect::visit_ty %s", debug!("reflect::visit_ty %s",
ty_to_str(bcx.ccx().tcx, t)); ty_to_str(bcx.ccx().tcx, t));
match ty::get(t).sty { match /*bad*/copy ty::get(t).sty {
ty::ty_bot => self.leaf(~"bot"), ty::ty_bot => self.leaf(~"bot"),
ty::ty_nil => self.leaf(~"nil"), ty::ty_nil => self.leaf(~"nil"),
ty::ty_bool => self.leaf(~"bool"), ty::ty_bool => self.leaf(~"bool"),
@ -219,11 +223,12 @@ impl reflector {
ast::noreturn => 0u, ast::noreturn => 0u,
ast::return_val => 1u ast::return_val => 1u
}; };
// XXX: Must we allocate here?
let extra = ~[self.c_uint(pureval), let extra = ~[self.c_uint(pureval),
self.c_uint(protoval), self.c_uint(protoval),
self.c_uint(vec::len(fty.sig.inputs)), self.c_uint(vec::len(fty.sig.inputs)),
self.c_uint(retval)]; self.c_uint(retval)];
self.visit(~"enter_fn", extra); self.visit(~"enter_fn", copy extra); // XXX: Bad copy.
for fty.sig.inputs.eachi |i, arg| { for fty.sig.inputs.eachi |i, arg| {
let modeval = match arg.mode { let modeval = match arg.mode {
ast::infer(_) => 0u, ast::infer(_) => 0u,

View File

@ -11,6 +11,7 @@
// A "shape" is a compact encoding of a type that is used by interpreted glue. // A "shape" is a compact encoding of a type that is used by interpreted glue.
// This substitutes for the runtime tags used by e.g. MLs. // This substitutes for the runtime tags used by e.g. MLs.
use back::abi; use back::abi;
use lib::llvm::llvm; use lib::llvm::llvm;
use lib::llvm::{True, False, ModuleRef, TypeRef, ValueRef}; use lib::llvm::{True, False, ModuleRef, TypeRef, ValueRef};

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back::abi; use back::abi;
use lib::llvm::{ValueRef, TypeRef}; use lib::llvm::{ValueRef, TypeRef};
use middle::trans::build::*; use middle::trans::build::*;
@ -257,7 +258,7 @@ fn trans_lit_str(bcx: block,
SaveIn(lldest) => { SaveIn(lldest) => {
let bytes = lit_str.len() + 1; // count null-terminator too let bytes = lit_str.len() + 1; // count null-terminator too
let llbytes = C_uint(bcx.ccx(), bytes); let llbytes = C_uint(bcx.ccx(), bytes);
let llcstr = C_cstr(bcx.ccx(), *lit_str); let llcstr = C_cstr(bcx.ccx(), /*bad*/copy *lit_str);
let llcstr = llvm::LLVMConstPointerCast(llcstr, T_ptr(T_i8())); let llcstr = llvm::LLVMConstPointerCast(llcstr, T_ptr(T_i8()));
Store(bcx, llcstr, GEPi(bcx, lldest, [0u, abi::slice_elt_base])); Store(bcx, llcstr, GEPi(bcx, lldest, [0u, abi::slice_elt_base]));
Store(bcx, llbytes, GEPi(bcx, lldest, [0u, abi::slice_elt_len])); Store(bcx, llbytes, GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
@ -314,7 +315,7 @@ fn write_content(bcx: block,
bcx.expr_to_str(vstore_expr)); bcx.expr_to_str(vstore_expr));
let _indenter = indenter(); let _indenter = indenter();
match content_expr.node { match /*bad*/copy content_expr.node {
ast::expr_lit(@{node: ast::lit_str(s), span: _}) => { ast::expr_lit(@{node: ast::lit_str(s), span: _}) => {
match dest { match dest {
Ignore => { Ignore => {
@ -323,7 +324,7 @@ fn write_content(bcx: block,
SaveIn(lldest) => { SaveIn(lldest) => {
let bytes = s.len() + 1; // copy null-terminator too let bytes = s.len() + 1; // copy null-terminator too
let llbytes = C_uint(bcx.ccx(), bytes); let llbytes = C_uint(bcx.ccx(), bytes);
let llcstr = C_cstr(bcx.ccx(), *s); let llcstr = C_cstr(bcx.ccx(), /*bad*/copy *s);
base::call_memcpy(bcx, lldest, llcstr, llbytes); base::call_memcpy(bcx, lldest, llcstr, llbytes);
return bcx; return bcx;
} }
@ -420,7 +421,7 @@ fn vec_types(bcx: block, vec_ty: ty::t) -> VecTypes {
fn elements_required(bcx: block, content_expr: @ast::expr) -> uint { fn elements_required(bcx: block, content_expr: @ast::expr) -> uint {
//! Figure out the number of elements we need to store this content //! Figure out the number of elements we need to store this content
match content_expr.node { match /*bad*/copy content_expr.node {
ast::expr_lit(@{node: ast::lit_str(s), span: _}) => s.len() + 1, ast::expr_lit(@{node: ast::lit_str(s), span: _}) => s.len() + 1,
ast::expr_vec(es, _) => es.len(), ast::expr_vec(es, _) => es.len(),
ast::expr_repeat(_, count_expr, _) => { ast::expr_repeat(_, count_expr, _) => {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use lib::llvm::llvm; use lib::llvm::llvm;
use lib::llvm::{TypeRef}; use lib::llvm::{TypeRef};
use middle::trans::common::*; use middle::trans::common::*;
@ -107,7 +108,8 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
return llty; return llty;
} }
let llty = match ty::get(t).sty { // XXX: This is a terrible terrible copy.
let llty = match /*bad*/copy ty::get(t).sty {
ty::ty_nil | ty::ty_bot => T_nil(), ty::ty_nil | ty::ty_bot => T_nil(),
ty::ty_bool => T_bool(), ty::ty_bool => T_bool(),
ty::ty_int(t) => T_int_ty(cx, t), ty::ty_int(t) => T_int_ty(cx, t),
@ -122,7 +124,10 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
// avoids creating more than one copy of the enum when one // avoids creating more than one copy of the enum when one
// of the enum's variants refers to the enum itself. // of the enum's variants refers to the enum itself.
common::T_named_struct(llvm_type_name(cx, an_enum, did, substs.tps)) common::T_named_struct(llvm_type_name(cx,
an_enum,
did,
/*bad*/copy substs.tps))
} }
ty::ty_estr(ty::vstore_box) => { ty::ty_estr(ty::vstore_box) => {
T_box_ptr(T_box(cx, T_vec(cx, T_i8()))) T_box_ptr(T_box(cx, T_vec(cx, T_i8())))
@ -187,7 +192,10 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
// in *after* placing it into the type cache. This prevents // in *after* placing it into the type cache. This prevents
// infinite recursion with recursive struct types. // infinite recursion with recursive struct types.
common::T_named_struct(llvm_type_name(cx, a_struct, did, substs.tps)) common::T_named_struct(llvm_type_name(cx,
a_struct,
did,
/*bad*/ copy substs.tps))
} }
ty::ty_self => cx.tcx.sess.unimpl(~"type_of: ty_self"), ty::ty_self => cx.tcx.sess.unimpl(~"type_of: ty_self"),
ty::ty_infer(*) => cx.tcx.sess.bug(~"type_of with ty_infer"), ty::ty_infer(*) => cx.tcx.sess.bug(~"type_of with ty_infer"),

View File

@ -27,6 +27,7 @@
// much information, but have the disadvantage of being very // much information, but have the disadvantage of being very
// invasive.) // invasive.)
use metadata::csearch; use metadata::csearch;
use middle::freevars; use middle::freevars;
use middle::trans::common::*; use middle::trans::common::*;
@ -84,11 +85,11 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
if fn_id_loc.crate != local_crate { if fn_id_loc.crate != local_crate {
let uses = vec::from_mut(copy cx.uses); let uses = vec::from_mut(copy cx.uses);
ccx.type_use_cache.insert(fn_id, uses); ccx.type_use_cache.insert(fn_id, copy uses);
return uses; return uses;
} }
let map_node = match ccx.tcx.items.find(fn_id_loc.node) { let map_node = match ccx.tcx.items.find(fn_id_loc.node) {
Some(ref x) => (*x), Some(ref x) => (/*bad*/copy *x),
None => ccx.sess.bug(fmt!("type_uses_for: unbound item ID %?", None => ccx.sess.bug(fmt!("type_uses_for: unbound item ID %?",
fn_id_loc)) fn_id_loc))
}; };
@ -165,7 +166,8 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
} }
} }
let uses = vec::from_mut(copy cx.uses); let uses = vec::from_mut(copy cx.uses);
ccx.type_use_cache.insert(fn_id, uses); // XXX: Bad copy, use @vec instead?
ccx.type_use_cache.insert(fn_id, copy uses);
uses uses
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use back; use back;
use lib::llvm::ValueRef; use lib::llvm::ValueRef;
use middle::trans::base::*; use middle::trans::base::*;

View File

@ -1172,9 +1172,9 @@ fn mk_mut_unboxed_vec(cx: ctxt, ty: t) -> t {
mk_t(cx, ty_unboxed_vec({ty: ty, mutbl: ast::m_imm})) mk_t(cx, ty_unboxed_vec({ty: ty, mutbl: ast::m_imm}))
} }
fn mk_rec(cx: ctxt, fs: ~[field]) -> t { mk_t(cx, ty_rec(fs)) } fn mk_rec(cx: ctxt, +fs: ~[field]) -> t { mk_t(cx, ty_rec(fs)) }
fn mk_tup(cx: ctxt, ts: ~[t]) -> t { mk_t(cx, ty_tup(ts)) } fn mk_tup(cx: ctxt, +ts: ~[t]) -> t { mk_t(cx, ty_tup(ts)) }
// take a copy because we want to own the various vectors inside // take a copy because we want to own the various vectors inside
fn mk_fn(cx: ctxt, +fty: FnTy) -> t { mk_t(cx, ty_fn(fty)) } fn mk_fn(cx: ctxt, +fty: FnTy) -> t { mk_t(cx, ty_fn(fty)) }
@ -1213,7 +1213,7 @@ fn mk_opaque_closure_ptr(cx: ctxt, proto: ast::Proto) -> t {
fn mk_opaque_box(cx: ctxt) -> t { mk_t(cx, ty_opaque_box) } fn mk_opaque_box(cx: ctxt) -> t { mk_t(cx, ty_opaque_box) }
fn mk_with_id(cx: ctxt, base: t, def_id: ast::def_id) -> t { fn mk_with_id(cx: ctxt, base: t, def_id: ast::def_id) -> t {
mk_t_with_id(cx, get(base).sty, Some(def_id)) mk_t_with_id(cx, /*bad*/copy get(base).sty, Some(def_id))
} }
// Converts s to its machine type equivalent // Converts s to its machine type equivalent
@ -1222,7 +1222,7 @@ pure fn mach_sty(cfg: @session::config, t: t) -> sty {
ty_int(ast::ty_i) => ty_int(cfg.int_type), ty_int(ast::ty_i) => ty_int(cfg.int_type),
ty_uint(ast::ty_u) => ty_uint(cfg.uint_type), ty_uint(ast::ty_u) => ty_uint(cfg.uint_type),
ty_float(ast::ty_f) => ty_float(cfg.float_type), ty_float(ast::ty_f) => ty_float(cfg.float_type),
ref s => (*s) ref s => (/*bad*/copy *s)
} }
} }
@ -1286,7 +1286,7 @@ fn walk_ty(ty: t, f: fn(t)) {
fn maybe_walk_ty(ty: t, f: fn(t) -> bool) { fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
if !f(ty) { return; } if !f(ty) { return; }
match get(ty).sty { match /*bad*/copy get(ty).sty {
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_estr(_) | ty_type | ty_opaque_box | ty_self | ty_estr(_) | ty_type | ty_opaque_box | ty_self |
ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => { ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => {
@ -1322,7 +1322,7 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty {
tps: substs.tps.map(|t| fldop(*t))} tps: substs.tps.map(|t| fldop(*t))}
} }
match *sty { match /*bad*/copy *sty {
ty_box(tm) => { ty_box(tm) => {
ty_box({ty: fldop(tm.ty), mutbl: tm.mutbl}) ty_box({ty: fldop(tm.ty), mutbl: tm.mutbl})
} }
@ -1376,7 +1376,7 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty {
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) | ty_err | ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) | ty_err |
ty_opaque_box | ty_infer(_) | ty_param(*) | ty_self => { ty_opaque_box | ty_infer(_) | ty_param(*) | ty_self => {
*sty /*bad*/copy *sty
} }
} }
} }
@ -1476,7 +1476,7 @@ fn apply_op_on_t_to_ty_fn(
f: &FnTy, f: &FnTy,
t_op: fn(t) -> t) -> FnTy t_op: fn(t) -> t) -> FnTy
{ {
let t0 = ty::mk_fn(cx, *f); let t0 = ty::mk_fn(cx, /*bad*/copy *f);
let t1 = t_op(t0); let t1 = t_op(t0);
match ty::get(t1).sty { match ty::get(t1).sty {
ty::ty_fn(copy f) => { ty::ty_fn(copy f) => {
@ -1701,7 +1701,7 @@ fn sequence_element_type(cx: ctxt, ty: t) -> t {
} }
fn get_element_type(ty: t, i: uint) -> t { fn get_element_type(ty: t, i: uint) -> t {
match get(ty).sty { match /*bad*/copy get(ty).sty {
ty_rec(flds) => return flds[i].mt.ty, ty_rec(flds) => return flds[i].mt.ty,
ty_tup(ts) => return ts[i], ty_tup(ts) => return ts[i],
_ => fail ~"get_element_type called on invalid type" _ => fail ~"get_element_type called on invalid type"
@ -1794,7 +1794,7 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
} }
let mut accum = false; let mut accum = false;
let result = match get(ty).sty { let result = match /*bad*/copy get(ty).sty {
// scalar types // scalar types
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) | ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
ty_type | ty_ptr(_) | ty_rptr(_, _) | ty_type | ty_ptr(_) | ty_rptr(_, _) |
@ -2154,7 +2154,7 @@ fn type_kind_ext(cx: ctxt, ty: t, allow_ty_var: bool) -> Kind {
// Insert a default in case we loop back on self recursively. // Insert a default in case we loop back on self recursively.
cx.kind_cache.insert(ty, kind_top()); cx.kind_cache.insert(ty, kind_top());
let mut result = match get(ty).sty { let mut result = match /*bad*/copy get(ty).sty {
// Scalar and unique types are sendable, constant, and owned // Scalar and unique types are sendable, constant, and owned
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_ptr(_) => { ty_ptr(_) => {
@ -2326,7 +2326,7 @@ fn type_implicitly_moves(cx: ctxt, ty: t) -> bool {
/// gives a rough estimate of how much space it takes to represent /// gives a rough estimate of how much space it takes to represent
/// an instance of `ty`. Used for the mode transition. /// an instance of `ty`. Used for the mode transition.
fn type_size(cx: ctxt, ty: t) -> uint { fn type_size(cx: ctxt, ty: t) -> uint {
match get(ty).sty { match /*bad*/copy get(ty).sty {
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_ptr(_) | ty_box(_) | ty_uniq(_) | ty_estr(vstore_uniq) | ty_ptr(_) | ty_box(_) | ty_uniq(_) | ty_estr(vstore_uniq) |
ty_trait(*) | ty_rptr(*) | ty_evec(_, vstore_uniq) | ty_trait(*) | ty_rptr(*) | ty_evec(_, vstore_uniq) |
@ -2411,7 +2411,7 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
::util::ppaux::ty_to_str(cx, r_ty), ::util::ppaux::ty_to_str(cx, r_ty),
::util::ppaux::ty_to_str(cx, ty)); ::util::ppaux::ty_to_str(cx, ty));
let r = match get(ty).sty { let r = match /*bad*/copy get(ty).sty {
ty_nil | ty_nil |
ty_bot | ty_bot |
ty_bool | ty_bool |
@ -2503,7 +2503,7 @@ fn type_structurally_contains(cx: ctxt, ty: t, test: fn(x: &sty) -> bool) ->
debug!("type_structurally_contains: %s", debug!("type_structurally_contains: %s",
::util::ppaux::ty_to_str(cx, ty)); ::util::ppaux::ty_to_str(cx, ty));
if test(sty) { return true; } if test(sty) { return true; }
match *sty { match /*bad*/copy *sty {
ty_enum(did, ref substs) => { ty_enum(did, ref substs) => {
for vec::each(*enum_variants(cx, did)) |variant| { for vec::each(*enum_variants(cx, did)) |variant| {
for variant.args.each |aty| { for variant.args.each |aty| {
@ -2589,7 +2589,7 @@ fn type_is_signed(ty: t) -> bool {
// that the cycle collector might care about. // that the cycle collector might care about.
fn type_is_pod(cx: ctxt, ty: t) -> bool { fn type_is_pod(cx: ctxt, ty: t) -> bool {
let mut result = true; let mut result = true;
match get(ty).sty { match /*bad*/copy get(ty).sty {
// Scalar types // Scalar types
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) | ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
ty_type | ty_ptr(_) => result = true, ty_type | ty_ptr(_) => result = true,
@ -2602,7 +2602,7 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
ty_enum(did, ref substs) => { ty_enum(did, ref substs) => {
let variants = enum_variants(cx, did); let variants = enum_variants(cx, did);
for vec::each(*variants) |variant| { for vec::each(*variants) |variant| {
let tup_ty = mk_tup(cx, variant.args); let tup_ty = mk_tup(cx, /*bad*/copy variant.args);
// Perform any type parameter substitutions. // Perform any type parameter substitutions.
let tup_ty = subst(cx, substs, tup_ty); let tup_ty = subst(cx, substs, tup_ty);
@ -2943,7 +2943,7 @@ fn node_id_has_type_params(cx: ctxt, id: ast::node_id) -> bool {
// Type accessors for substructures of types // Type accessors for substructures of types
fn ty_fn_args(fty: t) -> ~[arg] { fn ty_fn_args(fty: t) -> ~[arg] {
match get(fty).sty { match get(fty).sty {
ty_fn(ref f) => f.sig.inputs, ty_fn(ref f) => /*bad*/copy f.sig.inputs,
_ => fail ~"ty_fn_args() called on non-fn type" _ => fail ~"ty_fn_args() called on non-fn type"
} }
} }
@ -3054,8 +3054,8 @@ fn method_call_bounds(tcx: ctxt, method_map: typeck::method_map,
// trait itself. This ought to be harmonized. // trait itself. This ought to be harmonized.
let trt_bounds = let trt_bounds =
ty::lookup_item_type(tcx, trt_id).bounds; ty::lookup_item_type(tcx, trt_id).bounds;
let mth = ty::trait_methods(tcx, trt_id)[n_mth]; let mth = /*bad*/copy ty::trait_methods(tcx, trt_id)[n_mth];
@(vec::append(*trt_bounds, *mth.tps)) @(vec::append(/*bad*/copy *trt_bounds, *mth.tps))
} }
} }
} }
@ -3252,7 +3252,7 @@ fn get_field(tcx: ctxt, rec_ty: t, id: ast::ident) -> field {
} }
fn get_fields(rec_ty:t) -> ~[field] { fn get_fields(rec_ty:t) -> ~[field] {
match get(rec_ty).sty { match /*bad*/copy get(rec_ty).sty {
ty_rec(fields) => fields, ty_rec(fields) => fields,
// Can we check at the caller? // Can we check at the caller?
_ => fail ~"get_fields: not a record type" _ => fail ~"get_fields: not a record type"
@ -3597,7 +3597,7 @@ fn provided_trait_methods(cx: ctxt, id: ast::def_id) -> ~[ast::ident] {
node: item_trait(_, _, ref ms), node: item_trait(_, _, ref ms),
_ _
}, _)) => }, _)) =>
match ast_util::split_trait_methods((*ms)) { match ast_util::split_trait_methods((/*bad*/copy *ms)) {
(_, p) => p.map(|method| method.ident) (_, p) => p.map(|method| method.ident)
}, },
_ => cx.sess.bug(fmt!("provided_trait_methods: %? is not a trait", _ => cx.sess.bug(fmt!("provided_trait_methods: %? is not a trait",
@ -3627,7 +3627,7 @@ fn trait_supertraits(cx: ctxt, id: ast::def_id) -> @~[InstantiatedTraitRef] {
ty_trait(def_id, ref substs, _) => { ty_trait(def_id, ref substs, _) => {
result.push(InstantiatedTraitRef { result.push(InstantiatedTraitRef {
def_id: def_id, def_id: def_id,
tpt: { substs: (*substs), ty: *trait_type } tpt: { substs: (/*bad*/copy *substs), ty: *trait_type }
}); });
} }
_ => cx.sess.bug(~"trait_supertraits: trait ref wasn't a trait") _ => cx.sess.bug(~"trait_supertraits: trait ref wasn't a trait")
@ -3665,7 +3665,7 @@ fn impl_traits(cx: ctxt, id: ast::def_id, vstore: vstore) -> ~[t] {
match ty::get(ty).sty { match ty::get(ty).sty {
ty::ty_trait(_, _, trait_vstore) if vstore == trait_vstore => ty, ty::ty_trait(_, _, trait_vstore) if vstore == trait_vstore => ty,
ty::ty_trait(did, ref substs, _) => { ty::ty_trait(did, ref substs, _) => {
mk_trait(cx, did, (*substs), vstore) mk_trait(cx, did, (/*bad*/copy *substs), vstore)
} }
_ => cx.sess.bug(~"impl_traits: not a trait") _ => cx.sess.bug(~"impl_traits: not a trait")
} }
@ -3745,7 +3745,7 @@ fn substd_enum_variants(cx: ctxt,
let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty); let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty);
@VariantInfo_{args: substd_args, ctor_ty: substd_ctor_ty, @VariantInfo_{args: substd_args, ctor_ty: substd_ctor_ty,
..**variant_info} ../*bad*/copy **variant_info}
} }
} }
@ -3817,19 +3817,22 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
ast_map::path_name(item.ident) ast_map::path_name(item.ident)
} }
}; };
vec::append_one(*path, item_elt) vec::append_one(/*bad*/copy *path, item_elt)
} }
ast_map::node_foreign_item(nitem, _, path) => { ast_map::node_foreign_item(nitem, _, path) => {
vec::append_one(*path, ast_map::path_name(nitem.ident)) vec::append_one(/*bad*/copy *path,
ast_map::path_name(nitem.ident))
} }
ast_map::node_method(method, _, path) => { ast_map::node_method(method, _, path) => {
vec::append_one(*path, ast_map::path_name(method.ident)) vec::append_one(/*bad*/copy *path,
ast_map::path_name(method.ident))
} }
ast_map::node_trait_method(trait_method, _, path) => { ast_map::node_trait_method(trait_method, _, path) => {
let method = ast_util::trait_method_to_ty_method(*trait_method); let method = ast_util::trait_method_to_ty_method(*trait_method);
vec::append_one(*path, ast_map::path_name(method.ident)) vec::append_one(/*bad*/copy *path,
ast_map::path_name(method.ident))
} }
ast_map::node_variant(ref variant, _, path) => { ast_map::node_variant(ref variant, _, path) => {
@ -3838,12 +3841,12 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
} }
ast_map::node_dtor(_, _, _, path) => { ast_map::node_dtor(_, _, _, path) => {
vec::append_one(*path, ast_map::path_name( vec::append_one(/*bad*/copy *path, ast_map::path_name(
syntax::parse::token::special_idents::literally_dtor)) syntax::parse::token::special_idents::literally_dtor))
} }
ast_map::node_struct_ctor(_, item, path) => { ast_map::node_struct_ctor(_, item, path) => {
vec::append_one(*path, ast_map::path_name(item.ident)) vec::append_one(/*bad*/copy *path, ast_map::path_name(item.ident))
} }
ast_map::node_stmt(*) | ast_map::node_expr(*) | ast_map::node_stmt(*) | ast_map::node_expr(*) |
@ -3885,7 +3888,7 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] {
node: ast::item_enum(ref enum_definition, _), node: ast::item_enum(ref enum_definition, _),
_ _
}, _) => { }, _) => {
let variants = (*enum_definition).variants; let variants = /*bad*/copy (*enum_definition).variants;
let mut disr_val = -1; let mut disr_val = -1;
@vec::map(variants, |variant| { @vec::map(variants, |variant| {
match variant.node.kind { match variant.node.kind {
@ -3994,7 +3997,7 @@ fn lookup_struct_fields(cx: ctxt, did: ast::def_id) -> ~[field_ty] {
Some(ast_map::node_item(i,_)) => { Some(ast_map::node_item(i,_)) => {
match i.node { match i.node {
ast::item_struct(struct_def, _) => { ast::item_struct(struct_def, _) => {
struct_field_tys(struct_def.fields) struct_field_tys(/*bad*/copy struct_def.fields)
} }
_ => cx.sess.bug(~"struct ID bound to non-struct") _ => cx.sess.bug(~"struct ID bound to non-struct")
} }
@ -4002,7 +4005,7 @@ fn lookup_struct_fields(cx: ctxt, did: ast::def_id) -> ~[field_ty] {
Some(ast_map::node_variant(ref variant, _, _)) => { Some(ast_map::node_variant(ref variant, _, _)) => {
match (*variant).node.kind { match (*variant).node.kind {
ast::struct_variant_kind(struct_def) => { ast::struct_variant_kind(struct_def) => {
struct_field_tys(struct_def.fields) struct_field_tys(/*bad*/copy struct_def.fields)
} }
_ => { _ => {
cx.sess.bug(~"struct ID bound to enum variant that isn't \ cx.sess.bug(~"struct ID bound to enum variant that isn't \
@ -4211,7 +4214,7 @@ fn normalize_ty(cx: ctxt, t: t) -> t {
region: ty::re_static, region: ty::re_static,
..fn_ty.meta ..fn_ty.meta
}, },
sig: fn_ty.sig sig: /*bad*/copy fn_ty.sig
}) })
} }
@ -4222,7 +4225,7 @@ fn normalize_ty(cx: ctxt, t: t) -> t {
mk_enum(cx, did, mk_enum(cx, did,
{self_r: Some(ty::re_static), {self_r: Some(ty::re_static),
self_ty: None, self_ty: None,
tps: (*r).tps}), tps: /*bad*/copy (*r).tps}),
None => None =>
t t
}, },
@ -4233,7 +4236,7 @@ fn normalize_ty(cx: ctxt, t: t) -> t {
// Ditto. // Ditto.
mk_struct(cx, did, {self_r: Some(ty::re_static), mk_struct(cx, did, {self_r: Some(ty::re_static),
self_ty: None, self_ty: None,
tps: (*r).tps}), tps: /*bad*/copy (*r).tps}),
None => None =>
t t
}, },
@ -4537,7 +4540,7 @@ impl InferTy : cmp::Eq {
impl sty : cmp::Eq { impl sty : cmp::Eq {
pure fn eq(&self, other: &sty) -> bool { pure fn eq(&self, other: &sty) -> bool {
match (*self) { match (/*bad*/copy *self) {
ty_nil => { ty_nil => {
match (*other) { match (*other) {
ty_nil => true, ty_nil => true,
@ -4617,7 +4620,7 @@ impl sty : cmp::Eq {
} }
} }
ty_rec(e0a) => { ty_rec(e0a) => {
match (*other) { match (/*bad*/copy *other) {
ty_rec(e0b) => e0a == e0b, ty_rec(e0b) => e0a == e0b,
_ => false _ => false
} }
@ -4642,7 +4645,7 @@ impl sty : cmp::Eq {
} }
} }
ty_tup(e0a) => { ty_tup(e0a) => {
match (*other) { match (/*bad*/copy *other) {
ty_tup(e0b) => e0a == e0b, ty_tup(e0b) => e0a == e0b,
_ => false _ => false
} }

View File

@ -52,6 +52,7 @@
* an rptr (`&r.T`) use the region `r` that appears in the rptr. * an rptr (`&r.T`) use the region `r` that appears in the rptr.
*/ */
use middle::ty::{FnTyBase, FnMeta, FnSig}; use middle::ty::{FnTyBase, FnMeta, FnSig};
use middle::ty; use middle::ty;
use middle::typeck::check::fn_ctxt; use middle::typeck::check::fn_ctxt;
@ -80,7 +81,7 @@ fn get_region_reporting_err(tcx: ty::ctxt,
match res { match res {
result::Ok(r) => r, result::Ok(r) => r,
result::Err(ref e) => { result::Err(ref e) => {
tcx.sess.span_err(span, (*e)); tcx.sess.span_err(span, (/*bad*/copy *e));
ty::re_static ty::re_static
} }
} }
@ -145,7 +146,8 @@ fn ast_path_to_substs_and_ty<AC: ast_conv, RS: region_scope Copy Durable>(
let tps = path.types.map(|a_t| ast_ty_to_ty(self, rscope, *a_t)); let tps = path.types.map(|a_t| ast_ty_to_ty(self, rscope, *a_t));
let substs = {self_r:self_r, self_ty:None, tps:tps}; let substs = {self_r:self_r, self_ty:None, tps:tps};
{substs: substs, ty: ty::subst(tcx, &substs, decl_ty)} let ty = ty::subst(tcx, &substs, decl_ty);
{substs: substs, ty: ty}
} }
pub fn ast_path_to_ty<AC: ast_conv, RS: region_scope Copy Durable>( pub fn ast_path_to_ty<AC: ast_conv, RS: region_scope Copy Durable>(
@ -161,7 +163,7 @@ pub fn ast_path_to_ty<AC: ast_conv, RS: region_scope Copy Durable>(
let {substs: substs, ty: ty} = let {substs: substs, ty: ty} =
ast_path_to_substs_and_ty(self, rscope, did, path); ast_path_to_substs_and_ty(self, rscope, did, path);
write_ty_to_tcx(tcx, path_id, ty); write_ty_to_tcx(tcx, path_id, ty);
write_substs_to_tcx(tcx, path_id, substs.tps); write_substs_to_tcx(tcx, path_id, /*bad*/copy substs.tps);
return {substs: substs, ty: ty}; return {substs: substs, ty: ty};
} }
@ -225,7 +227,7 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope Copy Durable>(
} }
} }
return ty::mk_trait(tcx, trait_def_id, return ty::mk_trait(tcx, trait_def_id,
(*substs), vst); /*bad*/copy *substs, vst);
} }
_ => {} _ => {}
@ -274,7 +276,7 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope Copy Durable>(
} }
tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_unresolved); tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_unresolved);
let typ = match ast_ty.node { let typ = match /*bad*/copy ast_ty.node {
ast::ty_nil => ty::mk_nil(tcx), ast::ty_nil => ty::mk_nil(tcx),
ast::ty_bot => ty::mk_bot(tcx), ast::ty_bot => ty::mk_bot(tcx),
ast::ty_box(mt) => { ast::ty_box(mt) => {

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::pat_util::{pat_is_binding, pat_is_const}; use middle::pat_util::{pat_is_binding, pat_is_const};
use middle::pat_util::{pat_is_variant_or_struct}; use middle::pat_util::{pat_is_variant_or_struct};
use middle::ty; use middle::ty;
@ -69,7 +70,7 @@ struct pat_ctxt {
} }
fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path, fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
subpats: Option<~[@ast::pat]>, expected: ty::t) { +subpats: Option<~[@ast::pat]>, expected: ty::t) {
// Typecheck the path. // Typecheck the path.
let fcx = pcx.fcx; let fcx = pcx.fcx;
@ -150,7 +151,7 @@ fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
let subpats_len; let subpats_len;
match subpats { match subpats {
None => subpats_len = arg_len, None => subpats_len = arg_len,
Some(subpats) => subpats_len = subpats.len() Some(ref subpats) => subpats_len = subpats.len()
} }
if arg_len > 0u { if arg_len > 0u {
@ -244,7 +245,7 @@ fn check_struct_pat_fields(pcx: pat_ctxt,
fn check_struct_pat(pcx: pat_ctxt, pat_id: ast::node_id, span: span, fn check_struct_pat(pcx: pat_ctxt, pat_id: ast::node_id, span: span,
expected: ty::t, path: @ast::path, expected: ty::t, path: @ast::path,
fields: ~[ast::field_pat], etc: bool, +fields: ~[ast::field_pat], etc: bool,
class_id: ast::def_id, substitutions: &ty::substs) { class_id: ast::def_id, substitutions: &ty::substs) {
let fcx = pcx.fcx; let fcx = pcx.fcx;
let tcx = pcx.fcx.ccx.tcx; let tcx = pcx.fcx.ccx.tcx;
@ -285,7 +286,7 @@ fn check_struct_like_enum_variant_pat(pcx: pat_ctxt,
span: span, span: span,
expected: ty::t, expected: ty::t,
path: @ast::path, path: @ast::path,
fields: ~[ast::field_pat], +fields: ~[ast::field_pat],
etc: bool, etc: bool,
enum_id: ast::def_id, enum_id: ast::def_id,
substitutions: &ty::substs) { substitutions: &ty::substs) {
@ -322,7 +323,7 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
let fcx = pcx.fcx; let fcx = pcx.fcx;
let tcx = pcx.fcx.ccx.tcx; let tcx = pcx.fcx.ccx.tcx;
match pat.node { match /*bad*/copy pat.node {
ast::pat_wild => { ast::pat_wild => {
fcx.write_ty(pat.id, expected); fcx.write_ty(pat.id, expected);
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use middle::typeck::check::fn_ctxt; use middle::typeck::check::fn_ctxt;
use middle::typeck::infer; use middle::typeck::infer;

View File

@ -79,6 +79,7 @@ obtained the type `Foo`, we would never match this method.
*/ */
use middle::resolve::{Impl, MethodInfo}; use middle::resolve::{Impl, MethodInfo};
use middle::resolve; use middle::resolve;
use middle::ty::*; use middle::ty::*;
@ -358,7 +359,7 @@ impl LookupContext {
let bound_substs = match ty::get(bound_trait_ty).sty { let bound_substs = match ty::get(bound_trait_ty).sty {
ty::ty_trait(_, ref substs, _) => (*substs), ty::ty_trait(_, ref substs, _) => (/*bad*/copy *substs),
_ => { _ => {
self.bug(fmt!("add_candidates_from_param: \ self.bug(fmt!("add_candidates_from_param: \
non-trait bound %s", non-trait bound %s",
@ -386,7 +387,7 @@ impl LookupContext {
let mut i = 0; let mut i = 0;
while i < worklist.len() { while i < worklist.len() {
let (init_trait_ty, init_substs) = worklist[i]; let (init_trait_ty, init_substs) = /*bad*/copy worklist[i];
i += 1; i += 1;
let init_trait_id = ty::ty_to_def_id(init_trait_ty).get(); let init_trait_id = ty::ty_to_def_id(init_trait_ty).get();
@ -491,7 +492,7 @@ impl LookupContext {
// `trait_ty` for `self` here, because it allows the compiler // `trait_ty` for `self` here, because it allows the compiler
// to soldier on. An error will be reported should this // to soldier on. An error will be reported should this
// candidate be selected if the method refers to `self`. // candidate be selected if the method refers to `self`.
let rcvr_substs = {self_ty: Some(self_ty), ..*substs}; let rcvr_substs = {self_ty: Some(self_ty), ../*bad*/copy *substs};
let (rcvr_ty, rcvr_substs) = let (rcvr_ty, rcvr_substs) =
self.create_rcvr_ty_and_substs_for_method(method.self_ty, self.create_rcvr_ty_and_substs_for_method(method.self_ty,
@ -522,7 +523,7 @@ impl LookupContext {
} }
let method = &methods[index]; let method = &methods[index];
let rcvr_substs = { self_ty: Some(self_ty), ..*substs }; let rcvr_substs = { self_ty: Some(self_ty), ../*bad*/copy *substs };
let (rcvr_ty, rcvr_substs) = let (rcvr_ty, rcvr_substs) =
self.create_rcvr_ty_and_substs_for_method( self.create_rcvr_ty_and_substs_for_method(
method.self_ty, method.self_ty,
@ -893,13 +894,13 @@ impl LookupContext {
let mut merged = ~[]; let mut merged = ~[];
let mut i = 0; let mut i = 0;
while i < candidates.len() { while i < candidates.len() {
let candidate_a = candidates[i]; let candidate_a = /*bad*/copy candidates[i];
let mut skip = false; let mut skip = false;
let mut j = i + 1; let mut j = i + 1;
while j < candidates.len() { while j < candidates.len() {
let candidate_b = candidates[j]; let candidate_b = /*bad*/copy candidates[j];
debug!("attempting to merge %? and %?", debug!("attempting to merge %? and %?",
candidate_a, candidate_b); candidate_a, candidate_b);
let candidates_same = match (&candidate_a.origin, let candidates_same = match (&candidate_a.origin,
@ -985,9 +986,11 @@ impl LookupContext {
// Construct the full set of type parameters for the method, // Construct the full set of type parameters for the method,
// which is equal to the class tps + the method tps. // which is equal to the class tps + the method tps.
let all_substs = {tps: vec::append(candidate.rcvr_substs.tps, let all_substs = {
m_substs), tps: vec::append(/*bad*/copy candidate.rcvr_substs.tps,
..candidate.rcvr_substs}; m_substs),
../*bad*/copy candidate.rcvr_substs
};
self.fcx.write_ty_substs(self.callee_id, fty, all_substs); self.fcx.write_ty_substs(self.callee_id, fty, all_substs);
return {self_arg: {mode: ast::expl(candidate.self_mode), return {self_arg: {mode: ast::expl(candidate.self_mode),
@ -1072,7 +1075,7 @@ impl LookupContext {
trait_did: def_id, trait_did: def_id,
method_num: uint) -> ty::t { method_num: uint) -> ty::t {
let trait_methods = ty::trait_methods(tcx, trait_did); let trait_methods = ty::trait_methods(tcx, trait_did);
ty::mk_fn(tcx, trait_methods[method_num].fty) ty::mk_fn(tcx, /*bad*/copy trait_methods[method_num].fty)
} }
} }
@ -1147,7 +1150,7 @@ impl LookupContext {
ty::item_path_str(self.tcx(), did) ty::item_path_str(self.tcx(), did)
} }
fn bug(&self, s: ~str) -> ! { fn bug(&self, +s: ~str) -> ! {
self.tcx().sess.bug(s) self.tcx().sess.bug(s)
} }
} }

View File

@ -76,6 +76,7 @@ type parameter).
*/ */
use middle::capture; use middle::capture;
use middle::const_eval; use middle::const_eval;
use middle::pat_util; use middle::pat_util;
@ -349,7 +350,8 @@ fn check_fn(ccx: @crate_ctxt,
} }
}; };
gather_locals(fcx, decl, body, arg_tys, self_info); // XXX: Bad copy.
gather_locals(fcx, decl, body, copy arg_tys, self_info);
check_block(fcx, body); check_block(fcx, body);
// We unify the tail expr's type with the // We unify the tail expr's type with the
@ -546,13 +548,16 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
ty::item_path_str(ccx.tcx, local_def(it.id))); ty::item_path_str(ccx.tcx, local_def(it.id)));
let _indenter = indenter(); let _indenter = indenter();
match it.node { match /*bad*/copy it.node {
ast::item_const(_, e) => check_const(ccx, it.span, e, it.id), ast::item_const(_, e) => check_const(ccx, it.span, e, it.id),
ast::item_enum(ref enum_definition, _) => { ast::item_enum(ref enum_definition, _) => {
check_enum_variants(ccx, it.span, (*enum_definition).variants, it.id); check_enum_variants(ccx,
it.span,
/*bad*/copy (*enum_definition).variants,
it.id);
} }
ast::item_fn(decl, _, _, ref body) => { ast::item_fn(ref decl, _, _, ref body) => {
check_bare_fn(ccx, decl, (*body), it.id, None); check_bare_fn(ccx, *decl, (*body), it.id, None);
} }
ast::item_impl(_, _, ty, ms) => { ast::item_impl(_, _, ty, ms) => {
let rp = ccx.tcx.region_paramd_items.find(it.id); let rp = ccx.tcx.region_paramd_items.find(it.id);
@ -743,7 +748,7 @@ impl @fn_ctxt {
} }
fn node_ty_substs(id: ast::node_id) -> ty::substs { fn node_ty_substs(id: ast::node_id) -> ty::substs {
match self.inh.node_type_substs.find(id) { match self.inh.node_type_substs.find(id) {
Some(ref ts) => (*ts), Some(ref ts) => (/*bad*/copy *ts),
None => { None => {
self.tcx().sess.bug( self.tcx().sess.bug(
fmt!("no type substs for node %d: %s in fcx %s", fmt!("no type substs for node %d: %s in fcx %s",
@ -973,13 +978,13 @@ pub fn impl_self_ty(vcx: &VtableContext,
let {n_tps, region_param, raw_ty} = if did.crate == ast::local_crate { let {n_tps, region_param, raw_ty} = if did.crate == ast::local_crate {
let region_param = tcx.region_paramd_items.find(did.node); let region_param = tcx.region_paramd_items.find(did.node);
match tcx.items.find(did.node) { match tcx.items.find(did.node) {
Some(ast_map::node_item(@{node: ast::item_impl(ts, _, st, _), Some(ast_map::node_item(@{node: ast::item_impl(ref ts, _, st, _),
_}, _)) => { _}, _)) => {
{n_tps: ts.len(), {n_tps: ts.len(),
region_param: region_param, region_param: region_param,
raw_ty: vcx.ccx.to_ty(rscope::type_rscope(region_param), st)} raw_ty: vcx.ccx.to_ty(rscope::type_rscope(region_param), st)}
} }
Some(ast_map::node_item(@{node: ast::item_struct(_, ts), Some(ast_map::node_item(@{node: ast::item_struct(_, ref ts),
id: class_id, _},_)) => { id: class_id, _},_)) => {
/* If the impl is a class, the self ty is just the class ty /* If the impl is a class, the self ty is just the class ty
(doing a no-op subst for the ty params; in the next step, (doing a no-op subst for the ty params; in the next step,
@ -990,7 +995,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
raw_ty: ty::mk_struct(tcx, local_def(class_id), raw_ty: ty::mk_struct(tcx, local_def(class_id),
{self_r: rscope::bound_self_region(region_param), {self_r: rscope::bound_self_region(region_param),
self_ty: None, self_ty: None,
tps: ty::ty_params_to_tys(tcx, ts)})} tps: ty::ty_params_to_tys(tcx, /*bad*/copy *ts)})}
} }
_ => { tcx.sess.bug(~"impl_self_ty: unbound item or item that \ _ => { tcx.sess.bug(~"impl_self_ty: unbound item or item that \
doesn't have a self_ty"); } doesn't have a self_ty"); }
@ -1036,6 +1041,10 @@ pub enum DerefArgs {
DoDerefArgs DoDerefArgs
} }
fn break_here() {
debug!("break here!");
}
fn check_expr_with_unifier(fcx: @fn_ctxt, fn check_expr_with_unifier(fcx: @fn_ctxt,
expr: @ast::expr, expr: @ast::expr,
expected: Option<ty::t>, expected: Option<ty::t>,
@ -1072,7 +1081,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let fty = let fty =
match structure_of(fcx, sp, in_fty) { match structure_of(fcx, sp, in_fty) {
ty::ty_fn(ref fn_ty) => { ty::ty_fn(ref fn_ty) => {
let fn_ty = replace_bound_regions_in_fn_ty(tcx, @Nil, let fn_ty =
/*bad*/copy replace_bound_regions_in_fn_ty(tcx, @Nil,
None, fn_ty, |_br| fcx.infcx().next_region_var(sp, None, fn_ty, |_br| fcx.infcx().next_region_var(sp,
call_expr_id)).fn_ty; call_expr_id)).fn_ty;
@ -1189,7 +1199,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
call_expr_id: ast::node_id, call_expr_id: ast::node_id,
fn_ty: ty::t, fn_ty: ty::t,
expr: @ast::expr, expr: @ast::expr,
args: ~[@ast::expr], +args: ~[@ast::expr],
bot: bool) bot: bool)
-> bool { -> bool {
let mut bot = bot; let mut bot = bot;
@ -1220,11 +1230,10 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
// A generic function for doing all of the checking for call expressions // A generic function for doing all of the checking for call expressions
fn check_call(fcx: @fn_ctxt, sp: span, call_expr_id: ast::node_id, fn check_call(fcx: @fn_ctxt, sp: span, call_expr_id: ast::node_id,
f: @ast::expr, args: ~[@ast::expr]) -> bool { f: @ast::expr, +args: ~[@ast::expr]) -> bool {
// Index expressions need to be handled separately, to inform them // Index expressions need to be handled separately, to inform them
// that they appear in call position. // that they appear in call position.
let mut bot = match f.node { let mut bot = match /*bad*/copy f.node {
ast::expr_field(base, field, tys) => { ast::expr_field(base, field, tys) => {
check_field(fcx, f, true, base, field, tys) check_field(fcx, f, true, base, field, tys)
} }
@ -1245,7 +1254,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
expr: @ast::expr, expr: @ast::expr,
rcvr: @ast::expr, rcvr: @ast::expr,
method_name: ast::ident, method_name: ast::ident,
args: ~[@ast::expr], +args: ~[@ast::expr],
tps: ~[@ast::Ty]) tps: ~[@ast::Ty])
-> bool { -> bool {
let bot = check_expr(fcx, rcvr, None); let bot = check_expr(fcx, rcvr, None);
@ -1331,7 +1340,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
fn lookup_op_method(fcx: @fn_ctxt, op_ex: @ast::expr, fn lookup_op_method(fcx: @fn_ctxt, op_ex: @ast::expr,
self_ex: @ast::expr, self_t: ty::t, self_ex: @ast::expr, self_t: ty::t,
opname: ast::ident, args: ~[@ast::expr], opname: ast::ident, +args: ~[@ast::expr],
+deref_args: DerefArgs) +deref_args: DerefArgs)
-> Option<(ty::t, bool)> -> Option<(ty::t, bool)>
{ {
@ -1509,7 +1518,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
replace_bound_regions_in_fn_ty( replace_bound_regions_in_fn_ty(
tcx, @Nil, None, fn_ty, tcx, @Nil, None, fn_ty,
|br| ty::re_bound(ty::br_cap_avoid(id, @br))); |br| ty::re_bound(ty::br_cap_avoid(id, @br)));
(Some({inputs: fn_ty.sig.inputs, (Some({inputs: /*bad*/copy fn_ty.sig.inputs,
output: fn_ty.sig.output}), output: fn_ty.sig.output}),
fn_ty.meta.purity, fn_ty.meta.purity,
fn_ty.meta.proto, fn_ty.meta.proto,
@ -1535,7 +1544,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
/*bounds:*/ @~[], /*opt_region:*/ None, /*bounds:*/ @~[], /*opt_region:*/ None,
decl, expected_tys, expr.span); decl, expected_tys, expr.span);
let fty = ty::mk_fn(tcx, fn_ty); // XXX: Bad copy.
let fty = ty::mk_fn(tcx, copy fn_ty);
debug!("check_expr_fn_with_unifier %s fty=%s", debug!("check_expr_fn_with_unifier %s fty=%s",
expr_to_str(expr, tcx.sess.intr()), expr_to_str(expr, tcx.sess.intr()),
@ -1724,7 +1734,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
tcx.region_paramd_items.find(class_id.node); tcx.region_paramd_items.find(class_id.node);
match tcx.items.find(class_id.node) { match tcx.items.find(class_id.node) {
Some(ast_map::node_item(@{ Some(ast_map::node_item(@{
node: ast::item_struct(_, type_parameters), node: ast::item_struct(_, ref type_parameters),
_ _
}, _)) => { }, _)) => {
@ -1736,7 +1746,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
raw_type = ty::mk_struct(tcx, class_id, { raw_type = ty::mk_struct(tcx, class_id, {
self_r: self_region, self_r: self_region,
self_ty: None, self_ty: None,
tps: ty::ty_params_to_tys(tcx, type_parameters) tps: ty::ty_params_to_tys(
tcx,
/*bad*/copy *type_parameters)
}); });
} }
_ => { _ => {
@ -1805,7 +1817,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
tcx.region_paramd_items.find(enum_id.node); tcx.region_paramd_items.find(enum_id.node);
match tcx.items.find(enum_id.node) { match tcx.items.find(enum_id.node) {
Some(ast_map::node_item(@{ Some(ast_map::node_item(@{
node: ast::item_enum(_, type_parameters), node: ast::item_enum(_, ref type_parameters),
_ _
}, _)) => { }, _)) => {
@ -1817,7 +1829,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
raw_type = ty::mk_enum(tcx, enum_id, { raw_type = ty::mk_enum(tcx, enum_id, {
self_r: self_region, self_r: self_region,
self_ty: None, self_ty: None,
tps: ty::ty_params_to_tys(tcx, type_parameters) tps: ty::ty_params_to_tys(
tcx,
/*bad*/copy *type_parameters)
}); });
} }
_ => { _ => {
@ -1864,9 +1878,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let tcx = fcx.ccx.tcx; let tcx = fcx.ccx.tcx;
let id = expr.id; let id = expr.id;
let mut bot = false; let mut bot = false;
match expr.node { match /*bad*/copy expr.node {
ast::expr_vstore(ev, vst) => { ast::expr_vstore(ev, vst) => {
let typ = match ev.node { let typ = match /*bad*/copy ev.node {
ast::expr_lit(@{node: ast::lit_str(s), span:_}) => { ast::expr_lit(@{node: ast::lit_str(s), span:_}) => {
let tt = ast_expr_vstore_to_vstore(fcx, ev, str::len(*s), vst); let tt = ast_expr_vstore_to_vstore(fcx, ev, str::len(*s), vst);
ty::mk_estr(tcx, tt) ty::mk_estr(tcx, tt)
@ -2108,16 +2122,16 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
bot = !may_break(tcx, expr.id, (*body)); bot = !may_break(tcx, expr.id, (*body));
} }
ast::expr_match(discrim, ref arms) => { ast::expr_match(discrim, ref arms) => {
bot = alt::check_alt(fcx, expr, discrim, (*arms)); bot = alt::check_alt(fcx, expr, discrim, (/*bad*/copy *arms));
} }
ast::expr_fn(proto, decl, ref body, cap_clause) => { ast::expr_fn(proto, ref decl, ref body, cap_clause) => {
check_expr_fn(fcx, expr, Some(proto), check_expr_fn(fcx, expr, Some(proto),
decl, (*body), Vanilla, expected); *decl, (*body), Vanilla, expected);
capture::check_capture_clause(tcx, expr.id, cap_clause); capture::check_capture_clause(tcx, expr.id, cap_clause);
} }
ast::expr_fn_block(decl, ref body, cap_clause) => { ast::expr_fn_block(ref decl, ref body, cap_clause) => {
check_expr_fn(fcx, expr, None, check_expr_fn(fcx, expr, None,
decl, (*body), Vanilla, expected); *decl, (*body), Vanilla, expected);
capture::check_capture_clause(tcx, expr.id, cap_clause); capture::check_capture_clause(tcx, expr.id, cap_clause);
} }
ast::expr_loop_body(b) => { ast::expr_loop_body(b) => {
@ -2148,7 +2162,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
ty::mk_fn(tcx, FnTyBase { ty::mk_fn(tcx, FnTyBase {
meta: (*fty).meta, meta: (*fty).meta,
sig: FnSig {output: ty::mk_nil(tcx), sig: FnSig {output: ty::mk_nil(tcx),
..(*fty).sig} ../*bad*/copy (*fty).sig}
}) })
} }
_ => _ =>
@ -2171,9 +2185,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
} }
}; };
match b.node { match b.node {
ast::expr_fn_block(decl, ref body, cap_clause) => { ast::expr_fn_block(ref decl, ref body, cap_clause) => {
check_expr_fn(fcx, b, None, check_expr_fn(fcx, b, None,
decl, (*body), ForLoop, Some(inner_ty)); *decl, (*body), ForLoop, Some(inner_ty));
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b)); demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
capture::check_capture_clause(tcx, b.id, cap_clause); capture::check_capture_clause(tcx, b.id, cap_clause);
} }
@ -2188,7 +2202,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
fcx.write_ty(expr.id, ty::mk_fn(tcx, FnTyBase { fcx.write_ty(expr.id, ty::mk_fn(tcx, FnTyBase {
meta: (*fty).meta, meta: (*fty).meta,
sig: FnSig {output: ty::mk_bool(tcx), sig: FnSig {output: ty::mk_bool(tcx),
..(*fty).sig} ../*bad*/copy (*fty).sig}
})); }));
} }
else { else {
@ -2202,7 +2216,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let expected_sty = unpack_expected(fcx, expected, |x| Some(x)); let expected_sty = unpack_expected(fcx, expected, |x| Some(x));
let inner_ty = match expected_sty { let inner_ty = match expected_sty {
Some(ty::ty_fn(ref fty)) => { Some(ty::ty_fn(ref fty)) => {
ty::mk_fn(tcx, (*fty)) ty::mk_fn(tcx, (/*bad*/copy *fty))
} }
_ => match expected { _ => match expected {
Some(expected_t) => { Some(expected_t) => {
@ -2220,9 +2234,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
} }
}; };
match b.node { match b.node {
ast::expr_fn_block(decl, ref body, cap_clause) => { ast::expr_fn_block(ref decl, ref body, cap_clause) => {
check_expr_fn(fcx, b, None, check_expr_fn(fcx, b, None,
decl, (*body), DoBlock, Some(inner_ty)); *decl, (*body), DoBlock, Some(inner_ty));
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b)); demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
capture::check_capture_clause(tcx, b.id, cap_clause); capture::check_capture_clause(tcx, b.id, cap_clause);
} }
@ -2233,7 +2247,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
fcx, expr.span, fcx.node_ty(b.id)); fcx, expr.span, fcx.node_ty(b.id));
match ty::get(block_ty).sty { match ty::get(block_ty).sty {
ty::ty_fn(ref fty) => { ty::ty_fn(ref fty) => {
fcx.write_ty(expr.id, ty::mk_fn(tcx, (*fty))); fcx.write_ty(expr.id, ty::mk_fn(tcx, (/*bad*/copy *fty)));
} }
_ => fail ~"expected fn ty" _ => fail ~"expected fn ty"
} }
@ -2315,7 +2329,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
} }
ast::expr_tup(elts) => { ast::expr_tup(elts) => {
let flds = unpack_expected(fcx, expected, |sty| { let flds = unpack_expected(fcx, expected, |sty| {
match sty { ty::ty_tup(flds) => Some(flds), _ => None } // XXX: Beware! If you remove `copy` below, the borrow checker
// will NOT complain, but you will get a segfault at runtime! This
// is because the mode computation is currently unaware of
// argument modes.
match copy sty { ty::ty_tup(flds) => Some(flds), _ => None }
}); });
let elt_ts = do elts.mapi |i, e| { let elt_ts = do elts.mapi |i, e| {
check_expr(fcx, *e, flds.map(|fs| fs[i])); check_expr(fcx, *e, flds.map(|fs| fs[i]));
@ -2330,7 +2348,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
Some(fcx.expr_ty(base.get())) Some(fcx.expr_ty(base.get()))
} else { expected }; } else { expected };
let flds = unpack_expected(fcx, expected, |sty| let flds = unpack_expected(fcx, expected, |sty|
match sty { ty::ty_rec(flds) => Some(flds), _ => None } // XXX: Beware! If you remove `copy` below, the borrow checker
// will NOT complain, but you will get a segfault at runtime! This
// is because the mode computation is currently unaware of
// argument modes.
match copy sty {
ty::ty_rec(flds) => Some(flds),
_ => None
}
); );
let fields_t = vec::map((*fields), |f| { let fields_t = vec::map((*fields), |f| {
bot |= check_expr(fcx, f.node.expr, flds.chain_ref(|flds| bot |= check_expr(fcx, f.node.expr, flds.chain_ref(|flds|
@ -2392,11 +2417,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
match tcx.def_map.find(id) { match tcx.def_map.find(id) {
Some(ast::def_struct(type_def_id)) => { Some(ast::def_struct(type_def_id)) => {
check_struct_constructor(fcx, id, expr.span, type_def_id, check_struct_constructor(fcx, id, expr.span, type_def_id,
(*fields), base_expr); (/*bad*/copy *fields), base_expr);
} }
Some(ast::def_variant(enum_id, variant_id)) => { Some(ast::def_variant(enum_id, variant_id)) => {
check_struct_enum_variant(fcx, id, expr.span, enum_id, check_struct_enum_variant(fcx, id, expr.span, enum_id,
variant_id, (*fields)); variant_id, (/*bad*/copy *fields));
} }
_ => { _ => {
tcx.sess.span_bug(path.span, ~"structure constructor does \ tcx.sess.span_bug(path.span, ~"structure constructor does \
@ -2441,8 +2466,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
} }
if bot { fcx.write_bot(expr.id); } if bot { fcx.write_bot(expr.id); }
debug!("type of expr %s is %s, expected is %s", debug!("type of expr %s is...",
syntax::print::pprust::expr_to_str(expr, tcx.sess.intr()), syntax::print::pprust::expr_to_str(expr, tcx.sess.intr()));
debug!("... %s, expected is %s",
ppaux::ty_to_str(tcx, fcx.expr_ty(expr)), ppaux::ty_to_str(tcx, fcx.expr_ty(expr)),
match expected { match expected {
Some(t) => ppaux::ty_to_str(tcx, t), Some(t) => ppaux::ty_to_str(tcx, t),
@ -2502,7 +2528,7 @@ fn check_stmt(fcx: @fn_ctxt, stmt: @ast::stmt) -> bool {
match stmt.node { match stmt.node {
ast::stmt_decl(decl, id) => { ast::stmt_decl(decl, id) => {
node_id = id; node_id = id;
match decl.node { match /*bad*/copy decl.node {
ast::decl_local(ls) => for ls.each |l| { ast::decl_local(ls) => for ls.each |l| {
bot |= check_decl_local(fcx, *l); bot |= check_decl_local(fcx, *l);
}, },
@ -2614,7 +2640,7 @@ fn check_instantiable(tcx: ty::ctxt,
fn check_enum_variants(ccx: @crate_ctxt, fn check_enum_variants(ccx: @crate_ctxt,
sp: span, sp: span,
vs: ~[ast::variant], +vs: ~[ast::variant],
id: ast::node_id) { id: ast::node_id) {
fn do_check(ccx: @crate_ctxt, sp: span, vs: ~[ast::variant], fn do_check(ccx: @crate_ctxt, sp: span, vs: ~[ast::variant],
id: ast::node_id, disr_vals: &mut ~[int], disr_val: &mut int, id: ast::node_id, disr_vals: &mut ~[int], disr_val: &mut int,
@ -2659,7 +2685,7 @@ fn check_enum_variants(ccx: @crate_ctxt,
*disr_val += 1; *disr_val += 1;
match v.node.kind { match v.node.kind {
ast::tuple_variant_kind(args) if args.len() > 0u => { ast::tuple_variant_kind(ref args) if args.len() > 0u => {
arg_tys = Some(ty::ty_fn_args(ctor_ty).map(|a| a.ty)); arg_tys = Some(ty::ty_fn_args(ctor_ty).map(|a| a.ty));
} }
ast::tuple_variant_kind(_) => { ast::tuple_variant_kind(_) => {
@ -2672,7 +2698,13 @@ fn check_enum_variants(ccx: @crate_ctxt,
} }
ast::enum_variant_kind(_) => { ast::enum_variant_kind(_) => {
arg_tys = None; arg_tys = None;
do_check(ccx, sp, vs, id, disr_vals, disr_val, variants); do_check(ccx,
sp,
/*bad*/copy vs,
id,
disr_vals,
disr_val,
variants);
} }
} }
@ -2809,6 +2841,8 @@ fn instantiate_path(fcx: @fn_ctxt,
span: span, span: span,
node_id: ast::node_id, node_id: ast::node_id,
region_lb: ty::Region) { region_lb: ty::Region) {
debug!(">>> instantiate_path");
let ty_param_count = vec::len(*tpt.bounds); let ty_param_count = vec::len(*tpt.bounds);
let ty_substs_len = vec::len(pth.types); let ty_substs_len = vec::len(pth.types);
@ -2855,6 +2889,8 @@ fn instantiate_path(fcx: @fn_ctxt,
let substs = {self_r: self_r, self_ty: None, tps: tps}; let substs = {self_r: self_r, self_ty: None, tps: tps};
fcx.write_ty_substs(node_id, tpt.ty, substs); fcx.write_ty_substs(node_id, tpt.ty, substs);
debug!("<<<");
} }
// Resolves `typ` by a single level if `typ` is a type variable. If no // Resolves `typ` by a single level if `typ` is a type variable. If no
@ -2873,7 +2909,7 @@ fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
// Returns the one-level-deep structure of the given type. // Returns the one-level-deep structure of the given type.
fn structure_of(fcx: @fn_ctxt, sp: span, typ: ty::t) -> ty::sty { fn structure_of(fcx: @fn_ctxt, sp: span, typ: ty::t) -> ty::sty {
ty::get(structurally_resolved_type(fcx, sp, typ)).sty /*bad*/copy ty::get(structurally_resolved_type(fcx, sp, typ)).sty
} }
fn type_is_integral(fcx: @fn_ctxt, sp: span, typ: ty::t) -> bool { fn type_is_integral(fcx: @fn_ctxt, sp: span, typ: ty::t) -> bool {

View File

@ -27,6 +27,7 @@ this point a bit better.
*/ */
use middle::freevars::get_freevars; use middle::freevars::get_freevars;
use middle::pat_util::pat_bindings; use middle::pat_util::pat_bindings;
use middle::ty::{encl_region, re_scope}; use middle::ty::{encl_region, re_scope};
@ -168,7 +169,7 @@ fn visit_expr(expr: @ast::expr, &&rcx: @rcx, v: rvt) {
debug!("visit_expr(e=%s)", debug!("visit_expr(e=%s)",
pprust::expr_to_str(expr, rcx.fcx.tcx().sess.intr())); pprust::expr_to_str(expr, rcx.fcx.tcx().sess.intr()));
match expr.node { match /*bad*/copy expr.node {
ast::expr_path(*) => { ast::expr_path(*) => {
// Avoid checking the use of local variables, as we // Avoid checking the use of local variables, as we
// already check their definitions. The def'n always // already check their definitions. The def'n always

View File

@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
// #[warn(deprecated_mode)]; // #[warn(deprecated_mode)];
// #[warn(deprecated_pattern)];
use middle::ty; use middle::ty;
use util::ppaux; use util::ppaux;
@ -60,7 +59,7 @@ fn replace_bound_regions_in_fn_ty(
debug!("br=%?", br); debug!("br=%?", br);
mapf(br) mapf(br)
}; };
let ty_fn = ty::ty_fn(*fn_ty); let ty_fn = ty::ty_fn(/*bad*/copy *fn_ty);
let t_fn = ty::fold_sty_to_ty(tcx, &ty_fn, |t| { let t_fn = ty::fold_sty_to_ty(tcx, &ty_fn, |t| {
replace_bound_regions(tcx, isr, t) replace_bound_regions(tcx, isr, t)
}); });
@ -80,7 +79,7 @@ fn replace_bound_regions_in_fn_ty(
return {isr: isr, return {isr: isr,
self_info: new_self_info, self_info: new_self_info,
fn_ty: match ty::get(t_fn).sty { ty::ty_fn(ref o) => (*o), fn_ty: match ty::get(t_fn).sty { ty::ty_fn(ref o) => /*bad*/copy *o,
_ => tcx.sess.bug(~"replace_bound_regions_in_fn_ty: impossible")}}; _ => tcx.sess.bug(~"replace_bound_regions_in_fn_ty: impossible")}};

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::resolve; use middle::resolve;
use middle::ty; use middle::ty;
use middle::typeck::check::{fn_ctxt, impl_self_ty}; use middle::typeck::check::{fn_ctxt, impl_self_ty};
@ -95,7 +96,7 @@ fn lookup_vtables(vcx: &VtableContext,
ppaux::ty_to_str(tcx, trait_ty), ppaux::ty_to_str(tcx, trait_ty),
ty::substs_to_str(tcx, substs)); ty::substs_to_str(tcx, substs));
let new_substs = {self_ty: Some(*ty), ..*substs}; let new_substs = {self_ty: Some(*ty), ../*bad*/copy *substs};
let trait_ty = ty::subst(tcx, &new_substs, trait_ty); let trait_ty = ty::subst(tcx, &new_substs, trait_ty);
debug!("after subst: %?", debug!("after subst: %?",
@ -129,14 +130,14 @@ fn lookup_vtables(vcx: &VtableContext,
} }
fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo, fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
id: ast::def_id, substs: ty::substs, id: ast::def_id, +substs: ty::substs,
is_early: bool) -> Option<ty::substs> { is_early: bool) -> Option<ty::substs> {
let tcx = vcx.tcx(); let tcx = vcx.tcx();
// use a dummy type just to package up the substs that need fixing up // use a dummy type just to package up the substs that need fixing up
let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static)); let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static));
do fixup_ty(vcx, location_info, t, is_early).map |t_f| { do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
match ty::get(*t_f).sty { match ty::get(*t_f).sty {
ty::ty_trait(_, ref substs_f, _) => (*substs_f), ty::ty_trait(_, ref substs_f, _) => (/*bad*/copy *substs_f),
_ => fail ~"t_f should be a trait" _ => fail ~"t_f should be a trait"
} }
} }
@ -162,7 +163,8 @@ fn lookup_vtable(vcx: &VtableContext,
let tcx = vcx.tcx(); let tcx = vcx.tcx();
let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty { let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty {
ty::ty_trait(did, ref substs, vstore) => (did, (*substs), vstore), ty::ty_trait(did, ref substs, vstore) =>
(did, (/*bad*/copy *substs), vstore),
_ => tcx.sess.impossible_case(location_info.span, _ => tcx.sess.impossible_case(location_info.span,
"lookup_vtable: \ "lookup_vtable: \
don't know how to handle a non-trait") don't know how to handle a non-trait")
@ -221,7 +223,7 @@ fn lookup_vtable(vcx: &VtableContext,
relate_trait_tys(vcx, location_info, trait_ty, ty); relate_trait_tys(vcx, location_info, trait_ty, ty);
if !allow_unsafe && !is_early { if !allow_unsafe && !is_early {
for vec::each(*ty::trait_methods(tcx, did)) |m| { for vec::each(*ty::trait_methods(tcx, did)) |m| {
if ty::type_has_self(ty::mk_fn(tcx, m.fty)) { if ty::type_has_self(ty::mk_fn(tcx, /*bad*/copy m.fty)) {
tcx.sess.span_err( tcx.sess.span_err(
location_info.span, location_info.span,
~"a boxed trait with self types may not be \ ~"a boxed trait with self types may not be \
@ -235,7 +237,7 @@ fn lookup_vtable(vcx: &VtableContext,
} }
} }
} }
return Some(vtable_trait(did, (*substs).tps)); return Some(vtable_trait(did, /*bad*/copy (*substs).tps));
} }
_ => { _ => {
@ -349,7 +351,7 @@ fn lookup_vtable(vcx: &VtableContext,
// trait_substs. Now we extract out the // trait_substs. Now we extract out the
// types themselves from trait_substs. // types themselves from trait_substs.
let trait_tps = trait_substs.tps; let trait_tps = /*bad*/copy trait_substs.tps;
debug!("Casting to a trait ty whose substs \ debug!("Casting to a trait ty whose substs \
(trait_tps) are %s", (trait_tps) are %s",
@ -368,7 +370,7 @@ fn lookup_vtable(vcx: &VtableContext,
trait_id, trait_id,
substs, substs,
is_early) { is_early) {
Some(ref substs) => (*substs), Some(ref substs) => (/*bad*/copy *substs),
None => { None => {
assert is_early; assert is_early;
// Bail out with a bogus answer // Bail out with a bogus answer
@ -393,7 +395,7 @@ fn lookup_vtable(vcx: &VtableContext,
im.did).bounds; im.did).bounds;
connect_trait_tps(vcx, connect_trait_tps(vcx,
location_info, location_info,
substs_f.tps, /*bad*/copy substs_f.tps,
trait_tps, trait_tps,
im.did, im.did,
trait_vstore); trait_vstore);
@ -407,7 +409,8 @@ fn lookup_vtable(vcx: &VtableContext,
// of type substitutions for the target // of type substitutions for the target
// trait. // trait.
found.push( found.push(
vtable_static(im.did, substs_f.tps, vtable_static(im.did,
/*bad*/copy substs_f.tps,
subres)); subres));
} }
} }
@ -416,14 +419,14 @@ fn lookup_vtable(vcx: &VtableContext,
match found.len() { match found.len() {
0 => { /* fallthrough */ } 0 => { /* fallthrough */ }
1 => { return Some(found[0]); } 1 => { return Some(/*bad*/copy found[0]); }
_ => { _ => {
if !is_early { if !is_early {
vcx.tcx().sess.span_err( vcx.tcx().sess.span_err(
location_info.span, location_info.span,
~"multiple applicable methods in scope"); ~"multiple applicable methods in scope");
} }
return Some(found[0]); return Some(/*bad*/copy found[0]);
} }
} }
} }
@ -518,7 +521,7 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
let item_ty = ty::lookup_item_type(cx.tcx, did); let item_ty = ty::lookup_item_type(cx.tcx, did);
debug!("early resolve expr: def %? %?, %?, %?", ex.id, did, def, debug!("early resolve expr: def %? %?, %?, %?", ex.id, did, def,
fcx.infcx().ty_to_str(item_ty.ty)); fcx.infcx().ty_to_str(item_ty.ty));
if has_trait_bounds(*item_ty.bounds) { if has_trait_bounds(/*bad*/copy *item_ty.bounds) {
for item_ty.bounds.each |bounds| { for item_ty.bounds.each |bounds| {
debug!("early_resolve_expr: looking up vtables for bound \ debug!("early_resolve_expr: looking up vtables for bound \
%s", %s",
@ -545,7 +548,7 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
ast::expr_index(*) | ast::expr_method_call(*) => { ast::expr_index(*) | ast::expr_method_call(*) => {
match ty::method_call_bounds(cx.tcx, cx.method_map, ex.id) { match ty::method_call_bounds(cx.tcx, cx.method_map, ex.id) {
Some(bounds) => { Some(bounds) => {
if has_trait_bounds(*bounds) { if has_trait_bounds(/*bad*/copy *bounds) {
let callee_id = match ex.node { let callee_id = match ex.node {
ast::expr_field(_, _, _) => ex.id, ast::expr_field(_, _, _) => ex.id,
_ => ex.callee_id _ => ex.callee_id

View File

@ -12,6 +12,7 @@
// unresolved type variables and replaces "ty_var" types with their // unresolved type variables and replaces "ty_var" types with their
// substitutions. // substitutions.
use middle::pat_util; use middle::pat_util;
use middle::ty; use middle::ty;
use middle::typeck::check::{fn_ctxt, lookup_local}; use middle::typeck::check::{fn_ctxt, lookup_local};
@ -154,7 +155,7 @@ fn visit_expr(e: @ast::expr, wbcx: wb_ctxt, v: wb_vt) {
resolve_type_vars_for_node(wbcx, e.span, e.id); resolve_type_vars_for_node(wbcx, e.span, e.id);
resolve_method_map_entry(wbcx.fcx, e.span, e.id); resolve_method_map_entry(wbcx.fcx, e.span, e.id);
resolve_method_map_entry(wbcx.fcx, e.span, e.callee_id); resolve_method_map_entry(wbcx.fcx, e.span, e.callee_id);
match e.node { match /*bad*/copy e.node {
ast::expr_fn(_, decl, _, _) | ast::expr_fn(_, decl, _, _) |
ast::expr_fn_block(decl, _, _) => { ast::expr_fn_block(decl, _, _) => {
for vec::each(decl.inputs) |input| { for vec::each(decl.inputs) |input| {

View File

@ -14,6 +14,7 @@
// has at most one implementation for each type. Then we build a mapping from // has at most one implementation for each type. Then we build a mapping from
// each trait in the system to its implementations. // each trait in the system to its implementations.
use driver; use driver;
use metadata::csearch::{ProvidedTraitMethodInfo, each_path, get_impl_traits}; use metadata::csearch::{ProvidedTraitMethodInfo, each_path, get_impl_traits};
use metadata::csearch::{get_impls_for_mod}; use metadata::csearch::{get_impls_for_mod};
@ -510,10 +511,13 @@ impl CoherenceChecker {
self_ty: None, self_ty: None,
tps: type_parameters tps: type_parameters
}; };
let monotype = subst(self.crate_context.tcx, let monotype = subst(self.crate_context.tcx,
&substitutions, &substitutions,
polytype.ty); polytype.ty);
// Get our type parameters back.
let { self_r: _, self_ty: _, tps: type_parameters } = substitutions;
UniversalQuantificationResult { UniversalQuantificationResult {
monotype: monotype, monotype: monotype,
type_variables: move type_parameters, type_variables: move type_parameters,
@ -583,7 +587,7 @@ impl CoherenceChecker {
fn check_privileged_scopes(crate: @crate) { fn check_privileged_scopes(crate: @crate) {
visit_crate(*crate, (), mk_vt(@{ visit_crate(*crate, (), mk_vt(@{
visit_item: |item, _context, visitor| { visit_item: |item, _context, visitor| {
match item.node { match /*bad*/copy item.node {
item_mod(module_) => { item_mod(module_) => {
// Then visit the module items. // Then visit the module items.
visit_mod(module_, item.span, item.id, (), visitor); visit_mod(module_, item.span, item.id, (), visitor);
@ -717,7 +721,7 @@ impl CoherenceChecker {
} }
} }
match item.node { match /*bad*/copy item.node {
item_impl(_, trait_refs, _, ast_methods) => { item_impl(_, trait_refs, _, ast_methods) => {
let mut methods = ~[]; let mut methods = ~[];
for ast_methods.each |ast_method| { for ast_methods.each |ast_method| {

View File

@ -62,7 +62,7 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
if crate_item.ident if crate_item.ident
== ::syntax::parse::token::special_idents::intrinsic { == ::syntax::parse::token::special_idents::intrinsic {
match crate_item.node { match /*bad*/copy crate_item.node {
ast::item_mod(m) => { ast::item_mod(m) => {
for m.items.each |intrinsic_item| { for m.items.each |intrinsic_item| {
let def_id = { crate: ast::local_crate, let def_id = { crate: ast::local_crate,
@ -150,7 +150,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
// constructors get turned into functions. // constructors get turned into functions.
let result_ty; let result_ty;
match variant.node.kind { match variant.node.kind {
ast::tuple_variant_kind(args) if args.len() > 0 => { ast::tuple_variant_kind(ref args) if args.len() > 0 => {
let rs = type_rscope(rp); let rs = type_rscope(rp);
let args = args.map(|va| { let args = args.map(|va| {
let arg_ty = ccx.to_ty(rs, va.ty); let arg_ty = ccx.to_ty(rs, va.ty);
@ -172,11 +172,18 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
} }
ast::struct_variant_kind(struct_def) => { ast::struct_variant_kind(struct_def) => {
// XXX: Merge with computation of the the same value below? // XXX: Merge with computation of the the same value below?
let tpt = {bounds: ty_param_bounds(ccx, ty_params), let tpt = {
region_param: rp, bounds: ty_param_bounds(ccx, /*bad*/copy ty_params),
ty: enum_ty}; region_param: rp,
ty: enum_ty
};
convert_struct( convert_struct(
ccx, rp, struct_def, ty_params, tpt, variant.node.id); ccx,
rp,
struct_def,
/*bad*/copy ty_params,
tpt,
variant.node.id);
// Compute the ctor arg types from the struct fields // Compute the ctor arg types from the struct fields
let struct_fields = do struct_def.fields.map |struct_field| { let struct_fields = do struct_def.fields.map |struct_field| {
{mode: ast::expl(ast::by_val), {mode: ast::expl(ast::by_val),
@ -195,8 +202,8 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
ast::enum_variant_kind(ref enum_definition) => { ast::enum_variant_kind(ref enum_definition) => {
get_enum_variant_types(ccx, get_enum_variant_types(ccx,
enum_ty, enum_ty,
enum_definition.variants, /*bad*/copy enum_definition.variants,
ty_params, /*bad*/copy ty_params,
rp); rp);
result_ty = None; result_ty = None;
} }
@ -205,9 +212,11 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
match result_ty { match result_ty {
None => {} None => {}
Some(result_ty) => { Some(result_ty) => {
let tpt = {bounds: ty_param_bounds(ccx, ty_params), let tpt = {
region_param: rp, bounds: ty_param_bounds(ccx, /*bad*/copy ty_params),
ty: result_ty}; region_param: rp,
ty: result_ty
};
tcx.tcache.insert(local_def(variant.node.id), tpt); tcx.tcache.insert(local_def(variant.node.id), tpt);
write_ty_to_tcx(tcx, variant.node.id, result_ty); write_ty_to_tcx(tcx, variant.node.id, result_ty);
} }
@ -217,7 +226,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) { fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) {
fn store_methods<T>(ccx: @crate_ctxt, id: ast::node_id, fn store_methods<T>(ccx: @crate_ctxt, id: ast::node_id,
stuff: ~[T], f: fn@(v: &T) -> ty::method) { stuff: ~[T], f: &fn(v: &T) -> ty::method) {
ty::store_trait_methods(ccx.tcx, id, @vec::map(stuff, f)); ty::store_trait_methods(ccx.tcx, id, @vec::map(stuff, f));
} }
@ -250,7 +259,9 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) {
let substs = { self_r: None, self_ty: Some(self_param), let substs = { self_r: None, self_ty: Some(self_param),
tps: non_shifted_trait_tps + shifted_method_tps }; tps: non_shifted_trait_tps + shifted_method_tps };
let ty = ty::subst(ccx.tcx, &substs, ty::mk_fn(ccx.tcx, m.fty)); let ty = ty::subst(ccx.tcx,
&substs,
ty::mk_fn(ccx.tcx, /*bad*/copy m.fty));
let bounds = @(*trait_bounds + ~[@~[ty::bound_trait(trait_ty)]] let bounds = @(*trait_bounds + ~[@~[ty::bound_trait(trait_ty)]]
+ *m.tps); + *m.tps);
ccx.tcx.tcache.insert(local_def(am.id), ccx.tcx.tcache.insert(local_def(am.id),
@ -264,10 +275,10 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) {
let region_paramd = tcx.region_paramd_items.find(id); let region_paramd = tcx.region_paramd_items.find(id);
match tcx.items.get(id) { match tcx.items.get(id) {
ast_map::node_item(@{ ast_map::node_item(@{
node: ast::item_trait(params, _, ref ms), node: ast::item_trait(ref params, _, ref ms),
_ _
}, _) => { }, _) => {
store_methods::<ast::trait_method>(ccx, id, (*ms), |m| { store_methods::<ast::trait_method>(ccx, id, (/*bad*/copy *ms), |m| {
let def_id; let def_id;
match *m { match *m {
ast::required(ref ty_method) => { ast::required(ref ty_method) => {
@ -276,7 +287,7 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) {
ast::provided(method) => def_id = local_def(method.id) ast::provided(method) => def_id = local_def(method.id)
} }
let trait_bounds = ty_param_bounds(ccx, params); let trait_bounds = ty_param_bounds(ccx, copy *params);
let ty_m = trait_method_to_ty_method(*m); let ty_m = trait_method_to_ty_method(*m);
let method_ty = ty_of_ty_method(ccx, ty_m, region_paramd, def_id); let method_ty = ty_of_ty_method(ccx, ty_m, region_paramd, def_id);
if ty_m.self_ty.node == ast::sty_static { if ty_m.self_ty.node == ast::sty_static {
@ -430,7 +441,7 @@ fn compare_impl_method(tcx: ty::ctxt,
// that correspond to the parameters we will find on the impl // that correspond to the parameters we will find on the impl
// - replace self region with a fresh, dummy region // - replace self region with a fresh, dummy region
let impl_fty = { let impl_fty = {
let impl_fty = ty::mk_fn(tcx, impl_m.fty); let impl_fty = ty::mk_fn(tcx, /*bad*/copy impl_m.fty);
debug!("impl_fty (pre-subst): %s", ppaux::ty_to_str(tcx, impl_fty)); debug!("impl_fty (pre-subst): %s", ppaux::ty_to_str(tcx, impl_fty));
replace_bound_self(tcx, impl_fty, dummy_self_r) replace_bound_self(tcx, impl_fty, dummy_self_r)
}; };
@ -448,7 +459,7 @@ fn compare_impl_method(tcx: ty::ctxt,
self_ty: Some(self_ty), self_ty: Some(self_ty),
tps: vec::append(trait_tps, dummy_tps) tps: vec::append(trait_tps, dummy_tps)
}; };
let trait_fty = ty::mk_fn(tcx, trait_m.fty); let trait_fty = ty::mk_fn(tcx, /*bad*/copy trait_m.fty);
debug!("trait_fty (pre-subst): %s", ppaux::ty_to_str(tcx, trait_fty)); debug!("trait_fty (pre-subst): %s", ppaux::ty_to_str(tcx, trait_fty));
ty::subst(tcx, &substs, trait_fty) ty::subst(tcx, &substs, trait_fty)
}; };
@ -554,15 +565,15 @@ fn convert_methods(ccx: @crate_ctxt,
let tcx = ccx.tcx; let tcx = ccx.tcx;
do vec::map(ms) |m| { do vec::map(ms) |m| {
let bounds = ty_param_bounds(ccx, m.tps); let bounds = ty_param_bounds(ccx, /*bad*/copy m.tps);
let mty = ty_of_method(ccx, *m, rp); let mty = ty_of_method(ccx, *m, rp);
let fty = ty::mk_fn(tcx, mty.fty); let fty = ty::mk_fn(tcx, /*bad*/copy mty.fty);
tcx.tcache.insert( tcx.tcache.insert(
local_def(m.id), local_def(m.id),
// n.b.: the type of a method is parameterized by both // n.b.: the type of a method is parameterized by both
// the tps on the receiver and those on the method itself // the tps on the receiver and those on the method itself
{bounds: @(vec::append(*rcvr_bounds, *bounds)), {bounds: @(vec::append(/*bad*/copy *rcvr_bounds, *bounds)),
region_param: rp, region_param: rp,
ty: fty}); ty: fty});
write_ty_to_tcx(tcx, m.id, fty); write_ty_to_tcx(tcx, m.id, fty);
@ -576,17 +587,19 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
let rp = tcx.region_paramd_items.find(it.id); let rp = tcx.region_paramd_items.find(it.id);
debug!("convert: item %s with id %d rp %?", debug!("convert: item %s with id %d rp %?",
tcx.sess.str_of(it.ident), it.id, rp); tcx.sess.str_of(it.ident), it.id, rp);
match it.node { match /*bad*/copy it.node {
// These don't define types. // These don't define types.
ast::item_foreign_mod(_) | ast::item_mod(_) => {} ast::item_foreign_mod(_) | ast::item_mod(_) => {}
ast::item_enum(ref enum_definition, ty_params) => { ast::item_enum(ref enum_definition, ref ty_params) => {
let tpt = ty_of_item(ccx, it); let tpt = ty_of_item(ccx, it);
write_ty_to_tcx(tcx, it.id, tpt.ty); write_ty_to_tcx(tcx, it.id, tpt.ty);
get_enum_variant_types(ccx, tpt.ty, (*enum_definition).variants, get_enum_variant_types(ccx,
ty_params, rp); tpt.ty,
/*bad*/copy (*enum_definition).variants,
/*bad*/copy *ty_params, rp);
} }
ast::item_impl(tps, trait_ref, selfty, ms) => { ast::item_impl(ref tps, trait_ref, selfty, ref ms) => {
let i_bounds = ty_param_bounds(ccx, tps); let i_bounds = ty_param_bounds(ccx, /*bad*/copy *tps);
let selfty = ccx.to_ty(type_rscope(rp), selfty); let selfty = ccx.to_ty(type_rscope(rp), selfty);
write_ty_to_tcx(tcx, it.id, selfty); write_ty_to_tcx(tcx, it.id, selfty);
tcx.tcache.insert(local_def(it.id), tcx.tcache.insert(local_def(it.id),
@ -594,21 +607,24 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
region_param: rp, region_param: rp,
ty: selfty}); ty: selfty});
let cms = convert_methods(ccx, ms, rp, i_bounds); // XXX: Bad copy of `ms` below.
let cms = convert_methods(ccx, /*bad*/copy *ms, rp, i_bounds);
for trait_ref.each |t| { for trait_ref.each |t| {
check_methods_against_trait(ccx, tps, rp, selfty, *t, cms); check_methods_against_trait(ccx, /*bad*/copy *tps, rp, selfty,
*t, /*bad*/copy cms);
} }
} }
ast::item_trait(tps, supertraits, ref trait_methods) => { ast::item_trait(ref tps, ref supertraits, ref trait_methods) => {
let tpt = ty_of_item(ccx, it); let tpt = ty_of_item(ccx, it);
debug!("item_trait(it.id=%d, tpt.ty=%s)", debug!("item_trait(it.id=%d, tpt.ty=%s)",
it.id, ppaux::ty_to_str(tcx, tpt.ty)); it.id, ppaux::ty_to_str(tcx, tpt.ty));
write_ty_to_tcx(tcx, it.id, tpt.ty); write_ty_to_tcx(tcx, it.id, tpt.ty);
ensure_trait_methods(ccx, it.id, tpt.ty); ensure_trait_methods(ccx, it.id, tpt.ty);
ensure_supertraits(ccx, it.id, it.span, rp, supertraits); ensure_supertraits(ccx, it.id, it.span, rp, *supertraits);
let (_, provided_methods) = split_trait_methods((*trait_methods)); let (_, provided_methods) =
let {bounds, _} = mk_substs(ccx, tps, rp); split_trait_methods(/*bad*/copy *trait_methods);
let {bounds, _} = mk_substs(ccx, /*bad*/copy *tps, rp);
let _cms = convert_methods(ccx, provided_methods, rp, bounds); let _cms = convert_methods(ccx, provided_methods, rp, bounds);
// FIXME (#2616): something like this, when we start having // FIXME (#2616): something like this, when we start having
// trait inheritance? // trait inheritance?
@ -637,7 +653,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
fn convert_struct(ccx: @crate_ctxt, fn convert_struct(ccx: @crate_ctxt,
rp: Option<ty::region_variance>, rp: Option<ty::region_variance>,
struct_def: @ast::struct_def, struct_def: @ast::struct_def,
tps: ~[ast::ty_param], +tps: ~[ast::ty_param],
tpt: ty::ty_param_bounds_and_ty, tpt: ty::ty_param_bounds_and_ty,
id: ast::node_id) { id: ast::node_id) {
let tcx = ccx.tcx; let tcx = ccx.tcx;
@ -720,7 +736,7 @@ fn ty_of_method(ccx: @crate_ctxt,
m: @ast::method, m: @ast::method,
rp: Option<ty::region_variance>) -> ty::method { rp: Option<ty::region_variance>) -> ty::method {
{ident: m.ident, {ident: m.ident,
tps: ty_param_bounds(ccx, m.tps), tps: ty_param_bounds(ccx, /*bad*/copy m.tps),
fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::ProtoBare, fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::ProtoBare,
m.purity, ast::Many, m.purity, ast::Many,
/*bounds:*/ @~[], /*opt_region:*/ None, /*bounds:*/ @~[], /*opt_region:*/ None,
@ -735,7 +751,7 @@ fn ty_of_ty_method(self: @crate_ctxt,
rp: Option<ty::region_variance>, rp: Option<ty::region_variance>,
id: ast::def_id) -> ty::method { id: ast::def_id) -> ty::method {
{ident: m.ident, {ident: m.ident,
tps: ty_param_bounds(self, m.tps), tps: ty_param_bounds(self, /*bad*/copy m.tps),
fty: ty_of_fn_decl(self, type_rscope(rp), ast::ProtoBare, fty: ty_of_fn_decl(self, type_rscope(rp), ast::ProtoBare,
m.purity, ast::Many, m.purity, ast::Many,
/*bounds:*/ @~[], /*opt_region:*/ None, /*bounds:*/ @~[], /*opt_region:*/ None,
@ -785,7 +801,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
_ => {} _ => {}
} }
let rp = tcx.region_paramd_items.find(it.id); let rp = tcx.region_paramd_items.find(it.id);
match it.node { match /*bad*/copy it.node {
ast::item_const(t, _) => { ast::item_const(t, _) => {
let typ = ccx.to_ty(empty_rscope, t); let typ = ccx.to_ty(empty_rscope, t);
let tpt = no_params(typ); let tpt = no_params(typ);
@ -870,7 +886,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item) fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
-> ty::ty_param_bounds_and_ty { -> ty::ty_param_bounds_and_ty {
match it.node { match /*bad*/copy it.node {
ast::foreign_item_fn(fn_decl, purity, params) => { ast::foreign_item_fn(fn_decl, purity, params) => {
return ty_of_foreign_fn_decl(ccx, fn_decl, purity, params, return ty_of_foreign_fn_decl(ccx, fn_decl, purity, params,
local_def(it.id)); local_def(it.id));
@ -939,9 +955,8 @@ fn ty_param_bounds(ccx: @crate_ctxt,
fn ty_of_foreign_fn_decl(ccx: @crate_ctxt, fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
decl: ast::fn_decl, decl: ast::fn_decl,
purity: ast::purity, purity: ast::purity,
ty_params: ~[ast::ty_param], +ty_params: ~[ast::ty_param],
def_id: ast::def_id) -> ty::ty_param_bounds_and_ty { def_id: ast::def_id) -> ty::ty_param_bounds_and_ty {
let bounds = ty_param_bounds(ccx, ty_params); let bounds = ty_param_bounds(ccx, ty_params);
let rb = in_binding_rscope(empty_rscope); let rb = in_binding_rscope(empty_rscope);
let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, rb, *a, None) ); let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, rb, *a, None) );
@ -966,7 +981,8 @@ fn mk_ty_params(ccx: @crate_ctxt, atps: ~[ast::ty_param])
-> {bounds: @~[ty::param_bounds], params: ~[ty::t]} { -> {bounds: @~[ty::param_bounds], params: ~[ty::t]} {
let mut i = 0u; let mut i = 0u;
let bounds = ty_param_bounds(ccx, atps); // XXX: Bad copy.
let bounds = ty_param_bounds(ccx, copy atps);
{bounds: bounds, {bounds: bounds,
params: vec::map(atps, |atp| { params: vec::map(atps, |atp| {
let t = ty::mk_param(ccx.tcx, i, local_def(atp.id)); let t = ty::mk_param(ccx.tcx, i, local_def(atp.id));
@ -975,10 +991,10 @@ fn mk_ty_params(ccx: @crate_ctxt, atps: ~[ast::ty_param])
})} })}
} }
fn mk_substs(ccx: @crate_ctxt, atps: ~[ast::ty_param], fn mk_substs(ccx: @crate_ctxt,
+atps: ~[ast::ty_param],
rp: Option<ty::region_variance>) rp: Option<ty::region_variance>)
-> {bounds: @~[ty::param_bounds], substs: ty::substs} { -> {bounds: @~[ty::param_bounds], substs: ty::substs} {
let {bounds, params} = mk_ty_params(ccx, atps); let {bounds, params} = mk_ty_params(ccx, atps);
let self_r = rscope::bound_self_region(rp); let self_r = rscope::bound_self_region(rp);
{bounds: bounds, substs: {self_r: self_r, self_ty: None, tps: params}} {bounds: bounds, substs: {self_r: self_r, self_ty: None, tps: params}}

View File

@ -58,6 +58,7 @@
// A. But this upper-bound might be stricter than what is truly // A. But this upper-bound might be stricter than what is truly
// needed. // needed.
use middle::ty; use middle::ty;
use middle::typeck::infer::combine::combine_fields; use middle::typeck::infer::combine::combine_fields;
use middle::typeck::infer::to_str::ToStr; use middle::typeck::infer::to_str::ToStr;
@ -84,7 +85,13 @@ impl Assign {
b.to_str(self.infcx)); b.to_str(self.infcx));
let _r = indenter(); let _r = indenter();
match (ty::get(a).sty, ty::get(b).sty) { debug!("Assign.tys: copying first type");
let copy_a = copy ty::get(a).sty;
debug!("Assign.tys: copying second type");
let copy_b = copy ty::get(b).sty;
debug!("Assign.tys: performing match");
let r = match (copy_a, copy_b) {
(ty::ty_bot, _) => { (ty::ty_bot, _) => {
Ok(None) Ok(None)
} }
@ -119,7 +126,11 @@ impl Assign {
(_, _) => { (_, _) => {
self.assign_tys_or_sub(a, b, Some(a), Some(b)) self.assign_tys_or_sub(a, b, Some(a), Some(b))
} }
} };
debug!("Assign.tys end");
move r
} }
} }
@ -150,7 +161,8 @@ priv impl Assign {
match (a_bnd, b_bnd) { match (a_bnd, b_bnd) {
(Some(a_bnd), Some(b_bnd)) => { (Some(a_bnd), Some(b_bnd)) => {
match (ty::get(a_bnd).sty, ty::get(b_bnd).sty) { match (/*bad*/copy ty::get(a_bnd).sty,
/*bad*/copy ty::get(b_bnd).sty) {
// check for a case where a non-region pointer (@, ~) is // check for a case where a non-region pointer (@, ~) is
// being assigned to a region pointer: // being assigned to a region pointer:
(ty::ty_box(_), ty::ty_rptr(r_b, mt_b)) => { (ty::ty_box(_), ty::ty_rptr(r_b, mt_b)) => {
@ -192,7 +204,7 @@ priv impl Assign {
let nr_b = ty::mk_fn(self.infcx.tcx, ty::FnTyBase { let nr_b = ty::mk_fn(self.infcx.tcx, ty::FnTyBase {
meta: ty::FnMeta {proto: a_f.meta.proto, meta: ty::FnMeta {proto: a_f.meta.proto,
..b_f.meta}, ..b_f.meta},
sig: b_f.sig sig: /*bad*/copy b_f.sig
}); });
self.try_assign(0, ty::AutoBorrowFn, self.try_assign(0, ty::AutoBorrowFn,
a, nr_b, m_imm, b_f.meta.region) a, nr_b, m_imm, b_f.meta.region)

View File

@ -54,8 +54,6 @@
// terms of error reporting, although we do not do that properly right // terms of error reporting, although we do not do that properly right
// now. // now.
#[warn(vecs_implicitly_copyable)];
use middle::ty; use middle::ty;
use middle::ty::{FnTyBase, FnMeta, FnSig}; use middle::ty::{FnTyBase, FnMeta, FnSig};
use middle::typeck::infer::sub::Sub; use middle::typeck::infer::sub::Sub;
@ -226,7 +224,7 @@ fn super_substs<C:combine>(
do relate_region_param(self, did, do relate_region_param(self, did,
a.self_r, b.self_r).chain |self_r| a.self_r, b.self_r).chain |self_r|
{ {
Ok({self_r: self_r, self_ty: self_ty, tps: tps}) Ok({self_r: self_r, self_ty: self_ty, tps: /*bad*/copy tps})
} }
} }
} }
@ -345,10 +343,10 @@ fn super_fn_metas<C:combine>(
} }
fn super_fn_sigs<C:combine>( fn super_fn_sigs<C:combine>(
self: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig> self: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig> {
{ fn argvecs<C:combine>(self: &C,
fn argvecs<C:combine>(self: &C, a_args: ~[ty::arg], +a_args: ~[ty::arg],
b_args: ~[ty::arg]) -> cres<~[ty::arg]> { +b_args: ~[ty::arg]) -> cres<~[ty::arg]> {
if vec::same_length(a_args, b_args) { if vec::same_length(a_args, b_args) {
map_vec2(a_args, b_args, |a, b| self.args(*a, *b)) map_vec2(a_args, b_args, |a, b| self.args(*a, *b))
@ -357,9 +355,10 @@ fn super_fn_sigs<C:combine>(
} }
} }
do argvecs(self, a_f.inputs, b_f.inputs).chain |inputs| { do argvecs(self, /*bad*/copy a_f.inputs, /*bad*/copy b_f.inputs)
.chain |inputs| {
do self.tys(a_f.output, b_f.output).chain |output| { do self.tys(a_f.output, b_f.output).chain |output| {
Ok(FnSig {inputs: inputs, output: output}) Ok(FnSig {inputs: /*bad*/copy inputs, output: output})
} }
} }
} }
@ -378,7 +377,7 @@ fn super_tys<C:combine>(
self: &C, a: ty::t, b: ty::t) -> cres<ty::t> { self: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
let tcx = self.infcx().tcx; let tcx = self.infcx().tcx;
match (ty::get(a).sty, ty::get(b).sty) { match (/*bad*/copy ty::get(a).sty, /*bad*/copy ty::get(b).sty) {
// The "subtype" ought to be handling cases involving bot or var: // The "subtype" ought to be handling cases involving bot or var:
(ty::ty_bot, _) | (ty::ty_bot, _) |
(_, ty::ty_bot) | (_, ty::ty_bot) |
@ -418,8 +417,8 @@ fn super_tys<C:combine>(
(ty::ty_int(_), _) | (ty::ty_int(_), _) |
(ty::ty_uint(_), _) | (ty::ty_uint(_), _) |
(ty::ty_float(_), _) => { (ty::ty_float(_), _) => {
let as_ = ty::get(a).sty; let as_ = /*bad*/copy ty::get(a).sty;
let bs = ty::get(b).sty; let bs = /*bad*/copy ty::get(b).sty;
if as_ == bs { if as_ == bs {
Ok(a) Ok(a)
} else { } else {
@ -454,7 +453,7 @@ fn super_tys<C:combine>(
if a_id == b_id => { if a_id == b_id => {
do self.substs(a_id, a_substs, b_substs).chain |substs| { do self.substs(a_id, a_substs, b_substs).chain |substs| {
do self.vstores(ty::terr_trait, a_vstore, b_vstore).chain |vs| { do self.vstores(ty::terr_trait, a_vstore, b_vstore).chain |vs| {
Ok(ty::mk_trait(tcx, a_id, substs, vs)) Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, vs))
} }
} }
} }

View File

@ -14,6 +14,7 @@ Code related to floating-point type inference.
*/ */
use middle::ty; use middle::ty;
use middle::ty::ty_float; use middle::ty::ty_float;
use middle::typeck::infer::to_str::ToStr; use middle::typeck::infer::to_str::ToStr;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use middle::typeck::infer::combine::*; use middle::typeck::infer::combine::*;
use middle::typeck::infer::lattice::*; use middle::typeck::infer::lattice::*;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use middle::typeck::infer::combine::*; use middle::typeck::infer::combine::*;
use middle::typeck::infer::unify::*; use middle::typeck::infer::unify::*;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use middle::typeck::infer::combine::*; use middle::typeck::infer::combine::*;
use middle::typeck::infer::lattice::*; use middle::typeck::infer::lattice::*;

View File

@ -19,4 +19,4 @@ macro_rules! if_ok(
) )
); );
} }

View File

@ -46,6 +46,7 @@
// future). If you want to resolve everything but one type, you are // future). If you want to resolve everything but one type, you are
// probably better off writing `resolve_all - resolve_ivar`. // probably better off writing `resolve_all - resolve_ivar`.
use middle::ty; use middle::ty;
use middle::typeck::infer::floating::*; use middle::typeck::infer::floating::*;
use middle::typeck::infer::floating; use middle::typeck::infer::floating;
@ -110,7 +111,8 @@ impl resolve_state {
assert vec::is_empty(self.v_seen); assert vec::is_empty(self.v_seen);
match self.err { match self.err {
None => { None => {
debug!("Resolved to %s (modes=%x)", debug!("Resolved to %s + %s (modes=%x)",
ty_to_str(self.infcx.tcx, rty),
ty_to_str(self.infcx.tcx, rty), ty_to_str(self.infcx.tcx, rty),
self.modes); self.modes);
return Ok(rty); return Ok(rty);
@ -133,7 +135,7 @@ impl resolve_state {
indent(fn&() -> ty::t { indent(fn&() -> ty::t {
if !ty::type_needs_infer(typ) { return typ; } if !ty::type_needs_infer(typ) { return typ; }
match ty::get(typ).sty { match copy ty::get(typ).sty {
ty::ty_infer(TyVar(vid)) => { ty::ty_infer(TyVar(vid)) => {
self.resolve_ty_var(vid) self.resolve_ty_var(vid)
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use middle::typeck::infer::combine::*; use middle::typeck::infer::combine::*;
use middle::typeck::infer::to_str::ToStr; use middle::typeck::infer::to_str::ToStr;

View File

@ -16,6 +16,7 @@ Note: This module is only compiled when doing unit testing.
*/ */
use std::getopts; use std::getopts;
use std::map::HashMap; use std::map::HashMap;
use std::getopts; use std::getopts;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use middle::typeck::infer::integral::int_ty_set; use middle::typeck::infer::integral::int_ty_set;
use middle::typeck::infer::floating::float_ty_set; use middle::typeck::infer::floating::float_ty_set;

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use middle::typeck::infer::combine::combine; use middle::typeck::infer::combine::combine;
use middle::typeck::infer::floating::*; use middle::typeck::infer::floating::*;

View File

@ -347,7 +347,8 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
match tcx.items.find(main_id) { match tcx.items.find(main_id) {
Some(ast_map::node_item(it,_)) => { Some(ast_map::node_item(it,_)) => {
match it.node { match it.node {
ast::item_fn(_,_,ps,_) if vec::is_not_empty(ps) => { ast::item_fn(_, _, ref ps, _)
if vec::is_not_empty(*ps) => {
tcx.sess.span_err( tcx.sess.span_err(
main_span, main_span,
~"main function is not allowed \ ~"main function is not allowed \

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use core::result::Result; use core::result::Result;

View File

@ -22,7 +22,7 @@
#[legacy_modes]; #[legacy_modes];
#[legacy_exports]; #[legacy_exports];
#[allow(vecs_implicitly_copyable)]; #[allow(non_implicitly_copyable_typarams)];
#[allow(non_camel_case_types)]; #[allow(non_camel_case_types)];
#[allow(deprecated_mode)]; #[allow(deprecated_mode)];
#[warn(deprecated_pattern)]; #[warn(deprecated_pattern)];
@ -262,7 +262,7 @@ Available lint options:
fn describe_debug_flags() { fn describe_debug_flags() {
io::println(fmt!("\nAvailable debug options:\n")); io::println(fmt!("\nAvailable debug options:\n"));
for session::debugging_opts_map().each |pair| { for session::debugging_opts_map().each |pair| {
let (name, desc, _) = *pair; let (name, desc, _) = /*bad*/copy *pair;
io::println(fmt!(" -Z %-20s -- %s", name, desc)); io::println(fmt!(" -Z %-20s -- %s", name, desc));
} }
} }
@ -271,7 +271,7 @@ fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
// Don't display log spew by default. Can override with RUST_LOG. // Don't display log spew by default. Can override with RUST_LOG.
logging::console_off(); logging::console_off();
let mut args = *args; let mut args = /*bad*/copy *args;
let binary = args.shift(); let binary = args.shift();
if args.is_empty() { usage(binary); return; } if args.is_empty() { usage(binary); return; }
@ -308,7 +308,7 @@ fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
let input = match vec::len(matches.free) { let input = match vec::len(matches.free) {
0u => early_error(demitter, ~"no input filename given"), 0u => early_error(demitter, ~"no input filename given"),
1u => { 1u => {
let ifile = matches.free[0]; let ifile = /*bad*/copy matches.free[0];
if ifile == ~"-" { if ifile == ~"-" {
let src = str::from_bytes(io::stdin().read_whole_stream()); let src = str::from_bytes(io::stdin().read_whole_stream());
str_input(src) str_input(src)
@ -319,7 +319,8 @@ fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
_ => early_error(demitter, ~"multiple input filenames provided") _ => early_error(demitter, ~"multiple input filenames provided")
}; };
let sopts = build_session_options(binary, matches, demitter); // XXX: Bad copy.
let sopts = build_session_options(copy binary, matches, demitter);
let sess = build_session(sopts, demitter); let sess = build_session(sopts, demitter);
let odir = getopts::opt_maybe_str(matches, ~"out-dir"); let odir = getopts::opt_maybe_str(matches, ~"out-dir");
let odir = odir.map(|o| Path(*o)); let odir = odir.map(|o| Path(*o));

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use syntax::ast; use syntax::ast;
use syntax::codemap::{span}; use syntax::codemap::{span};
use syntax::visit; use syntax::visit;
@ -101,7 +102,7 @@ fn is_main_name(path: syntax::ast_map::path) -> bool {
) )
} }
fn pluralize(n: uint, s: ~str) -> ~str { fn pluralize(n: uint, +s: ~str) -> ~str {
if n == 1 { s } if n == 1 { s }
else { str::concat([s, ~"s"]) } else { str::concat([s, ~"s"]) }
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use middle::ty;
use middle::ty::{arg, canon_mode}; use middle::ty::{arg, canon_mode};
use middle::ty::{bound_copy, bound_const, bound_durable, bound_owned, use middle::ty::{bound_copy, bound_const, bound_durable, bound_owned,
@ -354,14 +355,14 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
} }
// if there is an id, print that instead of the structural type: // if there is an id, print that instead of the structural type:
for ty::type_def_id(typ).each |def_id| { /*for ty::type_def_id(typ).each |def_id| {
// note that this typedef cannot have type parameters // note that this typedef cannot have type parameters
return ast_map::path_to_str(ty::item_path(cx, *def_id), return ast_map::path_to_str(ty::item_path(cx, *def_id),
cx.sess.intr()); cx.sess.intr());
} }*/
// pretty print the structural type representation: // pretty print the structural type representation:
return match ty::get(typ).sty { return match /*bad*/copy ty::get(typ).sty {
ty_nil => ~"()", ty_nil => ~"()",
ty_bot => ~"_|_", ty_bot => ~"_|_",
ty_bool => ~"bool", ty_bool => ~"bool",
@ -395,7 +396,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
f.meta.purity, f.meta.purity,
f.meta.onceness, f.meta.onceness,
None, None,
f.sig.inputs, /*bad*/copy f.sig.inputs,
f.sig.output, f.sig.output,
f.meta.ret_style) f.meta.ret_style)
} }
@ -408,12 +409,15 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
ty_enum(did, ref substs) | ty_struct(did, ref substs) => { ty_enum(did, ref substs) | ty_struct(did, ref substs) => {
let path = ty::item_path(cx, did); let path = ty::item_path(cx, did);
let base = ast_map::path_to_str(path, cx.sess.intr()); let base = ast_map::path_to_str(path, cx.sess.intr());
parameterized(cx, base, (*substs).self_r, (*substs).tps) parameterized(cx, base, (*substs).self_r, /*bad*/copy (*substs).tps)
} }
ty_trait(did, ref substs, vs) => { ty_trait(did, ref substs, vs) => {
let path = ty::item_path(cx, did); let path = ty::item_path(cx, did);
let base = ast_map::path_to_str(path, cx.sess.intr()); let base = ast_map::path_to_str(path, cx.sess.intr());
let result = parameterized(cx, base, (*substs).self_r, (*substs).tps); let result = parameterized(cx,
base,
substs.self_r,
/*bad*/copy substs.tps);
vstore_ty_to_str(cx, result, vs) vstore_ty_to_str(cx, result, vs)
} }
ty_evec(mt, vs) => { ty_evec(mt, vs) => {