diff --git a/mk/tests.mk b/mk/tests.mk index 6776345ec2b38..97c47178feb91 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -394,7 +394,8 @@ $(3)/stage$(1)/test/rustdoctest-$(2)$$(X_$(2)): \ $$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS) \ $$(SREQ$(1)_T_$(2)_H_$(3)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2)) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2)) + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2)) \ + $$(SUNDOWN_LIB_$(2)) @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \ -L $$(SUNDOWN_DIR_$(2)) diff --git a/src/driver/driver.rs b/src/driver/driver.rs index bfd623a28da32..9402578d5525a 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -9,15 +9,15 @@ // except according to those terms. #[cfg(rustpkg)] -extern mod this(name = "rustpkg"); +extern mod this = "rustpkg"; #[cfg(rustdoc)] -extern mod this(name = "rustdoc"); +extern mod this = "rustdoc"; #[cfg(rustc)] -extern mod this(name = "rustc"); +extern mod this = "rustc"; #[cfg(rustdoc_ng)] -extern mod this(name = "rustdoc_ng"); +extern mod this = "rustdoc_ng"; fn main() { this::main() } diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py index 5815e5448aee1..afecf0875c053 100755 --- a/src/etc/combine-tests.py +++ b/src/etc/combine-tests.py @@ -42,6 +42,7 @@ def scrub(b): c = open("tmp/run_pass_stage2.rc", "w") i = 0 c.write("// AUTO-GENERATED FILE: DO NOT EDIT\n") +c.write("#[pkgid=\"run_pass_stage2#0.1\"];\n") c.write("#[link(name=\"run_pass_stage2\", vers=\"0.1\")];\n") c.write("#[feature(globs, macro_rules, struct_variant, managed_boxes)];\n") c.write("#[allow(attribute_usage)];\n") diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs index ca2b76b620a96..6532ae3dc5cb0 100644 --- a/src/libextra/lib.rs +++ b/src/libextra/lib.rs @@ -20,6 +20,8 @@ Rust extras are part of the standard Rust distribution. */ +#[pkgid="extra#0.9-pre"]; +// NOTE: remove after the next snapshot #[link(name = "extra", package_id = "extra", vers = "0.9-pre", diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 451213ab694f7..786b463c37ec2 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -24,11 +24,10 @@ use middle::trans::common::gensym_name; use middle::ty; use util::common::time; use util::ppaux; +use util::sha2::{Digest, Sha256}; use std::c_str::ToCStr; use std::char; -use std::hash::Streaming; -use std::hash; use std::os::consts::{macos, freebsd, linux, android, win32}; use std::ptr; use std::run; @@ -39,8 +38,8 @@ use syntax::abi; use syntax::ast; use syntax::ast_map::{path, path_mod, path_name, path_pretty_name}; use syntax::attr; -use syntax::attr::{AttrMetaMethods}; -use syntax::print::pprust; +use syntax::attr::AttrMetaMethods; +use syntax::pkgid::PkgId; #[deriving(Clone, Eq)] pub enum output_type { @@ -52,10 +51,6 @@ pub enum output_type { output_type_exe, } -fn write_string(writer: &mut W, string: &str) { - writer.write(string.as_bytes()); -} - pub fn llvm_err(sess: Session, msg: ~str) -> ! { unsafe { let cstr = llvm::LLVMRustGetLastError(); @@ -413,7 +408,7 @@ pub mod write { * - Symbols with the same name but different types need to get different * linkage-names. We do this by hashing a string-encoding of the type into * a fixed-size (currently 16-byte hex) cryptographic hash function (CHF: - * we use SHA1) to "prevent collisions". This is not airtight but 16 hex + * we use SHA256) to "prevent collisions". This is not airtight but 16 hex * digits on uniform probability means you're going to need 2**32 same-name * symbols in the same process before you're even hitting birthday-paradox * collision probability. @@ -421,209 +416,82 @@ pub mod write { * - Symbols in different crates but with same names "within" the crate need * to get different linkage-names. * - * So here is what we do: + * - The hash shown in the filename needs to be predictable and stable for + * build tooling integration. It also needs to be using a hash function + * which is easy to use from Python, make, etc. * - * - Separate the meta tags into two sets: exported and local. Only work with - * the exported ones when considering linkage. + * So here is what we do: * - * - Consider two exported tags as special (and mandatory): name and vers. - * Every crate gets them; if it doesn't name them explicitly we infer them - * as basename(crate) and "0.1", respectively. Call these CNAME, CVERS. + * - Consider the package id; every crate has one (specified with pkgid + * attribute). If a package id isn't provided explicitly, we infer a + * versionless one from the output name. The version will end up being 0.0 + * in this case. CNAME and CVERS are taken from this package id. For + * example, github.com/mozilla/CNAME#CVERS. * - * - Define CMETA as all the non-name, non-vers exported meta tags in the - * crate (in sorted order). + * - Define CMH as SHA256(pkgid). * - * - Define CMH as hash(CMETA + hashes of dependent crates). + * - Define CMH8 as the first 8 characters of CMH. * - * - Compile our crate to lib CNAME-CMH-CVERS.so + * - Compile our crate to lib CNAME-CMH8-CVERS.so * - * - Define STH(sym) as hash(CNAME, CMH, type_str(sym)) + * - Define STH(sym) as SHA256(CMH, type_str(sym)) * * - Suffix a mangled sym with ::STH@CVERS, so that it is unique in the * name, non-name metadata, and type sense, and versioned in the way * system linkers understand. - * */ pub fn build_link_meta(sess: Session, c: &ast::Crate, output: &Path, - symbol_hasher: &mut hash::State) + symbol_hasher: &mut Sha256) -> LinkMeta { - struct ProvidedMetas { - name: Option<@str>, - vers: Option<@str>, - pkg_id: Option<@str>, - cmh_items: ~[@ast::MetaItem] - } - - fn provided_link_metas(sess: Session, c: &ast::Crate) -> - ProvidedMetas { - let mut name = None; - let mut vers = None; - let mut pkg_id = None; - let mut cmh_items = ~[]; - let linkage_metas = attr::find_linkage_metas(c.attrs); - attr::require_unique_names(sess.diagnostic(), linkage_metas); - for meta in linkage_metas.iter() { - match meta.name_str_pair() { - Some((n, value)) if "name" == n => name = Some(value), - Some((n, value)) if "vers" == n => vers = Some(value), - Some((n, value)) if "package_id" == n => pkg_id = Some(value), - _ => cmh_items.push(*meta) - } - } - - ProvidedMetas { - name: name, - vers: vers, - pkg_id: pkg_id, - cmh_items: cmh_items - } - } - // This calculates CMH as defined above - fn crate_meta_extras_hash(symbol_hasher: &mut hash::State, - cmh_items: ~[@ast::MetaItem], - dep_hashes: ~[@str], - pkg_id: Option<@str>) -> @str { - fn len_and_str(s: &str) -> ~str { - format!("{}_{}", s.len(), s) - } - - fn len_and_str_lit(l: ast::lit) -> ~str { - len_and_str(pprust::lit_to_str(&l)) - } - - let cmh_items = attr::sort_meta_items(cmh_items); - - fn hash(symbol_hasher: &mut hash::State, m: &@ast::MetaItem) { - match m.node { - ast::MetaNameValue(key, value) => { - write_string(symbol_hasher, len_and_str(key)); - write_string(symbol_hasher, len_and_str_lit(value)); - } - ast::MetaWord(name) => { - write_string(symbol_hasher, len_and_str(name)); - } - ast::MetaList(name, ref mis) => { - write_string(symbol_hasher, len_and_str(name)); - for m_ in mis.iter() { - hash(symbol_hasher, m_); - } - } - } - } - + fn crate_hash(symbol_hasher: &mut Sha256, pkgid: &PkgId) -> @str { symbol_hasher.reset(); - for m in cmh_items.iter() { - hash(symbol_hasher, m); - } - - for dh in dep_hashes.iter() { - write_string(symbol_hasher, len_and_str(*dh)); - } - - for p in pkg_id.iter() { - write_string(symbol_hasher, len_and_str(*p)); - } - - return truncated_hash_result(symbol_hasher).to_managed(); - } - - fn warn_missing(sess: Session, name: &str, default: &str) { - if !*sess.building_library { return; } - sess.warn(format!("missing crate link meta `{}`, using `{}` as default", - name, default)); - } - - fn crate_meta_name(sess: Session, output: &Path, opt_name: Option<@str>) - -> @str { - match opt_name { - Some(v) if !v.is_empty() => v, - _ => { - // to_managed could go away if there was a version of - // filestem that returned an @str - // FIXME (#9639): Non-utf8 filenames will give a misleading error - let name = session::expect(sess, - output.filestem_str(), - || format!("output file name `{}` doesn't\ - appear to have a stem", - output.display())).to_managed(); - if name.is_empty() { - sess.fatal("missing crate link meta `name`, and the \ - inferred name is blank"); - } - warn_missing(sess, "name", name); - name - } - } + symbol_hasher.input_str(pkgid.to_str()); + truncated_hash_result(symbol_hasher).to_managed() } - fn crate_meta_vers(sess: Session, opt_vers: Option<@str>) -> @str { - match opt_vers { - Some(v) if !v.is_empty() => v, - _ => { - let vers = @"0.0"; - warn_missing(sess, "vers", vers); - vers - } + let pkgid = match attr::find_pkgid(c.attrs) { + None => { + let stem = session::expect( + sess, + output.filestem_str(), + || format!("output file name '{}' doesn't appear to have a stem", + output.display())); + from_str(stem).unwrap() } - } - - fn crate_meta_pkgid(sess: Session, name: @str, opt_pkg_id: Option<@str>) - -> @str { - match opt_pkg_id { - Some(v) if !v.is_empty() => v, - _ => { - let pkg_id = name.clone(); - warn_missing(sess, "package_id", pkg_id); - pkg_id - } - } - } + Some(s) => s, + }; - let ProvidedMetas { - name: opt_name, - vers: opt_vers, - pkg_id: opt_pkg_id, - cmh_items: cmh_items - } = provided_link_metas(sess, c); - let name = crate_meta_name(sess, output, opt_name); - let vers = crate_meta_vers(sess, opt_vers); - let pkg_id = crate_meta_pkgid(sess, name, opt_pkg_id); - let dep_hashes = cstore::get_dep_hashes(sess.cstore); - let extras_hash = - crate_meta_extras_hash(symbol_hasher, cmh_items, - dep_hashes, Some(pkg_id)); + let hash = crate_hash(symbol_hasher, &pkgid); LinkMeta { - name: name, - vers: vers, - package_id: Some(pkg_id), - extras_hash: extras_hash + pkgid: pkgid, + crate_hash: hash, } } -pub fn truncated_hash_result(symbol_hasher: &mut hash::State) -> ~str { +pub fn truncated_hash_result(symbol_hasher: &mut Sha256) -> ~str { symbol_hasher.result_str() } // This calculates STH for a symbol, as defined above pub fn symbol_hash(tcx: ty::ctxt, - symbol_hasher: &mut hash::State, + symbol_hasher: &mut Sha256, t: ty::t, - link_meta: LinkMeta) -> @str { + link_meta: &LinkMeta) -> @str { // NB: do *not* use abbrevs here as we want the symbol names // to be independent of one another in the crate. symbol_hasher.reset(); - write_string(symbol_hasher, link_meta.name); - write_string(symbol_hasher, "-"); - write_string(symbol_hasher, link_meta.extras_hash); - write_string(symbol_hasher, "-"); - write_string(symbol_hasher, encoder::encoded_ty(tcx, t)); + symbol_hasher.input_str(link_meta.pkgid.name); + symbol_hasher.input_str("-"); + symbol_hasher.input_str(link_meta.crate_hash); + symbol_hasher.input_str("-"); + symbol_hasher.input_str(encoder::encoded_ty(tcx, t)); let mut hash = truncated_hash_result(symbol_hasher); // Prefix with 'h' so that it never blends into adjacent digits hash.unshift_char('h'); @@ -635,7 +503,7 @@ pub fn get_symbol_hash(ccx: &mut CrateContext, t: ty::t) -> @str { match ccx.type_hashcodes.find(&t) { Some(&h) => h, None => { - let hash = symbol_hash(ccx.tcx, &mut ccx.symbol_hasher, t, ccx.link_meta); + let hash = symbol_hash(ccx.tcx, &mut ccx.symbol_hasher, t, &ccx.link_meta); ccx.type_hashcodes.insert(t, hash); hash } @@ -774,7 +642,7 @@ pub fn mangle_exported_name(ccx: &mut CrateContext, let hash = get_symbol_hash(ccx, t); return exported_name(ccx.sess, path, hash, - ccx.link_meta.vers); + ccx.link_meta.pkgid.version_or_default()); } pub fn mangle_internal_name_by_type_only(ccx: &mut CrateContext, @@ -813,8 +681,11 @@ pub fn mangle_internal_name_by_path(ccx: &mut CrateContext, path: path) -> ~str mangle(ccx.sess, path, None, None) } -pub fn output_lib_filename(lm: LinkMeta) -> ~str { - format!("{}-{}-{}", lm.name, lm.extras_hash, lm.vers) +pub fn output_lib_filename(lm: &LinkMeta) -> ~str { + format!("{}-{}-{}", + lm.pkgid.name, + lm.crate_hash.slice_chars(0, 8), + lm.pkgid.version_or_default()) } pub fn get_cc_prog(sess: Session) -> ~str { @@ -848,7 +719,8 @@ pub fn get_cc_prog(sess: Session) -> ~str { pub fn link_binary(sess: Session, trans: &CrateTranslation, obj_filename: &Path, - out_filename: &Path) { + out_filename: &Path, + lm: &LinkMeta) { // If we're generating a test executable, then ignore all other output // styles at all other locations let outputs = if sess.opts.test { @@ -858,7 +730,7 @@ pub fn link_binary(sess: Session, }; for output in outputs.move_iter() { - link_binary_output(sess, trans, output, obj_filename, out_filename); + link_binary_output(sess, trans, output, obj_filename, out_filename, lm); } // Remove the temporary object file and metadata if we aren't saving temps @@ -881,8 +753,9 @@ fn link_binary_output(sess: Session, trans: &CrateTranslation, output: session::OutputStyle, obj_filename: &Path, - out_filename: &Path) { - let libname = output_lib_filename(trans.link); + out_filename: &Path, + lm: &LinkMeta) { + let libname = output_lib_filename(lm); let out_filename = match output { session::OutputRlib => { out_filename.with_filename(format!("lib{}.rlib", libname)) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index c0ee53da97053..ec0424994075d 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -389,7 +389,8 @@ pub fn phase_6_link_output(sess: Session, link::link_binary(sess, trans, &outputs.obj_filename, - &outputs.out_filename)); + &outputs.out_filename, + &trans.link)); } pub fn stop_after_phase_3(sess: Session) -> bool { @@ -977,17 +978,13 @@ pub fn build_output_filenames(input: &input, str_input(_) => @"rust_out" }; - // If a linkage name meta is present, we use it as the link name - let linkage_metas = attr::find_linkage_metas(attrs); - if !linkage_metas.is_empty() { - // But if a linkage meta is present, that overrides - let maybe_name = linkage_metas.iter().find(|m| "name" == m.name()); - match maybe_name.and_then(|m| m.value_str()) { - Some(s) => stem = s, - _ => () + // If a pkgid is present, we use it as the link name + let pkgid = attr::find_pkgid(attrs); + match pkgid { + None => {} + Some(pkgid) => { + stem = pkgid.name.to_managed() } - // If the name is missing, we just default to the filename - // version } if *sess.building_library { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 3de33e13ecc19..090329bc4a09b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="rustc#0.9-pre"]; +// NOTE: remove after the next snapshot #[link(name = "rustc", package_id = "rustc", vers = "0.9-pre", @@ -109,6 +111,7 @@ pub mod driver; pub mod util { pub mod common; pub mod ppaux; + pub mod sha2; } pub mod lib { diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index f6eadfcc916e5..bd6794b1d9ff7 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -7,7 +7,9 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. + use std::cast; +use syntax::pkgid::PkgId; // EBML enum definitions and utils shared by the encoder and decoder @@ -202,10 +204,8 @@ pub static tag_native_libraries_lib: uint = 0x104; pub static tag_native_libraries_name: uint = 0x105; pub static tag_native_libraries_kind: uint = 0x106; +#[deriving(Clone)] pub struct LinkMeta { - name: @str, - vers: @str, - // Optional package ID - package_id: Option<@str>, // non-None if this was a URL-like package ID - extras_hash: @str + pkgid: PkgId, + crate_hash: @str, } diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 67b684a2c514c..955ba54a404fd 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -17,7 +17,6 @@ use metadata::loader; use std::hashmap::HashMap; use syntax::ast; -use std::vec; use syntax::abi; use syntax::attr; use syntax::attr::AttrMetaMethods; @@ -25,6 +24,7 @@ use syntax::codemap::{Span, dummy_sp}; use syntax::diagnostic::span_handler; use syntax::parse::token; use syntax::parse::token::ident_interner; +use syntax::pkgid::PkgId; use syntax::visit; // Traverses an AST, reading all the information about use'd crates and extern @@ -64,7 +64,7 @@ struct cache_entry { cnum: ast::CrateNum, span: Span, hash: @str, - metas: @~[@ast::MetaItem] + pkgid: PkgId, } fn dump_crates(crate_cache: &[cache_entry]) { @@ -80,12 +80,10 @@ fn warn_if_multiple_versions(e: @mut Env, diag: @mut span_handler, crate_cache: &[cache_entry]) { if crate_cache.len() != 0u { - let name = loader::crate_name_from_metas( - *crate_cache[crate_cache.len() - 1].metas - ); + let name = crate_cache[crate_cache.len() - 1].pkgid.name.clone(); let (matches, non_matches) = crate_cache.partitioned(|entry| - name == loader::crate_name_from_metas(*entry.metas)); + name == entry.pkgid.name); assert!(!matches.is_empty()); @@ -94,11 +92,7 @@ fn warn_if_multiple_versions(e: @mut Env, format!("using multiple versions of crate `{}`", name)); for match_ in matches.iter() { diag.span_note(match_.span, "used here"); - let attrs = ~[ - attr::mk_attr(attr::mk_list_item(@"link", - (*match_.metas).clone())) - ]; - loader::note_linkage_attrs(e.intr, diag, attrs); + loader::note_pkgid_attr(diag, &match_.pkgid); } } @@ -129,28 +123,30 @@ fn visit_crate(e: &Env, c: &ast::Crate) { fn visit_view_item(e: @mut Env, i: &ast::view_item) { match i.node { - ast::view_item_extern_mod(ident, path_opt, ref meta_items, id) => { + ast::view_item_extern_mod(ident, path_opt, _, id) => { let ident = token::ident_to_str(&ident); - let meta_items = match path_opt { - None => meta_items.clone(), - Some((p, _path_str_style)) => { - let p_path = Path::new(p); - match p_path.filestem_str() { - None|Some("") => - e.sess.span_bug(i.span, "Bad package path in `extern mod` item"), - Some(s) => - vec::append( - ~[attr::mk_name_value_item_str(@"package_id", p), - attr::mk_name_value_item_str(@"name", s.to_managed())], - *meta_items) + debug!("resolving extern mod stmt. ident: {:?} path_opt: {:?}", + ident, path_opt); + let (name, version) = match path_opt { + Some((path_str, _)) => { + let pkgid: Option = from_str(path_str); + match pkgid { + None => (@"", @""), + Some(pkgid) => { + let version = match pkgid.version { + None => @"", + Some(ref ver) => ver.to_managed(), + }; + (pkgid.name.to_managed(), version) + } } - } + } + None => (ident, @""), }; - debug!("resolving extern mod stmt. ident: {:?}, meta: {:?}", - ident, meta_items); let cnum = resolve_crate(e, ident, - meta_items, + name, + version, @"", i.span); cstore::add_extern_mod_stmt_cnum(e.sess.cstore, id, cnum); @@ -233,46 +229,36 @@ fn visit_item(e: &Env, i: @ast::item) { } } -fn metas_with(ident: @str, key: @str, mut metas: ~[@ast::MetaItem]) - -> ~[@ast::MetaItem] { - // Check if key isn't there yet. - if !attr::contains_name(metas, key) { - metas.push(attr::mk_name_value_item_str(key, ident)); - } - metas -} - -fn metas_with_ident(ident: @str, metas: ~[@ast::MetaItem]) - -> ~[@ast::MetaItem] { - metas_with(ident, @"name", metas) -} - -fn existing_match(e: &Env, metas: &[@ast::MetaItem], hash: &str) - -> Option { +fn existing_match(e: &Env, name: @str, version: @str, hash: &str) -> Option { for c in e.crate_cache.iter() { - if loader::metadata_matches(*c.metas, metas) - && (hash.is_empty() || c.hash.as_slice() == hash) { + let pkgid_version = match c.pkgid.version { + None => @"0.0", + Some(ref ver) => ver.to_managed(), + }; + if (name.is_empty() || c.pkgid.name.to_managed() == name) && + (version.is_empty() || pkgid_version == version) && + (hash.is_empty() || c.hash.as_slice() == hash) { return Some(c.cnum); } } - return None; + None } fn resolve_crate(e: @mut Env, ident: @str, - metas: ~[@ast::MetaItem], + name: @str, + version: @str, hash: @str, span: Span) -> ast::CrateNum { - let metas = metas_with_ident(ident, metas); - - match existing_match(e, metas, hash) { + match existing_match(e, name, version, hash) { None => { let load_ctxt = loader::Context { sess: e.sess, span: span, ident: ident, - metas: metas, + name: name, + version: version, hash: hash, os: e.os, intr: e.intr @@ -282,7 +268,7 @@ fn resolve_crate(e: @mut Env, } = load_ctxt.load_library_crate(); let attrs = decoder::get_crate_attributes(metadata); - let linkage_metas = attr::find_linkage_metas(attrs); + let pkgid = attr::find_pkgid(attrs).unwrap(); let hash = decoder::get_crate_hash(metadata); // Claim this crate number and cache it @@ -291,21 +277,15 @@ fn resolve_crate(e: @mut Env, cnum: cnum, span: span, hash: hash, - metas: @linkage_metas + pkgid: pkgid, }); e.next_crate_num += 1; // Now resolve the crates referenced by this crate let cnum_map = resolve_crate_deps(e, metadata); - let cname = - match attr::last_meta_item_value_str_by_name(load_ctxt.metas, - "name") { - Some(v) => v, - None => ident - }; let cmeta = @cstore::crate_metadata { - name: cname, + name: name, data: metadata, cnum_map: cnum_map, cnum: cnum @@ -336,12 +316,9 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map { for dep in r.iter() { let extrn_cnum = dep.cnum; let cname_str = token::ident_to_str(&dep.name); - let cmetas = metas_with(dep.vers, @"vers", ~[]); debug!("resolving dep crate {} ver: {} hash: {}", cname_str, dep.vers, dep.hash); - match existing_match(e, - metas_with_ident(cname_str, cmetas.clone()), - dep.hash) { + match existing_match(e, cname_str, dep.vers, dep.hash) { Some(local_cnum) => { debug!("already have it"); // We've already seen this crate @@ -353,8 +330,8 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map { // FIXME (#2404): Need better error reporting than just a bogus // span. let fake_span = dummy_sp(); - let local_cnum = resolve_crate(e, cname_str, cmetas, dep.hash, - fake_span); + let local_cnum = resolve_crate(e, cname_str, cname_str, dep.vers, + dep.hash, fake_span); cnum_map.insert(extrn_cnum, local_cnum); } } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index c6a1da655aade..dd4df7481d43a 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1171,11 +1171,9 @@ pub fn get_crate_hash(data: @~[u8]) -> @str { pub fn get_crate_vers(data: @~[u8]) -> @str { let attrs = decoder::get_crate_attributes(data); - let linkage_attrs = attr::find_linkage_metas(attrs); - - match attr::last_meta_item_value_str_by_name(linkage_attrs, "vers") { - Some(ver) => ver, - None => @"0.0" + match attr::find_pkgid(attrs) { + None => @"0.0", + Some(pkgid) => pkgid.version_or_default().to_managed(), } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index bf50da3d7892e..209ed5e2d1858 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1482,67 +1482,30 @@ fn encode_attributes(ebml_w: &mut writer::Encoder, attrs: &[Attribute]) { ebml_w.end_tag(); } -// So there's a special crate attribute called 'link' which defines the -// metadata that Rust cares about for linking crates. This attribute requires -// 'name', 'vers' and 'package_id' items, so if the user didn't provide them we -// will throw them in anyway with default values. +// So there's a special crate attribute called 'pkgid' which defines the +// metadata that Rust cares about for linking crates. If the user didn't +// provide it we will throw it in anyway with a default value. fn synthesize_crate_attrs(ecx: &EncodeContext, crate: &Crate) -> ~[Attribute] { - fn synthesize_link_attr(ecx: &EncodeContext, items: ~[@MetaItem]) -> - Attribute { - - assert!(!ecx.link_meta.name.is_empty()); - assert!(!ecx.link_meta.vers.is_empty()); - - let name_item = - attr::mk_name_value_item_str(@"name", - ecx.link_meta.name); - let vers_item = - attr::mk_name_value_item_str(@"vers", - ecx.link_meta.vers); - - let pkgid_item = match ecx.link_meta.package_id { - Some(pkg_id) => attr::mk_name_value_item_str(@"package_id", - pkg_id), - // uses package_id equal to name; - // this should never happen here but package_id is an Option - // FIXME (#10370): change package_id in LinkMeta to @str instead of Option<@str> - _ => attr::mk_name_value_item_str(@"package_id", - ecx.link_meta.name) - }; - - let mut meta_items = ~[name_item, vers_item, pkgid_item]; - - for &mi in items.iter().filter(|mi| "name" != mi.name() && "vers" != mi.name() && - "package_id" != mi.name()) { - meta_items.push(mi); - } - let link_item = attr::mk_list_item(@"link", meta_items); + fn synthesize_pkgid_attr(ecx: &EncodeContext) -> Attribute { + assert!(!ecx.link_meta.pkgid.name.is_empty()); - return attr::mk_attr(link_item); + attr::mk_attr( + attr::mk_name_value_item_str( + @"pkgid", + ecx.link_meta.pkgid.to_str().to_managed())) } let mut attrs = ~[]; - let mut found_link_attr = false; for attr in crate.attrs.iter() { - attrs.push( - if "link" != attr.name() { - *attr - } else { - match attr.meta_item_list() { - Some(l) => { - found_link_attr = true;; - synthesize_link_attr(ecx, l.to_owned()) - } - _ => *attr - } - }); + if "pkgid" != attr.name() { + attrs.push(*attr); + } } + attrs.push(synthesize_pkgid_attr(ecx)); - if !found_link_attr { attrs.push(synthesize_link_attr(ecx, ~[])); } - - return attrs; + attrs } fn encode_crate_deps(ecx: &EncodeContext, @@ -1800,7 +1763,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] { let mut ebml_w = writer::Encoder(wr); - encode_hash(&mut ebml_w, ecx.link_meta.extras_hash); + encode_hash(&mut ebml_w, ecx.link_meta.crate_hash); let mut i = wr.tell(); let crate_attrs = synthesize_crate_attrs(&ecx, crate); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 5b1385c757973..dd5d082ddb7c8 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -20,8 +20,8 @@ use metadata::filesearch; use syntax::codemap::Span; use syntax::diagnostic::span_handler; use syntax::parse::token::ident_interner; -use syntax::print::pprust; -use syntax::{ast, attr}; +use syntax::pkgid::PkgId; +use syntax::attr; use syntax::attr::AttrMetaMethods; use std::c_str::ToCStr; @@ -47,7 +47,8 @@ pub struct Context { sess: Session, span: Span, ident: @str, - metas: ~[@ast::MetaItem], + name: @str, + version: @str, hash: @str, os: Os, intr: @ident_interner @@ -72,9 +73,8 @@ impl Context { } fn find_library_crate(&self) -> Option { - attr::require_unique_names(self.sess.diagnostic(), self.metas); let filesearch = self.sess.filesearch; - let crate_name = crate_name_from_metas(self.metas); + let crate_name = self.name; let (dyprefix, dysuffix) = self.dylibname(); // want: crate_name.dir_part() + prefix + crate_name.file_part + "-" @@ -103,9 +103,8 @@ impl Context { } else if candidate { match get_metadata_section(self.sess, self.os, path) { Some(cvec) => - if crate_matches(cvec, self.metas, self.hash) { - debug!("found {} with matching metadata", - path.display()); + if crate_matches(cvec, self.name, self.version, self.hash) { + debug!("found {} with matching pkgid", path.display()); let (rlib, dylib) = if file.ends_with(".rlib") { (Some(path.clone()), None) } else { @@ -118,7 +117,7 @@ impl Context { }); FileMatches } else { - debug!("skipping {}, metadata doesn't match", + debug!("skipping {}, pkgid doesn't match", path.display()); FileDoesntMatch }, @@ -156,7 +155,12 @@ impl Context { None => {} } let attrs = decoder::get_crate_attributes(lib.metadata); - note_linkage_attrs(self.intr, self.sess.diagnostic(), attrs); + match attr::find_pkgid(attrs) { + None => {} + Some(pkgid) => { + note_pkgid_attr(self.sess.diagnostic(), &pkgid); + } + } } self.sess.abort_if_errors(); None @@ -217,56 +221,27 @@ impl Context { } } -pub fn crate_name_from_metas(metas: &[@ast::MetaItem]) -> @str { - for m in metas.iter() { - match m.name_str_pair() { - Some((name, s)) if "name" == name => { return s; } - _ => {} - } - } - fail!("expected to find the crate name") -} - -pub fn package_id_from_metas(metas: &[@ast::MetaItem]) -> Option<@str> { - for m in metas.iter() { - match m.name_str_pair() { - Some((name, s)) if "package_id" == name => { return Some(s); } - _ => {} - } - } - None -} - -pub fn note_linkage_attrs(intr: @ident_interner, - diag: @mut span_handler, - attrs: ~[ast::Attribute]) { - let r = attr::find_linkage_metas(attrs); - for mi in r.iter() { - diag.handler().note(format!("meta: {}", pprust::meta_item_to_str(*mi,intr))); - } +pub fn note_pkgid_attr(diag: @mut span_handler, + pkgid: &PkgId) { + diag.handler().note(format!("pkgid: {}", pkgid.to_str())); } fn crate_matches(crate_data: @~[u8], - metas: &[@ast::MetaItem], + name: @str, + version: @str, hash: @str) -> bool { let attrs = decoder::get_crate_attributes(crate_data); - let linkage_metas = attr::find_linkage_metas(attrs); - if !hash.is_empty() { - let chash = decoder::get_crate_hash(crate_data); - if chash != hash { return false; } + match attr::find_pkgid(attrs) { + None => false, + Some(pkgid) => { + if !hash.is_empty() { + let chash = decoder::get_crate_hash(crate_data); + if chash != hash { return false; } + } + name == pkgid.name.to_managed() && + (version.is_empty() || version == pkgid.version_or_default().to_managed()) + } } - metadata_matches(linkage_metas, metas) -} - -pub fn metadata_matches(extern_metas: &[@ast::MetaItem], - local_metas: &[@ast::MetaItem]) -> bool { - -// extern_metas: metas we read from the crate -// local_metas: metas we're looking for - debug!("matching {} metadata requirements against {} items", - local_metas.len(), extern_metas.len()); - - local_metas.iter().all(|needed| attr::contains(extern_metas, *needed)) } fn get_metadata_section(sess: Session, os: Os, filename: &Path) -> Option<@~[u8]> { diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 2a69b8226ae91..c3fbc83f0a772 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -816,7 +816,7 @@ fn check_heap_item(cx: &Context, it: &ast::item) { } static crate_attrs: &'static [&'static str] = &[ - "crate_type", "feature", "no_uv", "no_main", "no_std", + "crate_type", "feature", "no_uv", "no_main", "no_std", "pkgid", "desc", "comment", "license", "copyright", // not used in rustc now ]; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 8a89cd35d0e47..b95f4affc847e 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -64,11 +64,10 @@ use middle::trans::value::Value; use middle::ty; use util::common::indenter; use util::ppaux::{Repr, ty_to_str}; - +use util::sha2::Sha256; use middle::trans::type_::Type; use std::c_str::ToCStr; -use std::hash; use std::hashmap::HashMap; use std::libc::c_uint; use std::vec; @@ -2939,8 +2938,8 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, let sym_name = if is_top { ~"_rust_crate_map_toplevel" } else { - symname(sess, "_rust_crate_map_" + mapmeta.name, mapmeta.extras_hash, - mapmeta.vers) + symname(sess, "_rust_crate_map_" + mapmeta.pkgid.name, mapmeta.crate_hash, + mapmeta.pkgid.version_or_default()) }; let slicetype = Type::struct_([int_type, int_type], false); @@ -3059,8 +3058,8 @@ pub fn write_metadata(cx: &CrateContext, crate: &ast::Crate) -> ~[u8] { flate::deflate_bytes(metadata); let llmeta = C_bytes(compressed); let llconst = C_struct([llmeta], false); - let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.name, - cx.link_meta.vers, cx.link_meta.extras_hash); + let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.pkgid.name, + cx.link_meta.pkgid.version_or_default(), cx.link_meta.crate_hash); let llglobal = name.with_c_str(|buf| { unsafe { llvm::LLVMAddGlobal(cx.metadata_llmod, val_ty(llconst).to_ref(), buf) @@ -3084,7 +3083,7 @@ pub fn trans_crate(sess: session::Session, sess.bug("couldn't enable multi-threaded LLVM"); } - let mut symbol_hasher = hash::default_state(); + let mut symbol_hasher = Sha256::new(); let link_meta = link::build_link_meta(sess, &crate, output, &mut symbol_hasher); @@ -3096,7 +3095,7 @@ pub 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.to_owned() + ".rc"; + let llmod_id = link_meta.pkgid.name.clone() + ".rc"; let ccx = @mut CrateContext::new(sess, llmod_id, @@ -3171,7 +3170,7 @@ pub fn trans_crate(sess: session::Session, } let llcx = ccx.llcx; - let link_meta = ccx.link_meta; + let link_meta = ccx.link_meta.clone(); let llmod = ccx.llmod; let mut reachable = ccx.reachable.iter().filter_map(|id| { ccx.item_symbols.find(id).map(|s| s.to_owned()) diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index c483a0f48f8c9..3dbe70ecf690d 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -26,8 +26,9 @@ use middle::ty; use middle::trans::type_::Type; +use util::sha2::Sha256; + use std::c_str::ToCStr; -use std::hash; use std::hashmap::{HashMap, HashSet}; use std::local_data; use std::vec; @@ -98,7 +99,7 @@ pub struct CrateContext { lltypes: HashMap, llsizingtypes: HashMap, adt_reprs: HashMap, - symbol_hasher: hash::State, + symbol_hasher: Sha256, type_hashcodes: HashMap, type_short_names: HashMap, all_llvm_symbols: HashSet<@str>, @@ -126,7 +127,7 @@ impl CrateContext { tcx: ty::ctxt, emap2: resolve::ExportMap2, maps: astencode::Maps, - symbol_hasher: hash::State, + symbol_hasher: Sha256, link_meta: LinkMeta, reachable: @mut HashSet) -> CrateContext { @@ -168,8 +169,7 @@ impl CrateContext { tn.associate_type("tydesc", &tydesc_type); tn.associate_type("str_slice", &str_slice_ty); - let (crate_map_name, crate_map) = decl_crate_map(sess, link_meta, - llmod); + let (crate_map_name, crate_map) = decl_crate_map(sess, link_meta.clone(), llmod); let dbg_cx = if sess.opts.debuginfo { Some(debuginfo::CrateDebugContext::new(llmod, name.to_owned())) } else { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 37346715d2848..8346228e88187 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -2728,7 +2728,7 @@ fn namespace_for_item(cx: &mut CrateContext, if def_id.crate == ast::LOCAL_CRATE { // prepend crate name if not already present - let crate_namespace_ident = token::str_to_ident(cx.link_meta.name); + let crate_namespace_ident = token::str_to_ident(cx.link_meta.pkgid.name); item_path.insert(0, ast_map::path_mod(crate_namespace_ident)); } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index a66e6f90ac763..d5b70284f1117 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1795,7 +1795,7 @@ pub fn trans_log_level(bcx: @mut Block) -> DatumBlock { Some(&src) => { cstore::get_crate_data(ccx.sess.cstore, src.crate).name } - None => ccx.link_meta.name, + None => ccx.link_meta.pkgid.name.to_managed(), }; let mut modpath = ~[path_mod(ccx.sess.ident_of(srccrate))]; for e in bcx.fcx.path.iter() { diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index 110e964bdbc48..f83bdd799598e 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -286,7 +286,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, } "type_id" => { let hash = ty::hash_crate_independent(ccx.tcx, substs.tys[0], - ccx.link_meta.extras_hash); + ccx.link_meta.crate_hash); // NB: This needs to be kept in lockstep with the TypeId struct in // libstd/unstable/intrinsics.rs let val = C_named_struct(type_of::type_of(ccx, output_type), [C_u64(hash)]); diff --git a/src/librustc/util/sha2.rs b/src/librustc/util/sha2.rs new file mode 100644 index 0000000000000..1ac5b73192164 --- /dev/null +++ b/src/librustc/util/sha2.rs @@ -0,0 +1,670 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! This module implements only the Sha256 function since that is all that is needed for internal +//! use. This implementation is not intended for external use or for any use where security is +//! important. + +use std::iter::range_step; +use std::num::Zero; +use std::vec; +use std::vec::bytes::{MutableByteVector, copy_memory}; +use extra::hex::ToHex; + +/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian +/// format. +fn write_u32_be(dst: &mut[u8], input: u32) { + use std::cast::transmute; + use std::unstable::intrinsics::to_be32; + assert!(dst.len() == 4); + unsafe { + let x: *mut i32 = transmute(dst.unsafe_mut_ref(0)); + *x = to_be32(input as i32); + } +} + +/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format. +fn read_u32v_be(dst: &mut[u32], input: &[u8]) { + use std::cast::transmute; + use std::unstable::intrinsics::to_be32; + assert!(dst.len() * 4 == input.len()); + unsafe { + let mut x: *mut i32 = transmute(dst.unsafe_mut_ref(0)); + let mut y: *i32 = transmute(input.unsafe_ref(0)); + dst.len().times(|| { + *x = to_be32(*y); + x = x.offset(1); + y = y.offset(1); + }); + } +} + +trait ToBits { + /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the + /// high-order value and the 2nd item is the low order value. + fn to_bits(self) -> (Self, Self); +} + +impl ToBits for u64 { + fn to_bits(self) -> (u64, u64) { + return (self >> 61, self << 3); + } +} + +/// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric +/// overflow. +fn add_bytes_to_bits(bits: T, bytes: T) -> T { + let (new_high_bits, new_low_bits) = bytes.to_bits(); + + if new_high_bits > Zero::zero() { + fail!("Numeric overflow occured.") + } + + match bits.checked_add(&new_low_bits) { + Some(x) => return x, + None => fail!("Numeric overflow occured.") + } +} + +/// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it +/// must be processed. The input() method takes care of processing and then clearing the buffer +/// automatically. However, other methods do not and require the caller to process the buffer. Any +/// method that modifies the buffer directory or provides the caller with bytes that can be modified +/// results in those bytes being marked as used by the buffer. +trait FixedBuffer { + /// Input a vector of bytes. If the buffer becomes full, process it with the provided + /// function and then clear the buffer. + fn input(&mut self, input: &[u8], func: |&[u8]|); + + /// Reset the buffer. + fn reset(&mut self); + + /// Zero the buffer up until the specified index. The buffer position currently must not be + /// greater than that index. + fn zero_until(&mut self, idx: uint); + + /// Get a slice of the buffer of the specified size. There must be at least that many bytes + /// remaining in the buffer. + fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8]; + + /// Get the current buffer. The buffer must already be full. This clears the buffer as well. + fn full_buffer<'s>(&'s mut self) -> &'s [u8]; + + /// Get the current position of the buffer. + fn position(&self) -> uint; + + /// Get the number of bytes remaining in the buffer until it is full. + fn remaining(&self) -> uint; + + /// Get the size of the buffer + fn size(&self) -> uint; +} + +/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize. +struct FixedBuffer64 { + priv buffer: [u8, ..64], + priv buffer_idx: uint, +} + +impl FixedBuffer64 { + /// Create a new FixedBuffer64 + fn new() -> FixedBuffer64 { + return FixedBuffer64 { + buffer: [0u8, ..64], + buffer_idx: 0 + }; + } +} + +impl FixedBuffer for FixedBuffer64 { + fn input(&mut self, input: &[u8], func: |&[u8]|) { + let mut i = 0; + + let size = self.size(); + + // If there is already data in the buffer, copy as much as we can into it and process + // the data if the buffer becomes full. + if self.buffer_idx != 0 { + let buffer_remaining = size - self.buffer_idx; + if input.len() >= buffer_remaining { + copy_memory( + self.buffer.mut_slice(self.buffer_idx, size), + input.slice_to(buffer_remaining), + buffer_remaining); + self.buffer_idx = 0; + func(self.buffer); + i += buffer_remaining; + } else { + copy_memory( + self.buffer.mut_slice(self.buffer_idx, self.buffer_idx + input.len()), + input, + input.len()); + self.buffer_idx += input.len(); + return; + } + } + + // While we have at least a full buffer size chunks's worth of data, process that data + // without copying it into the buffer + while input.len() - i >= size { + func(input.slice(i, i + size)); + i += size; + } + + // Copy any input data into the buffer. At this point in the method, the ammount of + // data left in the input vector will be less than the buffer size and the buffer will + // be empty. + let input_remaining = input.len() - i; + copy_memory( + self.buffer.mut_slice(0, input_remaining), + input.slice_from(i), + input.len() - i); + self.buffer_idx += input_remaining; + } + + fn reset(&mut self) { + self.buffer_idx = 0; + } + + fn zero_until(&mut self, idx: uint) { + assert!(idx >= self.buffer_idx); + self.buffer.mut_slice(self.buffer_idx, idx).set_memory(0); + self.buffer_idx = idx; + } + + fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] { + self.buffer_idx += len; + return self.buffer.mut_slice(self.buffer_idx - len, self.buffer_idx); + } + + fn full_buffer<'s>(&'s mut self) -> &'s [u8] { + assert!(self.buffer_idx == 64); + self.buffer_idx = 0; + return self.buffer.slice_to(64); + } + + fn position(&self) -> uint { self.buffer_idx } + + fn remaining(&self) -> uint { 64 - self.buffer_idx } + + fn size(&self) -> uint { 64 } +} + +/// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct. +trait StandardPadding { + /// Add padding to the buffer. The buffer must not be full when this method is called and is + /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least + /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled + /// with zeros again until only rem bytes are remaining. + fn standard_padding(&mut self, rem: uint, func: |&[u8]|); +} + +impl StandardPadding for T { + fn standard_padding(&mut self, rem: uint, func: |&[u8]|) { + let size = self.size(); + + self.next(1)[0] = 128; + + if self.remaining() < rem { + self.zero_until(size); + func(self.full_buffer()); + } + + self.zero_until(size - rem); + } +} + +/// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2 +/// family of digest functions. +pub trait Digest { + /// Provide message data. + /// + /// # Arguments + /// + /// * input - A vector of message data + fn input(&mut self, input: &[u8]); + + /// Retrieve the digest result. This method may be called multiple times. + /// + /// # Arguments + /// + /// * out - the vector to hold the result. Must be large enough to contain output_bits(). + fn result(&mut self, out: &mut [u8]); + + /// Reset the digest. This method must be called after result() and before supplying more + /// data. + fn reset(&mut self); + + /// Get the output size in bits. + fn output_bits(&self) -> uint; + + /// Convenience function that feeds a string into a digest. + /// + /// # Arguments + /// + /// * `input` The string to feed into the digest + fn input_str(&mut self, input: &str) { + self.input(input.as_bytes()); + } + + /// Convenience function that retrieves the result of a digest as a + /// newly allocated vec of bytes. + fn result_bytes(&mut self) -> ~[u8] { + let mut buf = vec::from_elem((self.output_bits()+7)/8, 0u8); + self.result(buf); + buf + } + + /// Convenience function that retrieves the result of a digest as a + /// ~str in hexadecimal format. + fn result_str(&mut self) -> ~str { + self.result_bytes().to_hex() + } +} + +// A structure that represents that state of a digest computation for the SHA-2 512 family of digest +// functions +struct Engine256State { + H0: u32, + H1: u32, + H2: u32, + H3: u32, + H4: u32, + H5: u32, + H6: u32, + H7: u32, +} + +impl Engine256State { + fn new(h: &[u32, ..8]) -> Engine256State { + return Engine256State { + H0: h[0], + H1: h[1], + H2: h[2], + H3: h[3], + H4: h[4], + H5: h[5], + H6: h[6], + H7: h[7] + }; + } + + fn reset(&mut self, h: &[u32, ..8]) { + self.H0 = h[0]; + self.H1 = h[1]; + self.H2 = h[2]; + self.H3 = h[3]; + self.H4 = h[4]; + self.H5 = h[5]; + self.H6 = h[6]; + self.H7 = h[7]; + } + + fn process_block(&mut self, data: &[u8]) { + fn ch(x: u32, y: u32, z: u32) -> u32 { + ((x & y) ^ ((!x) & z)) + } + + fn maj(x: u32, y: u32, z: u32) -> u32 { + ((x & y) ^ (x & z) ^ (y & z)) + } + + fn sum0(x: u32) -> u32 { + ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)) + } + + fn sum1(x: u32) -> u32 { + ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)) + } + + fn sigma0(x: u32) -> u32 { + ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3) + } + + fn sigma1(x: u32) -> u32 { + ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10) + } + + let mut a = self.H0; + let mut b = self.H1; + let mut c = self.H2; + let mut d = self.H3; + let mut e = self.H4; + let mut f = self.H5; + let mut g = self.H6; + let mut h = self.H7; + + let mut W = [0u32, ..64]; + + // Sha-512 and Sha-256 use basically the same calculations which are implemented + // by these macros. Inlining the calculations seems to result in better generated code. + macro_rules! schedule_round( ($t:expr) => ( + W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16]; + ) + ) + + macro_rules! sha2_round( + ($A:ident, $B:ident, $C:ident, $D:ident, + $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => ( + { + $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t]; + $D += $H; + $H += sum0($A) + maj($A, $B, $C); + } + ) + ) + + read_u32v_be(W.mut_slice(0, 16), data); + + // Putting the message schedule inside the same loop as the round calculations allows for + // the compiler to generate better code. + for t in range_step(0u, 48, 8) { + schedule_round!(t + 16); + schedule_round!(t + 17); + schedule_round!(t + 18); + schedule_round!(t + 19); + schedule_round!(t + 20); + schedule_round!(t + 21); + schedule_round!(t + 22); + schedule_round!(t + 23); + + sha2_round!(a, b, c, d, e, f, g, h, K32, t); + sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1); + sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2); + sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3); + sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4); + sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5); + sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6); + sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7); + } + + for t in range_step(48u, 64, 8) { + sha2_round!(a, b, c, d, e, f, g, h, K32, t); + sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1); + sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2); + sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3); + sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4); + sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5); + sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6); + sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7); + } + + self.H0 += a; + self.H1 += b; + self.H2 += c; + self.H3 += d; + self.H4 += e; + self.H5 += f; + self.H6 += g; + self.H7 += h; + } +} + +static K32: [u32, ..64] = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +]; + +// A structure that keeps track of the state of the Sha-256 operation and contains the logic +// necessary to perform the final calculations. +struct Engine256 { + length_bits: u64, + buffer: FixedBuffer64, + state: Engine256State, + finished: bool, +} + +impl Engine256 { + fn new(h: &[u32, ..8]) -> Engine256 { + return Engine256 { + length_bits: 0, + buffer: FixedBuffer64::new(), + state: Engine256State::new(h), + finished: false + } + } + + fn reset(&mut self, h: &[u32, ..8]) { + self.length_bits = 0; + self.buffer.reset(); + self.state.reset(h); + self.finished = false; + } + + fn input(&mut self, input: &[u8]) { + assert!(!self.finished) + // Assumes that input.len() can be converted to u64 without overflow + self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64); + self.buffer.input(input, |input: &[u8]| { self.state.process_block(input) }); + } + + fn finish(&mut self) { + if self.finished { + return; + } + + self.buffer.standard_padding(8, |input: &[u8]| { self.state.process_block(input) }); + write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 ); + write_u32_be(self.buffer.next(4), self.length_bits as u32); + self.state.process_block(self.buffer.full_buffer()); + + self.finished = true; + } +} + +/// The SHA-256 hash algorithm +pub struct Sha256 { + priv engine: Engine256 +} + +impl Sha256 { + /// Construct an new instance of a SHA-256 digest. + pub fn new() -> Sha256 { + Sha256 { + engine: Engine256::new(&H256) + } + } +} + +impl Digest for Sha256 { + fn input(&mut self, d: &[u8]) { + self.engine.input(d); + } + + fn result(&mut self, out: &mut [u8]) { + self.engine.finish(); + + write_u32_be(out.mut_slice(0, 4), self.engine.state.H0); + write_u32_be(out.mut_slice(4, 8), self.engine.state.H1); + write_u32_be(out.mut_slice(8, 12), self.engine.state.H2); + write_u32_be(out.mut_slice(12, 16), self.engine.state.H3); + write_u32_be(out.mut_slice(16, 20), self.engine.state.H4); + write_u32_be(out.mut_slice(20, 24), self.engine.state.H5); + write_u32_be(out.mut_slice(24, 28), self.engine.state.H6); + write_u32_be(out.mut_slice(28, 32), self.engine.state.H7); + } + + fn reset(&mut self) { + self.engine.reset(&H256); + } + + fn output_bits(&self) -> uint { 256 } +} + +static H256: [u32, ..8] = [ + 0x6a09e667, + 0xbb67ae85, + 0x3c6ef372, + 0xa54ff53a, + 0x510e527f, + 0x9b05688c, + 0x1f83d9ab, + 0x5be0cd19 +]; + +#[cfg(test)] +mod tests { + use super::{Digest, Sha256}; + use std::vec; + use std::rand::isaac::IsaacRng; + use std::rand::Rng; + use extra::hex::FromHex; + + // A normal addition - no overflow occurs + #[test] + fn test_add_bytes_to_bits_ok() { + assert!(super::add_bytes_to_bits::(100, 10) == 180); + } + + // A simple failure case - adding 1 to the max value + #[test] + #[should_fail] + fn test_add_bytes_to_bits_overflow() { + super::add_bytes_to_bits::(Bounded::max_value(), 1); + } + + struct Test { + input: ~str, + output_str: ~str, + } + + fn test_hash(sh: &mut D, tests: &[Test]) { + // Test that it works when accepting the message all at once + for t in tests.iter() { + sh.reset(); + sh.input_str(t.input); + let out_str = sh.result_str(); + assert!(out_str == t.output_str); + } + + // Test that it works when accepting the message in pieces + for t in tests.iter() { + sh.reset(); + let len = t.input.len(); + let mut left = len; + while left > 0u { + let take = (left + 1u) / 2u; + sh.input_str(t.input.slice(len - left, take + len - left)); + left = left - take; + } + let out_str = sh.result_str(); + assert!(out_str == t.output_str); + } + } + + #[test] + fn test_sha256() { + // Examples from wikipedia + let wikipedia_tests = ~[ + Test { + input: ~"", + output_str: ~"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog", + output_str: ~"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog.", + output_str: ~"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c" + }, + ]; + + let tests = wikipedia_tests; + + let mut sh = ~Sha256::new(); + + test_hash(sh, tests); + } + + /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is + /// correct. + fn test_digest_1million_random(digest: &mut D, blocksize: uint, expected: &str) { + let total_size = 1000000; + let buffer = vec::from_elem(blocksize * 2, 'a' as u8); + let mut rng = IsaacRng::new_unseeded(); + let mut count = 0; + + digest.reset(); + + while count < total_size { + let next: uint = rng.gen_range(0, 2 * blocksize + 1); + let remaining = total_size - count; + let size = if next > remaining { remaining } else { next }; + digest.input(buffer.slice_to(size)); + count += size; + } + + let result_str = digest.result_str(); + let result_bytes = digest.result_bytes(); + + assert_eq!(expected, result_str.as_slice()); + assert_eq!(expected.from_hex().unwrap(), result_bytes); + } + + #[test] + fn test_1million_random_sha256() { + let mut sh = Sha256::new(); + test_digest_1million_random( + &mut sh, + 64, + "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); + } +} + +#[cfg(test)] +mod bench { + use extra::test::BenchHarness; + use super::Sha256; + + #[bench] + pub fn sha256_10(bh: &mut BenchHarness) { + let mut sh = Sha256::new(); + let bytes = [1u8, ..10]; + bh.iter(|| { + sh.input(bytes); + }); + bh.bytes = bytes.len() as u64; + } + + #[bench] + pub fn sha256_1k(bh: &mut BenchHarness) { + let mut sh = Sha256::new(); + let bytes = [1u8, ..1024]; + bh.iter(|| { + sh.input(bytes); + }); + bh.bytes = bytes.len() as u64; + } + + #[bench] + pub fn sha256_64k(bh: &mut BenchHarness) { + let mut sh = Sha256::new(); + let bytes = [1u8, ..65536]; + bh.iter(|| { + sh.input(bytes); + }); + bh.bytes = bytes.len() as u64; + } +} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 39e2b908b5075..f8b86da03c1f7 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="rustdoc#0.9-pre"]; +// NOTE: remove after the next snapshot #[link(name = "rustdoc", package_id = "rustdoc", vers = "0.9-pre", diff --git a/src/librustpkg/lib.rs b/src/librustpkg/lib.rs index 7801742bc910b..0526e7dd434c4 100644 --- a/src/librustpkg/lib.rs +++ b/src/librustpkg/lib.rs @@ -10,6 +10,8 @@ // rustpkg - a package manager and build system for Rust +#[pkgid="rustpkg#0.9-pre"]; +// NOTE: remove after the next snapshot #[link(name = "rustpkg", package_id = "rustpkg", vers = "0.9-pre", @@ -36,6 +38,7 @@ use extra::workcache; use rustc::driver::{driver, session}; use rustc::metadata::filesearch; use rustc::metadata::filesearch::rust_path; +use rustc::util::sha2; use extra::{getopts}; use syntax::{ast, diagnostic}; use messages::{error, warn, note}; @@ -52,7 +55,7 @@ use context::{Context, BuildContext, use package_id::PkgId; use package_source::PkgSrc; use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench}; -use target::{Tests, MaybeCustom, Inferred, JustOne}; +use target::{Main, Tests, MaybeCustom, Inferred, JustOne}; use workcache_support::digest_only_date; use exit_codes::{COPY_FAILED_CODE, BAD_FLAG_CODE}; @@ -66,7 +69,6 @@ mod messages; pub mod package_id; pub mod package_source; mod path_util; -mod sha1; mod source_control; mod target; #[cfg(not(windows), test)] // FIXME test failure on windows: #10471 @@ -151,7 +153,8 @@ impl<'self> PkgScript<'self> { Nothing, &self.build_dir, sess, - crate); + crate, + Main); // Discover the output // FIXME (#9639): This needs to handle non-utf8 paths // Discover the output diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 135ba9e9702c9..59fdf20941ec2 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -15,8 +15,6 @@ use std::{os, run, str, task}; use std::io; use std::io::fs; use std::io::File; -use std::io::process; -use std::io::process::ProcessExit; use extra::arc::Arc; use extra::arc::RWArc; use extra::tempfile::TempDir; @@ -739,8 +737,8 @@ fn test_package_ids_must_be_relative_path_like() { let whatever = PkgId::new("foo"); - assert_eq!(~"foo-0.1", whatever.to_str()); - assert!("github.com/catamorphism/test-pkg-0.1" == + assert_eq!(~"foo-0.0", whatever.to_str()); + assert!("github.com/catamorphism/test-pkg-0.0" == PkgId::new("github.com/catamorphism/test-pkg").to_str()); cond.trap(|(p, e)| { @@ -749,7 +747,7 @@ fn test_package_ids_must_be_relative_path_like() { whatever.clone() }).inside(|| { let x = PkgId::new(""); - assert_eq!(~"foo-0.1", x.to_str()); + assert_eq!(~"foo-0.0", x.to_str()); }); cond.trap(|(p, e)| { @@ -761,9 +759,8 @@ fn test_package_ids_must_be_relative_path_like() { let zp = os::make_absolute(&Path::new("foo/bar/quux")); // FIXME (#9639): This needs to handle non-utf8 paths let z = PkgId::new(zp.as_str().unwrap()); - assert_eq!(~"foo-0.1", z.to_str()); + assert_eq!(~"foo-0.0", z.to_str()); }) - } #[test] @@ -896,7 +893,7 @@ fn package_script_with_default_build() { let source = Path::new(file!()).dir_path().join_many( [~"testsuite", ~"pass", ~"src", ~"fancy-lib", ~"pkg.rs"]); debug!("package_script_with_default_build: {}", source.display()); - fs::copy(&source, &dir.join_many(["src", "fancy-lib-0.1", "pkg.rs"])); + fs::copy(&source, &dir.join_many(["src", "fancy-lib-0.0", "pkg.rs"])); command_line_test([~"install", ~"fancy-lib"], dir); assert_lib_exists(dir, &Path::new("fancy-lib"), NoVersion); assert!(target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"]).exists()); @@ -1349,7 +1346,7 @@ fn test_import_rustpkg() { let p_id = PkgId::new("foo"); let workspace = create_local_package(&p_id); let workspace = workspace.path(); - writeFile(&workspace.join_many(["src", "foo-0.1", "pkg.rs"]), + writeFile(&workspace.join_many(["src", "foo-0.0", "pkg.rs"]), "extern mod rustpkg; fn main() {}"); command_line_test([~"build", ~"foo"], workspace); debug!("workspace = {}", workspace.display()); @@ -1362,7 +1359,7 @@ fn test_macro_pkg_script() { let p_id = PkgId::new("foo"); let workspace = create_local_package(&p_id); let workspace = workspace.path(); - writeFile(&workspace.join_many(["src", "foo-0.1", "pkg.rs"]), + writeFile(&workspace.join_many(["src", "foo-0.0", "pkg.rs"]), "extern mod rustpkg; fn main() { debug!(\"Hi\"); }"); command_line_test([~"build", ~"foo"], workspace); debug!("workspace = {}", workspace.display()); @@ -1404,7 +1401,7 @@ fn rust_path_hack_test(hack_flag: bool) { let workspace = workspace.path(); let dest_workspace = mk_empty_workspace(&Path::new("bar"), &NoVersion, "dest_workspace"); let dest_workspace = dest_workspace.path(); - let foo_path = workspace.join_many(["src", "foo-0.1"]); + let foo_path = workspace.join_many(["src", "foo-0.0"]); let rust_path = Some(~[(~"RUST_PATH", format!("{}:{}", dest_workspace.as_str().unwrap(), @@ -1534,9 +1531,9 @@ fn rust_path_hack_build_with_dependency() { let dep_workspace = dep_workspace.path(); let dest_workspace = mk_emptier_workspace("dep"); let dest_workspace = dest_workspace.path(); - let source_dir = work_dir.join_many(["src", "foo-0.1"]); + let source_dir = work_dir.join_many(["src", "foo-0.0"]); writeFile(&source_dir.join("lib.rs"), "extern mod dep; pub fn f() { }"); - let dep_dir = dep_workspace.join_many(["src", "dep-0.1"]); + let dep_dir = dep_workspace.join_many(["src", "dep-0.0"]); let rust_path = Some(~[(~"RUST_PATH", format!("{}:{}", dest_workspace.display(), @@ -1706,7 +1703,7 @@ fn test_cfg_build() { let workspace = create_local_package(&p_id); let workspace = workspace.path(); // If the cfg flag gets messed up, this won't compile - writeFile(&workspace.join_many(["src", "foo-0.1", "main.rs"]), + writeFile(&workspace.join_many(["src", "foo-0.0", "main.rs"]), "#[cfg(quux)] fn main() {}"); let test_sys = test_sysroot(); // FIXME (#9639): This needs to handle non-utf8 paths @@ -1724,7 +1721,7 @@ fn test_cfg_fail() { let p_id = PkgId::new("foo"); let workspace = create_local_package(&p_id); let workspace = workspace.path(); - writeFile(&workspace.join_many(["src", "foo-0.1", "main.rs"]), + writeFile(&workspace.join_many(["src", "foo-0.0", "main.rs"]), "#[cfg(quux)] fn main() {}"); let test_sys = test_sysroot(); // FIXME (#9639): This needs to handle non-utf8 paths @@ -1892,11 +1889,13 @@ fn pkgid_pointing_to_subdir() { "extras", "bar"]); fs::mkdir_recursive(&foo_dir, io::UserRWX); fs::mkdir_recursive(&bar_dir, io::UserRWX); - writeFile(&foo_dir.join("lib.rs"), "pub fn f() {}"); - writeFile(&bar_dir.join("lib.rs"), "pub fn g() {}"); + writeFile(&foo_dir.join("lib.rs"), + "#[pkgid=\"mockgithub.com/mozilla/some_repo/extras/foo\"]; pub fn f() {}"); + writeFile(&bar_dir.join("lib.rs"), + "#[pkgid=\"mockgithub.com/mozilla/some_repo/extras/bar\"]; pub fn g() {}"); debug!("Creating a file in {}", workspace.display()); - let testpkg_dir = workspace.join_many(["src", "testpkg-0.1"]); + let testpkg_dir = workspace.join_many(["src", "testpkg-0.0"]); fs::mkdir_recursive(&testpkg_dir, io::UserRWX); writeFile(&testpkg_dir.join("main.rs"), @@ -1916,13 +1915,13 @@ fn test_recursive_deps() { let c_id = PkgId::new("c"); let b_workspace = create_local_package_with_dep(&b_id, &c_id); let b_workspace = b_workspace.path(); - writeFile(&b_workspace.join_many(["src", "c-0.1", "lib.rs"]), + writeFile(&b_workspace.join_many(["src", "c-0.0", "lib.rs"]), "pub fn g() {}"); let a_workspace = create_local_package(&a_id); let a_workspace = a_workspace.path(); - writeFile(&a_workspace.join_many(["src", "a-0.1", "main.rs"]), + writeFile(&a_workspace.join_many(["src", "a-0.0", "main.rs"]), "extern mod b; use b::f; fn main() { f(); }"); - writeFile(&b_workspace.join_many(["src", "b-0.1", "lib.rs"]), + writeFile(&b_workspace.join_many(["src", "b-0.0", "lib.rs"]), "extern mod c; use c::g; pub fn f() { g(); }"); // FIXME (#9639): This needs to handle non-utf8 paths let environment = Some(~[(~"RUST_PATH", b_workspace.as_str().unwrap().to_owned())]); @@ -1999,7 +1998,7 @@ fn test_dependencies_terminate() { let b_id = PkgId::new("b"); let workspace = create_local_package(&b_id); let workspace = workspace.path(); - let b_dir = workspace.join_many(["src", "b-0.1"]); + let b_dir = workspace.join_many(["src", "b-0.0"]); let b_subdir = b_dir.join("test"); fs::mkdir_recursive(&b_subdir, io::UserRWX); writeFile(&b_subdir.join("test.rs"), @@ -2066,10 +2065,10 @@ fn correct_package_name_with_rust_path_hack() { let dest_workspace = mk_empty_workspace(&Path::new("bar"), &NoVersion, "dest_workspace"); let dest_workspace = dest_workspace.path(); - writeFile(&dest_workspace.join_many(["src", "bar-0.1", "main.rs"]), + writeFile(&dest_workspace.join_many(["src", "bar-0.0", "main.rs"]), "extern mod blat; fn main() { let _x = (); }"); - let foo_path = foo_workspace.join_many(["src", "foo-0.1"]); + let foo_path = foo_workspace.join_many(["src", "foo-0.0"]); // FIXME (#9639): This needs to handle non-utf8 paths let rust_path = Some(~[(~"RUST_PATH", format!("{}:{}", dest_workspace.as_str().unwrap(), foo_path.as_str().unwrap()))]); @@ -2092,7 +2091,7 @@ fn test_rustpkg_test_creates_exec() { let foo_id = PkgId::new("foo"); let foo_workspace = create_local_package(&foo_id); let foo_workspace = foo_workspace.path(); - writeFile(&foo_workspace.join_many(["src", "foo-0.1", "test.rs"]), + writeFile(&foo_workspace.join_many(["src", "foo-0.0", "test.rs"]), "#[test] fn f() { assert!('a' == 'a'); }"); command_line_test([~"test", ~"foo"], foo_workspace); assert!(test_executable_exists(foo_workspace, "foo")); @@ -2115,7 +2114,7 @@ fn test_rustpkg_test_failure_exit_status() { let foo_id = PkgId::new("foo"); let foo_workspace = create_local_package(&foo_id); let foo_workspace = foo_workspace.path(); - writeFile(&foo_workspace.join_many(["src", "foo-0.1", "test.rs"]), + writeFile(&foo_workspace.join_many(["src", "foo-0.0", "test.rs"]), "#[test] fn f() { assert!('a' != 'a'); }"); let res = command_line_test_partial([~"test", ~"foo"], foo_workspace); match res { @@ -2129,7 +2128,7 @@ fn test_rustpkg_test_cfg() { let foo_id = PkgId::new("foo"); let foo_workspace = create_local_package(&foo_id); let foo_workspace = foo_workspace.path(); - writeFile(&foo_workspace.join_many(["src", "foo-0.1", "test.rs"]), + writeFile(&foo_workspace.join_many(["src", "foo-0.0", "test.rs"]), "#[test] #[cfg(not(foobar))] fn f() { assert!('a' != 'a'); }"); let output = command_line_test([~"test", ~"--cfg", ~"foobar", ~"foo"], foo_workspace); @@ -2142,7 +2141,7 @@ fn test_rebuild_when_needed() { let foo_id = PkgId::new("foo"); let foo_workspace = create_local_package(&foo_id); let foo_workspace = foo_workspace.path(); - let test_crate = foo_workspace.join_many(["src", "foo-0.1", "test.rs"]); + let test_crate = foo_workspace.join_many(["src", "foo-0.0", "test.rs"]); writeFile(&test_crate, "#[test] fn f() { assert!('a' == 'a'); }"); command_line_test([~"test", ~"foo"], foo_workspace); assert!(test_executable_exists(foo_workspace, "foo")); @@ -2163,7 +2162,7 @@ fn test_no_rebuilding() { let foo_id = PkgId::new("foo"); let foo_workspace = create_local_package(&foo_id); let foo_workspace = foo_workspace.path(); - let test_crate = foo_workspace.join_many(["src", "foo-0.1", "test.rs"]); + let test_crate = foo_workspace.join_many(["src", "foo-0.0", "test.rs"]); writeFile(&test_crate, "#[test] fn f() { assert!('a' == 'a'); }"); command_line_test([~"test", ~"foo"], foo_workspace); assert!(test_executable_exists(foo_workspace, "foo")); @@ -2182,7 +2181,7 @@ fn test_no_rebuilding() { fn test_installed_read_only() { // Install sources from a "remote" (actually a local github repo) // Check that afterward, sources are read-only and installed under build/ - let temp_pkg_id = git_repo_pkg(); + let mut temp_pkg_id = git_repo_pkg(); let repo = init_git_repo(&temp_pkg_id.path); let repo = repo.path(); debug!("repo = {}", repo.display()); @@ -2194,6 +2193,8 @@ fn test_installed_read_only() { writeFile(&repo_subdir.join("lib.rs"), "pub fn f() { let _x = (); }"); add_git_tag(&repo_subdir, ~"0.1"); // this has the effect of committing the files + // update pkgid to what will be auto-detected + temp_pkg_id.version = ExactRevision(~"0.1"); // FIXME (#9639): This needs to handle non-utf8 paths command_line_test([~"install", temp_pkg_id.path.as_str().unwrap().to_owned()], repo); @@ -2247,7 +2248,7 @@ fn test_installed_local_changes() { let target_dir = hacking_workspace.join_many(["src", "mockgithub.com", "catamorphism", - "test-pkg-0.1"]); + "test-pkg-0.0"]); debug!("---- git clone {} {}", repo_subdir.display(), target_dir.display()); let c_res = safe_git_clone(&repo_subdir, &NoVersion, &target_dir); @@ -2294,7 +2295,7 @@ fn test_compile_error() { let foo_id = PkgId::new("foo"); let foo_workspace = create_local_package(&foo_id); let foo_workspace = foo_workspace.path(); - let main_crate = foo_workspace.join_many(["src", "foo-0.1", "main.rs"]); + let main_crate = foo_workspace.join_many(["src", "foo-0.0", "main.rs"]); // Write something bogus writeFile(&main_crate, "pub fn main() { if 42 != ~\"the answer\" { fail!(); } }"); let result = command_line_test_partial([~"build", ~"foo"], foo_workspace); @@ -2327,15 +2328,15 @@ fn test_c_dependency_ok() { let dir = create_local_package(&PkgId::new("cdep")); let dir = dir.path(); - writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]), + writeFile(&dir.join_many(["src", "cdep-0.0", "main.rs"]), "#[link_args = \"-lfoo\"]\nextern { fn f(); } \ \nfn main() { unsafe { f(); } }"); - writeFile(&dir.join_many(["src", "cdep-0.1", "foo.c"]), "void f() {}"); + writeFile(&dir.join_many(["src", "cdep-0.0", "foo.c"]), "void f() {}"); debug!("dir = {}", dir.display()); let source = Path::new(file!()).dir_path().join_many( [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); - fs::copy(&source, &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])); + fs::copy(&source, &dir.join_many([~"src", ~"cdep-0.0", ~"pkg.rs"])); command_line_test([~"build", ~"cdep"], dir); assert_executable_exists(dir, "cdep"); let out_dir = target_build_dir(dir).join("cdep"); @@ -2344,20 +2345,21 @@ fn test_c_dependency_ok() { assert!(c_library_path.exists()); } +#[ignore(reason="rustpkg is not reentrant")] #[test] #[ignore(reason="busted")] fn test_c_dependency_no_rebuilding() { let dir = create_local_package(&PkgId::new("cdep")); let dir = dir.path(); - writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]), + writeFile(&dir.join_many(["src", "cdep-0.0", "main.rs"]), "#[link_args = \"-lfoo\"]\nextern { fn f(); } \ \nfn main() { unsafe { f(); } }"); - writeFile(&dir.join_many(["src", "cdep-0.1", "foo.c"]), "void f() {}"); + writeFile(&dir.join_many(["src", "cdep-0.0", "foo.c"]), "void f() {}"); debug!("dir = {}", dir.display()); let source = Path::new(file!()).dir_path().join_many( [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); - fs::copy(&source, &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])); + fs::copy(&source, &dir.join_many([~"src", ~"cdep-0.0", ~"pkg.rs"])); command_line_test([~"build", ~"cdep"], dir); assert_executable_exists(dir, "cdep"); let out_dir = target_build_dir(dir).join("cdep"); @@ -2383,15 +2385,15 @@ fn test_c_dependency_no_rebuilding() { fn test_c_dependency_yes_rebuilding() { let dir = create_local_package(&PkgId::new("cdep")); let dir = dir.path(); - writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]), + writeFile(&dir.join_many(["src", "cdep-0.0", "main.rs"]), "#[link_args = \"-lfoo\"]\nextern { fn f(); } \ \nfn main() { unsafe { f(); } }"); - let c_file_name = dir.join_many(["src", "cdep-0.1", "foo.c"]); + let c_file_name = dir.join_many(["src", "cdep-0.0", "foo.c"]); writeFile(&c_file_name, "void f() {}"); let source = Path::new(file!()).dir_path().join_many( [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); - let target = dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"]); + let target = dir.join_many([~"src", ~"cdep-0.0", ~"pkg.rs"]); debug!("Copying {} -> {}", source.display(), target.display()); fs::copy(&source, &target); command_line_test([~"build", ~"cdep"], dir); @@ -2420,13 +2422,13 @@ fn test_c_dependency_yes_rebuilding() { fn correct_error_dependency() { // Supposing a package we're trying to install via a dependency doesn't // exist, we should throw a condition, and not ICE - let dir = create_local_package(&PkgId::new("badpkg")); + let workspace_dir = create_local_package(&PkgId::new("badpkg")); - let dir = dir.path(); - writeFile(&dir.join_many(["src", "badpkg-0.1", "main.rs"]), + let dir = workspace_dir.path(); + let main_rs = dir.join_many(["src", "badpkg-0.0", "main.rs"]); + writeFile(&main_rs, "extern mod p = \"some_package_that_doesnt_exist\"; fn main() {}"); - match command_line_test_partial([~"build", ~"badpkg"], dir) { Fail(ProcessOutput{ error: error, output: output, .. }) => { assert!(str::is_utf8(error)); diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs index 122f80a52f1ca..e5386aa701bf1 100644 --- a/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs +++ b/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs @@ -42,7 +42,7 @@ pub fn main() { let mut context = api::default_context(sysroot, path_for_db); let my_workspace = api::my_workspace(&context.context, "cdep"); - let foo_c_name = my_workspace.join_many(["src", "cdep-0.1", "foo.c"]); + let foo_c_name = my_workspace.join_many(["src", "cdep-0.0", "foo.c"]); let out_lib_path = context.workcache_context.with_prep("foo.c", |prep| { let sub_cx = context.context.clone(); diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 3f6d5b5506627..97fba807c0e60 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -290,23 +290,17 @@ pub fn compile_input(context: &BuildContext, addl_lib_search_paths.insert(p); }); - // Inject the link attributes so we get the right package name and version - if attr::find_linkage_metas(crate.attrs).is_empty() { - let name_to_use = match what { - Test => format!("{}test", pkg_id.short_name).to_managed(), - Bench => format!("{}bench", pkg_id.short_name).to_managed(), - _ => pkg_id.short_name.to_managed() - }; - debug!("Injecting link name: {}", name_to_use); + // Inject the pkgid attribute so we get the right package name and version + if !attr::contains_name(crate.attrs, "pkgid") { // FIXME (#9639): This needs to handle non-utf8 paths - let link_options = - ~[attr::mk_name_value_item_str(@"name", name_to_use), - attr::mk_name_value_item_str(@"vers", pkg_id.version.to_str().to_managed())] + - ~[attr::mk_name_value_item_str(@"package_id", - pkg_id.path.as_str().unwrap().to_managed())]; - - debug!("link options: {:?}", link_options); - crate.attrs = ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))]; + let pkgid_attr = + attr::mk_name_value_item_str(@"pkgid", + format!("{}\\#{}", + pkg_id.path.as_str().unwrap(), + pkg_id.version.to_str()).to_managed()); + + debug!("pkgid attr: {:?}", pkgid_attr); + crate.attrs = ~[attr::mk_attr(pkgid_attr)]; } debug!("calling compile_crate_from_input, workspace = {}, @@ -316,7 +310,8 @@ pub fn compile_input(context: &BuildContext, context.compile_upto(), &out_dir, sess, - crate); + crate, + what); // Discover the output let discovered_output = if what == Lib { built_library_in_workspace(pkg_id, workspace) // Huh??? @@ -351,15 +346,29 @@ pub fn compile_crate_from_input(input: &Path, sess: session::Session, // Returns None if one of the flags that suppresses compilation output was // given - crate: ast::Crate) -> Option { + crate: ast::Crate, + what: OutputType) -> Option { debug!("Calling build_output_filenames with {}, building library? {:?}", out_dir.display(), sess.building_library); // bad copy debug!("out_dir = {}", out_dir.display()); - let outputs = driver::build_output_filenames(&driver::file_input(input.clone()), - &Some(out_dir.clone()), &None, - crate.attrs, sess); + let mut outputs = driver::build_output_filenames(&driver::file_input(input.clone()), + &Some(out_dir.clone()), &None, + crate.attrs, sess); + match what { + Lib | Main => {} + Test => { + let mut ofile = outputs.out_filename.filename_str().unwrap().to_owned(); + ofile.push_str("test"); + outputs.out_filename.set_filename(ofile); + } + Bench => { + let mut ofile = outputs.out_filename.filename_str().unwrap().to_owned(); + ofile.push_str("bench"); + outputs.out_filename.set_filename(ofile); + } + }; debug!("Outputs are out_filename: {} and obj_filename: {} and output type = {:?}", outputs.out_filename.display(), diff --git a/src/librustpkg/version.rs b/src/librustpkg/version.rs index eced433868f22..ba6cf5f513b77 100644 --- a/src/librustpkg/version.rs +++ b/src/librustpkg/version.rs @@ -24,7 +24,7 @@ pub enum Version { SemanticVersion(semver::Version), Tagged(~str), // String that can't be parsed as a version. // Requirements get interpreted exactly - NoVersion // user didn't specify a version -- prints as 0.1 + NoVersion // user didn't specify a version -- prints as 0.0 } // Equality on versions is non-symmetric: if self is NoVersion, it's equal to @@ -81,7 +81,7 @@ impl ToStr for Version { match *self { ExactRevision(ref n) | Tagged(ref n) => format!("{}", n.to_str()), SemanticVersion(ref v) => format!("{}", v.to_str()), - NoVersion => ~"0.1" + NoVersion => ~"0.0" } } } diff --git a/src/librustpkg/workcache_support.rs b/src/librustpkg/workcache_support.rs index 42f0aec6b7437..824ba5341d4f6 100644 --- a/src/librustpkg/workcache_support.rs +++ b/src/librustpkg/workcache_support.rs @@ -11,7 +11,7 @@ use std::io; use std::io::File; use extra::workcache; -use sha1::{Digest, Sha1}; +use sha2::{Digest, Sha256}; /// Hashes the file contents along with the last-modified time pub fn digest_file_with_date(path: &Path) -> ~str { @@ -19,7 +19,7 @@ pub fn digest_file_with_date(path: &Path) -> ~str { match io::result(|| File::open(path).read_to_end()) { Ok(bytes) => { - let mut sha = Sha1::new(); + let mut sha = Sha256::new(); sha.input(bytes); let st = path.stat(); sha.input_str(st.modified.to_str()); @@ -34,7 +34,7 @@ pub fn digest_file_with_date(path: &Path) -> ~str { /// Hashes only the last-modified time pub fn digest_only_date(path: &Path) -> ~str { - let mut sha = Sha1::new(); + let mut sha = Sha256::new(); let st = path.stat(); sha.input_str(st.modified.to_str()); sha.result_str() diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index ad1c53e97397f..d8b7c4db69c80 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -34,6 +34,8 @@ via `close` and `delete` methods. */ +#[pkgid="rustuv#0.9-pre"]; +// NOTE: remove after the next snapshot #[link(name = "rustuv", package_id = "rustuv", vers = "0.9-pre", diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 6fe757976f033..e267400621503 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -43,6 +43,8 @@ //! //! use std::prelude::*; +#[pkgid="std#0.9-pre"]; +// NOTE: remove after the next snapshot #[link(name = "std", package_id = "std", vers = "0.9-pre", @@ -69,13 +71,13 @@ // When testing libstd, bring in libuv as the I/O backend so tests can print // things and all of the std::io tests have an I/O interface to run on top // of -#[cfg(test)] extern mod rustuv(vers = "0.9-pre"); +#[cfg(test)] extern mod rustuv = "rustuv#0.9-pre"; // Make extra accessible for benchmarking -#[cfg(test)] extern mod extra(vers = "0.9-pre"); +#[cfg(test)] extern mod extra = "extra#0.9-pre"; // Make std testable by not duplicating lang items. See #2912 -#[cfg(test)] extern mod realstd(name = "std"); +#[cfg(test)] extern mod realstd = "std#0.9-pre"; #[cfg(test)] pub use kinds = realstd::kinds; #[cfg(test)] pub use ops = realstd::ops; #[cfg(test)] pub use cmp = realstd::cmp; diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 5ad1d92fb157d..eb5b2df4ed967 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -917,8 +917,6 @@ fn new_sched_rng() -> XorShiftRng { #[cfg(test)] mod test { - extern mod extra; - use prelude::*; use rt::test::*; use unstable::run_in_bare_thread; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 05a65de16b8a1..ac5254f1abafc 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -18,6 +18,7 @@ use codemap::{Span, Spanned, spanned, dummy_spanned}; use codemap::BytePos; use diagnostic::span_handler; use parse::comments::{doc_comment_style, strip_doc_comment_decoration}; +use pkgid::PkgId; use std::hashmap::HashSet; @@ -235,6 +236,13 @@ pub fn find_linkage_metas(attrs: &[Attribute]) -> ~[@MetaItem] { result } +pub fn find_pkgid(attrs: &[Attribute]) -> Option { + match first_attr_value_str_by_name(attrs, "pkgid") { + None => None, + Some(id) => from_str::(id), + } +} + #[deriving(Eq)] pub enum InlineAttr { InlineNone, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index c9b3ba9d4600f..4382e6d67b883 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -13,6 +13,8 @@ * macros. */ +#[pkgid="syntax#0.9-pre"]; +// NOTE: remove after the next snapshot #[link(name = "syntax", package_id = "syntax", vers = "0.9-pre", @@ -51,6 +53,7 @@ pub mod fold; pub mod parse; +pub mod pkgid; pub mod print { pub mod pp; diff --git a/src/libsyntax/pkgid.rs b/src/libsyntax/pkgid.rs new file mode 100644 index 0000000000000..1e840ca700bd1 --- /dev/null +++ b/src/libsyntax/pkgid.rs @@ -0,0 +1,160 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deriving(Clone, Eq)] +pub struct PkgId { + path: ~str, + name: ~str, + version: Option<~str>, +} + +impl ToStr for PkgId { + fn to_str(&self) -> ~str { + let version = match self.version { + None => "0.0", + Some(ref version) => version.as_slice(), + }; + if self.path.is_empty() { + format!("{}\\#{}", self.name, version) + } else { + format!("{}/{}\\#{}", self.path, self.name, version) + } + } +} + +impl FromStr for PkgId { + fn from_str(s: &str) -> Option { + let hash_idx = match s.find('#') { + None => s.len(), + Some(idx) => idx, + }; + let prefix = s.slice_to(hash_idx); + let name_idx = match prefix.rfind('/') { + None => 0, + Some(idx) => idx + 1, + }; + if name_idx >= prefix.len() { + return None; + } + let name = prefix.slice_from(name_idx); + if name.len() <= 0 { + return None; + } + + let path = if name_idx == 0 { + "" + } else { + prefix.slice_to(name_idx - 1) + }; + let check_path = Path::new(path); + if !check_path.is_relative() { + return None; + } + + let version = match s.find('#') { + None => None, + Some(idx) => { + if idx >= s.len() { + None + } else { + let v = s.slice_from(idx + 1); + if v.is_empty() { + None + } else { + Some(v.to_owned()) + } + } + } + }; + + Some(PkgId{ + path: path.to_owned(), + name: name.to_owned(), + version: version, + }) + } +} + +impl PkgId { + pub fn version_or_default<'a>(&'a self) -> &'a str { + match self.version { + None => "0.0", + Some(ref version) => version.as_slice(), + } + } +} + +#[test] +fn bare_name() { + let pkgid: PkgId = from_str("foo").expect("valid pkgid"); + assert_eq!(pkgid.name, ~"foo"); + assert_eq!(pkgid.version, None); + assert_eq!(pkgid.path, ~""); +} + +#[test] +fn bare_name_single_char() { + let pkgid: PkgId = from_str("f").expect("valid pkgid"); + assert_eq!(pkgid.name, ~"f"); + assert_eq!(pkgid.version, None); + assert_eq!(pkgid.path, ~""); +} + +#[test] +fn empty_pkgid() { + let pkgid: Option = from_str(""); + assert!(pkgid.is_none()); +} + +#[test] +fn simple_path() { + let pkgid: PkgId = from_str("example.com/foo/bar").expect("valid pkgid"); + assert_eq!(pkgid.name, ~"bar"); + assert_eq!(pkgid.version, None); + assert_eq!(pkgid.path, ~"example.com/foo"); +} + +#[test] +fn simple_version() { + let pkgid: PkgId = from_str("foo#1.0").expect("valid pkgid"); + assert_eq!(pkgid.name, ~"foo"); + assert_eq!(pkgid.version, Some(~"1.0")); + assert_eq!(pkgid.path, ~""); +} + +#[test] +fn absolute_path() { + let pkgid: Option = from_str("/foo/bar"); + assert!(pkgid.is_none()); +} + +#[test] +fn path_and_version() { + let pkgid: PkgId = from_str("example.com/foo/bar#1.0").expect("valid pkgid"); + assert_eq!(pkgid.name, ~"bar"); + assert_eq!(pkgid.version, Some(~"1.0")); + assert_eq!(pkgid.path, ~"example.com/foo"); +} + +#[test] +fn single_chars() { + let pkgid: PkgId = from_str("a/b#1").expect("valid pkgid"); + assert_eq!(pkgid.name, ~"b"); + assert_eq!(pkgid.version, Some(~"1")); + assert_eq!(pkgid.path, ~"a"); +} + +#[test] +fn missing_version() { + let pkgid: PkgId = from_str("foo#").expect("valid pkgid"); + assert_eq!(pkgid.name, ~"foo"); + assert_eq!(pkgid.version, None); + assert_eq!(pkgid.path, ~""); +} \ No newline at end of file diff --git a/src/test/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/auxiliary/anon-extern-mod-cross-crate-1.rs index cce7df5650489..0c1906500c07f 100644 --- a/src/test/auxiliary/anon-extern-mod-cross-crate-1.rs +++ b/src/test/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -8,13 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[link(name = "anonexternmod", vers = "0.1")]; - -#[crate_type = "lib"]; +#[pkgid="anonexternmod#0.1"]; use std::libc; -#[link(name = "rustrt")] +#[link(name="rustrt")] extern { pub fn rust_get_test_int() -> libc::intptr_t; } diff --git a/src/test/auxiliary/cci_impl_lib.rs b/src/test/auxiliary/cci_impl_lib.rs index f038acf67a82e..16c03fa8e3b33 100644 --- a/src/test/auxiliary/cci_impl_lib.rs +++ b/src/test/auxiliary/cci_impl_lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="cci_impl_lib"]; +// NOTE: remove after the next snapshot #[link(name="cci_impl_lib", vers="0.0")]; trait uint_helpers { diff --git a/src/test/auxiliary/cci_iter_lib.rs b/src/test/auxiliary/cci_iter_lib.rs index e08a2f7fcbbec..903563055b7f1 100644 --- a/src/test/auxiliary/cci_iter_lib.rs +++ b/src/test/auxiliary/cci_iter_lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="cci_iter_lib"]; +// NOTE: remove after the next snapshot #[link(name="cci_iter_lib", vers="0.0")]; #[inline] diff --git a/src/test/auxiliary/cci_no_inline_lib.rs b/src/test/auxiliary/cci_no_inline_lib.rs index 99d13e91752ab..ea06cbf793a4d 100644 --- a/src/test/auxiliary/cci_no_inline_lib.rs +++ b/src/test/auxiliary/cci_no_inline_lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="cci_no_inline_lib"]; +// NOTE: remove after the next snapshot #[link(name="cci_no_inline_lib", vers="0.0")]; // same as cci_iter_lib, more-or-less, but not marked inline diff --git a/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs b/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs index 700f95f3d7063..921082440d86b 100644 --- a/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs +++ b/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs @@ -9,6 +9,8 @@ // except according to those terms. #[feature(managed_boxes)]; +#[pkgid="crate_method_reexport_grrrrrrr2"]; +// NOTE: remove after the next snapshot #[link(name = "crate_method_reexport_grrrrrrr2")]; pub use name_pool::add; diff --git a/src/test/auxiliary/crateresolve1-1.rs b/src/test/auxiliary/crateresolve1-1.rs index 818d4da52ed08..d7600f95ecdb1 100644 --- a/src/test/auxiliary/crateresolve1-1.rs +++ b/src/test/auxiliary/crateresolve1-1.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve1#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve1", vers = "0.1")]; diff --git a/src/test/auxiliary/crateresolve1-2.rs b/src/test/auxiliary/crateresolve1-2.rs index 6edbcbfdb857e..239d11b198577 100644 --- a/src/test/auxiliary/crateresolve1-2.rs +++ b/src/test/auxiliary/crateresolve1-2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve1#0.2"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve1", vers = "0.2")]; diff --git a/src/test/auxiliary/crateresolve1-3.rs b/src/test/auxiliary/crateresolve1-3.rs index ce23867c2c7ef..7acb3804fd307 100644 --- a/src/test/auxiliary/crateresolve1-3.rs +++ b/src/test/auxiliary/crateresolve1-3.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve1#0.3"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve1", vers = "0.3")]; diff --git a/src/test/auxiliary/crateresolve2-1.rs b/src/test/auxiliary/crateresolve2-1.rs index 4d0694f473bfc..149314e5a0744 100644 --- a/src/test/auxiliary/crateresolve2-1.rs +++ b/src/test/auxiliary/crateresolve2-1.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve2#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve2", vers = "0.1")]; diff --git a/src/test/auxiliary/crateresolve2-2.rs b/src/test/auxiliary/crateresolve2-2.rs index 4ae0ce0109fc7..9286b68586a98 100644 --- a/src/test/auxiliary/crateresolve2-2.rs +++ b/src/test/auxiliary/crateresolve2-2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve2#0.2"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve2", vers = "0.2")]; diff --git a/src/test/auxiliary/crateresolve2-3.rs b/src/test/auxiliary/crateresolve2-3.rs index 6d401b50f8ca9..37ccbbd40d70e 100644 --- a/src/test/auxiliary/crateresolve2-3.rs +++ b/src/test/auxiliary/crateresolve2-3.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve2#0.3"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve2", vers = "0.3")]; diff --git a/src/test/auxiliary/crateresolve3-1.rs b/src/test/auxiliary/crateresolve3-1.rs index b890508f74458..e2c46a9a88d2f 100644 --- a/src/test/auxiliary/crateresolve3-1.rs +++ b/src/test/auxiliary/crateresolve3-1.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve3#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve3", vers = "0.1")]; diff --git a/src/test/auxiliary/crateresolve3-2.rs b/src/test/auxiliary/crateresolve3-2.rs index f11dc8eb3a01f..cda986f21cbf6 100644 --- a/src/test/auxiliary/crateresolve3-2.rs +++ b/src/test/auxiliary/crateresolve3-2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve3#0.2"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve3", vers = "0.2")]; diff --git a/src/test/auxiliary/crateresolve4a-1.rs b/src/test/auxiliary/crateresolve4a-1.rs index fcb167de4538b..eeb946b1da771 100644 --- a/src/test/auxiliary/crateresolve4a-1.rs +++ b/src/test/auxiliary/crateresolve4a-1.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve4a#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve4a", vers = "0.1")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/crateresolve4a-2.rs b/src/test/auxiliary/crateresolve4a-2.rs index 6b933631c1915..9c089fd214139 100644 --- a/src/test/auxiliary/crateresolve4a-2.rs +++ b/src/test/auxiliary/crateresolve4a-2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve4a#0.2"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve4a", vers= "0.2")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/crateresolve4b-1.rs b/src/test/auxiliary/crateresolve4b-1.rs index 50de9c8962548..9fbfdcf1687d1 100644 --- a/src/test/auxiliary/crateresolve4b-1.rs +++ b/src/test/auxiliary/crateresolve4b-1.rs @@ -10,9 +10,11 @@ // aux-build:crateresolve4a-1.rs // aux-build:crateresolve4a-2.rs +#[pkgid="crateresolve4b#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve4b", vers = "0.1")]; #[crate_type = "lib"]; -extern mod crateresolve4a(vers="0.2"); +extern mod crateresolve4a = "crateresolve4a#0.2"; pub fn f() -> int { crateresolve4a::g() } diff --git a/src/test/auxiliary/crateresolve4b-2.rs b/src/test/auxiliary/crateresolve4b-2.rs index af02498ae7ce3..73484ab223201 100644 --- a/src/test/auxiliary/crateresolve4b-2.rs +++ b/src/test/auxiliary/crateresolve4b-2.rs @@ -10,9 +10,11 @@ // aux-build:crateresolve4a-1.rs // aux-build:crateresolve4a-2.rs +#[pkgid="crateresolve4b#0.2"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve4b", vers = "0.2")]; #[crate_type = "lib"]; -extern mod crateresolve4a(vers="0.1"); +extern mod crateresolve4a = "crateresolve4a#0.1"; pub fn g() -> int { crateresolve4a::f() } diff --git a/src/test/auxiliary/crateresolve5-1.rs b/src/test/auxiliary/crateresolve5-1.rs index f20a143b658ba..726b3919f7ff3 100644 --- a/src/test/auxiliary/crateresolve5-1.rs +++ b/src/test/auxiliary/crateresolve5-1.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve5#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve5", vers = "0.1")]; diff --git a/src/test/auxiliary/crateresolve5-2.rs b/src/test/auxiliary/crateresolve5-2.rs index 10adc3381596a..05a760dea7384 100644 --- a/src/test/auxiliary/crateresolve5-2.rs +++ b/src/test/auxiliary/crateresolve5-2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve5#0.2"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve5", vers = "0.2")]; diff --git a/src/test/auxiliary/crateresolve8-1.rs b/src/test/auxiliary/crateresolve8-1.rs index 22ccde01c4af3..b0990d2e3036d 100644 --- a/src/test/auxiliary/crateresolve8-1.rs +++ b/src/test/auxiliary/crateresolve8-1.rs @@ -9,6 +9,8 @@ // except according to those terms. // default link meta for 'package_id' will be equal to filestem +#[pkgid="crateresolve8#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve8", vers = "0.1")]; diff --git a/src/test/auxiliary/crateresolve_calories-1.rs b/src/test/auxiliary/crateresolve_calories-1.rs index 827517bf2768c..0f000716e4de0 100644 --- a/src/test/auxiliary/crateresolve_calories-1.rs +++ b/src/test/auxiliary/crateresolve_calories-1.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve_calories#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve_calories", vers = "0.1", calories = "100")]; diff --git a/src/test/auxiliary/crateresolve_calories-2.rs b/src/test/auxiliary/crateresolve_calories-2.rs index 8dc5182c9847f..4d3ff1e2071ab 100644 --- a/src/test/auxiliary/crateresolve_calories-2.rs +++ b/src/test/auxiliary/crateresolve_calories-2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="crateresolve_calories#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "crateresolve_calories", vers = "0.1", calories = "200")]; diff --git a/src/test/auxiliary/extern-crosscrate-source.rs b/src/test/auxiliary/extern-crosscrate-source.rs index 89317a4517113..d6bf2dda9cedf 100644 --- a/src/test/auxiliary/extern-crosscrate-source.rs +++ b/src/test/auxiliary/extern-crosscrate-source.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="externcallback#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "externcallback", vers = "0.1")]; diff --git a/src/test/auxiliary/foreign_lib.rs b/src/test/auxiliary/foreign_lib.rs index 4705d13cd9685..4a92a8dd5666c 100644 --- a/src/test/auxiliary/foreign_lib.rs +++ b/src/test/auxiliary/foreign_lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="foreign_lib"]; +// NOTE: remove after the next snapshot #[link(name="foreign_lib", vers="0.0")]; pub mod rustrt { diff --git a/src/test/auxiliary/inline_dtor.rs b/src/test/auxiliary/inline_dtor.rs index 1e93cd6359167..67db37234cf00 100644 --- a/src/test/auxiliary/inline_dtor.rs +++ b/src/test/auxiliary/inline_dtor.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="inline_dtor#0.1"]; +// NOTE: remove after the next snapshot #[link(name="inline_dtor", vers="0.1")]; pub struct Foo; diff --git a/src/test/auxiliary/iss.rs b/src/test/auxiliary/iss.rs index 3855a348f60c0..83574fb218ad6 100644 --- a/src/test/auxiliary/iss.rs +++ b/src/test/auxiliary/iss.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="issue6919_3#0.1"]; +// NOTE: remove after the next snapshot #[link(name="iss6919_3", vers="0.1")]; // part of issue-6919.rs diff --git a/src/test/auxiliary/issue-2380.rs b/src/test/auxiliary/issue-2380.rs index 1ec88ba573593..a1534aa25e44e 100644 --- a/src/test/auxiliary/issue-2380.rs +++ b/src/test/auxiliary/issue-2380.rs @@ -9,6 +9,8 @@ // except according to those terms. #[feature(managed_boxes)]; +#[pkgid="a"]; +// NOTE: remove after the next snapshot #[link(name = "a", vers = "0.0")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/issue-2414-a.rs b/src/test/auxiliary/issue-2414-a.rs index 54bb39fd2dfad..9caf89deb4926 100644 --- a/src/test/auxiliary/issue-2414-a.rs +++ b/src/test/auxiliary/issue-2414-a.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="a#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "a", vers = "0.1")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/issue-2414-b.rs b/src/test/auxiliary/issue-2414-b.rs index f4ef02a2b7f87..726f8cc29ab30 100644 --- a/src/test/auxiliary/issue-2414-b.rs +++ b/src/test/auxiliary/issue-2414-b.rs @@ -10,6 +10,8 @@ // xfail-fast +#[pkgid="b#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "b", vers = "0.1")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index 8ed65628f54f9..cdbb081f9022e 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="issue_2526#0.2"]; +// NOTE: remove after the next snapshot #[link(name = "issue_2526", vers = "0.2", uuid = "54cc1bc9-02b8-447c-a227-75ebc923bc29")]; diff --git a/src/test/auxiliary/issue-2631-a.rs b/src/test/auxiliary/issue-2631-a.rs index fe68141e6dd34..451fde61ce7ef 100644 --- a/src/test/auxiliary/issue-2631-a.rs +++ b/src/test/auxiliary/issue-2631-a.rs @@ -9,6 +9,8 @@ // except according to those terms. #[feature(managed_boxes)]; +#[pkgid="req"]; +// NOTE: remove after the next snapshot #[link(name = "req")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/issue-3012-1.rs b/src/test/auxiliary/issue-3012-1.rs index f9bbfa7ecce07..f206911a7c06f 100644 --- a/src/test/auxiliary/issue-3012-1.rs +++ b/src/test/auxiliary/issue-3012-1.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="socketlib"]; +// NOTE: remove after the next snapshot #[link(name="socketlib", vers="0.0")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/issue-4208-cc.rs b/src/test/auxiliary/issue-4208-cc.rs index 26db69fb9e17f..35b19c6558c46 100644 --- a/src/test/auxiliary/issue-4208-cc.rs +++ b/src/test/auxiliary/issue-4208-cc.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="numeric#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "numeric", vers = "0.1")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/issue_2242_a.rs b/src/test/auxiliary/issue_2242_a.rs index 9f504db8f2a4f..cfa75be5b0eb2 100644 --- a/src/test/auxiliary/issue_2242_a.rs +++ b/src/test/auxiliary/issue_2242_a.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="a#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "a", vers = "0.1")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/issue_2242_c.rs b/src/test/auxiliary/issue_2242_c.rs index 40a2bcc114a53..331d253589314 100644 --- a/src/test/auxiliary/issue_2242_c.rs +++ b/src/test/auxiliary/issue_2242_c.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="c#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "c", vers = "0.1")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/issue_3979_traits.rs b/src/test/auxiliary/issue_3979_traits.rs index eb10553f19c24..e800e59b99782 100644 --- a/src/test/auxiliary/issue_3979_traits.rs +++ b/src/test/auxiliary/issue_3979_traits.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="issue_3979_traits#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "issue_3979_traits", vers = "0.1")]; diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs index af00a6876c27d..398d0268bc57e 100644 --- a/src/test/auxiliary/lint_stability.rs +++ b/src/test/auxiliary/lint_stability.rs @@ -7,6 +7,8 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="lint_stability#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "lint_stability", vers = "0.1")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/static-function-pointer-aux.rs b/src/test/auxiliary/static-function-pointer-aux.rs index 85f01666a3fb7..b80ac427dc21d 100644 --- a/src/test/auxiliary/static-function-pointer-aux.rs +++ b/src/test/auxiliary/static-function-pointer-aux.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="static-function-pointer-aux"]; + pub fn f(x: int) -> int { -x } pub static F: extern fn(int) -> int = f; diff --git a/src/test/auxiliary/static-methods-crate.rs b/src/test/auxiliary/static-methods-crate.rs index 6978b9209d8bc..c6f27ebb97189 100644 --- a/src/test/auxiliary/static-methods-crate.rs +++ b/src/test/auxiliary/static-methods-crate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="static_methods_crate#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "static_methods_crate", vers = "0.1")]; diff --git a/src/test/auxiliary/struct_variant_xc_aux.rs b/src/test/auxiliary/struct_variant_xc_aux.rs index f797669195b76..a090b052016fc 100644 --- a/src/test/auxiliary/struct_variant_xc_aux.rs +++ b/src/test/auxiliary/struct_variant_xc_aux.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="struct_variant_xc_aux#0.1"]; +// NOTE: remove after the next snapshot #[link(name = "struct_variant_xc_aux", vers = "0.1")]; #[crate_type = "lib"]; diff --git a/src/test/auxiliary/trait_default_method_xc_aux.rs b/src/test/auxiliary/trait_default_method_xc_aux.rs index 123ad24e7a91e..a0b50f860ddc1 100644 --- a/src/test/auxiliary/trait_default_method_xc_aux.rs +++ b/src/test/auxiliary/trait_default_method_xc_aux.rs @@ -1,3 +1,4 @@ +#[pkgid="trait_default_method_xc_aux"]; pub struct Something { x: int } diff --git a/src/test/auxiliary/trait_default_method_xc_aux_2.rs b/src/test/auxiliary/trait_default_method_xc_aux_2.rs index 2d4f539f82bbd..849709dfd2210 100644 --- a/src/test/auxiliary/trait_default_method_xc_aux_2.rs +++ b/src/test/auxiliary/trait_default_method_xc_aux_2.rs @@ -1,6 +1,6 @@ // aux-build:trait_default_method_xc_aux.rs -extern mod aux(name = "trait_default_method_xc_aux"); +extern mod aux = "trait_default_method_xc_aux"; use aux::A; pub struct a_struct { x: int } diff --git a/src/test/compile-fail/crateresolve2.rs b/src/test/compile-fail/crateresolve2.rs index 130954d3a6655..b1565d4b3a150 100644 --- a/src/test/compile-fail/crateresolve2.rs +++ b/src/test/compile-fail/crateresolve2.rs @@ -13,10 +13,10 @@ // aux-build:crateresolve2-3.rs // error-pattern:using multiple versions of crate `crateresolve2` -extern mod crateresolve2(vers = "0.1"); +extern mod crateresolve2 = "crateresolve2#0.1"; mod m { - pub extern mod crateresolve2(vers = "0.2"); + pub extern mod crateresolve2 = "crateresolve2#0.2"; } fn main() { diff --git a/src/test/compile-fail/crateresolve5.rs b/src/test/compile-fail/crateresolve5.rs index 1ad190827dae9..8bf47d664ed97 100644 --- a/src/test/compile-fail/crateresolve5.rs +++ b/src/test/compile-fail/crateresolve5.rs @@ -12,8 +12,8 @@ // aux-build:crateresolve5-1.rs // aux-build:crateresolve5-2.rs -extern mod cr5_1 (name = "crateresolve5", vers = "0.1"); -extern mod cr5_2 (name = "crateresolve5", vers = "0.2"); +extern mod cr5_1 = "crateresolve5#0.1"; +extern mod cr5_2 = "crateresolve5#0.2"; fn main() { diff --git a/src/test/compile-fail/dup-link-name.rs b/src/test/compile-fail/dup-link-name.rs deleted file mode 100644 index f8ccdf118bbae..0000000000000 --- a/src/test/compile-fail/dup-link-name.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern:duplicate meta item `name` - -#[link(name = "test", name)]; - -fn main() { } diff --git a/src/test/compile-fail/use-meta-dup.rs b/src/test/compile-fail/use-meta-dup.rs deleted file mode 100644 index dd57382afbbb7..0000000000000 --- a/src/test/compile-fail/use-meta-dup.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern:duplicate meta item `name` - -extern mod extra(name = "extra", name = "nonstd"); - -fn main() { } diff --git a/src/test/compile-fail/use-meta-mismatch.rs b/src/test/compile-fail/use-meta-mismatch.rs index 118fce8a891b6..dc8250d4134fe 100644 --- a/src/test/compile-fail/use-meta-mismatch.rs +++ b/src/test/compile-fail/use-meta-mismatch.rs @@ -10,6 +10,6 @@ // error-pattern:can't find crate for `extra` -extern mod extra(complex(meta(item))); +extern mod extra = "fake-crate"; fn main() { } diff --git a/src/test/compile-fail/use-meta.rc b/src/test/compile-fail/use-meta.rc index 3be2b03575d3c..61d18a4a2f7e5 100644 --- a/src/test/compile-fail/use-meta.rc +++ b/src/test/compile-fail/use-meta.rc @@ -10,5 +10,4 @@ // error-pattern:can't find crate for `std` -extern mod std (name = "std", - vers = "bogus"); \ No newline at end of file +extern mod std = "std#bogus"; diff --git a/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs b/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs index 85941ec74a8da..e42382fa84c2a 100644 --- a/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs +++ b/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[link(package_id = "boot", name = "boot", vers = "0.1")]; -#[crate_type = "lib"]; +#[pkgid="boot#0.1"]; +#[crate_type="lib"]; extern mod rustuv; // pull in uvio diff --git a/src/test/run-pass/crateresolve1.rs b/src/test/run-pass/crateresolve1.rs index 737a60470ad3e..563a036fecdbd 100644 --- a/src/test/run-pass/crateresolve1.rs +++ b/src/test/run-pass/crateresolve1.rs @@ -13,7 +13,7 @@ // aux-build:crateresolve1-2.rs // aux-build:crateresolve1-3.rs -extern mod crateresolve1(vers = "0.2"); +extern mod crateresolve1 = "crateresolve1#0.2"; pub fn main() { assert_eq!(crateresolve1::f(), 20); diff --git a/src/test/run-pass/crateresolve2.rs b/src/test/run-pass/crateresolve2.rs index 1ffbf8320e51d..d78f8cf66baf6 100644 --- a/src/test/run-pass/crateresolve2.rs +++ b/src/test/run-pass/crateresolve2.rs @@ -14,17 +14,17 @@ // aux-build:crateresolve2-3.rs mod a { - extern mod crateresolve2(vers = "0.1"); + extern mod crateresolve2 = "crateresolve2#0.1"; pub fn f() { assert!(crateresolve2::f() == 10); } } mod b { - extern mod crateresolve2(vers = "0.2"); + extern mod crateresolve2 = "crateresolve2#0.2"; pub fn f() { assert!(crateresolve2::f() == 20); } } mod c { - extern mod crateresolve2(vers = "0.3"); + extern mod crateresolve2 = "crateresolve2#0.3"; pub fn f() { assert!(crateresolve2::f() == 30); } } diff --git a/src/test/run-pass/crateresolve3.rs b/src/test/run-pass/crateresolve3.rs index 519e67acdd6a3..3114ee0fae06d 100644 --- a/src/test/run-pass/crateresolve3.rs +++ b/src/test/run-pass/crateresolve3.rs @@ -16,12 +16,12 @@ // as long as no name collision on invoked functions. mod a { - extern mod crateresolve3(vers = "0.1"); + extern mod crateresolve3 = "crateresolve3#0.1"; pub fn f() { assert!(crateresolve3::f() == 10); } } mod b { - extern mod crateresolve3(vers = "0.2"); + extern mod crateresolve3 = "crateresolve3#0.2"; pub fn f() { assert!(crateresolve3::g() == 20); } } diff --git a/src/test/run-pass/crateresolve4.rs b/src/test/run-pass/crateresolve4.rs index ead2a2131b0cc..d913d487c0fb6 100644 --- a/src/test/run-pass/crateresolve4.rs +++ b/src/test/run-pass/crateresolve4.rs @@ -15,12 +15,12 @@ // aux-build:crateresolve4b-2.rs pub mod a { - extern mod crateresolve4b(vers = "0.1"); + extern mod crateresolve4b = "crateresolve4b#0.1"; pub fn f() { assert!(crateresolve4b::f() == 20); } } pub mod b { - extern mod crateresolve4b(vers = "0.2"); + extern mod crateresolve4b = "crateresolve4b#0.2"; pub fn f() { assert!(crateresolve4b::g() == 10); } } diff --git a/src/test/run-pass/crateresolve5.rs b/src/test/run-pass/crateresolve5.rs index 688853dd9aefc..00c8cd90f84fc 100644 --- a/src/test/run-pass/crateresolve5.rs +++ b/src/test/run-pass/crateresolve5.rs @@ -12,8 +12,8 @@ // aux-build:crateresolve5-1.rs // aux-build:crateresolve5-2.rs -extern mod cr5_1 (name = "crateresolve5", vers = "0.1"); -extern mod cr5_2 (name = "crateresolve5", vers = "0.2"); +extern mod cr5_1 = "crateresolve5#0.1"; +extern mod cr5_2 = "crateresolve5#0.2"; pub fn main() { // Structural types can be used between two versions of the same crate diff --git a/src/test/run-pass/crateresolve6.rs b/src/test/run-pass/crateresolve6.rs deleted file mode 100644 index 883f48656bcf6..0000000000000 --- a/src/test/run-pass/crateresolve6.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-fast -// aux-build:crateresolve_calories-1.rs -// aux-build:crateresolve_calories-2.rs -// error-pattern:mismatched types - -// These both have the same version but differ in other metadata -extern mod cr6_1 (name = "crateresolve_calories", vers = "0.1", calories="100"); -extern mod cr6_2 (name = "crateresolve_calories", vers = "0.1", calories="200"); - -pub fn main() { - assert_eq!(cr6_1::f(), 100); - assert_eq!(cr6_2::f(), 200); -} diff --git a/src/test/run-pass/crateresolve7.rs b/src/test/run-pass/crateresolve7.rs deleted file mode 100644 index 86fc72aa489c6..0000000000000 --- a/src/test/run-pass/crateresolve7.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-fast -// aux-build:crateresolve_calories-1.rs -// aux-build:crateresolve_calories-2.rs -// aux-build:crateresolve7x.rs - -extern mod crateresolve7x; - -pub fn main() { - assert_eq!(crateresolve7x::a::f(), 100); - assert_eq!(crateresolve7x::b::f(), 200); -} diff --git a/src/test/run-pass/crateresolve8.rs b/src/test/run-pass/crateresolve8.rs index 8ade79a4a84a1..ad716edd5ef05 100644 --- a/src/test/run-pass/crateresolve8.rs +++ b/src/test/run-pass/crateresolve8.rs @@ -11,7 +11,9 @@ // xfail-fast // aux-build:crateresolve8-1.rs -extern mod crateresolve8(vers = "0.1", package_id="crateresolve8"); +#[pkgid="crateresolve8#0.1"]; + +extern mod crateresolve8(vers = "0.1", package_id="crateresolve8#0.1"); //extern mod crateresolve8(vers = "0.1"); pub fn main() { diff --git a/src/test/run-pass/issue-1251.rs b/src/test/run-pass/issue-1251.rs index a78a10e20e8b0..7fb897f9f2020 100644 --- a/src/test/run-pass/issue-1251.rs +++ b/src/test/run-pass/issue-1251.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[pkgid="rust_get_test_int"]; +// NOTE: remove after the next snapshot #[link(name = "rust_get_test_int")]; mod rustrt { diff --git a/src/test/run-pass/issue-4545.rs b/src/test/run-pass/issue-4545.rs index 4b13563726efc..dfee437ba35e6 100644 --- a/src/test/run-pass/issue-4545.rs +++ b/src/test/run-pass/issue-4545.rs @@ -11,5 +11,5 @@ // xfail-fast check-fast doesn't like aux-build // aux-build:issue-4545.rs -extern mod somelib(name = "issue-4545"); +extern mod somelib = "issue-4545"; fn main() { somelib::mk::(); } diff --git a/src/test/run-pass/issue-6919.rs b/src/test/run-pass/issue-6919.rs index f63811fa82bdd..041c0609dcd9e 100644 --- a/src/test/run-pass/issue-6919.rs +++ b/src/test/run-pass/issue-6919.rs @@ -11,9 +11,11 @@ // aux-build:iss.rs // xfail-fast -extern mod iss ( name = "iss6919_3" ); +#[pkgid="issue-6919"]; + +extern mod issue6919_3; pub fn main() { - iss::D.k; + issue6919_3::D.k; } diff --git a/src/test/run-pass/issue-8044.rs b/src/test/run-pass/issue-8044.rs index 300f54aa10682..15d490e98d64f 100644 --- a/src/test/run-pass/issue-8044.rs +++ b/src/test/run-pass/issue-8044.rs @@ -11,7 +11,7 @@ // xfail-fast check-fast doesn't like aux-build // aux-build:issue-8044.rs -extern mod minimal(name= "issue-8044"); +extern mod minimal = "issue-8044"; use minimal::{BTree, leaf}; fn main() { diff --git a/src/test/run-pass/issue-9906.rs b/src/test/run-pass/issue-9906.rs index ac15fef362226..e44374cb23a35 100644 --- a/src/test/run-pass/issue-9906.rs +++ b/src/test/run-pass/issue-9906.rs @@ -11,7 +11,7 @@ // xfail-fast check-fast doesn't like extern mod // aux-build:issue-9906.rs -extern mod testmod(name = "issue-9906"); +extern mod testmod = "issue-9906"; fn main() { testmod::foo(); diff --git a/src/test/run-pass/issue-9968.rs b/src/test/run-pass/issue-9968.rs index ebe268cce1c42..4ea5aba91dac4 100644 --- a/src/test/run-pass/issue-9968.rs +++ b/src/test/run-pass/issue-9968.rs @@ -11,7 +11,7 @@ // xfail-fast check-fast doesn't like extern mod // aux-build:issue-9968.rs -extern mod lib(name = "issue-9968"); +extern mod lib = "issue-9968"; use lib::{Trait, Struct}; diff --git a/src/test/run-pass/item-attributes.rs b/src/test/run-pass/item-attributes.rs index 310dbea50d102..99ada9cc650d5 100644 --- a/src/test/run-pass/item-attributes.rs +++ b/src/test/run-pass/item-attributes.rs @@ -16,6 +16,8 @@ #[attr3]; #[attr4(attr5)]; +#[pkgid="extra#0.1"]; +// NOTE: remove after the next snapshot // Special linkage attributes for the crate #[link(name = "extra", vers = "0.1", diff --git a/src/test/run-pass/linkage-visibility.rs b/src/test/run-pass/linkage-visibility.rs index 645be40250aff..438fd21e81040 100644 --- a/src/test/run-pass/linkage-visibility.rs +++ b/src/test/run-pass/linkage-visibility.rs @@ -13,7 +13,7 @@ // xfail-android: FIXME(#10379) // xfail-win32: std::unstable::dynamic_lib does not work on win32 well -extern mod foo(name = "linkage-visibility"); +extern mod foo = "linkage-visibility"; fn main() { foo::test(); diff --git a/src/test/run-pass/priv-impl-prim-ty.rs b/src/test/run-pass/priv-impl-prim-ty.rs index 4439da4f6f513..0c722e1ede591 100644 --- a/src/test/run-pass/priv-impl-prim-ty.rs +++ b/src/test/run-pass/priv-impl-prim-ty.rs @@ -11,7 +11,7 @@ // xfail-fast // aux-build:priv-impl-prim-ty.rs -extern mod bar(name = "priv-impl-prim-ty"); +extern mod bar = "priv-impl-prim-ty"; fn main() { bar::frob(1i); diff --git a/src/test/run-pass/reexport-should-still-link.rs b/src/test/run-pass/reexport-should-still-link.rs index f2d90a2374ac3..fcfcc30c98898 100644 --- a/src/test/run-pass/reexport-should-still-link.rs +++ b/src/test/run-pass/reexport-should-still-link.rs @@ -11,7 +11,7 @@ // aux-build:reexport-should-still-link.rs // xfail-fast check-fast doesn't like extern mod -extern mod foo(name = "reexport-should-still-link"); +extern mod foo = "reexport-should-still-link"; fn main() { foo::bar(); diff --git a/src/test/run-pass/static-fn-inline-xc.rs b/src/test/run-pass/static-fn-inline-xc.rs index e3441661d5b19..e772488c8727b 100644 --- a/src/test/run-pass/static-fn-inline-xc.rs +++ b/src/test/run-pass/static-fn-inline-xc.rs @@ -11,7 +11,7 @@ // xfail-fast // aux-build:static_fn_inline_xc_aux.rs -extern mod mycore(name ="static_fn_inline_xc_aux"); +extern mod mycore = "static_fn_inline_xc_aux"; use mycore::num; diff --git a/src/test/run-pass/static-fn-trait-xc.rs b/src/test/run-pass/static-fn-trait-xc.rs index 41665871451f0..ef40d2789e46a 100644 --- a/src/test/run-pass/static-fn-trait-xc.rs +++ b/src/test/run-pass/static-fn-trait-xc.rs @@ -1,7 +1,7 @@ // aux-build:static_fn_trait_xc_aux.rs // xfail-fast -extern mod mycore(name ="static_fn_trait_xc_aux"); +extern mod mycore = "static_fn_trait_xc_aux"; use mycore::num; diff --git a/src/test/run-pass/static-function-pointer-xc.rs b/src/test/run-pass/static-function-pointer-xc.rs index 0ba47320a67b9..61790e9358411 100644 --- a/src/test/run-pass/static-function-pointer-xc.rs +++ b/src/test/run-pass/static-function-pointer-xc.rs @@ -10,7 +10,7 @@ // xfail-fast // aux-build:static-function-pointer-aux.rs -extern mod aux(name = "static-function-pointer-aux"); +extern mod aux = "static-function-pointer-aux"; fn f(x: int) -> int { x } diff --git a/src/test/run-pass/trait-default-method-xc-2.rs b/src/test/run-pass/trait-default-method-xc-2.rs index 1dad5d23b8823..171971e73e02e 100644 --- a/src/test/run-pass/trait-default-method-xc-2.rs +++ b/src/test/run-pass/trait-default-method-xc-2.rs @@ -3,8 +3,8 @@ // aux-build:trait_default_method_xc_aux_2.rs -extern mod aux(name = "trait_default_method_xc_aux"); -extern mod aux2(name = "trait_default_method_xc_aux_2"); +extern mod aux = "trait_default_method_xc_aux"; +extern mod aux2 = "trait_default_method_xc_aux_2"; use aux::A; use aux2::{a_struct, welp}; diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs index fe0194d6f8cea..9813864724c2b 100644 --- a/src/test/run-pass/trait-default-method-xc.rs +++ b/src/test/run-pass/trait-default-method-xc.rs @@ -4,7 +4,7 @@ // aux-build:trait_default_method_xc_aux.rs -extern mod aux(name = "trait_default_method_xc_aux"); +extern mod aux = "trait_default_method_xc_aux"; use aux::{A, TestEquality, Something}; use aux::B; diff --git a/src/test/run-pass/trait-inheritance-auto-xc-2.rs b/src/test/run-pass/trait-inheritance-auto-xc-2.rs index 3f8d536888469..6793db96509a1 100644 --- a/src/test/run-pass/trait-inheritance-auto-xc-2.rs +++ b/src/test/run-pass/trait-inheritance-auto-xc-2.rs @@ -11,7 +11,7 @@ // xfail-fast // aux-build:trait_inheritance_auto_xc_2_aux.rs -extern mod aux(name = "trait_inheritance_auto_xc_2_aux"); +extern mod aux = "trait_inheritance_auto_xc_2_aux"; // aux defines impls of Foo, Bar and Baz for A use aux::{Foo, Bar, Baz, A}; diff --git a/src/test/run-pass/trait-inheritance-auto-xc.rs b/src/test/run-pass/trait-inheritance-auto-xc.rs index 2e8883f026788..d4f718608a968 100644 --- a/src/test/run-pass/trait-inheritance-auto-xc.rs +++ b/src/test/run-pass/trait-inheritance-auto-xc.rs @@ -11,7 +11,7 @@ // xfail-fast // aux-build:trait_inheritance_auto_xc_aux.rs -extern mod aux(name = "trait_inheritance_auto_xc_aux"); +extern mod aux = "trait_inheritance_auto_xc_aux"; use aux::{Foo, Bar, Baz, Quux}; diff --git a/src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs b/src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs index eddec87472c5a..0cdc1d0e27fec 100644 --- a/src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs +++ b/src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs @@ -11,7 +11,7 @@ // xfail-fast // aux-build:trait_inheritance_cross_trait_call_xc_aux.rs -extern mod aux(name = "trait_inheritance_cross_trait_call_xc_aux"); +extern mod aux = "trait_inheritance_cross_trait_call_xc_aux"; use aux::Foo; diff --git a/src/test/run-pass/typeid-intrinsic.rs b/src/test/run-pass/typeid-intrinsic.rs index 1999043c6cdd2..a500e167a8b5f 100644 --- a/src/test/run-pass/typeid-intrinsic.rs +++ b/src/test/run-pass/typeid-intrinsic.rs @@ -12,8 +12,8 @@ // aux-build:typeid-intrinsic.rs // aux-build:typeid-intrinsic2.rs -extern mod other1(name = "typeid-intrinsic"); -extern mod other2(name = "typeid-intrinsic2"); +extern mod other1 = "typeid-intrinsic"; +extern mod other2 = "typeid-intrinsic2"; use std::unstable::intrinsics; use std::unstable::intrinsics::TypeId; diff --git a/src/test/run-pass/use-crate-name-alias.rs b/src/test/run-pass/use-crate-name-alias.rs index 4954de3919ffe..d9f40e5f1f3d8 100644 --- a/src/test/run-pass/use-crate-name-alias.rs +++ b/src/test/run-pass/use-crate-name-alias.rs @@ -9,6 +9,6 @@ // except according to those terms. // Issue #1706 -extern mod stdlib(name="extra"); +extern mod stdlib = "extra"; pub fn main() {} diff --git a/src/test/run-pass/use.rs b/src/test/run-pass/use.rs index 8ae8dafc23ede..ddd4b10fd5c95 100644 --- a/src/test/run-pass/use.rs +++ b/src/test/run-pass/use.rs @@ -14,8 +14,8 @@ #[no_std]; extern mod std; -extern mod zed(name = "std"); -extern mod bar(name = "std", vers = "0.9-pre"); +extern mod zed = "std"; +extern mod bar = "std#0.9-pre"; use std::str; diff --git a/src/test/run-pass/xcrate-address-insignificant.rs b/src/test/run-pass/xcrate-address-insignificant.rs index 91b8c99ca19be..8a5a4a0cfe517 100644 --- a/src/test/run-pass/xcrate-address-insignificant.rs +++ b/src/test/run-pass/xcrate-address-insignificant.rs @@ -11,7 +11,7 @@ // xfail-fast check-fast doesn't like aux-build // aux-build:xcrate_address_insignificant.rs -extern mod foo(name = "xcrate_address_insignificant"); +extern mod foo = "xcrate_address_insignificant"; fn main() { assert_eq!(foo::foo::(), foo::bar()); diff --git a/src/test/run-pass/xcrate-trait-lifetime-param.rs b/src/test/run-pass/xcrate-trait-lifetime-param.rs index 51ba05f1faf39..941efdb24a8a6 100644 --- a/src/test/run-pass/xcrate-trait-lifetime-param.rs +++ b/src/test/run-pass/xcrate-trait-lifetime-param.rs @@ -11,7 +11,7 @@ // xfail-fast // aux-build:xcrate-trait-lifetime-param.rs -extern mod other(name = "xcrate-trait-lifetime-param"); +extern mod other = "xcrate-trait-lifetime-param"; struct Reader<'a> { b : &'a [u8]