From 2f42b14b4f57d602ffa446a8f30840c2dcbeb127 Mon Sep 17 00:00:00 2001 From: Haitao Li Date: Fri, 6 Apr 2012 18:45:49 +0800 Subject: [PATCH] Use version and hash in crate_map name Related issue #2137 --- src/rustc/metadata/cstore.rs | 16 +++++++++++++++- src/rustc/middle/trans/base.rs | 14 +++++++++----- src/test/auxiliary/crateresolve3-1.rs | 6 ++++++ src/test/auxiliary/crateresolve3-2.rs | 6 ++++++ src/test/run-pass/crateresolve3.rs | 21 +++++++++++++++++++++ 5 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 src/test/auxiliary/crateresolve3-1.rs create mode 100644 src/test/auxiliary/crateresolve3-2.rs create mode 100644 src/test/run-pass/crateresolve3.rs diff --git a/src/rustc/metadata/cstore.rs b/src/rustc/metadata/cstore.rs index c9a944b320914..fd7f82a7bc787 100644 --- a/src/rustc/metadata/cstore.rs +++ b/src/rustc/metadata/cstore.rs @@ -3,7 +3,7 @@ import std::map; import std::map::hashmap; -import syntax::ast; +import syntax::{ast, attr}; import util::common::*; export cstore::{}; @@ -12,6 +12,8 @@ export crate_metadata; export mk_cstore; export get_crate_data; export set_crate_data; +export get_crate_hash; +export get_crate_vers; export have_crate_data; export iter_crate_data; export add_used_crate_file; @@ -79,6 +81,18 @@ fn get_crate_data(cstore: cstore, cnum: ast::crate_num) -> crate_metadata { ret p(cstore).metas.get(cnum); } +fn get_crate_hash(cstore: cstore, cnum: ast::crate_num) -> str { + let cdata = get_crate_data(cstore, cnum); + ret decoder::get_crate_hash(cdata.data); +} + +fn get_crate_vers(cstore: cstore, cnum: ast::crate_num) -> str { + let cdata = get_crate_data(cstore, cnum); + let attrs = decoder::get_crate_attributes(cdata.data); + ret option::get(attr::meta_item_value_from_list( + attr::find_linkage_metas(attrs), "vers")); +} + fn set_crate_data(cstore: cstore, cnum: ast::crate_num, data: crate_metadata) { p(cstore).metas.insert(cnum, data); diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 468d34c001067..1c195024ed4ab 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -4748,14 +4748,16 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef { } -fn decl_crate_map(sess: session::session, mapname: str, +fn decl_crate_map(sess: session::session, mapmeta: link::link_meta, llmod: ModuleRef) -> ValueRef { let targ_cfg = sess.targ_cfg; let int_type = T_int(targ_cfg); let mut n_subcrates = 1; let cstore = sess.cstore; while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; } - let mapname = if sess.building_library { mapname } else { "toplevel" }; + let mapname = if sess.building_library { + mapmeta.name + "_" + mapmeta.vers + "_" + mapmeta.extras_hash + } else { "toplevel" }; let sym_name = "_rust_crate_map_" + mapname; let arrtype = T_array(int_type, n_subcrates as uint); let maptype = T_struct([int_type, arrtype]); @@ -4766,13 +4768,15 @@ fn decl_crate_map(sess: session::session, mapname: str, ret map; } -// FIXME use hashed metadata instead of crate names once we have that fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) { let mut subcrates: [ValueRef] = []; let mut i = 1; let cstore = ccx.sess.cstore; while cstore::have_crate_data(cstore, i) { - let nm = "_rust_crate_map_" + cstore::get_crate_data(cstore, i).name; + let cdata = cstore::get_crate_data(cstore, i); + let nm = "_rust_crate_map_" + cdata.name + + "_" + cstore::get_crate_vers(cstore, i) + + "_" + cstore::get_crate_hash(cstore, i); let cr = str::as_c_str(nm, {|buf| llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) }); @@ -4857,7 +4861,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, lib::llvm::associate_type(tn, "taskptr", taskptr_type); let tydesc_type = T_tydesc(targ_cfg); lib::llvm::associate_type(tn, "tydesc", tydesc_type); - let crate_map = decl_crate_map(sess, link_meta.name, llmod); + let crate_map = decl_crate_map(sess, link_meta, llmod); let dbg_cx = if sess.opts.debuginfo { option::some(debuginfo::mk_ctxt(llmod_id)) } else { diff --git a/src/test/auxiliary/crateresolve3-1.rs b/src/test/auxiliary/crateresolve3-1.rs new file mode 100644 index 0000000000000..a2315e4c74992 --- /dev/null +++ b/src/test/auxiliary/crateresolve3-1.rs @@ -0,0 +1,6 @@ +#[link(name = "crateresolve3", + vers = "0.1")]; + +#[crate_type = "lib"]; + +fn f() -> int { 10 } diff --git a/src/test/auxiliary/crateresolve3-2.rs b/src/test/auxiliary/crateresolve3-2.rs new file mode 100644 index 0000000000000..2e3684c340f4e --- /dev/null +++ b/src/test/auxiliary/crateresolve3-2.rs @@ -0,0 +1,6 @@ +#[link(name = "crateresolve3", + vers = "0.2")]; + +#[crate_type = "lib"]; + +fn g() -> int { 20 } diff --git a/src/test/run-pass/crateresolve3.rs b/src/test/run-pass/crateresolve3.rs new file mode 100644 index 0000000000000..29d4c0c368f8d --- /dev/null +++ b/src/test/run-pass/crateresolve3.rs @@ -0,0 +1,21 @@ +// xfail-fast +// aux-build:crateresolve3-1.rs +// aux-build:crateresolve3-2.rs + +// verify able to link with crates with same name but different versions +// as long as no name collision on invoked functions. + +mod a { + use crateresolve3(vers = "0.1"); + fn f() { assert crateresolve3::f() == 10; } +} + +mod b { + use crateresolve3(vers = "0.2"); + fn f() { assert crateresolve3::g() == 20; } +} + +fn main() { + a::f(); + b::f(); +}