From b349036e5f4f5f42e34ae9dd7859f3dc7a79de94 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Mon, 9 Dec 2013 14:56:53 -0700 Subject: [PATCH 1/2] Make crate hash stable and externally computable. This replaces the link meta attributes with a pkgid attribute and uses a hash of this as the crate hash. This makes the crate hash computable by things other than the Rust compiler. It also switches the hash function ot SHA1 since that is much more likely to be available in shell, Python, etc than SipHash. Fixes #10188, #8523. --- src/driver/driver.rs | 8 +- src/etc/combine-tests.py | 1 + src/libextra/lib.rs | 2 + src/librustc/back/link.rs | 237 ++----- src/librustc/driver/driver.rs | 19 +- src/librustc/lib.rs | 3 + src/librustc/metadata/common.rs | 10 +- src/librustc/metadata/creader.rs | 111 ++- src/librustc/metadata/decoder.rs | 8 +- src/librustc/metadata/encoder.rs | 67 +- src/librustc/metadata/loader.rs | 83 +-- src/librustc/middle/lint.rs | 2 +- src/librustc/middle/trans/base.rs | 17 +- src/librustc/middle/trans/context.rs | 10 +- src/librustc/middle/trans/debuginfo.rs | 2 +- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/trans/intrinsic.rs | 2 +- src/librustc/util/sha2.rs | 670 ++++++++++++++++++ src/librustdoc/lib.rs | 2 + src/librustpkg/lib.rs | 9 +- src/librustpkg/tests.rs | 92 +-- .../testsuite/pass/src/c-dependencies/pkg.rs | 2 +- src/librustpkg/util.rs | 51 +- src/librustpkg/version.rs | 4 +- src/librustpkg/workcache_support.rs | 6 +- src/librustuv/lib.rs | 2 + src/libstd/lib.rs | 8 +- src/libstd/rt/sched.rs | 2 - src/libsyntax/attr.rs | 8 + src/libsyntax/lib.rs | 3 + src/libsyntax/pkgid.rs | 160 +++++ .../anon-extern-mod-cross-crate-1.rs | 6 +- src/test/auxiliary/cci_impl_lib.rs | 2 + src/test/auxiliary/cci_iter_lib.rs | 2 + src/test/auxiliary/cci_no_inline_lib.rs | 2 + .../crate-method-reexport-grrrrrrr2.rs | 2 + src/test/auxiliary/crateresolve1-1.rs | 2 + src/test/auxiliary/crateresolve1-2.rs | 2 + src/test/auxiliary/crateresolve1-3.rs | 2 + src/test/auxiliary/crateresolve2-1.rs | 2 + src/test/auxiliary/crateresolve2-2.rs | 2 + src/test/auxiliary/crateresolve2-3.rs | 2 + src/test/auxiliary/crateresolve3-1.rs | 2 + src/test/auxiliary/crateresolve3-2.rs | 2 + src/test/auxiliary/crateresolve4a-1.rs | 2 + src/test/auxiliary/crateresolve4a-2.rs | 2 + src/test/auxiliary/crateresolve4b-1.rs | 4 +- src/test/auxiliary/crateresolve4b-2.rs | 4 +- src/test/auxiliary/crateresolve5-1.rs | 2 + src/test/auxiliary/crateresolve5-2.rs | 2 + src/test/auxiliary/crateresolve8-1.rs | 2 + src/test/auxiliary/crateresolve_calories-1.rs | 2 + src/test/auxiliary/crateresolve_calories-2.rs | 2 + .../auxiliary/extern-crosscrate-source.rs | 2 + src/test/auxiliary/foreign_lib.rs | 2 + src/test/auxiliary/inline_dtor.rs | 2 + src/test/auxiliary/iss.rs | 2 + src/test/auxiliary/issue-2380.rs | 2 + src/test/auxiliary/issue-2414-a.rs | 2 + src/test/auxiliary/issue-2414-b.rs | 2 + src/test/auxiliary/issue-2526.rs | 2 + src/test/auxiliary/issue-2631-a.rs | 2 + src/test/auxiliary/issue-3012-1.rs | 2 + src/test/auxiliary/issue-4208-cc.rs | 2 + src/test/auxiliary/issue_2242_a.rs | 2 + src/test/auxiliary/issue_2242_c.rs | 2 + src/test/auxiliary/issue_3979_traits.rs | 2 + src/test/auxiliary/lint_stability.rs | 2 + .../auxiliary/static-function-pointer-aux.rs | 2 + src/test/auxiliary/static-methods-crate.rs | 2 + src/test/auxiliary/struct_variant_xc_aux.rs | 2 + .../auxiliary/trait_default_method_xc_aux.rs | 1 + .../trait_default_method_xc_aux_2.rs | 2 +- src/test/compile-fail/crateresolve2.rs | 4 +- src/test/compile-fail/crateresolve5.rs | 4 +- src/test/compile-fail/dup-link-name.rs | 15 - src/test/compile-fail/use-meta-dup.rs | 15 - src/test/compile-fail/use-meta-mismatch.rs | 2 +- src/test/compile-fail/use-meta.rc | 3 +- .../bootstrap-from-c-with-uvio/lib.rs | 4 +- src/test/run-pass/crateresolve1.rs | 2 +- src/test/run-pass/crateresolve2.rs | 6 +- src/test/run-pass/crateresolve3.rs | 4 +- src/test/run-pass/crateresolve4.rs | 4 +- src/test/run-pass/crateresolve5.rs | 4 +- src/test/run-pass/crateresolve6.rs | 23 - src/test/run-pass/crateresolve7.rs | 21 - src/test/run-pass/crateresolve8.rs | 4 +- src/test/run-pass/issue-1251.rs | 2 + src/test/run-pass/issue-4545.rs | 2 +- src/test/run-pass/issue-6919.rs | 6 +- src/test/run-pass/issue-8044.rs | 2 +- src/test/run-pass/issue-9906.rs | 2 +- src/test/run-pass/issue-9968.rs | 2 +- src/test/run-pass/item-attributes.rs | 2 + src/test/run-pass/linkage-visibility.rs | 2 +- src/test/run-pass/priv-impl-prim-ty.rs | 2 +- .../run-pass/reexport-should-still-link.rs | 2 +- src/test/run-pass/static-fn-inline-xc.rs | 2 +- src/test/run-pass/static-fn-trait-xc.rs | 2 +- .../run-pass/static-function-pointer-xc.rs | 2 +- .../run-pass/trait-default-method-xc-2.rs | 4 +- src/test/run-pass/trait-default-method-xc.rs | 2 +- .../run-pass/trait-inheritance-auto-xc-2.rs | 2 +- .../run-pass/trait-inheritance-auto-xc.rs | 2 +- .../trait-inheritance-cross-trait-call-xc.rs | 2 +- src/test/run-pass/typeid-intrinsic.rs | 4 +- src/test/run-pass/use-crate-name-alias.rs | 2 +- src/test/run-pass/use.rs | 4 +- .../run-pass/xcrate-address-insignificant.rs | 2 +- .../run-pass/xcrate-trait-lifetime-param.rs | 2 +- 111 files changed, 1261 insertions(+), 604 deletions(-) create mode 100644 src/librustc/util/sha2.rs create mode 100644 src/libsyntax/pkgid.rs delete mode 100644 src/test/compile-fail/dup-link-name.rs delete mode 100644 src/test/compile-fail/use-meta-dup.rs delete mode 100644 src/test/run-pass/crateresolve6.rs delete mode 100644 src/test/run-pass/crateresolve7.rs 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] From a16753c18844ad37d63ee00fe0292303afc990ac Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Tue, 10 Dec 2013 17:04:17 -0700 Subject: [PATCH 2/2] Add missing sundown dependency to rustdoc tests. --- mk/tests.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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))