1
Fork 0

syntax/rustc: Eliminate some bad copies

r=pcwalton
This commit is contained in:
Tim Chevalier 2013-01-11 15:07:48 -08:00
parent 0ca369e9dc
commit a4dc65baa1
13 changed files with 103 additions and 101 deletions

View file

@ -457,32 +457,32 @@ mod write {
*
*/
fn build_link_meta(sess: Session, c: ast::crate, output: &Path,
fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
symbol_hasher: &hash::State) -> link_meta {
type provided_metas =
{name: Option<~str>,
vers: Option<~str>,
{name: Option<@str>,
vers: Option<@str>,
cmh_items: ~[@ast::meta_item]};
fn provided_link_metas(sess: Session, c: ast::crate) ->
fn provided_link_metas(sess: Session, c: &ast::crate) ->
provided_metas {
let mut name: Option<~str> = None;
let mut vers: Option<~str> = None;
let mut cmh_items: ~[@ast::meta_item] = ~[];
let linkage_metas =
attr::find_linkage_metas(/*bad*/copy c.node.attrs);
// XXX: Bad copy.
attr::require_unique_names(sess.diagnostic(), copy linkage_metas);
let mut name = None;
let mut vers = None;
let mut cmh_items = ~[];
let linkage_metas = attr::find_linkage_metas(c.node.attrs);
attr::require_unique_names(sess.diagnostic(), linkage_metas);
for linkage_metas.each |meta| {
if attr::get_meta_item_name(*meta) == ~"name" {
match attr::get_meta_item_value_str(*meta) {
Some(ref v) => { name = Some((/*bad*/copy *v)); }
// Changing attr would avoid the need for the copy
// here
Some(v) => { name = Some(v.to_managed()); }
None => cmh_items.push(*meta)
}
} else if attr::get_meta_item_name(*meta) == ~"vers" {
match attr::get_meta_item_value_str(*meta) {
Some(ref v) => { vers = Some((/*bad*/copy *v)); }
Some(v) => { vers = Some(v.to_managed()); }
None => cmh_items.push(*meta)
}
} else { cmh_items.push(*meta); }
@ -492,9 +492,8 @@ fn build_link_meta(sess: Session, c: ast::crate, output: &Path,
// This calculates CMH as defined above
fn crate_meta_extras_hash(symbol_hasher: &hash::State,
_crate: ast::crate,
metas: provided_metas,
dep_hashes: ~[~str]) -> ~str {
-cmh_items: ~[@ast::meta_item],
dep_hashes: ~[~str]) -> @str {
fn len_and_str(s: ~str) -> ~str {
return fmt!("%u_%s", str::len(s), s);
}
@ -503,7 +502,7 @@ fn build_link_meta(sess: Session, c: ast::crate, output: &Path,
return len_and_str(pprust::lit_to_str(@l));
}
let cmh_items = attr::sort_meta_items(/*bad*/copy metas.cmh_items);
let cmh_items = attr::sort_meta_items(cmh_items);
symbol_hasher.reset();
for cmh_items.each |m| {
@ -526,52 +525,53 @@ fn build_link_meta(sess: Session, c: ast::crate, output: &Path,
symbol_hasher.write_str(len_and_str(*dh));
}
return truncated_hash_result(symbol_hasher);
// tjc: allocation is unfortunate; need to change core::hash
return truncated_hash_result(symbol_hasher).to_managed();
}
fn warn_missing(sess: Session, name: ~str, default: ~str) {
fn warn_missing(sess: Session, name: &str, default: &str) {
if !sess.building_library { return; }
sess.warn(fmt!("missing crate link meta `%s`, using `%s` as default",
name, default));
}
fn crate_meta_name(sess: Session, _crate: ast::crate,
output: &Path, metas: provided_metas) -> ~str {
return match metas.name {
Some(ref v) => (/*bad*/copy *v),
fn crate_meta_name(sess: Session, output: &Path, -opt_name: Option<@str>)
-> @str {
return match opt_name {
Some(v) => v,
None => {
let name = match output.filestem() {
None => sess.fatal(fmt!("output file name `%s` doesn't\
// to_managed could go away if there was a version of
// filestem that returned an @str
let name = session::expect(sess,
output.filestem(),
|| fmt!("output file name `%s` doesn't\
appear to have a stem",
output.to_str())),
Some(ref s) => (/*bad*/copy *s)
};
// XXX: Bad copy.
warn_missing(sess, ~"name", copy name);
output.to_str())).to_managed();
warn_missing(sess, ~"name", name);
name
}
};
}
fn crate_meta_vers(sess: Session, _crate: ast::crate,
metas: provided_metas) -> ~str {
return match metas.vers {
Some(ref v) => (/*bad*/copy *v),
fn crate_meta_vers(sess: Session, opt_vers: Option<@str>) -> @str {
return match opt_vers {
Some(v) => v,
None => {
let vers = ~"0.0";
// Bad copy.
warn_missing(sess, ~"vers", copy vers);
let vers = @"0.0";
warn_missing(sess, ~"vers", vers);
vers
}
};
}
let provided_metas = provided_link_metas(sess, c);
let name = crate_meta_name(sess, c, output, provided_metas);
let vers = crate_meta_vers(sess, c, provided_metas);
let {name: opt_name, vers: opt_vers,
cmh_items: cmh_items} = provided_link_metas(sess, c);
let name = crate_meta_name(sess, output, move opt_name);
let vers = crate_meta_vers(sess, move opt_vers);
let dep_hashes = cstore::get_dep_hashes(sess.cstore);
let extras_hash =
crate_meta_extras_hash(symbol_hasher, c, provided_metas, dep_hashes);
crate_meta_extras_hash(symbol_hasher, move cmh_items,
dep_hashes);
return {name: name, vers: vers, extras_hash: extras_hash};
}
@ -583,7 +583,7 @@ fn truncated_hash_result(symbol_hasher: &hash::State) -> ~str unsafe {
// This calculates STH for a symbol, as defined above
fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t,
link_meta: link_meta) -> ~str {
link_meta: link_meta) -> @str {
// NB: do *not* use abbrevs here as we want the symbol names
// to be independent of one another in the crate.
@ -593,20 +593,20 @@ fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t,
symbol_hasher.write_str(link_meta.extras_hash);
symbol_hasher.write_str(~"-");
symbol_hasher.write_str(encoder::encoded_ty(tcx, t));
let hash = truncated_hash_result(symbol_hasher);
let mut hash = truncated_hash_result(symbol_hasher);
// Prefix with _ so that it never blends into adjacent digits
return ~"_" + hash;
str::unshift_char(&mut hash, '_');
// tjc: allocation is unfortunate; need to change core::hash
hash.to_managed()
}
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) {
Some(ref h) => return (/*bad*/copy *h),
Some(h) => h,
None => {
let hash = symbol_hash(ccx.tcx, ccx.symbol_hasher, t, ccx.link_meta);
// XXX: Bad copy. Prefer `@str`?
ccx.type_hashcodes.insert(t, copy hash);
return hash;
ccx.type_hashcodes.insert(t, hash);
hash
}
}
}
@ -664,30 +664,30 @@ fn mangle(sess: Session, ss: path) -> ~str {
fn exported_name(sess: Session,
+path: path,
+hash: ~str,
+vers: ~str) -> ~str {
hash: &str,
vers: &str) -> ~str {
return mangle(sess,
vec::append_one(
vec::append_one(path, path_name(sess.ident_of(hash))),
path_name(sess.ident_of(vers))));
vec::append_one(
vec::append_one(path, path_name(sess.ident_of(hash.to_owned()))),
path_name(sess.ident_of(vers.to_owned()))));
}
fn mangle_exported_name(ccx: @crate_ctxt, +path: path, t: ty::t) -> ~str {
let hash = get_symbol_hash(ccx, t);
return exported_name(ccx.sess, path,
hash,
/*bad*/copy ccx.link_meta.vers);
ccx.link_meta.vers);
}
fn mangle_internal_name_by_type_only(ccx: @crate_ctxt,
t: ty::t,
+name: ~str) -> ~str {
name: &str) -> ~str {
let s = ppaux::ty_to_short_str(ccx.tcx, t);
let hash = get_symbol_hash(ccx, t);
return mangle(ccx.sess,
~[path_name(ccx.sess.ident_of(name)),
path_name(ccx.sess.ident_of(s)),
path_name(ccx.sess.ident_of(hash))]);
~[path_name(ccx.sess.ident_of(name.to_owned())),
path_name(ccx.sess.ident_of(s)),
path_name(ccx.sess.ident_of(hash.to_owned()))]);
}
fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt,
@ -706,7 +706,7 @@ fn mangle_internal_name_by_seq(ccx: @crate_ctxt, +flav: ~str) -> ~str {
}
fn output_dll_filename(os: session::os, lm: &link_meta) -> ~str {
fn output_dll_filename(os: session::os, lm: link_meta) -> ~str {
let libname = fmt!("%s-%s-%s", lm.name, lm.extras_hash, lm.vers);
let (dll_prefix, dll_suffix) = match os {
session::os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
@ -736,7 +736,7 @@ fn link_binary(sess: Session,
}
let output = if sess.building_library {
let long_libname = output_dll_filename(sess.targ_cfg.os, &lm);
let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
debug!("link_meta.name: %s", lm.name);
debug!("long_libname: %s", long_libname);
debug!("out_filename: %s", out_filename.to_str());

View file

@ -108,8 +108,7 @@ fn default_configuration(sess: Session, +argv0: ~str, input: input) ->
}
fn append_configuration(+cfg: ast::crate_cfg, +name: ~str) -> ast::crate_cfg {
// XXX: Bad copy.
if attr::contains_name(copy cfg, copy name) {
if attr::contains_name(cfg, name) {
return cfg;
} else {
return vec::append_one(cfg, attr::mk_word_item(name));

View file

@ -297,7 +297,7 @@ fn mk_tests(cx: test_ctxt) -> @ast::item {
fn is_std(cx: test_ctxt) -> bool {
let is_std = {
let items = attr::find_linkage_metas(/*bad*/copy cx.crate.node.attrs);
let items = attr::find_linkage_metas(cx.crate.node.attrs);
match attr::last_meta_item_value_str_by_name(items, ~"name") {
Some(~"std") => true,
_ => false

View file

@ -152,5 +152,5 @@ const tag_lang_items_item: uint = 0x73;
const tag_lang_items_item_id: uint = 0x74;
const tag_lang_items_item_node_id: uint = 0x75;
type link_meta = {name: ~str, vers: ~str, extras_hash: ~str};
type link_meta = {name: @str, vers: @str, extras_hash: @str};

View file

@ -191,8 +191,7 @@ fn visit_item(e: env, i: @ast::item) {
fn metas_with(+ident: ~str, +key: ~str, +metas: ~[@ast::meta_item])
-> ~[@ast::meta_item] {
// XXX: Bad copies.
let name_items = attr::find_meta_items_by_name(copy metas, copy key);
let name_items = attr::find_meta_items_by_name(metas, key);
if name_items.is_empty() {
vec::append_one(metas, attr::mk_name_value_item_str(key, ident))
} else {

View file

@ -881,7 +881,7 @@ fn encode_info_for_foreign_item(ecx: @encode_ctxt,
}
fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
crate: @crate) -> ~[entry<int>] {
crate: &crate) -> ~[entry<int>] {
let index = @mut ~[];
ebml_w.start_tag(tag_items_data);
index.push({val: crate_node_id, pos: ebml_w.writer.tell()});
@ -1021,20 +1021,20 @@ fn encode_attributes(ebml_w: writer::Encoder, attrs: ~[attribute]) {
// metadata that Rust cares about for linking crates. This attribute requires
// 'name' and 'vers' items, so if the user didn't provide them we will throw
// 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]) ->
attribute {
assert (ecx.link_meta.name != ~"");
assert (ecx.link_meta.vers != ~"");
assert ecx.link_meta.name.is_not_empty();
assert ecx.link_meta.vers.is_not_empty();
let name_item =
attr::mk_name_value_item_str(~"name",
/*bad*/copy ecx.link_meta.name);
ecx.link_meta.name.to_owned());
let vers_item =
attr::mk_name_value_item_str(~"vers",
/*bad*/copy ecx.link_meta.vers);
ecx.link_meta.vers.to_owned());
let other_items =
{
@ -1156,7 +1156,7 @@ fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: writer::Encoder,
ebml_w.end_tag();
}
fn encode_hash(ebml_w: writer::Encoder, hash: ~str) {
fn encode_hash(ebml_w: writer::Encoder, hash: &str) {
ebml_w.start_tag(tag_crate_hash);
ebml_w.writer.write(str::to_bytes(hash));
ebml_w.end_tag();
@ -1169,7 +1169,7 @@ const metadata_encoding_version : &[u8] = &[0x72, //'r' as u8,
0x74, //'t' as u8,
0, 0, 0, 1 ];
fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
fn encode_metadata(parms: encode_parms, crate: &crate) -> ~[u8] {
let wr = @io::BytesWriter();
let stats =
{mut inline_bytes: 0,
@ -1197,7 +1197,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
let ebml_w = writer::Encoder(wr as io::Writer);
encode_hash(ebml_w, /*bad*/copy ecx.link_meta.extras_hash);
encode_hash(ebml_w, ecx.link_meta.extras_hash);
let mut i = wr.pos;
let crate_attrs = synthesize_crate_attrs(ecx, crate);

View file

@ -77,7 +77,7 @@ fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} {
}
fn find_library_crate(cx: ctxt) -> Option<{ident: ~str, data: @~[u8]}> {
attr::require_unique_names(cx.diag, /*bad*/copy cx.metas);
attr::require_unique_names(cx.diag, cx.metas);
find_library_crate_aux(cx, libname(cx), cx.filesearch)
}

View file

@ -106,6 +106,9 @@ priv impl &preserve_ctxt {
let scope_region = if self.root_ub == 0 {
ty::re_static
} else {
// Maybe if we pass in the parent instead here,
// we can prevent the "scope not found" error
debug!("scope_region thing: %? ", cmt.id);
ty::re_scope(self.tcx().region_map.get(cmt.id))
};

View file

@ -2530,7 +2530,7 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
}
}
fn trans_constants(ccx: @crate_ctxt, crate: @ast::crate) {
fn trans_constants(ccx: @crate_ctxt, crate: &ast::crate) {
visit::visit_crate(
*crate, (),
visit::mk_simple_visitor(@visit::SimpleVisitor {
@ -2808,7 +2808,8 @@ fn decl_crate_map(sess: session::Session, mapmeta: link_meta,
let cstore = sess.cstore;
while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; }
let mapname = if sess.building_library {
mapmeta.name + ~"_" + mapmeta.vers + ~"_" + mapmeta.extras_hash
mapmeta.name.to_owned() + ~"_" + mapmeta.vers.to_owned() + ~"_"
+ mapmeta.extras_hash.to_owned()
} else { ~"toplevel" };
let sym_name = ~"_rust_crate_map_" + mapname;
let arrtype = T_array(int_type, n_subcrates as uint);
@ -2881,7 +2882,7 @@ fn crate_ctxt_to_encode_parms(cx: @crate_ctxt) -> encoder::encode_parms {
};
}
fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) {
fn write_metadata(cx: @crate_ctxt, crate: &ast::crate) {
if !cx.sess.building_library { return; }
let encode_parms = crate_ctxt_to_encode_parms(cx);
let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
@ -2919,12 +2920,11 @@ fn trans_crate(sess: session::Session,
tcx: ty::ctxt,
output: &Path,
emap2: resolve::ExportMap2,
maps: astencode::maps)
-> (ModuleRef, link_meta) {
maps: astencode::maps) -> (ModuleRef, link_meta) {
let symbol_hasher = @hash::default_state();
let link_meta =
link::build_link_meta(sess, *crate, output, symbol_hasher);
link::build_link_meta(sess, crate, output, symbol_hasher);
let reachable = reachable::find_reachable(crate.node.module, emap2, tcx,
maps.method_map);
@ -2936,7 +2936,7 @@ fn trans_crate(sess: session::Session,
// crashes if the module identifer is same as other symbols
// such as a function name in the module.
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
let llmod_id = link_meta.name + ~".rc";
let llmod_id = link_meta.name.to_owned() + ~".rc";
unsafe {
let llmod = str::as_c_str(llmod_id, |buf| {
@ -2985,7 +2985,7 @@ fn trans_crate(sess: session::Session,
reachable: reachable,
item_symbols: HashMap(),
mut main_fn: None::<ValueRef>,
link_meta: copy link_meta, // XXX: Bad copy.
link_meta: link_meta,
enum_sizes: ty::new_ty_hash(),
discrims: HashMap(),
discrim_symbols: HashMap(),

View file

@ -200,7 +200,7 @@ struct crate_ctxt {
names: namegen,
next_addrspace: addrspace_gen,
symbol_hasher: @hash::State,
type_hashcodes: HashMap<ty::t, ~str>,
type_hashcodes: HashMap<ty::t, @str>,
type_short_names: HashMap<ty::t, ~str>,
all_llvm_symbols: Set<~str>,
tcx: ty::ctxt,

View file

@ -173,7 +173,7 @@ fn trans_log(log_ex: @ast::expr,
}
let modpath = vec::append(
~[path_mod(ccx.sess.ident_of(/*bad*/copy ccx.link_meta.name))],
~[path_mod(ccx.sess.ident_of(ccx.link_meta.name.to_owned()))],
bcx.fcx.path.filtered(|e|
match *e { path_mod(_) => true, _ => false }
));

View file

@ -2284,10 +2284,10 @@ fn type_kind_ext(cx: ctxt, ty: t, allow_ty_var: bool) -> Kind {
ty_enum(did, ref substs) => {
let mut lowest = kind_top();
let variants = enum_variants(cx, did);
if vec::len(*variants) == 0u {
if variants.is_empty() {
lowest = kind_owned_only() | kind_durable();
} else {
for vec::each(*variants) |variant| {
for variants.each |variant| {
for variant.args.each |aty| {
// Perform any type parameter substitutions.
let arg_ty = subst(cx, substs, *aty);

View file

@ -70,7 +70,7 @@ export require_unique_names;
/* Constructors */
fn mk_name_value_item_str(name: ~str, +value: ~str) ->
fn mk_name_value_item_str(name: ~str, value: ~str) ->
@ast::meta_item {
let value_lit = dummy_spanned(ast::lit_str(@value));
return mk_name_value_item(name, value_lit);
@ -193,14 +193,15 @@ fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) ->
}
/// Search a list of meta items and return only those with a specific name
fn find_meta_items_by_name(metas: ~[@ast::meta_item], name: ~str) ->
fn find_meta_items_by_name(metas: &[@ast::meta_item], name: &str) ->
~[@ast::meta_item] {
let filter = fn@(m: &@ast::meta_item) -> Option<@ast::meta_item> {
if get_meta_item_name(*m) == name {
option::Some(*m)
} else { option::None }
};
return vec::filter_map(metas, filter);
let mut rs = ~[];
for metas.each |mi| {
if name == get_meta_item_name(*mi) {
rs.push(*mi)
}
}
rs
}
/**
@ -237,7 +238,7 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool {
}
}
fn contains_name(metas: ~[@ast::meta_item], name: ~str) -> bool {
fn contains_name(metas: &[@ast::meta_item], name: &str) -> bool {
let matches = find_meta_items_by_name(metas, name);
return vec::len(matches) > 0u;
}
@ -323,7 +324,7 @@ fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) ->
* From a list of crate attributes get only the meta_items that affect crate
* linkage
*/
fn find_linkage_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] {
fn find_linkage_metas(attrs: &[ast::attribute]) -> ~[@ast::meta_item] {
do find_attrs_by_name(attrs, ~"link").flat_map |attr| {
match attr.node.value.node {
ast::meta_list(_, items) => /* FIXME (#2543) */ copy items,
@ -389,7 +390,7 @@ fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr {
fn require_unique_names(diagnostic: span_handler,
metas: ~[@ast::meta_item]) {
metas: &[@ast::meta_item]) {
let map = map::HashMap();
for metas.each |meta| {
let name = get_meta_item_name(*meta);