From 47515ad5bdd8503a518db6a2c1fa9a8abeb1d67d Mon Sep 17 00:00:00 2001 From: Liigo Zhuang Date: Mon, 24 Oct 2016 09:09:44 +0800 Subject: [PATCH 01/24] rustdoc: mark unsafe fns with icons --- src/librustdoc/html/render.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 77a5ff3243a6c..97193f37acba7 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1828,11 +1828,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, } else { String::new() }; + + let mut unsafety_flag = ""; + if let clean::FunctionItem(ref func) = myitem.inner { + if func.unsafety == hir::Unsafety::Unsafe { + unsafety_flag = ""; + } + } + let doc_value = myitem.doc_value().unwrap_or(""); write!(w, " {name} + title='{title}'>{name}{unsafety_flag} {stab_docs} {docs} @@ -1842,6 +1850,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, docs = shorter(Some(&Markdown(doc_value).to_string())), class = myitem.type_(), stab = myitem.stability_class(), + unsafety_flag = unsafety_flag, href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()), title = full_path(cx, myitem))?; } From 955829cee9a5bc5b07895200df50085225bca9f6 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 29 Oct 2016 15:23:49 -0700 Subject: [PATCH 02/24] Add documentation to write! and writeln! on using both io::Write and fmt::Write Various existing code does this, but the documentation doesn't explain how to do it. --- src/libcore/macros.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index e6c3f549ec8e6..dfd197a414865 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -348,6 +348,21 @@ macro_rules! try { /// /// assert_eq!(w, b"testformatted arguments"); /// ``` +/// +/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects +/// implementing either, as objects do not typically implement both. However, the module must +/// import the traits qualified so their names do not conflict: +/// +/// ``` +/// use std::fmt::Write as FmtWrite; +/// use std::io::Write as IoWrite; +/// +/// let mut s = String::new(); +/// let mut v = Vec::new(); +/// write!(&mut s, "{} {}", "abc", 123).unwrap(); // uses fmt::Write::write_fmt +/// write!(&mut v, "s = {:?}", s).unwrap(); // uses io::Write::write_fmt +/// assert_eq!(v, b"s = \"abc 123\""); +/// ``` #[macro_export] #[stable(feature = "core", since = "1.6.0")] macro_rules! write { @@ -391,6 +406,21 @@ macro_rules! write { /// /// assert_eq!(&w[..], "test\nformatted arguments\n".as_bytes()); /// ``` +/// +/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects +/// implementing either, as objects do not typically implement both. However, the module must +/// import the traits qualified so their names do not conflict: +/// +/// ``` +/// use std::fmt::Write as FmtWrite; +/// use std::io::Write as IoWrite; +/// +/// let mut s = String::new(); +/// let mut v = Vec::new(); +/// writeln!(&mut s, "{} {}", "abc", 123).unwrap(); // uses fmt::Write::write_fmt +/// writeln!(&mut v, "s = {:?}", s).unwrap(); // uses io::Write::write_fmt +/// assert_eq!(v, b"s = \"abc 123\\n\"\n"); +/// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! writeln { From 40c2c0f833c0480c3cf3904fa3614cb0a01d7f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 23 Oct 2016 18:54:31 -0700 Subject: [PATCH 03/24] Include type of missing trait methods in error Provide either a span pointing to the original definition of missing trait items, or a message with the inferred definitions. --- src/librustc_typeck/check/mod.rs | 33 +++++++--- src/test/run-make/missing-items/Makefile | 10 +++ src/test/run-make/missing-items/m1.rs | 17 +++++ src/test/run-make/missing-items/m2.rs | 19 ++++++ src/test/{compile-fail => ui/span}/E0046.rs | 1 + src/test/ui/span/E0046.stderr | 11 ++++ .../span}/impl-wrong-item-for-trait.rs | 9 ++- .../ui/span/impl-wrong-item-for-trait.stderr | 64 +++++++++++++++++++ .../{compile-fail => ui/span}/issue-23729.rs | 1 + src/test/ui/span/issue-23729.stderr | 10 +++ .../{compile-fail => ui/span}/issue-23827.rs | 1 + src/test/ui/span/issue-23827.stderr | 10 +++ .../{compile-fail => ui/span}/issue-24356.rs | 1 + src/test/ui/span/issue-24356.stderr | 10 +++ 14 files changed, 186 insertions(+), 11 deletions(-) create mode 100644 src/test/run-make/missing-items/Makefile create mode 100644 src/test/run-make/missing-items/m1.rs create mode 100644 src/test/run-make/missing-items/m2.rs rename src/test/{compile-fail => ui/span}/E0046.rs (95%) create mode 100644 src/test/ui/span/E0046.stderr rename src/test/{compile-fail => ui/span}/impl-wrong-item-for-trait.rs (92%) create mode 100644 src/test/ui/span/impl-wrong-item-for-trait.stderr rename src/test/{compile-fail => ui/span}/issue-23729.rs (96%) create mode 100644 src/test/ui/span/issue-23729.stderr rename src/test/{compile-fail => ui/span}/issue-23827.rs (96%) create mode 100644 src/test/ui/span/issue-23827.stderr rename src/test/{compile-fail => ui/span}/issue-24356.rs (94%) create mode 100644 src/test/ui/span/issue-24356.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 75a14bb3db922..d1cf3eb53a409 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1114,7 +1114,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, if !is_implemented { if !is_provided { - missing_items.push(trait_item.name()); + missing_items.push(trait_item); } else if associated_type_overridden { invalidated_items.push(trait_item.name()); } @@ -1122,16 +1122,25 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } if !missing_items.is_empty() { - struct_span_err!(tcx.sess, impl_span, E0046, + let mut err = struct_span_err!(tcx.sess, impl_span, E0046, "not all trait items implemented, missing: `{}`", missing_items.iter() - .map(|name| name.to_string()) - .collect::>().join("`, `")) - .span_label(impl_span, &format!("missing `{}` in implementation", + .map(|trait_item| trait_item.name().to_string()) + .collect::>().join("`, `")); + err.span_label(impl_span, &format!("missing `{}` in implementation", missing_items.iter() - .map(|name| name.to_string()) - .collect::>().join("`, `")) - ).emit(); + .map(|trait_item| trait_item.name().to_string()) + .collect::>().join("`, `"))); + for trait_item in missing_items { + if let Some(span) = tcx.map.span_if_local(trait_item.def_id()) { + err.span_label(span, &format!("`{}` from trait", trait_item.name())); + } else { + err.note(&format!("`{}` from trait: `{}`", + trait_item.name(), + signature(trait_item))); + } + } + err.emit(); } if !invalidated_items.is_empty() { @@ -1146,6 +1155,14 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } +fn signature<'a, 'tcx>(item: &ty::ImplOrTraitItem) -> String { + match *item { + ty::MethodTraitItem(ref item) => format!("{}", item.fty.sig.0), + ty::TypeTraitItem(ref item) => format!("type {};", item.name.to_string()), + ty::ConstTraitItem(ref item) => format!("const {}: {:?};", item.name.to_string(), item.ty), + } +} + /// Checks a constant with a given type. fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, expr: &'tcx hir::Expr, diff --git a/src/test/run-make/missing-items/Makefile b/src/test/run-make/missing-items/Makefile new file mode 100644 index 0000000000000..bcc9cdf2d6527 --- /dev/null +++ b/src/test/run-make/missing-items/Makefile @@ -0,0 +1,10 @@ +-include ../tools.mk + +all: + $(RUSTC) m1.rs -C prefer-dynamic + $(RUSTC) m2.rs 2>&1 | grep "error\[E0046\]: not all trait items implemented, missing: .*" + $(RUSTC) m2.rs 2>&1 | grep " --> m2.rs:18:1" + $(RUSTC) m2.rs 2>&1 | grep " | ^ missing .CONSTANT., .Type., .method. in implementation" + $(RUSTC) m2.rs 2>&1 | grep " = note: .CONSTANT. from trait: .const CONSTANT: u32;." + $(RUSTC) m2.rs 2>&1 | grep " = note: .Type. from trait: .type Type;." + $(RUSTC) m2.rs 2>&1 | grep " = note: .method. from trait: .fn(&Self, std::string::String) -> ::Type." diff --git a/src/test/run-make/missing-items/m1.rs b/src/test/run-make/missing-items/m1.rs new file mode 100644 index 0000000000000..060c7a9571b7b --- /dev/null +++ b/src/test/run-make/missing-items/m1.rs @@ -0,0 +1,17 @@ +// Copyright 2014 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. + +#![feature(associated_consts)] +#![crate_type = "dylib"] +pub trait X { + const CONSTANT: u32; + type Type; + fn method(&self, s: String) -> Self::Type; +} diff --git a/src/test/run-make/missing-items/m2.rs b/src/test/run-make/missing-items/m2.rs new file mode 100644 index 0000000000000..7055673acc9a9 --- /dev/null +++ b/src/test/run-make/missing-items/m2.rs @@ -0,0 +1,19 @@ +// Copyright 2014 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. + +#![feature(associated_consts)] +#![crate_type = "dylib"] +extern crate m1; + +struct X { +} + +impl m1::X for X { +} diff --git a/src/test/compile-fail/E0046.rs b/src/test/ui/span/E0046.rs similarity index 95% rename from src/test/compile-fail/E0046.rs rename to src/test/ui/span/E0046.rs index a8b56b2b9ab37..9e757860a857b 100644 --- a/src/test/compile-fail/E0046.rs +++ b/src/test/ui/span/E0046.rs @@ -10,6 +10,7 @@ trait Foo { fn foo(); + //~^ NOTE `foo` from trait } struct Bar; diff --git a/src/test/ui/span/E0046.stderr b/src/test/ui/span/E0046.stderr new file mode 100644 index 0000000000000..729a515612463 --- /dev/null +++ b/src/test/ui/span/E0046.stderr @@ -0,0 +1,11 @@ +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/E0046.rs:18:1 + | +12 | fn foo(); + | --------- `foo` from trait +... +18 | impl Foo for Bar {} + | ^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation + +error: aborting due to previous error + diff --git a/src/test/compile-fail/impl-wrong-item-for-trait.rs b/src/test/ui/span/impl-wrong-item-for-trait.rs similarity index 92% rename from src/test/compile-fail/impl-wrong-item-for-trait.rs rename to src/test/ui/span/impl-wrong-item-for-trait.rs index 388c9a1729cca..54ed42af5d582 100644 --- a/src/test/compile-fail/impl-wrong-item-for-trait.rs +++ b/src/test/ui/span/impl-wrong-item-for-trait.rs @@ -10,11 +10,11 @@ #![feature(associated_consts)] +use std::fmt::Debug; + trait Foo { fn bar(&self); - //~^ NOTE item in trait - //~| NOTE item in trait - const MY_CONST: u32; //~ NOTE item in trait + const MY_CONST: u32; } pub struct FooConstForMethod; @@ -50,4 +50,7 @@ impl Foo for FooTypeForMethod { const MY_CONST: u32 = 1; } +impl Debug for FooTypeForMethod { +} + fn main () {} diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr new file mode 100644 index 0000000000000..244285e358453 --- /dev/null +++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr @@ -0,0 +1,64 @@ +error[E0323]: item `bar` is an associated const, which doesn't match its trait `` + --> $DIR/impl-wrong-item-for-trait.rs:25:5 + | +16 | fn bar(&self); + | -------------- item in trait +... +25 | const bar: u64 = 1; + | ^^^^^^^^^^^^^^^^^^^ does not match trait + +error[E0046]: not all trait items implemented, missing: `bar` + --> $DIR/impl-wrong-item-for-trait.rs:22:1 + | +16 | fn bar(&self); + | -------------- `bar` from trait +... +22 | impl Foo for FooConstForMethod { + | ^ missing `bar` in implementation + +error[E0324]: item `MY_CONST` is an associated method, which doesn't match its trait `` + --> $DIR/impl-wrong-item-for-trait.rs:37:5 + | +17 | const MY_CONST: u32; + | -------------------- item in trait +... +37 | fn MY_CONST() {} + | ^^^^^^^^^^^^^^^^ does not match trait + +error[E0046]: not all trait items implemented, missing: `MY_CONST` + --> $DIR/impl-wrong-item-for-trait.rs:33:1 + | +17 | const MY_CONST: u32; + | -------------------- `MY_CONST` from trait +... +33 | impl Foo for FooMethodForConst { + | ^ missing `MY_CONST` in implementation + +error[E0325]: item `bar` is an associated type, which doesn't match its trait `` + --> $DIR/impl-wrong-item-for-trait.rs:47:5 + | +16 | fn bar(&self); + | -------------- item in trait +... +47 | type bar = u64; + | ^^^^^^^^^^^^^^^ does not match trait + +error[E0046]: not all trait items implemented, missing: `bar` + --> $DIR/impl-wrong-item-for-trait.rs:44:1 + | +16 | fn bar(&self); + | -------------- `bar` from trait +... +44 | impl Foo for FooTypeForMethod { + | ^ missing `bar` in implementation + +error[E0046]: not all trait items implemented, missing: `fmt` + --> $DIR/impl-wrong-item-for-trait.rs:53:1 + | +53 | impl Debug for FooTypeForMethod { + | ^ missing `fmt` in implementation + | + = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` + +error: aborting due to 7 previous errors + diff --git a/src/test/compile-fail/issue-23729.rs b/src/test/ui/span/issue-23729.rs similarity index 96% rename from src/test/compile-fail/issue-23729.rs rename to src/test/ui/span/issue-23729.rs index b1047ce18cccd..66134a03baf41 100644 --- a/src/test/compile-fail/issue-23729.rs +++ b/src/test/ui/span/issue-23729.rs @@ -20,6 +20,7 @@ fn main() { impl Iterator for Recurrence { //~^ ERROR E0046 //~| NOTE missing `Item` in implementation + //~| NOTE `Item` from trait: `type Item;` #[inline] fn next(&mut self) -> Option { if self.pos < 2 { diff --git a/src/test/ui/span/issue-23729.stderr b/src/test/ui/span/issue-23729.stderr new file mode 100644 index 0000000000000..493ca01778bc1 --- /dev/null +++ b/src/test/ui/span/issue-23729.stderr @@ -0,0 +1,10 @@ +error[E0046]: not all trait items implemented, missing: `Item` + --> $DIR/issue-23729.rs:20:9 + | +20 | impl Iterator for Recurrence { + | ^ missing `Item` in implementation + | + = note: `Item` from trait: `type Item;` + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-23827.rs b/src/test/ui/span/issue-23827.rs similarity index 96% rename from src/test/compile-fail/issue-23827.rs rename to src/test/ui/span/issue-23827.rs index 2062e2373129b..a5ab443597b9b 100644 --- a/src/test/compile-fail/issue-23827.rs +++ b/src/test/ui/span/issue-23827.rs @@ -36,6 +36,7 @@ impl FnMut<(C,)> for Prototype { impl FnOnce<(C,)> for Prototype { //~^ ERROR E0046 //~| NOTE missing `Output` in implementation + //~| NOTE `Output` from trait: `type Output;` extern "rust-call" fn call_once(self, (comp,): (C,)) -> Prototype { Fn::call(&self, (comp,)) } diff --git a/src/test/ui/span/issue-23827.stderr b/src/test/ui/span/issue-23827.stderr new file mode 100644 index 0000000000000..5130bb53a198b --- /dev/null +++ b/src/test/ui/span/issue-23827.stderr @@ -0,0 +1,10 @@ +error[E0046]: not all trait items implemented, missing: `Output` + --> $DIR/issue-23827.rs:36:1 + | +36 | impl FnOnce<(C,)> for Prototype { + | ^ missing `Output` in implementation + | + = note: `Output` from trait: `type Output;` + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-24356.rs b/src/test/ui/span/issue-24356.rs similarity index 94% rename from src/test/compile-fail/issue-24356.rs rename to src/test/ui/span/issue-24356.rs index d39fd539dcebc..0997dc802f88b 100644 --- a/src/test/compile-fail/issue-24356.rs +++ b/src/test/ui/span/issue-24356.rs @@ -30,6 +30,7 @@ fn main() { impl Deref for Thing { //~^ ERROR E0046 //~| NOTE missing `Target` in implementation + //~| NOTE `Target` from trait: `type Target;` fn deref(&self) -> i8 { self.0 } } diff --git a/src/test/ui/span/issue-24356.stderr b/src/test/ui/span/issue-24356.stderr new file mode 100644 index 0000000000000..906ef25ca0e10 --- /dev/null +++ b/src/test/ui/span/issue-24356.stderr @@ -0,0 +1,10 @@ +error[E0046]: not all trait items implemented, missing: `Target` + --> $DIR/issue-24356.rs:30:9 + | +30 | impl Deref for Thing { + | ^ missing `Target` in implementation + | + = note: `Target` from trait: `type Target;` + +error: aborting due to previous error + From b1a3f88e5501521548ddea4e918d55cc1c777187 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Oct 2016 01:40:02 +0200 Subject: [PATCH 04/24] Print more tags in rustdoc --- src/librustdoc/html/render.rs | 48 +++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a848a011f88db..e3efcc5c2f98d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2492,16 +2492,48 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, Ok(()) } +fn attribute_without_value(s: &str) -> bool { + vec!("must_use", "no_mangle", "unsafe_destructor_blind_to_params").iter().any(|x| x == &s) +} + +fn attribute_with_value(s: &str) -> bool { + vec!("export_name", "lang", "link_section", "must_use").iter().any(|x| x == &s) +} + +fn attribute_with_values(s: &str) -> bool { + vec!("repr").iter().any(|x| x == &s) +} + +fn render_attribute(attr: &clean::Attribute, recurse: bool) -> String { + match *attr { + clean::Word(ref s) if attribute_without_value(&*s) || recurse => { + format!("{}", s) + } + clean::NameValue(ref k, ref v) if attribute_with_value(&*k) => { + format!("{} = \"{}\"", k, v) + } + clean::List(ref k, ref values) if attribute_with_values(&*k) => { + let mut display = Vec::new(); + + for value in values { + let s = render_attribute(value, true); + if s.len() > 0 { + display.push(format!("{}", s)); + } + } + format!("{}({})", k, display.join(", ")) + } + _ => { + String::new() + } + } +} + fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { for attr in &it.attrs { - match *attr { - clean::Word(ref s) if *s == "must_use" => { - write!(w, "#[{}]\n", s)?; - } - clean::NameValue(ref k, ref v) if *k == "must_use" => { - write!(w, "#[{} = \"{}\"]\n", k, v)?; - } - _ => () + let s = render_attribute(attr, false); + if s.len() > 0 { + write!(w, "#[{}]\n", s)?; } } Ok(()) From a96247bcac385671757034bd928c13097fd2ce76 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 6 Nov 2016 20:06:01 +0100 Subject: [PATCH 05/24] Set possibility to hide attributes --- src/librustdoc/html/render.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e3efcc5c2f98d..aa1fd63082f98 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2493,24 +2493,24 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } fn attribute_without_value(s: &str) -> bool { - vec!("must_use", "no_mangle", "unsafe_destructor_blind_to_params").iter().any(|x| x == &s) + ["must_use", "no_mangle", "unsafe_destructor_blind_to_params"].iter().any(|x| x == &s) } fn attribute_with_value(s: &str) -> bool { - vec!("export_name", "lang", "link_section", "must_use").iter().any(|x| x == &s) + ["export_name", "lang", "link_section", "must_use"].iter().any(|x| x == &s) } fn attribute_with_values(s: &str) -> bool { - vec!("repr").iter().any(|x| x == &s) + ["repr"].iter().any(|x| x == &s) } -fn render_attribute(attr: &clean::Attribute, recurse: bool) -> String { +fn render_attribute(attr: &clean::Attribute, recurse: bool) -> Option { match *attr { clean::Word(ref s) if attribute_without_value(&*s) || recurse => { - format!("{}", s) + Some(format!("{}", s)) } clean::NameValue(ref k, ref v) if attribute_with_value(&*k) => { - format!("{} = \"{}\"", k, v) + Some(format!("{} = \"{}\"", k, v)) } clean::List(ref k, ref values) if attribute_with_values(&*k) => { let mut display = Vec::new(); @@ -2521,21 +2521,25 @@ fn render_attribute(attr: &clean::Attribute, recurse: bool) -> String { display.push(format!("{}", s)); } } - format!("{}({})", k, display.join(", ")) + Some(format!("{}({})", k, display.join(", "))) } _ => { - String::new() + None } } } fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { + let mut attrs = String::new(); + for attr in &it.attrs { - let s = render_attribute(attr, false); - if s.len() > 0 { - write!(w, "#[{}]\n", s)?; + if let Some(s) = render_attribute(attr, false) { + attrs.push_str(&format!("#[{}]\n", s)); } } + if attrs.len() > 0 { + write!(w, "
{}
", &attrs)?; + } Ok(()) } From 22dad4b0440b184568956c10f2cbedabf763065a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 6 Nov 2016 21:03:08 +0100 Subject: [PATCH 06/24] Improve attributes display and allow expansion --- src/librustdoc/html/render.rs | 17 +- src/librustdoc/html/static/main.js | 2 + src/librustdoc/html/static/rustdoc.css | 738 +++++++++++++------------ 3 files changed, 384 insertions(+), 373 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index aa1fd63082f98..0fd3a9aebf83a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2513,15 +2513,16 @@ fn render_attribute(attr: &clean::Attribute, recurse: bool) -> Option { Some(format!("{} = \"{}\"", k, v)) } clean::List(ref k, ref values) if attribute_with_values(&*k) => { - let mut display = Vec::new(); + let display: Vec<_> = values.iter() + .filter_map(|value| render_attribute(value, true)) + .map(|entry| format!("{}", entry)) + .collect(); - for value in values { - let s = render_attribute(value, true); - if s.len() > 0 { - display.push(format!("{}", s)); - } + if display.len() > 0 { + Some(format!("{}({})", k, display.join(", "))) + } else { + None } - Some(format!("{}({})", k, display.join(", "))) } _ => { None @@ -2538,7 +2539,7 @@ fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { } } if attrs.len() > 0 { - write!(w, "
{}
", &attrs)?; + write!(w, "
{}
", &attrs)?; } Ok(()) } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 9bb7246e7a92e..d0ca8c8645cf6 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1005,6 +1005,8 @@ .html(' Expand description')); var wrapper = $("
").append(mainToggle); $("#main > .docblock").before(wrapper); + var wrapper = $("
").append(mainToggle); + $("#main > pre > .docblock").before(wrapper); }); $('pre.line-numbers').on('click', 'span', function() { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index f49b8556f66cb..46b34b5a638b3 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -14,160 +14,160 @@ /* See FiraSans-LICENSE.txt for the Fira Sans license. */ @font-face { - font-family: 'Fira Sans'; - font-style: normal; - font-weight: 400; - src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff'); + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 400; + src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff'); } @font-face { - font-family: 'Fira Sans'; - font-style: normal; - font-weight: 500; - src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff'); + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 500; + src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff'); } /* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license and * Heuristica-LICENSE.txt for the Heuristica license. */ @font-face { - font-family: 'Source Serif Pro'; - font-style: normal; - font-weight: 400; - src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff'); + font-family: 'Source Serif Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff'); } @font-face { - font-family: 'Source Serif Pro'; - font-style: italic; - font-weight: 400; - src: url("Heuristica-Italic.woff") format('woff'); + font-family: 'Source Serif Pro'; + font-style: italic; + font-weight: 400; + src: url("Heuristica-Italic.woff") format('woff'); } @font-face { - font-family: 'Source Serif Pro'; - font-style: normal; - font-weight: 700; - src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff'); + font-family: 'Source Serif Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff'); } /* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */ @font-face { - font-family: 'Source Code Pro'; - font-style: normal; - font-weight: 400; - src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff'); + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff'); } @font-face { - font-family: 'Source Code Pro'; - font-style: normal; - font-weight: 600; - src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff'); + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 600; + src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff'); } * { -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } /* General structure and fonts */ body { - font: 16px/1.4 "Source Serif Pro", Georgia, Times, "Times New Roman", serif; - margin: 0; - position: relative; - padding: 10px 15px 20px 15px; + font: 16px/1.4 "Source Serif Pro", Georgia, Times, "Times New Roman", serif; + margin: 0; + position: relative; + padding: 10px 15px 20px 15px; - -webkit-font-feature-settings: "kern", "liga"; - -moz-font-feature-settings: "kern", "liga"; - font-feature-settings: "kern", "liga"; + -webkit-font-feature-settings: "kern", "liga"; + -moz-font-feature-settings: "kern", "liga"; + font-feature-settings: "kern", "liga"; } h1 { - font-size: 1.5em; + font-size: 1.5em; } h2 { - font-size: 1.4em; + font-size: 1.4em; } h3 { - font-size: 1.3em; + font-size: 1.3em; } h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { - font-weight: 500; - margin: 20px 0 15px 0; - padding-bottom: 6px; + font-weight: 500; + margin: 20px 0 15px 0; + padding-bottom: 6px; } h1.fqn { - border-bottom: 1px dashed; - margin-top: 0; - position: relative; + border-bottom: 1px dashed; + margin-top: 0; + position: relative; } h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { - border-bottom: 1px solid; + border-bottom: 1px solid; } h3.impl, h3.method, h4.method, h3.type, h4.type { - font-weight: 600; - margin-top: 10px; - margin-bottom: 10px; - position: relative; + font-weight: 600; + margin-top: 10px; + margin-bottom: 10px; + position: relative; } h3.impl, h3.method, h3.type { - margin-top: 15px; + margin-top: 15px; } h1, h2, h3, h4, .sidebar, a.source, .search-input, .content table :not(code)>a, .collapse-toggle { - font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } ol, ul { - padding-left: 25px; + padding-left: 25px; } ul ul, ol ul, ul ol, ol ol { - margin-bottom: 0; + margin-bottom: 0; } p { - margin: 0 0 .6em 0; + margin: 0 0 .6em 0; } code, pre { - font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace; - white-space: pre-wrap; + font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace; + white-space: pre-wrap; } .docblock code, .docblock-short code { - border-radius: 3px; - padding: 0 0.2em; + border-radius: 3px; + padding: 0 0.2em; } .docblock pre code, .docblock-short pre code { - padding: 0; + padding: 0; } pre { - padding: 14px; + padding: 14px; } .source pre { - padding: 20px; + padding: 20px; } img { - max-width: 100%; + max-width: 100%; } .content.source { - margin-top: 50px; - max-width: none; - overflow: visible; - margin-left: 0px; - min-width: 70em; + margin-top: 50px; + max-width: none; + overflow: visible; + margin-left: 0px; + min-width: 70em; } nav.sub { - font-size: 16px; - text-transform: uppercase; + font-size: 16px; + text-transform: uppercase; } .sidebar { - width: 200px; - position: absolute; - left: 0; - top: 0; - min-height: 100%; + width: 200px; + position: absolute; + left: 0; + top: 0; + min-height: 100%; } .content, nav { max-width: 960px; } @@ -177,88 +177,88 @@ nav.sub { .js-only, .hidden { display: none !important; } .sidebar { - padding: 10px; + padding: 10px; } .sidebar img { - margin: 20px auto; - display: block; + margin: 20px auto; + display: block; } .sidebar .location { - font-size: 17px; - margin: 30px 0 20px 0; - text-align: center; + font-size: 17px; + margin: 30px 0 20px 0; + text-align: center; } .location a:first-child { font-weight: 500; } .block { - padding: 0 10px; - margin-bottom: 14px; + padding: 0 10px; + margin-bottom: 14px; } .block h2, .block h3 { - margin-top: 0; - margin-bottom: 8px; - text-align: center; + margin-top: 0; + margin-bottom: 8px; + text-align: center; } .block ul, .block li { - margin: 0; - padding: 0; - list-style: none; + margin: 0; + padding: 0; + list-style: none; } .block a { - display: block; - text-overflow: ellipsis; - overflow: hidden; - line-height: 15px; - padding: 7px 5px; - font-size: 14px; - font-weight: 300; - transition: border 500ms ease-out; + display: block; + text-overflow: ellipsis; + overflow: hidden; + line-height: 15px; + padding: 7px 5px; + font-size: 14px; + font-weight: 300; + transition: border 500ms ease-out; } .content { - padding: 15px 0; + padding: 15px 0; } .content.source pre.rust { - white-space: pre; - overflow: auto; - padding-left: 0; + white-space: pre; + overflow: auto; + padding-left: 0; } .content pre.line-numbers { - float: left; - border: none; - position: relative; + float: left; + border: none; + position: relative; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } .line-numbers span { cursor: pointer; } .docblock-short p { - display: inline; + display: inline; } .docblock-short.nowrap { - display: block; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } .docblock-short p { - overflow: hidden; - text-overflow: ellipsis; - margin: 0; + overflow: hidden; + text-overflow: ellipsis; + margin: 0; } .docblock-short code { white-space: nowrap; } .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { - border-bottom: 1px solid; + border-bottom: 1px solid; } .docblock h1 { font-size: 1.3em; } @@ -266,53 +266,53 @@ nav.sub { .docblock h3, .docblock h4, .docblock h5 { font-size: 1em; } .docblock { - margin-left: 24px; + margin-left: 24px; } .content .out-of-band { - font-size: 23px; - margin: 0px; - padding: 0px; - text-align: right; - display: inline-block; - font-weight: normal; - position: absolute; - right: 0; + font-size: 23px; + margin: 0px; + padding: 0px; + text-align: right; + display: inline-block; + font-weight: normal; + position: absolute; + right: 0; } h3.impl > .out-of-band { - font-size: 21px; + font-size: 21px; } h4 > code, h3 > code, .invisible > code { - position: inherit; + position: inherit; } .in-band, code { - z-index: 5; + z-index: 5; } .invisible { - background: rgba(0, 0, 0, 0); - width: 100%; - display: inline-block; + background: rgba(0, 0, 0, 0); + width: 100%; + display: inline-block; } .content .in-band { - margin: 0px; - padding: 0px; - display: inline-block; + margin: 0px; + padding: 0px; + display: inline-block; } #main { position: relative; } #main > .since { - top: inherit; - font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + top: inherit; + font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } .content table { - border-spacing: 0 5px; - border-collapse: separate; + border-spacing: 0 5px; + border-collapse: separate; } .content td { vertical-align: top; } .content td:first-child { padding-right: 20px; } @@ -320,45 +320,45 @@ h4 > code, h3 > code, .invisible > code { .content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; } .docblock table { - border: 1px solid; - margin: .5em 0; - border-collapse: collapse; - width: 100%; + border: 1px solid; + margin: .5em 0; + border-collapse: collapse; + width: 100%; } .docblock table td { - padding: .5em; - border-top: 1px dashed; - border-bottom: 1px dashed; + padding: .5em; + border-top: 1px dashed; + border-bottom: 1px dashed; } .docblock table th { - padding: .5em; - text-align: left; - border-top: 1px solid; - border-bottom: 1px solid; + padding: .5em; + text-align: left; + border-top: 1px solid; + border-bottom: 1px solid; } .content .item-list { - list-style-type: none; - padding: 0; + list-style-type: none; + padding: 0; } .content .item-list li { margin-bottom: 3px; } .content .multi-column { - -moz-column-count: 5; - -moz-column-gap: 2.5em; - -webkit-column-count: 5; - -webkit-column-gap: 2.5em; - column-count: 5; - column-gap: 2.5em; + -moz-column-count: 5; + -moz-column-gap: 2.5em; + -webkit-column-count: 5; + -webkit-column-gap: 2.5em; + column-count: 5; + column-gap: 2.5em; } .content .multi-column li { width: 100%; display: inline-block; } .content .method { - font-size: 1em; - position: relative; + font-size: 1em; + position: relative; } /* Shift "where ..." part of method or fn definition down a line */ .content .method .where, .content .fn .where { display: block; } @@ -368,54 +368,54 @@ h4 > code, h3 > code, .invisible > code { .content .methods > div { margin-left: 40px; } .content .impl-items .docblock, .content .impl-items .stability { - margin-left: 40px; + margin-left: 40px; } .content .impl-items .method, .content .impl-items > .type { - margin-left: 20px; + margin-left: 20px; } .content .stability code { - font-size: 90%; + font-size: 90%; } /* Shift where in trait listing down a line */ pre.trait .where::before { - content: '\a '; + content: '\a '; } nav { - border-bottom: 1px solid; - padding-bottom: 10px; - margin-bottom: 10px; + border-bottom: 1px solid; + padding-bottom: 10px; + margin-bottom: 10px; } nav.main { - padding: 20px 0; - text-align: center; + padding: 20px 0; + text-align: center; } nav.main .current { - border-top: 1px solid; - border-bottom: 1px solid; + border-top: 1px solid; + border-bottom: 1px solid; } nav.main .separator { - border: 1px solid; - display: inline-block; - height: 23px; - margin: 0 20px; + border: 1px solid; + display: inline-block; + height: 23px; + margin: 0 20px; } nav.sum { text-align: right; } nav.sub form { display: inline; } nav.sub, .content { - margin-left: 230px; + margin-left: 230px; } a { - text-decoration: none; - background: transparent; + text-decoration: none; + background: transparent; } .docblock a:hover, .docblock-short a:hover, .stability a { - text-decoration: underline; + text-decoration: underline; } .content span.enum, .content a.enum, .block a.current.enum { color: #5e9766; } @@ -425,40 +425,40 @@ a { .block a.current.crate { font-weight: 500; } .search-input { - width: 100%; - /* Override Normalize.css: we have margins and do - not want to overflow - the `moz` attribute is necessary - until Firefox 29, too early to drop at this point */ - -moz-box-sizing: border-box !important; - box-sizing: border-box !important; - outline: none; - border: none; - border-radius: 1px; - margin-top: 5px; - padding: 10px 16px; - font-size: 17px; - transition: border-color 300ms ease; - transition: border-radius 300ms ease-in-out; - transition: box-shadow 300ms ease-in-out; + width: 100%; + /* Override Normalize.css: we have margins and do + not want to overflow - the `moz` attribute is necessary + until Firefox 29, too early to drop at this point */ + -moz-box-sizing: border-box !important; + box-sizing: border-box !important; + outline: none; + border: none; + border-radius: 1px; + margin-top: 5px; + padding: 10px 16px; + font-size: 17px; + transition: border-color 300ms ease; + transition: border-radius 300ms ease-in-out; + transition: box-shadow 300ms ease-in-out; } .search-input:focus { - border-color: #66afe9; - border-radius: 2px; - border: 0; - outline: 0; - box-shadow: 0 0 8px #078dd8; + border-color: #66afe9; + border-radius: 2px; + border: 0; + outline: 0; + box-shadow: 0 0 8px #078dd8; } .search-results .desc { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - display: block; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: block; } .search-results a { - display: block; + display: block; } .content .search-results td:first-child { padding-right: 0; } @@ -468,96 +468,96 @@ tr.result span.primitive::after { content: ' (primitive type)'; font-style: ital } body.blur > :not(#help) { - filter: blur(8px); - -webkit-filter: blur(8px); - opacity: .7; + filter: blur(8px); + -webkit-filter: blur(8px); + opacity: .7; } #help { - width: 100%; - height: 100vh; - position: fixed; - top: 0; - left: 0; - display: flex; - justify-content: center; - align-items: center; + width: 100%; + height: 100vh; + position: fixed; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; } #help > div { - flex: 0 0 auto; - background: #e9e9e9; - box-shadow: 0 0 6px rgba(0,0,0,.2); - width: 550px; - height: 330px; - border: 1px solid #bfbfbf; + flex: 0 0 auto; + background: #e9e9e9; + box-shadow: 0 0 6px rgba(0,0,0,.2); + width: 550px; + height: 330px; + border: 1px solid #bfbfbf; } #help dt { - float: left; - border-radius: 4px; - border: 1px solid #bfbfbf; - background: #fff; - width: 23px; - text-align: center; - clear: left; - display: block; - margin-top: -1px; + float: left; + border-radius: 4px; + border: 1px solid #bfbfbf; + background: #fff; + width: 23px; + text-align: center; + clear: left; + display: block; + margin-top: -1px; } #help dd { margin: 5px 33px; } #help .infos { padding-left: 0; } #help h1, #help h2 { margin-top: 0; } #help > div div { - width: 50%; - float: left; - padding: 20px; + width: 50%; + float: left; + padding: 20px; } em.stab { - display: inline-block; - border-width: 1px; - border-style: solid; - padding: 3px; - margin-bottom: 5px; - font-size: 90%; - font-style: normal; + display: inline-block; + border-width: 1px; + border-style: solid; + padding: 3px; + margin-bottom: 5px; + font-size: 90%; + font-style: normal; } em.stab p { - display: inline; + display: inline; } .module-item .stab { - border-width: 0; - padding: 0; - margin: 0; - background: inherit !important; + border-width: 0; + padding: 0; + margin: 0; + background: inherit !important; } .module-item.unstable { - opacity: 0.65; + opacity: 0.65; } .since { - font-weight: normal; - font-size: initial; - color: grey; - position: absolute; - right: 0; - top: 0; + font-weight: normal; + font-size: initial; + color: grey; + position: absolute; + right: 0; + top: 0; } .variants_table { - width: 100%; + width: 100%; } .variants_table tbody tr td:first-child { - width: 1%; /* make the variant name as small as possible */ + width: 1%; /* make the variant name as small as possible */ } td.summary-column { - width: 100%; + width: 100%; } .summary { - padding-right: 0px; + padding-right: 0px; } .line-numbers :target { background-color: transparent; } @@ -571,110 +571,118 @@ pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; } pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; } pre.rust .lifetime { color: #B76514; } pre.rust .question-mark { - color: #ff9011; - font-weight: bold; + color: #ff9011; + font-weight: bold; } pre.rust { position: relative; } a.test-arrow { - background-color: rgba(78, 139, 202, 0.2); - display: inline-block; - position: absolute; - padding: 5px 10px 5px 10px; - border-radius: 5px; - font-size: 130%; - top: 5px; - right: 5px; + background-color: rgba(78, 139, 202, 0.2); + display: inline-block; + position: absolute; + padding: 5px 10px 5px 10px; + border-radius: 5px; + font-size: 130%; + top: 5px; + right: 5px; } a.test-arrow:hover{ - background-color: #4e8bca; - text-decoration: none; + background-color: #4e8bca; + text-decoration: none; } .section-header:hover a:after { - content: '\2002\00a7\2002'; + content: '\2002\00a7\2002'; } .section-header:hover a { - text-decoration: none; + text-decoration: none; } .section-header a { - color: inherit; + color: inherit; } .collapse-toggle { - font-weight: 300; - position: absolute; - left: -23px; - color: #999; - top: 0; + font-weight: 300; + position: absolute; + left: -23px; + color: #999; + top: 0; } .toggle-wrapper > .collapse-toggle { - left: -24px; - margin-top: 0px; + left: -24px; + margin-top: 0px; } .toggle-wrapper { - position: relative; + position: relative; } .toggle-wrapper.collapsed { - height: 1em; - transition: height .2s; + height: 1em; + transition: height .2s; } .collapse-toggle > .inner { - display: inline-block; - width: 1.2ch; - text-align: center; + display: inline-block; + width: 1.2ch; + text-align: center; } .toggle-label { - color: #999; + color: #999; } .ghost { - display: none; + display: none; } .ghost + .since { - position: initial; - display: table-cell; + position: initial; + display: table-cell; } .since + .srclink { - display: table-cell; - padding-left: 10px; + display: table-cell; + padding-left: 10px; } span.since { - position: initial; - font-size: 20px; - margin-right: 5px; + position: initial; + font-size: 20px; + margin-right: 5px; } .toggle-wrapper > .collapse-toggle { - left: 0; + left: 0; } .variant + .toggle-wrapper > a { - margin-top: 5px; + margin-top: 5px; } .enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock { - margin-left: 30px; - margin-bottom: 20px; - margin-top: 5px; + margin-left: 30px; + margin-bottom: 20px; + margin-top: 5px; } .enum > .collapsed, .struct > .collapsed { - margin-bottom: 25px; + margin-bottom: 25px; } .enum .variant, .struct .structfield { - display: block; + display: block; +} + +.attributes { + display: block; + margin: 0px 0px 0px 30px !important; +} +.toggle-attributes.collapsed { + margin-bottom: 5px; } :target > code { @@ -685,71 +693,71 @@ span.since { /* Media Queries */ @media (max-width: 700px) { - body { - padding-top: 0px; - } - - .sidebar { - height: 40px; - min-height: 40px; - width: 100%; - margin: 0px; - padding: 0px; - position: static; - } - - .sidebar .location { - float: right; - margin: 0px; - padding: 3px 10px 1px 10px; - min-height: 39px; - background: inherit; - text-align: left; - font-size: 24px; - } - - .sidebar .location:empty { - padding: 0; - } - - .sidebar img { - width: 35px; - margin-top: 5px; - margin-bottom: 0px; - float: left; - } - - nav.sub { - margin: 0 auto; - } - - .sidebar .block { - display: none; - } - - .content { - margin-left: 0px; - } - - .content .in-band { - width: 100%; - } - - .content .out-of-band { - display: none; - } - - .toggle-wrapper > .collapse-toggle { - left: 0px; - } - - .toggle-wrapper { - height: 1.5em; - } + body { + padding-top: 0px; + } + + .sidebar { + height: 40px; + min-height: 40px; + width: 100%; + margin: 0px; + padding: 0px; + position: static; + } + + .sidebar .location { + float: right; + margin: 0px; + padding: 3px 10px 1px 10px; + min-height: 39px; + background: inherit; + text-align: left; + font-size: 24px; + } + + .sidebar .location:empty { + padding: 0; + } + + .sidebar img { + width: 35px; + margin-top: 5px; + margin-bottom: 0px; + float: left; + } + + nav.sub { + margin: 0 auto; + } + + .sidebar .block { + display: none; + } + + .content { + margin-left: 0px; + } + + .content .in-band { + width: 100%; + } + + .content .out-of-band { + display: none; + } + + .toggle-wrapper > .collapse-toggle { + left: 0px; + } + + .toggle-wrapper { + height: 1.5em; + } } @media print { - nav.sub, .content .out-of-band, .collapse-toggle { - display: none; - } + nav.sub, .content .out-of-band, .collapse-toggle { + display: none; + } } From 520d5f4cb9f88ccf99a869646a089d04c103f3ec Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 6 Nov 2016 21:06:20 +0100 Subject: [PATCH 07/24] Set attributes hidden by default --- src/librustdoc/html/static/main.js | 32 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index d0ca8c8645cf6..474d2bbe7fcb5 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -963,20 +963,22 @@ } } - $("#toggle-all-docs").on("click", toggleAllDocs); - - $(document).on("click", ".collapse-toggle", function() { - var toggle = $(this); + function collapseDocs(toggle, animate) { var relatedDoc = toggle.parent().next(); if (relatedDoc.is(".stability")) { relatedDoc = relatedDoc.next(); } if (relatedDoc.is(".docblock")) { if (relatedDoc.is(":visible")) { - relatedDoc.slideUp({duration: 'fast', easing: 'linear'}); + if (animate === true) { + relatedDoc.slideUp({duration: 'fast', easing: 'linear'}); + toggle.children(".toggle-label").fadeIn(); + } else { + relatedDoc.hide(); + toggle.children(".toggle-label").show(); + } toggle.parent(".toggle-wrapper").addClass("collapsed"); toggle.children(".inner").text(labelForToggleButton(true)); - toggle.children(".toggle-label").fadeIn(); } else { relatedDoc.slideDown({duration: 'fast', easing: 'linear'}); toggle.parent(".toggle-wrapper").removeClass("collapsed"); @@ -984,6 +986,12 @@ toggle.children(".toggle-label").hide(); } } + } + + $("#toggle-all-docs").on("click", toggleAllDocs); + + $(document).on("click", ".collapse-toggle", function() { + collapseDocs($(this), true) }); $(function() { @@ -999,14 +1007,22 @@ }); var mainToggle = - $(toggle).append( + $(toggle.clone()).append( $('', {'class': 'toggle-label'}) .css('display', 'none') .html(' Expand description')); var wrapper = $("
").append(mainToggle); $("#main > .docblock").before(wrapper); + var mainToggle = + $(toggle).append( + $('', {'class': 'toggle-label'}) + .css('display', 'none') + .html(' Expand attributes')); var wrapper = $("
").append(mainToggle); - $("#main > pre > .docblock").before(wrapper); + $("#main > pre > .attributes").each(function() { + $(this).before(wrapper); + collapseDocs($($(this).prev().children()[0]), false); + }); }); $('pre.line-numbers').on('click', 'span', function() { From d377cf5b3fbaae4baa67b4f29a952b565ef1a814 Mon Sep 17 00:00:00 2001 From: Josh Driver Date: Tue, 8 Nov 2016 08:30:26 +1030 Subject: [PATCH 08/24] Rename KNOWN_ATTRS to BUILT_ATTRS, and create KNOWN_ATTRS KNOWN_ATTRIBUTES should really be named BUILT_ATTRIBUTES, while KNOWN_ATTRIBUTES should be used to mark attributes as known, similar to USED_ATTRIBUTES. --- src/librustc_lint/unused.rs | 6 +++--- src/libsyntax/attr.rs | 26 +++++++++++++++++++++++++- src/libsyntax/feature_gate.rs | 10 ++++++---- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index a29ff18ab5318..ca47db6ccee2e 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -19,7 +19,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant}; use syntax::ast; use syntax::attr; -use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType}; +use syntax::feature_gate::{BUILTIN_ATTRIBUTES, AttributeType}; use syntax::parse::token::keywords; use syntax::ptr::P; use syntax_pos::Span; @@ -245,7 +245,7 @@ impl LateLintPass for UnusedAttributes { debug!("checking attribute: {:?}", attr); // Note that check_name() marks the attribute as used if it matches. - for &(ref name, ty, _) in KNOWN_ATTRIBUTES { + for &(ref name, ty, _) in BUILTIN_ATTRIBUTES { match ty { AttributeType::Whitelisted if attr.check_name(name) => { debug!("{:?} is Whitelisted", name); @@ -267,7 +267,7 @@ impl LateLintPass for UnusedAttributes { debug!("Emitting warning for: {:?}", attr); cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute"); // Is it a builtin attribute that must be used at the crate level? - let known_crate = KNOWN_ATTRIBUTES.iter() + let known_crate = BUILTIN_ATTRIBUTES.iter() .find(|&&(name, ty, _)| attr.name() == name && ty == AttributeType::CrateLevel) .is_some(); diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 0335f210347a2..57a936bf9b0cf 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -32,7 +32,8 @@ use std::cell::{RefCell, Cell}; use std::collections::HashSet; thread_local! { - static USED_ATTRS: RefCell> = RefCell::new(Vec::new()) + static USED_ATTRS: RefCell> = RefCell::new(Vec::new()); + static KNOWN_ATTRS: RefCell> = RefCell::new(Vec::new()); } enum AttrError { @@ -81,6 +82,29 @@ pub fn is_used(attr: &Attribute) -> bool { }) } +pub fn mark_known(attr: &Attribute) { + debug!("Marking {:?} as known.", attr); + let AttrId(id) = attr.node.id; + KNOWN_ATTRS.with(|slot| { + let idx = (id / 64) as usize; + let shift = id % 64; + if slot.borrow().len() <= idx { + slot.borrow_mut().resize(idx + 1, 0); + } + slot.borrow_mut()[idx] |= 1 << shift; + }); +} + +pub fn is_known(attr: &Attribute) -> bool { + let AttrId(id) = attr.node.id; + KNOWN_ATTRS.with(|slot| { + let idx = (id / 64) as usize; + let shift = id % 64; + slot.borrow().get(idx).map(|bits| bits & (1 << shift) != 0) + .unwrap_or(false) + }) +} + impl NestedMetaItem { /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem. pub fn meta_item(&self) -> Option<&P> { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 129e4a8233803..f543eae817936 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -417,11 +417,11 @@ macro_rules! cfg_fn { } pub fn deprecated_attributes() -> Vec<&'static (&'static str, AttributeType, AttributeGate)> { - KNOWN_ATTRIBUTES.iter().filter(|a| a.2.is_deprecated()).collect() + BUILTIN_ATTRIBUTES.iter().filter(|a| a.2.is_deprecated()).collect() } // Attributes that have a special meaning to rustc or rustdoc -pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGate)] = &[ +pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGate)] = &[ // Normal attributes ("warn", Normal, Ungated), @@ -790,12 +790,12 @@ impl<'a> Context<'a> { fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) { debug!("check_attribute(attr = {:?})", attr); let name = &*attr.name(); - for &(n, ty, ref gateage) in KNOWN_ATTRIBUTES { + for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES { if n == name { if let &Gated(_, ref name, ref desc, ref has_feature) = gateage { gate_feature_fn!(self, has_feature, attr.span, name, desc); } - debug!("check_attribute: {:?} is known, {:?}, {:?}", name, ty, gateage); + debug!("check_attribute: {:?} is builtin, {:?}, {:?}", name, ty, gateage); return; } } @@ -815,6 +815,8 @@ impl<'a> Context<'a> { are reserved for internal compiler diagnostics"); } else if name.starts_with("derive_") { gate_feature!(self, custom_derive, attr.span, EXPLAIN_DERIVE_UNDERSCORE); + } else if attr::is_known(attr) { + debug!("check_attribute: {:?} is known", name); } else { // Only run the custom attribute lint during regular // feature gate checking. Macro gating runs From 4b20221e14082919f4909b7b1ef6257f9d263362 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 8 Nov 2016 15:28:00 +1300 Subject: [PATCH 09/24] save-analysis: don't choke on stripped doc attributes --- src/librustc_save_analysis/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 7e008f741624b..f3b4d9026df7c 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -759,7 +759,11 @@ fn docs_for_attrs(attrs: &[Attribute]) -> String { for attr in attrs { if attr.name() == doc { if let Some(ref val) = attr.value_str() { - result.push_str(&strip_doc_comment_decoration(val)); + if attr.node.is_sugared_doc { + result.push_str(&strip_doc_comment_decoration(val)); + } else { + result.push_str(val); + } result.push('\n'); } } From eca1cc957fff157575f485ebfd2aaafb33ee98cb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 8 Nov 2016 14:01:38 +1100 Subject: [PATCH 10/24] Add FxHasher, a faster alternative to FnvHasher. --- src/librustc_data_structures/fx.rs | 115 +++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/librustc_data_structures/fx.rs diff --git a/src/librustc_data_structures/fx.rs b/src/librustc_data_structures/fx.rs new file mode 100644 index 0000000000000..1fb7673521d88 --- /dev/null +++ b/src/librustc_data_structures/fx.rs @@ -0,0 +1,115 @@ +// Copyright 2015 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. + +use std::collections::{HashMap, HashSet}; +use std::default::Default; +use std::hash::{Hasher, Hash, BuildHasherDefault}; +use std::ops::BitXor; + +pub type FxHashMap = HashMap>; +pub type FxHashSet = HashSet>; + +#[allow(non_snake_case)] +pub fn FxHashMap() -> FxHashMap { + HashMap::default() +} + +#[allow(non_snake_case)] +pub fn FxHashSet() -> FxHashSet { + HashSet::default() +} + +/// A speedy hash algorithm for use within rustc. The hashmap in libcollections +/// by default uses SipHash which isn't quite as speedy as we want. In the +/// compiler we're not really worried about DOS attempts, so we use a fast +/// non-cryptographic hash. +/// +/// This is the same as the algorithm used by Firefox -- which is a homespun +/// one not based on any widely-known algorithm -- though modified to produce +/// 64-bit hash values instead of 32-bit hash values. It consistently +/// out-performs an FNV-based hash within rustc itself -- the collision rate is +/// similar or slightly worse than FNV, but the speed of the hash function +/// itself is much higher because it works on up to 8 bytes at a time. +pub struct FxHasher { + hash: usize +} + +#[cfg(target_pointer_width = "32")] +const K: usize = 0x9e3779b9; +#[cfg(target_pointer_width = "64")] +const K: usize = 0x517cc1b727220a95; + +impl Default for FxHasher { + #[inline] + fn default() -> FxHasher { + FxHasher { hash: 0 } + } +} + +impl FxHasher { + #[inline] + fn add_to_hash(&mut self, i: usize) { + self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K); + } +} + +impl Hasher for FxHasher { + #[inline] + fn write(&mut self, bytes: &[u8]) { + for byte in bytes { + let i = *byte; + self.add_to_hash(i as usize); + } + } + + #[inline] + fn write_u8(&mut self, i: u8) { + self.add_to_hash(i as usize); + } + + #[inline] + fn write_u16(&mut self, i: u16) { + self.add_to_hash(i as usize); + } + + #[inline] + fn write_u32(&mut self, i: u32) { + self.add_to_hash(i as usize); + } + + #[cfg(target_pointer_width = "32")] + #[inline] + fn write_u64(&mut self, i: u64) { + self.add_to_hash(i as usize); + self.add_to_hash((i >> 32) as usize); + } + + #[cfg(target_pointer_width = "64")] + #[inline] + fn write_u64(&mut self, i: u64) { + self.add_to_hash(i as usize); + } + + #[inline] + fn write_usize(&mut self, i: usize) { + self.add_to_hash(i); + } + + #[inline] + fn finish(&self) -> u64 { + self.hash as u64 + } +} + +pub fn hash(v: &T) -> u64 { + let mut state = FxHasher::default(); + v.hash(&mut state); + state.finish() +} From 00e48affde2d349e3b3bfbd3d0f6afb5d76282a7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 8 Nov 2016 14:02:55 +1100 Subject: [PATCH 11/24] Replace FnvHasher use with FxHasher. This speeds up compilation by 3--6% across most of rustc-benchmarks. --- src/librustc/dep_graph/dep_tracking_map.rs | 6 +- src/librustc/dep_graph/edges.rs | 10 +- src/librustc/dep_graph/graph.rs | 12 +- src/librustc/dep_graph/query.rs | 6 +- src/librustc/hir/map/definitions.rs | 6 +- src/librustc/hir/mod.rs | 4 +- src/librustc/infer/freshen.rs | 6 +- src/librustc/infer/higher_ranked/mod.rs | 23 ++-- src/librustc/infer/mod.rs | 12 +- .../infer/region_inference/graphviz.rs | 12 +- src/librustc/infer/region_inference/mod.rs | 32 ++--- src/librustc/lint/context.rs | 22 ++-- src/librustc/middle/dead.rs | 12 +- src/librustc/middle/dependency_format.rs | 8 +- src/librustc/middle/lang_items.rs | 6 +- src/librustc/middle/privacy.rs | 4 +- src/librustc/middle/reachable.rs | 4 +- src/librustc/middle/region.rs | 6 +- src/librustc/middle/resolve_lifetime.rs | 12 +- src/librustc/middle/stability.rs | 20 +-- src/librustc/session/mod.rs | 8 +- src/librustc/traits/error_reporting.rs | 10 +- src/librustc/traits/fulfill.rs | 6 +- src/librustc/traits/select.rs | 12 +- src/librustc/traits/specialize/mod.rs | 6 +- .../traits/specialize/specialization_graph.rs | 6 +- src/librustc/traits/util.rs | 8 +- src/librustc/ty/contents.rs | 6 +- src/librustc/ty/context.rs | 54 ++++---- src/librustc/ty/fold.rs | 20 +-- src/librustc/ty/mod.rs | 22 ++-- src/librustc/ty/trait_def.rs | 6 +- src/librustc/ty/util.rs | 4 +- src/librustc/util/nodemap.rs | 20 +-- .../borrowck/mir/elaborate_drops.rs | 6 +- .../borrowck/mir/gather_moves.rs | 6 +- src/librustc_borrowck/borrowck/move_data.rs | 6 +- src/librustc_const_eval/_match.rs | 6 +- src/librustc_data_structures/lib.rs | 1 + .../obligation_forest/mod.rs | 10 +- .../snapshot_map/mod.rs | 6 +- src/librustc_incremental/assert_dep_graph.rs | 26 ++-- src/librustc_incremental/calculate_svh/mod.rs | 10 +- src/librustc_incremental/persist/data.rs | 4 +- .../persist/dirty_clean.rs | 14 +-- src/librustc_incremental/persist/fs.rs | 30 ++--- src/librustc_incremental/persist/hash.rs | 10 +- src/librustc_incremental/persist/load.rs | 12 +- src/librustc_incremental/persist/preds.rs | 10 +- src/librustc_incremental/persist/save.rs | 10 +- src/librustc_lint/types.rs | 6 +- src/librustc_lint/unused.rs | 4 +- src/librustc_metadata/creader.rs | 12 +- src/librustc_metadata/cstore.rs | 16 +-- src/librustc_metadata/decoder.rs | 4 +- src/librustc_metadata/encoder.rs | 12 +- src/librustc_metadata/locator.rs | 14 +-- src/librustc_mir/build/expr/as_rvalue.rs | 4 +- src/librustc_mir/build/matches/mod.rs | 4 +- src/librustc_mir/build/matches/test.rs | 6 +- src/librustc_mir/build/scope.rs | 6 +- src/librustc_mir/pretty.rs | 12 +- src/librustc_mir/transform/instcombine.rs | 4 +- src/librustc_passes/hir_stats.rs | 14 +-- src/librustc_resolve/build_reduced_graph.rs | 4 +- src/librustc_resolve/lib.rs | 74 +++++------ src/librustc_trans/base.rs | 10 +- src/librustc_trans/builder.rs | 4 +- src/librustc_trans/collector.rs | 18 +-- src/librustc_trans/context.rs | 118 +++++++++--------- src/librustc_trans/debuginfo/metadata.rs | 14 +-- src/librustc_trans/debuginfo/mod.rs | 14 +-- src/librustc_trans/mir/block.rs | 4 +- src/librustc_trans/partitioning.rs | 20 +-- src/librustc_trans/symbol_map.rs | 6 +- src/librustc_trans/type_.rs | 6 +- src/librustc_typeck/astconv.rs | 6 +- src/librustc_typeck/check/_match.rs | 6 +- src/librustc_typeck/check/dropck.rs | 6 +- src/librustc_typeck/check/intrinsic.rs | 6 +- src/librustc_typeck/check/method/probe.rs | 10 +- src/librustc_typeck/check/method/suggest.rs | 6 +- src/librustc_typeck/check/mod.rs | 14 +-- src/librustc_typeck/check/wfcheck.rs | 12 +- src/librustc_typeck/collect.rs | 20 +-- .../constrained_type_params.rs | 6 +- src/librustdoc/clean/inline.rs | 6 +- src/librustdoc/clean/mod.rs | 14 +-- src/librustdoc/core.rs | 14 +-- src/librustdoc/html/render.rs | 56 ++++----- src/librustdoc/visit_ast.rs | 6 +- 91 files changed, 588 insertions(+), 588 deletions(-) diff --git a/src/librustc/dep_graph/dep_tracking_map.rs b/src/librustc/dep_graph/dep_tracking_map.rs index 51f7890c7a2f4..50a478fcc2fd9 100644 --- a/src/librustc/dep_graph/dep_tracking_map.rs +++ b/src/librustc/dep_graph/dep_tracking_map.rs @@ -9,7 +9,7 @@ // except according to those terms. use hir::def_id::DefId; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use std::cell::RefCell; use std::ops::Index; use std::hash::Hash; @@ -24,7 +24,7 @@ use super::{DepNode, DepGraph}; pub struct DepTrackingMap { phantom: PhantomData, graph: DepGraph, - map: FnvHashMap, + map: FxHashMap, } pub trait DepTrackingMapConfig { @@ -38,7 +38,7 @@ impl DepTrackingMap { DepTrackingMap { phantom: PhantomData, graph: graph, - map: FnvHashMap() + map: FxHashMap() } } diff --git a/src/librustc/dep_graph/edges.rs b/src/librustc/dep_graph/edges.rs index 10f3d21f2af6d..8657a3e5a5878 100644 --- a/src/librustc/dep_graph/edges.rs +++ b/src/librustc/dep_graph/edges.rs @@ -8,15 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc_data_structures::fnv::{FnvHashMap, FnvHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use std::fmt::Debug; use std::hash::Hash; use super::{DepGraphQuery, DepNode}; pub struct DepGraphEdges { nodes: Vec>, - indices: FnvHashMap, IdIndex>, - edges: FnvHashSet<(IdIndex, IdIndex)>, + indices: FxHashMap, IdIndex>, + edges: FxHashSet<(IdIndex, IdIndex)>, open_nodes: Vec, } @@ -46,8 +46,8 @@ impl DepGraphEdges { pub fn new() -> DepGraphEdges { DepGraphEdges { nodes: vec![], - indices: FnvHashMap(), - edges: FnvHashSet(), + indices: FxHashMap(), + edges: FxHashSet(), open_nodes: Vec::new() } } diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index fac3586afc7b9..2637d34c5c56e 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -9,7 +9,7 @@ // except according to those terms. use hir::def_id::DefId; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use session::config::OutputType; use std::cell::{Ref, RefCell}; use std::rc::Rc; @@ -34,10 +34,10 @@ struct DepGraphData { /// things available to us. If we find that they are not dirty, we /// load the path to the file storing those work-products here into /// this map. We can later look for and extract that data. - previous_work_products: RefCell, WorkProduct>>, + previous_work_products: RefCell, WorkProduct>>, /// Work-products that we generate in this run. - work_products: RefCell, WorkProduct>>, + work_products: RefCell, WorkProduct>>, } impl DepGraph { @@ -45,8 +45,8 @@ impl DepGraph { DepGraph { data: Rc::new(DepGraphData { thread: DepGraphThreadData::new(enabled), - previous_work_products: RefCell::new(FnvHashMap()), - work_products: RefCell::new(FnvHashMap()), + previous_work_products: RefCell::new(FxHashMap()), + work_products: RefCell::new(FxHashMap()), }) } } @@ -117,7 +117,7 @@ impl DepGraph { /// Access the map of work-products created during this run. Only /// used during saving of the dep-graph. - pub fn work_products(&self) -> Ref, WorkProduct>> { + pub fn work_products(&self) -> Ref, WorkProduct>> { self.data.work_products.borrow() } } diff --git a/src/librustc/dep_graph/query.rs b/src/librustc/dep_graph/query.rs index 7a780c1d4ae24..4c791f9655342 100644 --- a/src/librustc/dep_graph/query.rs +++ b/src/librustc/dep_graph/query.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::{Direction, INCOMING, Graph, NodeIndex, OUTGOING}; use std::fmt::Debug; use std::hash::Hash; @@ -17,7 +17,7 @@ use super::DepNode; pub struct DepGraphQuery { pub graph: Graph, ()>, - pub indices: FnvHashMap, NodeIndex>, + pub indices: FxHashMap, NodeIndex>, } impl DepGraphQuery { @@ -25,7 +25,7 @@ impl DepGraphQuery { edges: &[(DepNode, DepNode)]) -> DepGraphQuery { let mut graph = Graph::new(); - let mut indices = FnvHashMap(); + let mut indices = FxHashMap(); for node in nodes { indices.insert(node.clone(), graph.next_node_index()); graph.add_node(node.clone()); diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index e8b3714bbe3b8..38157c7e56564 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -9,7 +9,7 @@ // except according to those terms. use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use std::fmt::Write; use std::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; @@ -22,7 +22,7 @@ use util::nodemap::NodeMap; #[derive(Clone)] pub struct Definitions { data: Vec, - key_map: FnvHashMap, + key_map: FxHashMap, node_map: NodeMap, } @@ -219,7 +219,7 @@ impl Definitions { pub fn new() -> Definitions { Definitions { data: vec![], - key_map: FnvHashMap(), + key_map: FxHashMap(), node_map: NodeMap(), } } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 5f57ceac353cc..cbd3e39f8703a 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -33,7 +33,7 @@ pub use self::PathParameters::*; use hir::def::Def; use hir::def_id::DefId; -use util::nodemap::{NodeMap, FnvHashSet}; +use util::nodemap::{NodeMap, FxHashSet}; use syntax_pos::{mk_sp, Span, ExpnId, DUMMY_SP}; use syntax::codemap::{self, respan, Spanned}; @@ -1605,4 +1605,4 @@ pub type TraitMap = NodeMap>; // Map from the NodeId of a glob import to a list of items which are actually // imported. -pub type GlobMap = NodeMap>; +pub type GlobMap = NodeMap>; diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 828f9f32baac8..30e18a4c569b2 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -32,7 +32,7 @@ use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::fold::TypeFolder; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use std::collections::hash_map::Entry; use super::InferCtxt; @@ -41,7 +41,7 @@ use super::unify_key::ToType; pub struct TypeFreshener<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, freshen_count: u32, - freshen_map: FnvHashMap>, + freshen_map: FxHashMap>, } impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> { @@ -50,7 +50,7 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> { TypeFreshener { infcx: infcx, freshen_count: 0, - freshen_map: FnvHashMap(), + freshen_map: FxHashMap(), } } diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 25b899b3c56cd..737ce8bdf681d 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -24,7 +24,7 @@ use ty::{self, TyCtxt, Binder, TypeFoldable}; use ty::error::TypeError; use ty::relate::{Relate, RelateResult, TypeRelation}; use syntax_pos::Span; -use util::nodemap::{FnvHashMap, FnvHashSet}; +use util::nodemap::{FxHashMap, FxHashSet}; pub struct HrMatchResult { pub value: U, @@ -135,7 +135,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // Map each skolemized region to a vector of other regions that it // must be equated with. (Note that this vector may include other // skolemized regions from `skol_map`.) - let skol_resolution_map: FnvHashMap<_, _> = + let skol_resolution_map: FxHashMap<_, _> = skol_map .iter() .map(|(&br, &skol)| { @@ -158,7 +158,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // `skol_map`. There should always be a representative if things // are properly well-formed. let mut unconstrained_regions = vec![]; - let skol_representatives: FnvHashMap<_, _> = + let skol_representatives: FxHashMap<_, _> = skol_resolution_map .iter() .map(|(&skol, &(br, ref regions))| { @@ -268,7 +268,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { snapshot: &CombinedSnapshot, debruijn: ty::DebruijnIndex, new_vars: &[ty::RegionVid], - a_map: &FnvHashMap, + a_map: &FxHashMap, r0: &'tcx ty::Region) -> &'tcx ty::Region { // Regions that pre-dated the LUB computation stay as they are. @@ -364,8 +364,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { snapshot: &CombinedSnapshot, debruijn: ty::DebruijnIndex, new_vars: &[ty::RegionVid], - a_map: &FnvHashMap, + a_map: &FxHashMap, a_vars: &[ty::RegionVid], b_vars: &[ty::RegionVid], r0: &'tcx ty::Region) @@ -434,7 +433,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, span: Span, - a_map: &FnvHashMap, + a_map: &FxHashMap, r: &'tcx ty::Region) -> &'tcx ty::Region { for (a_br, a_r) in a_map { @@ -457,7 +456,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { } fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>, - map: &FnvHashMap) + map: &FxHashMap) -> Vec { map.iter() .map(|(_, &r)| match *r { @@ -504,7 +503,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { snapshot: &CombinedSnapshot, r: &'tcx ty::Region, directions: TaintDirections) - -> FnvHashSet<&'tcx ty::Region> { + -> FxHashSet<&'tcx ty::Region> { self.region_vars.tainted(&snapshot.region_vars_snapshot, r, directions) } @@ -568,7 +567,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let escaping_types = self.type_variables.borrow_mut().types_escaping_snapshot(&snapshot.type_snapshot); - let mut escaping_region_vars = FnvHashSet(); + let mut escaping_region_vars = FxHashSet(); for ty in &escaping_types { self.tcx.collect_regions(ty, &mut escaping_region_vars); } @@ -764,7 +763,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // region back to the `ty::BoundRegion` that it originally // represented. Because `leak_check` passed, we know that // these taint sets are mutually disjoint. - let inv_skol_map: FnvHashMap<&'tcx ty::Region, ty::BoundRegion> = + let inv_skol_map: FxHashMap<&'tcx ty::Region, ty::BoundRegion> = skol_map .iter() .flat_map(|(&skol_br, &skol)| { @@ -837,7 +836,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { snapshot: &CombinedSnapshot) { debug!("pop_skolemized({:?})", skol_map); - let skol_regions: FnvHashSet<_> = skol_map.values().cloned().collect(); + let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect(); self.region_vars.pop_skolemized(&skol_regions, &snapshot.region_vars_snapshot); if !skol_map.is_empty() { self.projection_cache.borrow_mut().rollback_skolemized( diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 21820ca071921..ebafd206e26e2 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -39,7 +39,7 @@ use std::fmt; use syntax::ast; use errors::DiagnosticBuilder; use syntax_pos::{self, Span, DUMMY_SP}; -use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap}; +use util::nodemap::{FxHashMap, FxHashSet, NodeMap}; use self::combine::CombineFields; use self::higher_ranked::HrMatchResult; @@ -134,7 +134,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // the set of predicates on which errors have been reported, to // avoid reporting the same error twice. - pub reported_trait_errors: RefCell>>, + pub reported_trait_errors: RefCell>>, // Sadly, the behavior of projection varies a bit depending on the // stage of compilation. The specifics are given in the @@ -170,7 +170,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized /// region that each late-bound region was replaced with. -pub type SkolemizationMap<'tcx> = FnvHashMap; +pub type SkolemizationMap<'tcx> = FxHashMap; /// Why did we require that the two types be related? /// @@ -492,7 +492,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { selection_cache: traits::SelectionCache::new(), evaluation_cache: traits::EvaluationCache::new(), projection_cache: RefCell::new(traits::ProjectionCache::new()), - reported_trait_errors: RefCell::new(FnvHashSet()), + reported_trait_errors: RefCell::new(FxHashSet()), projection_mode: Reveal::NotSpecializable, tainted_by_errors_flag: Cell::new(false), err_count_on_creation: self.sess.err_count(), @@ -531,7 +531,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { parameter_environment: param_env, selection_cache: traits::SelectionCache::new(), evaluation_cache: traits::EvaluationCache::new(), - reported_trait_errors: RefCell::new(FnvHashSet()), + reported_trait_errors: RefCell::new(FxHashSet()), projection_mode: projection_mode, tainted_by_errors_flag: Cell::new(false), err_count_on_creation: tcx.sess.err_count(), @@ -1530,7 +1530,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { span: Span, lbrct: LateBoundRegionConversionTime, value: &ty::Binder) - -> (T, FnvHashMap) + -> (T, FxHashMap) where T : TypeFoldable<'tcx> { self.tcx.replace_late_bound_regions( diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs index 289f7d6c73800..95ce8d39ff488 100644 --- a/src/librustc/infer/region_inference/graphviz.rs +++ b/src/librustc/infer/region_inference/graphviz.rs @@ -23,7 +23,7 @@ use middle::region::CodeExtent; use super::Constraint; use infer::SubregionOrigin; use infer::region_inference::RegionVarBindings; -use util::nodemap::{FnvHashMap, FnvHashSet}; +use util::nodemap::{FxHashMap, FxHashSet}; use std::borrow::Cow; use std::collections::hash_map::Entry::Vacant; @@ -122,8 +122,8 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, graph_name: String, - map: &'a FnvHashMap, SubregionOrigin<'tcx>>, - node_ids: FnvHashMap, + map: &'a FxHashMap, SubregionOrigin<'tcx>>, + node_ids: FxHashMap, } #[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)] @@ -145,7 +145,7 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> { map: &'a ConstraintMap<'tcx>) -> ConstraintGraph<'a, 'gcx, 'tcx> { let mut i = 0; - let mut node_ids = FnvHashMap(); + let mut node_ids = FxHashMap(); { let mut add_node = |node| { if let Vacant(e) = node_ids.entry(node) { @@ -235,7 +235,7 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { type Node = Node; type Edge = Edge<'tcx>; fn nodes(&self) -> dot::Nodes { - let mut set = FnvHashSet(); + let mut set = FxHashSet(); for node in self.node_ids.keys() { set.insert(*node); } @@ -261,7 +261,7 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { } } -pub type ConstraintMap<'tcx> = FnvHashMap, SubregionOrigin<'tcx>>; +pub type ConstraintMap<'tcx> = FxHashMap, SubregionOrigin<'tcx>>; fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, map: &ConstraintMap<'tcx>, diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index ef36ffa831921..af6f2c50e72fc 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -19,7 +19,7 @@ pub use self::VarValue::*; use super::{RegionVariableOrigin, SubregionOrigin, MiscVariable}; use super::unify_key; -use rustc_data_structures::fnv::{FnvHashMap, FnvHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING}; use rustc_data_structures::unify::{self, UnificationTable}; use middle::free_region::FreeRegionMap; @@ -213,7 +213,7 @@ impl SameRegions { } } -pub type CombineMap<'tcx> = FnvHashMap, RegionVid>; +pub type CombineMap<'tcx> = FxHashMap, RegionVid>; pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, @@ -222,7 +222,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // Constraints of the form `A <= B` introduced by the region // checker. Here at least one of `A` and `B` must be a region // variable. - constraints: RefCell, SubregionOrigin<'tcx>>>, + constraints: RefCell, SubregionOrigin<'tcx>>>, // A "verify" is something that we need to verify after inference is // done, but which does not directly affect inference in any way. @@ -248,7 +248,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // record the fact that `'a <= 'b` is implied by the fn signature, // and then ignore the constraint when solving equations. This is // a bit of a hack but seems to work. - givens: RefCell>, + givens: RefCell>, lubs: RefCell>, glbs: RefCell>, @@ -305,14 +305,14 @@ impl TaintDirections { struct TaintSet<'tcx> { directions: TaintDirections, - regions: FnvHashSet<&'tcx ty::Region> + regions: FxHashSet<&'tcx ty::Region> } impl<'a, 'gcx, 'tcx> TaintSet<'tcx> { fn new(directions: TaintDirections, initial_region: &'tcx ty::Region) -> Self { - let mut regions = FnvHashSet(); + let mut regions = FxHashSet(); regions.insert(initial_region); TaintSet { directions: directions, regions: regions } } @@ -362,7 +362,7 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> { } } - fn into_set(self) -> FnvHashSet<&'tcx ty::Region> { + fn into_set(self) -> FxHashSet<&'tcx ty::Region> { self.regions } @@ -393,11 +393,11 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { tcx: tcx, var_origins: RefCell::new(Vec::new()), values: RefCell::new(None), - constraints: RefCell::new(FnvHashMap()), + constraints: RefCell::new(FxHashMap()), verifys: RefCell::new(Vec::new()), - givens: RefCell::new(FnvHashSet()), - lubs: RefCell::new(FnvHashMap()), - glbs: RefCell::new(FnvHashMap()), + givens: RefCell::new(FxHashSet()), + lubs: RefCell::new(FxHashMap()), + glbs: RefCell::new(FxHashMap()), skolemization_count: Cell::new(0), bound_count: Cell::new(0), undo_log: RefCell::new(Vec::new()), @@ -547,7 +547,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// completes to remove all trace of the skolemized regions /// created in that time. pub fn pop_skolemized(&self, - skols: &FnvHashSet<&'tcx ty::Region>, + skols: &FxHashSet<&'tcx ty::Region>, snapshot: &RegionSnapshot) { debug!("pop_skolemized_regions(skols={:?})", skols); @@ -601,7 +601,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { self.skolemization_count.set(snapshot.skolemization_count); return; - fn kill_constraint<'tcx>(skols: &FnvHashSet<&'tcx ty::Region>, + fn kill_constraint<'tcx>(skols: &FxHashSet<&'tcx ty::Region>, undo_entry: &UndoLogEntry<'tcx>) -> bool { match undo_entry { @@ -905,7 +905,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { mark: &RegionSnapshot, r0: &'tcx Region, directions: TaintDirections) - -> FnvHashSet<&'tcx ty::Region> { + -> FxHashSet<&'tcx ty::Region> { debug!("tainted(mark={:?}, r0={:?}, directions={:?})", mark, r0, directions); @@ -1414,13 +1414,13 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { dup_vec: &mut [u32]) -> (Vec>, bool) { struct WalkState<'tcx> { - set: FnvHashSet, + set: FxHashSet, stack: Vec, result: Vec>, dup_found: bool, } let mut state = WalkState { - set: FnvHashSet(), + set: FxHashSet(), stack: vec![orig_node_idx], result: Vec::new(), dup_found: false, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index f08aa2eb49f72..9cc2337e3dd1e 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -33,7 +33,7 @@ use lint::{Level, LevelSource, Lint, LintId, LintPass, LintSource}; use lint::{EarlyLintPassObject, LateLintPassObject}; use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid}; use lint::builtin; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use std::cmp; use std::default::Default as StdDefault; @@ -64,18 +64,18 @@ pub struct LintStore { late_passes: Option>, /// Lints indexed by name. - by_name: FnvHashMap, + by_name: FxHashMap, /// Current levels of each lint, and where they were set. - levels: FnvHashMap, + levels: FxHashMap, /// Map of registered lint groups to what lints they expand to. The bool /// is true if the lint group was added by a plugin. - lint_groups: FnvHashMap<&'static str, (Vec, bool)>, + lint_groups: FxHashMap<&'static str, (Vec, bool)>, /// Extra info for future incompatibility lints, descibing the /// issue or RFC that caused the incompatibility. - future_incompatible: FnvHashMap, + future_incompatible: FxHashMap, /// Maximum level a lint can be lint_cap: Option, @@ -171,10 +171,10 @@ impl LintStore { lints: vec![], early_passes: Some(vec![]), late_passes: Some(vec![]), - by_name: FnvHashMap(), - levels: FnvHashMap(), - future_incompatible: FnvHashMap(), - lint_groups: FnvHashMap(), + by_name: FxHashMap(), + levels: FxHashMap(), + future_incompatible: FxHashMap(), + lint_groups: FxHashMap(), lint_cap: None, } } @@ -304,8 +304,8 @@ impl LintStore { Err(FindLintError::Removed) => { } Err(_) => { match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone())) - .collect::>>() + .collect::>>() .get(&lint_name[..]) { Some(v) => { v.iter() diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 4212b1fb05ee3..7fc698fdbebf5 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -22,7 +22,7 @@ use ty::{self, TyCtxt}; use hir::def::Def; use hir::def_id::{DefId}; use lint; -use util::nodemap::FnvHashSet; +use util::nodemap::FxHashSet; use syntax::{ast, codemap}; use syntax::attr; @@ -48,7 +48,7 @@ fn should_explore<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, struct MarkSymbolVisitor<'a, 'tcx: 'a> { worklist: Vec, tcx: TyCtxt<'a, 'tcx, 'tcx>, - live_symbols: Box>, + live_symbols: Box>, struct_has_extern_repr: bool, ignore_non_const_paths: bool, inherited_pub_visibility: bool, @@ -61,7 +61,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { MarkSymbolVisitor { worklist: worklist, tcx: tcx, - live_symbols: box FnvHashSet(), + live_symbols: box FxHashSet(), struct_has_extern_repr: false, ignore_non_const_paths: false, inherited_pub_visibility: false, @@ -163,7 +163,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn mark_live_symbols(&mut self) { - let mut scanned = FnvHashSet(); + let mut scanned = FxHashSet(); while !self.worklist.is_empty() { let id = self.worklist.pop().unwrap(); if scanned.contains(&id) { @@ -396,7 +396,7 @@ fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, access_levels: &privacy::AccessLevels, krate: &hir::Crate) - -> Box> { + -> Box> { let worklist = create_and_seed_worklist(tcx, access_levels, krate); let mut symbol_visitor = MarkSymbolVisitor::new(tcx, worklist); symbol_visitor.mark_live_symbols(); @@ -414,7 +414,7 @@ fn get_struct_ctor_id(item: &hir::Item) -> Option { struct DeadVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - live_symbols: Box>, + live_symbols: Box>, } impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 656d3146fe5d1..c658f47ec1be0 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -66,7 +66,7 @@ use hir::def_id::CrateNum; use session; use session::config; use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic}; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use rustc_back::PanicStrategy; /// A list of dependencies for a certain crate type. @@ -80,7 +80,7 @@ pub type DependencyList = Vec; /// A mapping of all required dependencies for a particular flavor of output. /// /// This is local to the tcx, and is generally relevant to one session. -pub type Dependencies = FnvHashMap; +pub type Dependencies = FxHashMap; #[derive(Copy, Clone, PartialEq, Debug)] pub enum Linkage { @@ -149,7 +149,7 @@ fn calculate_type(sess: &session::Session, config::CrateTypeProcMacro => {}, } - let mut formats = FnvHashMap(); + let mut formats = FxHashMap(); // Sweep all crates for found dylibs. Add all dylibs, as well as their // dependencies, ensuring there are no conflicts. The only valid case for a @@ -240,7 +240,7 @@ fn calculate_type(sess: &session::Session, fn add_library(sess: &session::Session, cnum: CrateNum, link: LinkagePreference, - m: &mut FnvHashMap) { + m: &mut FxHashMap) { match m.get(&cnum) { Some(&link2) => { // If the linkages differ, then we'd have two copies of the library diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 3175230ab6a5e..3e7de79246b66 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -27,7 +27,7 @@ use session::Session; use hir::def_id::DefId; use ty; use middle::weak_lang_items; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use syntax::ast; use syntax::parse::token::InternedString; @@ -146,7 +146,7 @@ struct LanguageItemCollector<'a, 'tcx: 'a> { session: &'a Session, - item_refs: FnvHashMap<&'static str, usize>, + item_refs: FxHashMap<&'static str, usize>, } impl<'a, 'v, 'tcx> Visitor<'v> for LanguageItemCollector<'a, 'tcx> { @@ -169,7 +169,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for LanguageItemCollector<'a, 'tcx> { impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { pub fn new(session: &'a Session, ast_map: &'a hir_map::Map<'tcx>) -> LanguageItemCollector<'a, 'tcx> { - let mut item_refs = FnvHashMap(); + let mut item_refs = FxHashMap(); $( item_refs.insert($name, $variant as usize); )* diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 189150d426463..1376886968f74 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -12,7 +12,7 @@ //! outside their scopes. This pass will also generate a set of exported items //! which are available for use externally when compiled as a library. -use util::nodemap::{DefIdSet, FnvHashMap}; +use util::nodemap::{DefIdSet, FxHashMap}; use std::hash::Hash; use std::fmt; @@ -35,7 +35,7 @@ pub enum AccessLevel { // Accessibility levels for reachable HIR nodes #[derive(Clone)] pub struct AccessLevels { - pub map: FnvHashMap + pub map: FxHashMap } impl AccessLevels { diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 1a50d7aa0adc7..9898ec7597d90 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -22,7 +22,7 @@ use hir::def_id::DefId; use ty::{self, TyCtxt}; use middle::privacy; use session::config; -use util::nodemap::{NodeSet, FnvHashSet}; +use util::nodemap::{NodeSet, FxHashSet}; use syntax::abi::Abi; use syntax::ast; @@ -204,7 +204,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // Step 2: Mark all symbols that the symbols on the worklist touch. fn propagate(&mut self) { - let mut scanned = FnvHashSet(); + let mut scanned = FxHashSet(); loop { let search_item = match self.worklist.pop() { Some(item) => item, diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 30b735b9c24e3..8d51fda0cf2b1 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -19,7 +19,7 @@ use dep_graph::DepNode; use hir::map as ast_map; use session::Session; -use util::nodemap::{FnvHashMap, NodeMap, NodeSet}; +use util::nodemap::{FxHashMap, NodeMap, NodeSet}; use ty; use std::cell::RefCell; @@ -251,7 +251,7 @@ impl CodeExtent { /// The region maps encode information about region relationships. pub struct RegionMaps { code_extents: RefCell>, - code_extent_interner: RefCell>, + code_extent_interner: RefCell>, /// `scope_map` maps from a scope id to the enclosing scope id; /// this is usually corresponding to the lexical nesting, though /// in the case of closures the parent scope is the innermost @@ -1217,7 +1217,7 @@ pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps { let maps = RegionMaps { code_extents: RefCell::new(vec![]), - code_extent_interner: RefCell::new(FnvHashMap()), + code_extent_interner: RefCell::new(FxHashMap()), scope_map: RefCell::new(vec![]), var_map: RefCell::new(NodeMap()), rvalue_scopes: RefCell::new(NodeMap()), diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 2d93c33afb409..e6d960735299c 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -31,7 +31,7 @@ use syntax::parse::token::keywords; use syntax_pos::Span; use util::nodemap::NodeMap; -use rustc_data_structures::fnv::FnvHashSet; +use rustc_data_structures::fx::FxHashSet; use hir; use hir::print::lifetime_to_string; use hir::intravisit::{self, Visitor, FnKind}; @@ -847,13 +847,13 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, generics: &hir::Generics) { debug!("insert_late_bound_lifetimes(decl={:?}, generics={:?})", decl, generics); - let mut constrained_by_input = ConstrainedCollector { regions: FnvHashSet() }; + let mut constrained_by_input = ConstrainedCollector { regions: FxHashSet() }; for arg in &decl.inputs { constrained_by_input.visit_ty(&arg.ty); } let mut appears_in_output = AllCollector { - regions: FnvHashSet(), + regions: FxHashSet(), impl_trait: false }; intravisit::walk_fn_ret_ty(&mut appears_in_output, &decl.output); @@ -866,7 +866,7 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, // Subtle point: because we disallow nested bindings, we can just // ignore binders here and scrape up all names we see. let mut appears_in_where_clause = AllCollector { - regions: FnvHashSet(), + regions: FxHashSet(), impl_trait: false }; for ty_param in generics.ty_params.iter() { @@ -926,7 +926,7 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, return; struct ConstrainedCollector { - regions: FnvHashSet, + regions: FxHashSet, } impl<'v> Visitor<'v> for ConstrainedCollector { @@ -961,7 +961,7 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, } struct AllCollector { - regions: FnvHashSet, + regions: FxHashSet, impl_trait: bool } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index fd17e378787a5..f1755c82b8cbd 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -27,7 +27,7 @@ use syntax::ast; use syntax::ast::{NodeId, Attribute}; use syntax::feature_gate::{GateIssue, emit_feature_err, find_lang_feature_accepted_version}; use syntax::attr::{self, Stability, Deprecation}; -use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap}; +use util::nodemap::{DefIdMap, FxHashSet, FxHashMap}; use hir; use hir::{Item, Generics, StructField, Variant, PatKind}; @@ -102,7 +102,7 @@ pub struct Index<'tcx> { depr_map: DefIdMap>, /// Maps for each crate whether it is part of the staged API. - staged_api: FnvHashMap + staged_api: FxHashMap } // A private tree-walker for producing an Index. @@ -343,7 +343,7 @@ impl<'a, 'tcx> Index<'tcx> { } } - let mut staged_api = FnvHashMap(); + let mut staged_api = FxHashMap(); staged_api.insert(LOCAL_CRATE, is_staged_api); Index { staged_api: staged_api, @@ -357,7 +357,7 @@ impl<'a, 'tcx> Index<'tcx> { /// features and possibly prints errors. Returns a list of all /// features used. pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> FnvHashMap { + -> FxHashMap { let _task = tcx.dep_graph.in_task(DepNode::StabilityCheck); let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features; @@ -367,7 +367,7 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) let mut checker = Checker { tcx: tcx, active_features: active_features, - used_features: FnvHashMap(), + used_features: FxHashMap(), in_skip_block: 0, }; intravisit::walk_crate(&mut checker, tcx.map.krate()); @@ -377,8 +377,8 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) struct Checker<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - active_features: FnvHashSet, - used_features: FnvHashMap, + active_features: FxHashSet, + used_features: FxHashMap, // Within a block where feature gate checking can be skipped. in_skip_block: u32, } @@ -746,10 +746,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { /// were expected to be library features), and the list of features used from /// libraries, identify activated features that don't exist and error about them. pub fn check_unused_or_stable_features(sess: &Session, - lib_features_used: &FnvHashMap) { + lib_features_used: &FxHashMap) { let ref declared_lib_features = sess.features.borrow().declared_lib_features; - let mut remaining_lib_features: FnvHashMap + let mut remaining_lib_features: FxHashMap = declared_lib_features.clone().into_iter().collect(); fn format_stable_since_msg(version: &str) -> String { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b4dadbf7961fb..724b32d2cd715 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -17,7 +17,7 @@ use middle::dependency_format; use session::search_paths::PathKind; use session::config::DebugInfoLevel; use ty::tls; -use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet}; +use util::nodemap::{NodeMap, FxHashMap, FxHashSet}; use util::common::duration_to_secs_str; use mir::transform as mir_pass; @@ -78,7 +78,7 @@ pub struct Session { /// Set of (LintId, span, message) tuples tracking lint (sub)diagnostics /// that have been set once, but should not be set again, in order to avoid /// redundantly verbose output (Issue #24690). - pub one_time_diagnostics: RefCell>, + pub one_time_diagnostics: RefCell>, pub plugin_llvm_passes: RefCell>, pub mir_passes: RefCell, pub plugin_attributes: RefCell>, @@ -603,12 +603,12 @@ pub fn build_session_(sopts: config::Options, working_dir: env::current_dir().unwrap(), lint_store: RefCell::new(lint::LintStore::new()), lints: RefCell::new(NodeMap()), - one_time_diagnostics: RefCell::new(FnvHashSet()), + one_time_diagnostics: RefCell::new(FxHashSet()), plugin_llvm_passes: RefCell::new(Vec::new()), mir_passes: RefCell::new(mir_pass::Passes::new()), plugin_attributes: RefCell::new(Vec::new()), crate_types: RefCell::new(Vec::new()), - dependency_formats: RefCell::new(FnvHashMap()), + dependency_formats: RefCell::new(FxHashMap()), crate_disambiguator: RefCell::new(token::intern("").as_str()), features: RefCell::new(feature_gate::Features::new()), recursion_limit: Cell::new(64), diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 89c8162456c42..3522c738c160c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -33,7 +33,7 @@ use ty::error::ExpectedFound; use ty::fast_reject; use ty::fold::TypeFolder; use ty::subst::Subst; -use util::nodemap::{FnvHashMap, FnvHashSet}; +use util::nodemap::{FxHashMap, FxHashSet}; use std::cmp; use std::fmt; @@ -252,7 +252,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let generic_map = def.generics.types.iter().map(|param| { (param.name.as_str().to_string(), trait_ref.substs.type_for_def(param).to_string()) - }).collect::>(); + }).collect::>(); let parser = Parser::new(&istring); let mut errored = false; let err: String = parser.filter_map(|p| { @@ -647,7 +647,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { "the trait `{}` cannot be made into an object", trait_str )); - let mut reported_violations = FnvHashSet(); + let mut reported_violations = FxHashSet(); for violation in violations { if !reported_violations.insert(violation.clone()) { continue; @@ -786,7 +786,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn predicate_can_apply(&self, pred: ty::PolyTraitRef<'tcx>) -> bool { struct ParamToVarFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - var_map: FnvHashMap, Ty<'tcx>> + var_map: FxHashMap, Ty<'tcx>> } impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ParamToVarFolder<'a, 'gcx, 'tcx> { @@ -807,7 +807,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let cleaned_pred = pred.fold_with(&mut ParamToVarFolder { infcx: self, - var_map: FnvHashMap() + var_map: FxHashMap() }); let cleaned_pred = super::project::normalize( diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 906da4290361e..6de93adce3f83 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -18,7 +18,7 @@ use std::marker::PhantomData; use std::mem; use syntax::ast; use util::common::ErrorReported; -use util::nodemap::{FnvHashSet, NodeMap}; +use util::nodemap::{FxHashSet, NodeMap}; use super::CodeAmbiguity; use super::CodeProjectionError; @@ -37,7 +37,7 @@ impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { } pub struct GlobalFulfilledPredicates<'tcx> { - set: FnvHashSet>, + set: FxHashSet>, dep_graph: DepGraph, } @@ -673,7 +673,7 @@ fn register_region_obligation<'tcx>(t_a: Ty<'tcx>, impl<'a, 'gcx, 'tcx> GlobalFulfilledPredicates<'gcx> { pub fn new(dep_graph: DepGraph) -> GlobalFulfilledPredicates<'gcx> { GlobalFulfilledPredicates { - set: FnvHashSet(), + set: FxHashSet(), dep_graph: dep_graph, } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index e75c8bd433404..5e3f78b1208d5 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -51,7 +51,7 @@ use std::mem; use std::rc::Rc; use syntax::abi::Abi; use hir; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; struct InferredObligationsSnapshotVecDelegate<'tcx> { phantom: PhantomData<&'tcx i32>, @@ -104,8 +104,8 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> { #[derive(Clone)] pub struct SelectionCache<'tcx> { - hashmap: RefCell, - SelectionResult<'tcx, SelectionCandidate<'tcx>>>>, + hashmap: RefCell, + SelectionResult<'tcx, SelectionCandidate<'tcx>>>>, } pub enum MethodMatchResult { @@ -306,7 +306,7 @@ enum EvaluationResult { #[derive(Clone)] pub struct EvaluationCache<'tcx> { - hashmap: RefCell, EvaluationResult>> + hashmap: RefCell, EvaluationResult>> } impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { @@ -2937,7 +2937,7 @@ impl<'tcx> TraitObligation<'tcx> { impl<'tcx> SelectionCache<'tcx> { pub fn new() -> SelectionCache<'tcx> { SelectionCache { - hashmap: RefCell::new(FnvHashMap()) + hashmap: RefCell::new(FxHashMap()) } } } @@ -2945,7 +2945,7 @@ impl<'tcx> SelectionCache<'tcx> { impl<'tcx> EvaluationCache<'tcx> { pub fn new() -> EvaluationCache<'tcx> { EvaluationCache { - hashmap: RefCell::new(FnvHashMap()) + hashmap: RefCell::new(FxHashMap()) } } } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 909247d1cb245..4eef6944974c0 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -20,7 +20,7 @@ use super::{SelectionContext, FulfillmentContext}; use super::util::impl_trait_ref_and_oblig; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use hir::def_id::DefId; use infer::{InferCtxt, InferOk, TypeOrigin}; use middle::region; @@ -270,13 +270,13 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, } pub struct SpecializesCache { - map: FnvHashMap<(DefId, DefId), bool> + map: FxHashMap<(DefId, DefId), bool> } impl SpecializesCache { pub fn new() -> Self { SpecializesCache { - map: FnvHashMap() + map: FxHashMap() } } diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 1374719ef49c4..c746145474c75 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -17,7 +17,7 @@ use traits::{self, Reveal}; use ty::{self, TyCtxt, ImplOrTraitItem, TraitDef, TypeFoldable}; use ty::fast_reject::{self, SimplifiedType}; use syntax::ast::Name; -use util::nodemap::{DefIdMap, FnvHashMap}; +use util::nodemap::{DefIdMap, FxHashMap}; /// A per-trait graph of impls in specialization order. At the moment, this /// graph forms a tree rooted with the trait itself, with all other nodes @@ -57,7 +57,7 @@ struct Children { // the specialization graph. /// Impls of the trait. - nonblanket_impls: FnvHashMap>, + nonblanket_impls: FxHashMap>, /// Blanket impls associated with the trait. blanket_impls: Vec, @@ -78,7 +78,7 @@ enum Inserted { impl<'a, 'gcx, 'tcx> Children { fn new() -> Children { Children { - nonblanket_impls: FnvHashMap(), + nonblanket_impls: FxHashMap(), blanket_impls: vec![], } } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index a3d974216b6e0..52830164d1d91 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -13,7 +13,7 @@ use ty::subst::{Subst, Substs}; use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef}; use ty::outlives::Component; use util::common::ErrorReported; -use util::nodemap::FnvHashSet; +use util::nodemap::FxHashSet; use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized}; @@ -50,12 +50,12 @@ fn anonymize_predicate<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, struct PredicateSet<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, - set: FnvHashSet>, + set: FxHashSet>, } impl<'a, 'gcx, 'tcx> PredicateSet<'a, 'gcx, 'tcx> { fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> PredicateSet<'a, 'gcx, 'tcx> { - PredicateSet { tcx: tcx, set: FnvHashSet() } + PredicateSet { tcx: tcx, set: FxHashSet() } } fn insert(&mut self, pred: &ty::Predicate<'tcx>) -> bool { @@ -272,7 +272,7 @@ pub fn transitive_bounds<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>, pub struct SupertraitDefIds<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, stack: Vec, - visited: FnvHashSet, + visited: FxHashSet, } pub fn supertrait_def_ids<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>, diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs index b499e1346e73c..7ed4de38be97e 100644 --- a/src/librustc/ty/contents.rs +++ b/src/librustc/ty/contents.rs @@ -11,7 +11,7 @@ use hir::def_id::{DefId}; use ty::{self, Ty, TyCtxt}; use util::common::MemoizationMap; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use std::fmt; use std::ops; @@ -141,11 +141,11 @@ impl fmt::Debug for TypeContents { impl<'a, 'tcx> ty::TyS<'tcx> { pub fn type_contents(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> TypeContents { - return tcx.tc_cache.memoize(self, || tc_ty(tcx, self, &mut FnvHashMap())); + return tcx.tc_cache.memoize(self, || tc_ty(tcx, self, &mut FxHashMap())); fn tc_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>, - cache: &mut FnvHashMap, TypeContents>) -> TypeContents + cache: &mut FxHashMap, TypeContents>) -> TypeContents { // Subtle: Note that we are *not* using tcx.tc_cache here but rather a // private cache for this walk. This is needed in the case of cyclic diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 7e5e10435d516..b19f935123519 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -36,7 +36,7 @@ use ty::layout::{Layout, TargetDataLayout}; use ty::maps; use util::common::MemoizationMap; use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; -use util::nodemap::{FnvHashMap, FnvHashSet}; +use util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::accumulate_vec::AccumulateVec; use arena::TypedArena; @@ -96,26 +96,26 @@ pub struct CtxtInterners<'tcx> { /// Specifically use a speedy hash algorithm for these hash sets, /// they're accessed quite often. - type_: RefCell>>>, - type_list: RefCell>>>>, - substs: RefCell>>>, - bare_fn: RefCell>>>, - region: RefCell>>, - stability: RefCell>, - layout: RefCell>, + type_: RefCell>>>, + type_list: RefCell>>>>, + substs: RefCell>>>, + bare_fn: RefCell>>>, + region: RefCell>>, + stability: RefCell>, + layout: RefCell>, } impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { fn new(arenas: &'tcx CtxtArenas<'tcx>) -> CtxtInterners<'tcx> { CtxtInterners { arenas: arenas, - type_: RefCell::new(FnvHashSet()), - type_list: RefCell::new(FnvHashSet()), - substs: RefCell::new(FnvHashSet()), - bare_fn: RefCell::new(FnvHashSet()), - region: RefCell::new(FnvHashSet()), - stability: RefCell::new(FnvHashSet()), - layout: RefCell::new(FnvHashSet()) + type_: RefCell::new(FxHashSet()), + type_list: RefCell::new(FxHashSet()), + substs: RefCell::new(FxHashSet()), + bare_fn: RefCell::new(FxHashSet()), + region: RefCell::new(FxHashSet()), + stability: RefCell::new(FxHashSet()), + layout: RefCell::new(FxHashSet()) } } @@ -244,11 +244,11 @@ pub struct Tables<'tcx> { impl<'a, 'gcx, 'tcx> Tables<'tcx> { pub fn empty() -> Tables<'tcx> { Tables { - node_types: FnvHashMap(), + node_types: FxHashMap(), item_substs: NodeMap(), adjustments: NodeMap(), - method_map: FnvHashMap(), - upvar_capture_map: FnvHashMap(), + method_map: FxHashMap(), + upvar_capture_map: FxHashMap(), closure_tys: DefIdMap(), closure_kinds: DefIdMap(), liberated_fn_sigs: NodeMap(), @@ -451,16 +451,16 @@ pub struct GlobalCtxt<'tcx> { pub tcache: RefCell>>, // Internal cache for metadata decoding. No need to track deps on this. - pub rcache: RefCell>>, + pub rcache: RefCell>>, // Cache for the type-contents routine. FIXME -- track deps? - pub tc_cache: RefCell, ty::contents::TypeContents>>, + pub tc_cache: RefCell, ty::contents::TypeContents>>, // FIXME no dep tracking, but we should be able to remove this pub ty_param_defs: RefCell>>, // FIXME dep tracking -- should be harmless enough - pub normalized_cache: RefCell, Ty<'tcx>>>, + pub normalized_cache: RefCell, Ty<'tcx>>>, pub lang_items: middle::lang_items::LanguageItems, @@ -571,7 +571,7 @@ pub struct GlobalCtxt<'tcx> { pub data_layout: TargetDataLayout, /// Cache for layouts computed from types. - pub layout_cache: RefCell, &'tcx Layout>>, + pub layout_cache: RefCell, &'tcx Layout>>, /// Used to prevent layout from recursing too deeply. pub layout_depth: Cell, @@ -801,7 +801,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { types: common_types, named_region_map: named_region_map, region_maps: region_maps, - free_region_maps: RefCell::new(FnvHashMap()), + free_region_maps: RefCell::new(FxHashMap()), item_variance_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())), variance_computed: Cell::new(false), sess: s, @@ -820,13 +820,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { freevars: RefCell::new(freevars), maybe_unused_trait_imports: maybe_unused_trait_imports, tcache: RefCell::new(DepTrackingMap::new(dep_graph.clone())), - rcache: RefCell::new(FnvHashMap()), - tc_cache: RefCell::new(FnvHashMap()), + rcache: RefCell::new(FxHashMap()), + tc_cache: RefCell::new(FxHashMap()), impl_or_trait_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())), impl_or_trait_item_def_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())), trait_items_cache: RefCell::new(DepTrackingMap::new(dep_graph.clone())), ty_param_defs: RefCell::new(NodeMap()), - normalized_cache: RefCell::new(FnvHashMap()), + normalized_cache: RefCell::new(FxHashMap()), lang_items: lang_items, inherent_impls: RefCell::new(DepTrackingMap::new(dep_graph.clone())), used_unsafe: RefCell::new(NodeSet()), @@ -846,7 +846,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { fragment_infos: RefCell::new(DefIdMap()), crate_name: token::intern_and_get_ident(crate_name), data_layout: data_layout, - layout_cache: RefCell::new(FnvHashMap()), + layout_cache: RefCell::new(FxHashMap()), layout_depth: Cell::new(0), derive_macros: RefCell::new(NodeMap()), }, f) diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index b79ebdb14f552..354658ec4397f 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -45,7 +45,7 @@ use ty::adjustment; use ty::{self, Binder, Ty, TyCtxt, TypeFlags}; use std::fmt; -use util::nodemap::{FnvHashMap, FnvHashSet}; +use util::nodemap::{FxHashMap, FxHashSet}; /// The TypeFoldable trait is implemented for every type that can be folded. /// Basically, every type that has a corresponding method in TypeFolder. @@ -225,7 +225,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// whether any late-bound regions were skipped pub fn collect_regions(self, value: &T, - region_set: &mut FnvHashSet<&'tcx ty::Region>) + region_set: &mut FxHashSet<&'tcx ty::Region>) -> bool where T : TypeFoldable<'tcx> { @@ -319,14 +319,14 @@ struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, current_depth: u32, fld_r: &'a mut (FnMut(ty::BoundRegion) -> &'tcx ty::Region + 'a), - map: FnvHashMap + map: FxHashMap } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn replace_late_bound_regions(self, value: &Binder, mut f: F) - -> (T, FnvHashMap) + -> (T, FxHashMap) where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region, T : TypeFoldable<'tcx>, { @@ -390,7 +390,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// variables and equate `value` with something else, those /// variables will also be equated. pub fn collect_constrained_late_bound_regions(&self, value: &Binder) - -> FnvHashSet + -> FxHashSet where T : TypeFoldable<'tcx> { self.collect_late_bound_regions(value, true) @@ -398,14 +398,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns a set of all late-bound regions that appear in `value` anywhere. pub fn collect_referenced_late_bound_regions(&self, value: &Binder) - -> FnvHashSet + -> FxHashSet where T : TypeFoldable<'tcx> { self.collect_late_bound_regions(value, false) } fn collect_late_bound_regions(&self, value: &Binder, just_constraint: bool) - -> FnvHashSet + -> FxHashSet where T : TypeFoldable<'tcx> { let mut collector = LateBoundRegionsCollector::new(just_constraint); @@ -450,7 +450,7 @@ impl<'a, 'gcx, 'tcx> RegionReplacer<'a, 'gcx, 'tcx> { tcx: tcx, current_depth: 1, fld_r: fld_r, - map: FnvHashMap() + map: FxHashMap() } } } @@ -650,7 +650,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { /// Collects all the late-bound regions it finds into a hash set. struct LateBoundRegionsCollector { current_depth: u32, - regions: FnvHashSet, + regions: FxHashSet, just_constrained: bool, } @@ -658,7 +658,7 @@ impl LateBoundRegionsCollector { fn new(just_constrained: bool) -> Self { LateBoundRegionsCollector { current_depth: 1, - regions: FnvHashSet(), + regions: FxHashSet(), just_constrained: just_constrained, } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 2c15f08e89822..fcf9b5ff2730c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -31,7 +31,7 @@ use ty::subst::{Subst, Substs}; use ty::walk::TypeWalker; use util::common::MemoizationMap; use util::nodemap::NodeSet; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use serialize::{self, Encodable, Encoder}; use std::borrow::Cow; @@ -418,7 +418,7 @@ impl MethodCall { // maps from an expression id that corresponds to a method call to the details // of the method to be invoked -pub type MethodMap<'tcx> = FnvHashMap>; +pub type MethodMap<'tcx> = FxHashMap>; // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. @@ -650,7 +650,7 @@ pub struct UpvarBorrow<'tcx> { pub region: &'tcx ty::Region, } -pub type UpvarCaptureMap<'tcx> = FnvHashMap>; +pub type UpvarCaptureMap<'tcx> = FxHashMap>; #[derive(Copy, Clone)] pub struct ClosureUpvar<'tcx> { @@ -1251,10 +1251,10 @@ pub struct ParameterEnvironment<'tcx> { pub free_id_outlive: CodeExtent, /// A cache for `moves_by_default`. - pub is_copy_cache: RefCell, bool>>, + pub is_copy_cache: RefCell, bool>>, /// A cache for `type_is_sized` - pub is_sized_cache: RefCell, bool>>, + pub is_sized_cache: RefCell, bool>>, } impl<'a, 'tcx> ParameterEnvironment<'tcx> { @@ -1267,8 +1267,8 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { implicit_region_bound: self.implicit_region_bound, caller_bounds: caller_bounds, free_id_outlive: self.free_id_outlive, - is_copy_cache: RefCell::new(FnvHashMap()), - is_sized_cache: RefCell::new(FnvHashMap()), + is_copy_cache: RefCell::new(FxHashMap()), + is_sized_cache: RefCell::new(FxHashMap()), } } @@ -2752,8 +2752,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { caller_bounds: Vec::new(), implicit_region_bound: self.mk_region(ty::ReEmpty), free_id_outlive: free_id_outlive, - is_copy_cache: RefCell::new(FnvHashMap()), - is_sized_cache: RefCell::new(FnvHashMap()), + is_copy_cache: RefCell::new(FxHashMap()), + is_sized_cache: RefCell::new(FxHashMap()), } } @@ -2824,8 +2824,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)), caller_bounds: predicates, free_id_outlive: free_id_outlive, - is_copy_cache: RefCell::new(FnvHashMap()), - is_sized_cache: RefCell::new(FnvHashMap()), + is_copy_cache: RefCell::new(FxHashMap()), + is_sized_cache: RefCell::new(FxHashMap()), }; let cause = traits::ObligationCause::misc(span, free_id_outlive.node_id(&self.region_maps)); diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 3ff2ed76e571e..fc32029948388 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -16,7 +16,7 @@ use ty::fast_reject; use ty::{Ty, TyCtxt, TraitRef}; use std::cell::{Cell, RefCell}; use hir; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; /// As `TypeScheme` but for a trait ref. pub struct TraitDef<'tcx> { @@ -55,7 +55,7 @@ pub struct TraitDef<'tcx> { /// Impls of the trait. nonblanket_impls: RefCell< - FnvHashMap> + FxHashMap> >, /// Blanket impls associated with the trait. @@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> { unsafety: unsafety, generics: generics, trait_ref: trait_ref, - nonblanket_impls: RefCell::new(FnvHashMap()), + nonblanket_impls: RefCell::new(FxHashMap()), blanket_impls: RefCell::new(vec![]), flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS), specialization_graph: RefCell::new(traits::specialization_graph::Graph::new()), diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index cca4069ba5a17..b1aeaeb48d144 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -20,7 +20,7 @@ use ty::{Disr, ParameterEnvironment}; use ty::fold::TypeVisitor; use ty::layout::{Layout, LayoutError}; use ty::TypeVariants::*; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use rustc_const_math::{ConstInt, ConstIsize, ConstUsize}; @@ -594,7 +594,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: &ParameterEnvironment<'tcx>, bound: ty::BuiltinBound, - cache: &RefCell, bool>>, + cache: &RefCell, bool>>, span: Span) -> bool { if self.has_param_types() || self.has_self_ty() { diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index 69bcc9cbfffea..b03011fcb216d 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -15,17 +15,17 @@ use hir::def_id::DefId; use syntax::ast; -pub use rustc_data_structures::fnv::FnvHashMap; -pub use rustc_data_structures::fnv::FnvHashSet; +pub use rustc_data_structures::fx::FxHashMap; +pub use rustc_data_structures::fx::FxHashSet; -pub type NodeMap = FnvHashMap; -pub type DefIdMap = FnvHashMap; +pub type NodeMap = FxHashMap; +pub type DefIdMap = FxHashMap; -pub type NodeSet = FnvHashSet; -pub type DefIdSet = FnvHashSet; +pub type NodeSet = FxHashSet; +pub type DefIdSet = FxHashSet; -pub fn NodeMap() -> NodeMap { FnvHashMap() } -pub fn DefIdMap() -> DefIdMap { FnvHashMap() } -pub fn NodeSet() -> NodeSet { FnvHashSet() } -pub fn DefIdSet() -> DefIdSet { FnvHashSet() } +pub fn NodeMap() -> NodeMap { FxHashMap() } +pub fn DefIdMap() -> DefIdMap { FxHashMap() } +pub fn NodeSet() -> NodeSet { FxHashSet() } +pub fn DefIdSet() -> DefIdSet { FxHashSet() } diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index 191cd981b61eb..be85069db3135 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -21,7 +21,7 @@ use rustc::mir::*; use rustc::mir::transform::{Pass, MirPass, MirSource}; use rustc::middle::const_val::ConstVal; use rustc::middle::lang_items; -use rustc::util::nodemap::FnvHashMap; +use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_set::IdxSetBuf; use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; @@ -63,7 +63,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { env: &env, flow_inits: flow_inits, flow_uninits: flow_uninits, - drop_flags: FnvHashMap(), + drop_flags: FxHashMap(), patch: MirPatch::new(mir), }.elaborate() }; @@ -118,7 +118,7 @@ struct ElaborateDropsCtxt<'a, 'tcx: 'a> { env: &'a MoveDataParamEnv<'tcx>, flow_inits: DataflowResults>, flow_uninits: DataflowResults>, - drop_flags: FnvHashMap, + drop_flags: FxHashMap, patch: MirPatch<'tcx>, } diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index 1dc5769e63cf8..02064b52cb1fb 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -11,7 +11,7 @@ use rustc::ty::{self, TyCtxt, ParameterEnvironment}; use rustc::mir::*; -use rustc::util::nodemap::FnvHashMap; +use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::{IndexVec}; use syntax::codemap::DUMMY_SP; @@ -181,7 +181,7 @@ pub struct MovePathLookup<'tcx> { /// subsequent search so that it is solely relative to that /// base-lvalue). For the remaining lookup, we map the projection /// elem to the associated MovePathIndex. - projections: FnvHashMap<(MovePathIndex, AbstractElem<'tcx>), MovePathIndex> + projections: FxHashMap<(MovePathIndex, AbstractElem<'tcx>), MovePathIndex> } struct MoveDataBuilder<'a, 'tcx: 'a> { @@ -215,7 +215,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { locals: mir.local_decls.indices().map(Lvalue::Local).map(|v| { Self::new_move_path(&mut move_paths, &mut path_map, None, v) }).collect(), - projections: FnvHashMap(), + projections: FxHashMap(), }, move_paths: move_paths, path_map: path_map, diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index ba036f1a8b157..afc4ccef0cc0f 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -23,7 +23,7 @@ use rustc::middle::expr_use_visitor as euv; use rustc::middle::expr_use_visitor::MutateMode; use rustc::middle::mem_categorization as mc; use rustc::ty::{self, TyCtxt}; -use rustc::util::nodemap::{FnvHashMap, NodeSet}; +use rustc::util::nodemap::{FxHashMap, NodeSet}; use std::cell::RefCell; use std::rc::Rc; @@ -41,7 +41,7 @@ pub struct MoveData<'tcx> { pub paths: RefCell>>, /// Cache of loan path to move path index, for easy lookup. - pub path_map: RefCell>, MovePathIndex>>, + pub path_map: RefCell>, MovePathIndex>>, /// Each move or uninitialized variable gets an entry here. pub moves: RefCell>, @@ -217,7 +217,7 @@ impl<'a, 'tcx> MoveData<'tcx> { pub fn new() -> MoveData<'tcx> { MoveData { paths: RefCell::new(Vec::new()), - path_map: RefCell::new(FnvHashMap()), + path_map: RefCell::new(FxHashMap()), moves: RefCell::new(Vec::new()), path_assignments: RefCell::new(Vec::new()), var_assignments: RefCell::new(Vec::new()), diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index 7f5eb31612cb3..831d21b831042 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -17,7 +17,7 @@ use eval::{compare_const_vals}; use rustc_const_math::ConstInt; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use pattern::{FieldPattern, Pattern, PatternKind}; @@ -160,7 +160,7 @@ pub struct MatchCheckCtxt<'a, 'tcx: 'a> { /// associated types to get field types. pub wild_pattern: &'a Pattern<'tcx>, pub pattern_arena: &'a TypedArena>, - pub byte_array_map: FnvHashMap<*const Pattern<'tcx>, Vec<&'a Pattern<'tcx>>>, + pub byte_array_map: FxHashMap<*const Pattern<'tcx>, Vec<&'a Pattern<'tcx>>>, } impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { @@ -181,7 +181,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { tcx: tcx, wild_pattern: &wild_pattern, pattern_arena: &pattern_arena, - byte_array_map: FnvHashMap(), + byte_array_map: FxHashMap(), }) } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index fc963dac9495f..fdcbec6bac11a 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -60,6 +60,7 @@ pub mod snapshot_vec; pub mod transitive_relation; pub mod unify; pub mod fnv; +pub mod fx; pub mod tuple_slice; pub mod veccell; pub mod control_flow_graph; diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index a2bfa784e8aed..a46238309bb46 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -15,7 +15,7 @@ //! in the first place). See README.md for a general overview of how //! to use this class. -use fnv::{FnvHashMap, FnvHashSet}; +use fx::{FxHashMap, FxHashSet}; use std::cell::Cell; use std::collections::hash_map::Entry; @@ -68,9 +68,9 @@ pub struct ObligationForest { /// backtrace iterator (which uses `split_at`). nodes: Vec>, /// A cache of predicates that have been successfully completed. - done_cache: FnvHashSet, + done_cache: FxHashSet, /// An cache of the nodes in `nodes`, indexed by predicate. - waiting_cache: FnvHashMap, + waiting_cache: FxHashMap, /// A list of the obligations added in snapshots, to allow /// for their removal. cache_list: Vec, @@ -158,8 +158,8 @@ impl ObligationForest { ObligationForest { nodes: vec![], snapshots: vec![], - done_cache: FnvHashSet(), - waiting_cache: FnvHashMap(), + done_cache: FxHashSet(), + waiting_cache: FxHashMap(), cache_list: vec![], scratch: Some(vec![]), } diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/src/librustc_data_structures/snapshot_map/mod.rs index a4e6166032d81..cd7143ad3ce84 100644 --- a/src/librustc_data_structures/snapshot_map/mod.rs +++ b/src/librustc_data_structures/snapshot_map/mod.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use fnv::FnvHashMap; +use fx::FxHashMap; use std::hash::Hash; use std::ops; use std::mem; @@ -19,7 +19,7 @@ mod test; pub struct SnapshotMap where K: Hash + Clone + Eq { - map: FnvHashMap, + map: FxHashMap, undo_log: Vec>, } @@ -40,7 +40,7 @@ impl SnapshotMap { pub fn new() -> Self { SnapshotMap { - map: FnvHashMap(), + map: FxHashMap(), undo_log: vec![], } } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 28aab1fdd4167..37477da755c9f 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -48,7 +48,7 @@ use rustc::dep_graph::{DepGraphQuery, DepNode}; use rustc::dep_graph::debug::{DepNodeFilter, EdgeFilter}; use rustc::hir::def_id::DefId; use rustc::ty::TyCtxt; -use rustc_data_structures::fnv::FnvHashSet; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::{Direction, INCOMING, OUTGOING, NodeIndex}; use rustc::hir; use rustc::hir::intravisit::Visitor; @@ -244,7 +244,7 @@ fn dump_graph(tcx: TyCtxt) { } } -pub struct GraphvizDepGraph<'q>(FnvHashSet<&'q DepNode>, +pub struct GraphvizDepGraph<'q>(FxHashSet<&'q DepNode>, Vec<(&'q DepNode, &'q DepNode)>); impl<'a, 'tcx, 'q> dot::GraphWalk<'a> for GraphvizDepGraph<'q> { @@ -288,7 +288,7 @@ impl<'a, 'tcx, 'q> dot::Labeller<'a> for GraphvizDepGraph<'q> { // filter) or the set of nodes whose labels contain all of those // substrings. fn node_set<'q>(query: &'q DepGraphQuery, filter: &DepNodeFilter) - -> Option>> + -> Option>> { debug!("node_set(filter={:?})", filter); @@ -300,9 +300,9 @@ fn node_set<'q>(query: &'q DepGraphQuery, filter: &DepNodeFilter) } fn filter_nodes<'q>(query: &'q DepGraphQuery, - sources: &Option>>, - targets: &Option>>) - -> FnvHashSet<&'q DepNode> + sources: &Option>>, + targets: &Option>>) + -> FxHashSet<&'q DepNode> { if let &Some(ref sources) = sources { if let &Some(ref targets) = targets { @@ -318,11 +318,11 @@ fn filter_nodes<'q>(query: &'q DepGraphQuery, } fn walk_nodes<'q>(query: &'q DepGraphQuery, - starts: &FnvHashSet<&'q DepNode>, + starts: &FxHashSet<&'q DepNode>, direction: Direction) - -> FnvHashSet<&'q DepNode> + -> FxHashSet<&'q DepNode> { - let mut set = FnvHashSet(); + let mut set = FxHashSet(); for &start in starts { debug!("walk_nodes: start={:?} outgoing?={:?}", start, direction == OUTGOING); if set.insert(start) { @@ -342,9 +342,9 @@ fn walk_nodes<'q>(query: &'q DepGraphQuery, } fn walk_between<'q>(query: &'q DepGraphQuery, - sources: &FnvHashSet<&'q DepNode>, - targets: &FnvHashSet<&'q DepNode>) - -> FnvHashSet<&'q DepNode> + sources: &FxHashSet<&'q DepNode>, + targets: &FxHashSet<&'q DepNode>) + -> FxHashSet<&'q DepNode> { // This is a bit tricky. We want to include a node only if it is: // (a) reachable from a source and (b) will reach a target. And we @@ -410,7 +410,7 @@ fn walk_between<'q>(query: &'q DepGraphQuery, } fn filter_edges<'q>(query: &'q DepGraphQuery, - nodes: &FnvHashSet<&'q DepNode>) + nodes: &FxHashSet<&'q DepNode>) -> Vec<(&'q DepNode, &'q DepNode)> { query.edges() diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 3b0b37bb01ce3..58a2152997410 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -35,7 +35,7 @@ use rustc::hir; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::hir::intravisit as visit; use rustc::ty::TyCtxt; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc::util::common::record_time; use rustc::session::config::DebugInfoLevel::NoDebugInfo; @@ -51,21 +51,21 @@ mod caching_codemap_view; pub mod hasher; pub struct IncrementalHashesMap { - hashes: FnvHashMap, Fingerprint>, + hashes: FxHashMap, Fingerprint>, // These are the metadata hashes for the current crate as they were stored // during the last compilation session. They are only loaded if // -Z query-dep-graph was specified and are needed for auto-tests using // the #[rustc_metadata_dirty] and #[rustc_metadata_clean] attributes to // check whether some metadata hash has changed in between two revisions. - pub prev_metadata_hashes: RefCell>, + pub prev_metadata_hashes: RefCell>, } impl IncrementalHashesMap { pub fn new() -> IncrementalHashesMap { IncrementalHashesMap { - hashes: FnvHashMap(), - prev_metadata_hashes: RefCell::new(FnvHashMap()), + hashes: FxHashMap(), + prev_metadata_hashes: RefCell::new(FxHashMap()), } } diff --git a/src/librustc_incremental/persist/data.rs b/src/librustc_incremental/persist/data.rs index 734ffe6a94412..f0e4f4f99ef08 100644 --- a/src/librustc_incremental/persist/data.rs +++ b/src/librustc_incremental/persist/data.rs @@ -13,7 +13,7 @@ use rustc::dep_graph::{DepNode, WorkProduct, WorkProductId}; use rustc::hir::def_id::DefIndex; use std::sync::Arc; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use ich::Fingerprint; use super::directory::DefPathIndex; @@ -106,7 +106,7 @@ pub struct SerializedMetadataHashes { /// is only populated if -Z query-dep-graph is specified. It will be /// empty otherwise. Importing crates are perfectly happy with just having /// the DefIndex. - pub index_map: FnvHashMap + pub index_map: FxHashMap } /// The hash for some metadata that (when saving) will be exported diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 94478f6603a6e..69b9be12de46c 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -47,7 +47,7 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::Visitor; use syntax::ast::{self, Attribute, NestedMetaItem}; -use rustc_data_structures::fnv::{FnvHashSet, FnvHashMap}; +use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use syntax::parse::token::InternedString; use syntax_pos::Span; use rustc::ty::TyCtxt; @@ -67,7 +67,7 @@ pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let _ignore = tcx.dep_graph.in_ignore(); - let dirty_inputs: FnvHashSet> = + let dirty_inputs: FxHashSet> = dirty_inputs.iter() .filter_map(|d| retraced.map(d)) .collect(); @@ -84,7 +84,7 @@ pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub struct DirtyCleanVisitor<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, query: &'a DepGraphQuery, - dirty_inputs: FnvHashSet>, + dirty_inputs: FxHashSet>, } impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> { @@ -187,8 +187,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DirtyCleanVisitor<'a, 'tcx> { } pub fn check_dirty_clean_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - prev_metadata_hashes: &FnvHashMap, - current_metadata_hashes: &FnvHashMap) { + prev_metadata_hashes: &FxHashMap, + current_metadata_hashes: &FxHashMap) { if !tcx.sess.opts.debugging_opts.query_dep_graph { return; } @@ -205,8 +205,8 @@ pub fn check_dirty_clean_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub struct DirtyCleanMetadataVisitor<'a, 'tcx:'a, 'm> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - prev_metadata_hashes: &'m FnvHashMap, - current_metadata_hashes: &'m FnvHashMap, + prev_metadata_hashes: &'m FxHashMap, + current_metadata_hashes: &'m FxHashMap, } impl<'a, 'tcx, 'm> Visitor<'tcx> for DirtyCleanMetadataVisitor<'a, 'tcx, 'm> { diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index ff7c3d0512e4f..ca9c119202322 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -120,7 +120,7 @@ use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::util::fs as fs_util; use rustc_data_structures::flock; -use rustc_data_structures::fnv::{FnvHashSet, FnvHashMap}; +use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use std::ffi::OsString; use std::fs as std_fs; @@ -195,7 +195,7 @@ pub fn prepare_session_directory(tcx: TyCtxt) -> Result { debug!("crate-dir: {}", crate_dir.display()); try!(create_dir(tcx.sess, &crate_dir, "crate")); - let mut source_directories_already_tried = FnvHashSet(); + let mut source_directories_already_tried = FxHashSet(); loop { // Generate a session directory of the form: @@ -490,7 +490,7 @@ fn delete_session_dir_lock_file(sess: &Session, /// Find the most recent published session directory that is not in the /// ignore-list. fn find_source_directory(crate_dir: &Path, - source_directories_already_tried: &FnvHashSet) + source_directories_already_tried: &FxHashSet) -> Option { let iter = crate_dir.read_dir() .unwrap() // FIXME @@ -500,7 +500,7 @@ fn find_source_directory(crate_dir: &Path, } fn find_source_directory_in_iter(iter: I, - source_directories_already_tried: &FnvHashSet) + source_directories_already_tried: &FxHashSet) -> Option where I: Iterator { @@ -704,8 +704,8 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { // First do a pass over the crate directory, collecting lock files and // session directories - let mut session_directories = FnvHashSet(); - let mut lock_files = FnvHashSet(); + let mut session_directories = FxHashSet(); + let mut lock_files = FxHashSet(); for dir_entry in try!(crate_directory.read_dir()) { let dir_entry = match dir_entry { @@ -731,7 +731,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { } // Now map from lock files to session directories - let lock_file_to_session_dir: FnvHashMap> = + let lock_file_to_session_dir: FxHashMap> = lock_files.into_iter() .map(|lock_file_name| { assert!(lock_file_name.ends_with(LOCK_FILE_EXT)); @@ -774,7 +774,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { } // Filter out `None` directories - let lock_file_to_session_dir: FnvHashMap = + let lock_file_to_session_dir: FxHashMap = lock_file_to_session_dir.into_iter() .filter_map(|(lock_file_name, directory_name)| { directory_name.map(|n| (lock_file_name, n)) @@ -898,7 +898,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { } fn all_except_most_recent(deletion_candidates: Vec<(SystemTime, PathBuf, Option)>) - -> FnvHashMap> { + -> FxHashMap> { let most_recent = deletion_candidates.iter() .map(|&(timestamp, ..)| timestamp) .max(); @@ -909,7 +909,7 @@ fn all_except_most_recent(deletion_candidates: Vec<(SystemTime, PathBuf, Option< .map(|(_, path, lock)| (path, lock)) .collect() } else { - FnvHashMap() + FxHashMap() } } @@ -946,19 +946,19 @@ fn test_all_except_most_recent() { (UNIX_EPOCH + Duration::new(5, 0), PathBuf::from("5"), None), (UNIX_EPOCH + Duration::new(3, 0), PathBuf::from("3"), None), (UNIX_EPOCH + Duration::new(2, 0), PathBuf::from("2"), None), - ]).keys().cloned().collect::>(), + ]).keys().cloned().collect::>(), vec![ PathBuf::from("1"), PathBuf::from("2"), PathBuf::from("3"), PathBuf::from("4"), - ].into_iter().collect::>() + ].into_iter().collect::>() ); assert_eq!(all_except_most_recent( vec![ - ]).keys().cloned().collect::>(), - FnvHashSet() + ]).keys().cloned().collect::>(), + FxHashSet() ); } @@ -973,7 +973,7 @@ fn test_timestamp_serialization() { #[test] fn test_find_source_directory_in_iter() { - let already_visited = FnvHashSet(); + let already_visited = FxHashSet(); // Find newest assert_eq!(find_source_directory_in_iter( diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs index e365cbbd3a9a1..73311ee96c530 100644 --- a/src/librustc_incremental/persist/hash.rs +++ b/src/librustc_incremental/persist/hash.rs @@ -12,7 +12,7 @@ use rustc::dep_graph::DepNode; use rustc::hir::def_id::{CrateNum, DefId}; use rustc::hir::svh::Svh; use rustc::ty::TyCtxt; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::flock; use rustc_serialize::Decodable; use rustc_serialize::opaque::Decoder; @@ -26,8 +26,8 @@ use super::file_format; pub struct HashContext<'a, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, incremental_hashes_map: &'a IncrementalHashesMap, - item_metadata_hashes: FnvHashMap, - crate_hashes: FnvHashMap, + item_metadata_hashes: FxHashMap, + crate_hashes: FxHashMap, } impl<'a, 'tcx> HashContext<'a, 'tcx> { @@ -37,8 +37,8 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { HashContext { tcx: tcx, incremental_hashes_map: incremental_hashes_map, - item_metadata_hashes: FnvHashMap(), - crate_hashes: FnvHashMap(), + item_metadata_hashes: FxHashMap(), + crate_hashes: FxHashMap(), } } diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index 7cef246b6cb2c..12bf74c95116d 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -15,7 +15,7 @@ use rustc::hir::def_id::DefId; use rustc::hir::svh::Svh; use rustc::session::Session; use rustc::ty::TyCtxt; -use rustc_data_structures::fnv::{FnvHashSet, FnvHashMap}; +use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_serialize::Decodable as RustcDecodable; use rustc_serialize::opaque::Decoder; use std::fs; @@ -30,7 +30,7 @@ use super::hash::*; use super::fs::*; use super::file_format; -pub type DirtyNodes = FnvHashSet>; +pub type DirtyNodes = FxHashSet>; /// If we are in incremental mode, and a previous dep-graph exists, /// then load up those nodes/edges that are still valid into the @@ -183,7 +183,7 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Compute which work-products have an input that has changed or // been removed. Put the dirty ones into a set. - let mut dirty_target_nodes = FnvHashSet(); + let mut dirty_target_nodes = FxHashSet(); for &(raw_source_node, ref target_node) in &retraced_edges { if dirty_raw_source_nodes.contains(raw_source_node) { if !dirty_target_nodes.contains(target_node) { @@ -239,7 +239,7 @@ fn dirty_nodes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, retraced: &RetracedDefIdDirectory) -> DirtyNodes { let mut hcx = HashContext::new(tcx, incremental_hashes_map); - let mut dirty_nodes = FnvHashSet(); + let mut dirty_nodes = FxHashSet(); for hash in serialized_hashes { if let Some(dep_node) = retraced.map(&hash.dep_node) { @@ -270,7 +270,7 @@ fn dirty_nodes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// otherwise no longer applicable. fn reconcile_work_products<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, work_products: Vec, - dirty_target_nodes: &FnvHashSet>) { + dirty_target_nodes: &FxHashSet>) { debug!("reconcile_work_products({:?})", work_products); for swp in work_products { if dirty_target_nodes.contains(&DepNode::WorkProduct(swp.id.clone())) { @@ -314,7 +314,7 @@ fn delete_dirty_work_product(tcx: TyCtxt, fn load_prev_metadata_hashes(tcx: TyCtxt, retraced: &RetracedDefIdDirectory, - output: &mut FnvHashMap) { + output: &mut FxHashMap) { if !tcx.sess.opts.debugging_opts.query_dep_graph { return } diff --git a/src/librustc_incremental/persist/preds.rs b/src/librustc_incremental/persist/preds.rs index fe1d627253f28..e1968ce8d7b6a 100644 --- a/src/librustc_incremental/persist/preds.rs +++ b/src/librustc_incremental/persist/preds.rs @@ -10,7 +10,7 @@ use rustc::dep_graph::{DepGraphQuery, DepNode}; use rustc::hir::def_id::DefId; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::{DepthFirstTraversal, INCOMING, NodeIndex}; use super::hash::*; @@ -23,11 +23,11 @@ pub struct Predecessors<'query> { // nodes. // - Values: transitive predecessors of the key that are hashable // (e.g., HIR nodes, input meta-data nodes) - pub inputs: FnvHashMap<&'query DepNode, Vec<&'query DepNode>>, + pub inputs: FxHashMap<&'query DepNode, Vec<&'query DepNode>>, // - Keys: some hashable node // - Values: the hash thereof - pub hashes: FnvHashMap<&'query DepNode, Fingerprint>, + pub hashes: FxHashMap<&'query DepNode, Fingerprint>, } impl<'q> Predecessors<'q> { @@ -37,7 +37,7 @@ impl<'q> Predecessors<'q> { let all_nodes = query.graph.all_nodes(); let tcx = hcx.tcx; - let inputs: FnvHashMap<_, _> = all_nodes.iter() + let inputs: FxHashMap<_, _> = all_nodes.iter() .enumerate() .filter(|&(_, node)| match node.data { DepNode::WorkProduct(_) => true, @@ -60,7 +60,7 @@ impl<'q> Predecessors<'q> { }) .collect(); - let mut hashes = FnvHashMap(); + let mut hashes = FxHashMap(); for input in inputs.values().flat_map(|v| v.iter().cloned()) { hashes.entry(input) .or_insert_with(|| hcx.hash(input).unwrap()); diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index bc156b0e8913b..289eebb216208 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -13,7 +13,7 @@ use rustc::hir::def_id::DefId; use rustc::hir::svh::Svh; use rustc::session::Session; use rustc::ty::TyCtxt; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_serialize::Encodable as RustcEncodable; use rustc_serialize::opaque::Encoder; use std::hash::Hash; @@ -46,7 +46,7 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let query = tcx.dep_graph.query(); let mut hcx = HashContext::new(tcx, incremental_hashes_map); let preds = Predecessors::new(&query, &mut hcx); - let mut current_metadata_hashes = FnvHashMap(); + let mut current_metadata_hashes = FxHashMap(); // IMPORTANT: We are saving the metadata hashes *before* the dep-graph, // since metadata-encoding might add new entries to the @@ -186,7 +186,7 @@ pub fn encode_metadata_hashes(tcx: TyCtxt, svh: Svh, preds: &Predecessors, builder: &mut DefIdDirectoryBuilder, - current_metadata_hashes: &mut FnvHashMap, + current_metadata_hashes: &mut FxHashMap, encoder: &mut Encoder) -> io::Result<()> { // For each `MetaData(X)` node where `X` is local, accumulate a @@ -198,10 +198,10 @@ pub fn encode_metadata_hashes(tcx: TyCtxt, // (I initially wrote this with an iterator, but it seemed harder to read.) let mut serialized_hashes = SerializedMetadataHashes { hashes: vec![], - index_map: FnvHashMap() + index_map: FxHashMap() }; - let mut def_id_hashes = FnvHashMap(); + let mut def_id_hashes = FxHashMap(); for (&target, sources) in &preds.inputs { let def_id = match *target { diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index b04759955a956..48471282672ad 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -18,7 +18,7 @@ use rustc::traits::Reveal; use middle::const_val::ConstVal; use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::EvalHint::ExprTypeChecked; -use util::nodemap::FnvHashSet; +use util::nodemap::FxHashSet; use lint::{LateContext, LintContext, LintArray}; use lint::{LintPass, LateLintPass}; @@ -428,7 +428,7 @@ fn is_repr_nullable_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { /// Check if the given type is "ffi-safe" (has a stable, well-defined /// representation which can be exported to C code). - fn check_type_for_ffi(&self, cache: &mut FnvHashSet>, ty: Ty<'tcx>) -> FfiResult { + fn check_type_for_ffi(&self, cache: &mut FxHashSet>, ty: Ty<'tcx>) -> FfiResult { use self::FfiResult::*; let cx = self.cx.tcx; @@ -639,7 +639,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // any generic types right now: let ty = self.cx.tcx.normalize_associated_type(&ty); - match self.check_type_for_ffi(&mut FnvHashSet(), ty) { + match self.check_type_for_ffi(&mut FxHashSet(), ty) { FfiResult::FfiSafe => {} FfiResult::FfiUnsafe(s) => { self.cx.span_lint(IMPROPER_CTYPES, sp, s); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 15430a5c9f99d..a5339f7326a63 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -11,7 +11,7 @@ use rustc::hir::pat_util; use rustc::ty; use rustc::ty::adjustment; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use lint::{LateContext, EarlyContext, LintContext, LintArray}; use lint::{LintPass, EarlyLintPass, LateLintPass}; @@ -42,7 +42,7 @@ impl UnusedMut { // collect all mutable pattern and group their NodeIDs by their Identifier to // avoid false warnings in match arms with multiple patterns - let mut mutables = FnvHashMap(); + let mut mutables = FxHashMap(); for p in pats { pat_util::pat_bindings(p, |mode, id, _, path1| { let name = path1.node; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index e72ac8419941c..43c97cbe004b3 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -22,7 +22,7 @@ use rustc_back::PanicStrategy; use rustc::session::search_paths::PathKind; use rustc::middle; use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate}; -use rustc::util::nodemap::{FnvHashMap, FnvHashSet}; +use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc::hir::map::Definitions; use std::cell::{RefCell, Cell}; @@ -50,7 +50,7 @@ pub struct CrateLoader<'a> { pub sess: &'a Session, cstore: &'a CStore, next_crate_num: CrateNum, - foreign_item_map: FnvHashMap>, + foreign_item_map: FxHashMap>, local_crate_name: String, } @@ -148,7 +148,7 @@ impl<'a> CrateLoader<'a> { sess: sess, cstore: cstore, next_crate_num: cstore.next_crate_num(), - foreign_item_map: FnvHashMap(), + foreign_item_map: FxHashMap(), local_crate_name: local_crate_name.to_owned(), } } @@ -401,7 +401,7 @@ impl<'a> CrateLoader<'a> { fn update_extern_crate(&mut self, cnum: CrateNum, mut extern_crate: ExternCrate, - visited: &mut FnvHashSet<(CrateNum, bool)>) + visited: &mut FxHashSet<(CrateNum, bool)>) { if !visited.insert((cnum, extern_crate.direct)) { return } @@ -442,7 +442,7 @@ impl<'a> CrateLoader<'a> { // The map from crate numbers in the crate we're resolving to local crate // numbers let deps = crate_root.crate_deps.decode(metadata); - let map: FnvHashMap<_, _> = deps.enumerate().map(|(crate_num, dep)| { + let map: FxHashMap<_, _> = deps.enumerate().map(|(crate_num, dep)| { debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash); let (local_cnum, ..) = self.resolve_crate(root, &dep.name.as_str(), @@ -1021,7 +1021,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { let extern_crate = ExternCrate { def_id: def_id, span: item.span, direct: true, path_len: len }; - self.update_extern_crate(cnum, extern_crate, &mut FnvHashSet()); + self.update_extern_crate(cnum, extern_crate, &mut FxHashSet()); self.cstore.add_extern_mod_stmt_cnum(info.id, cnum); loaded_macros diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 58c70f959b7cc..f452cc23b7330 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -21,7 +21,7 @@ use rustc::hir::svh::Svh; use rustc::middle::cstore::ExternCrate; use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; -use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap}; +use rustc::util::nodemap::{FxHashMap, NodeMap, NodeSet, DefIdMap}; use std::cell::{RefCell, Cell}; use std::rc::Rc; @@ -76,7 +76,7 @@ pub struct CrateMetadata { /// hashmap, which gives the reverse mapping. This allows us to /// quickly retrace a `DefPath`, which is needed for incremental /// compilation support. - pub key_map: FnvHashMap, + pub key_map: FxHashMap, /// Flag if this crate is required by an rlib version of this crate, or in /// other words whether it was explicitly linked to. An example of a crate @@ -94,7 +94,7 @@ pub struct CachedInlinedItem { pub struct CStore { pub dep_graph: DepGraph, - metas: RefCell>>, + metas: RefCell>>, /// Map from NodeId's of local extern crate statements to crate numbers extern_mod_crate_map: RefCell>, used_crate_sources: RefCell>, @@ -110,15 +110,15 @@ impl CStore { pub fn new(dep_graph: &DepGraph) -> CStore { CStore { dep_graph: dep_graph.clone(), - metas: RefCell::new(FnvHashMap()), - extern_mod_crate_map: RefCell::new(FnvHashMap()), + metas: RefCell::new(FxHashMap()), + extern_mod_crate_map: RefCell::new(FxHashMap()), used_crate_sources: RefCell::new(Vec::new()), used_libraries: RefCell::new(Vec::new()), used_link_args: RefCell::new(Vec::new()), statically_included_foreign_items: RefCell::new(NodeSet()), - visible_parent_map: RefCell::new(FnvHashMap()), - inlined_item_cache: RefCell::new(FnvHashMap()), - defid_for_inlined_node: RefCell::new(FnvHashMap()), + visible_parent_map: RefCell::new(FxHashMap()), + inlined_item_cache: RefCell::new(FxHashMap()), + defid_for_inlined_node: RefCell::new(FxHashMap()), } } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index ccd497860de8a..630b07744249b 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -17,7 +17,7 @@ use schema::*; use rustc::hir::map as hir_map; use rustc::hir::map::{DefKey, DefPathData}; -use rustc::util::nodemap::FnvHashMap; +use rustc::util::nodemap::FxHashMap; use rustc::hir; use rustc::hir::intravisit::IdRange; @@ -432,7 +432,7 @@ impl<'a, 'tcx> MetadataBlob { /// Go through each item in the metadata and create a map from that /// item's def-key to the item's DefIndex. - pub fn load_key_map(&self, index: LazySeq) -> FnvHashMap { + pub fn load_key_map(&self, index: LazySeq) -> FxHashMap { index.iter_enumerated(self.raw_bytes()) .map(|(index, item)| (item.decode(self).def_key.decode(self), index)) .collect() diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index fdb117ef81b13..fb4fb50729628 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -23,7 +23,7 @@ use rustc::traits::specialization_graph; use rustc::ty::{self, Ty, TyCtxt}; use rustc::session::config::{self, CrateTypeProcMacro}; -use rustc::util::nodemap::{FnvHashMap, NodeSet}; +use rustc::util::nodemap::{FxHashMap, NodeSet}; use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque}; use std::hash::Hash; @@ -52,8 +52,8 @@ pub struct EncodeContext<'a, 'tcx: 'a> { reachable: &'a NodeSet, lazy_state: LazyState, - type_shorthands: FnvHashMap, usize>, - predicate_shorthands: FnvHashMap, usize>, + type_shorthands: FxHashMap, usize>, + predicate_shorthands: FxHashMap, usize>, } macro_rules! encoder_methods { @@ -200,7 +200,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { variant: &U, map: M) -> Result<(), ::Error> - where M: for<'b> Fn(&'b mut Self) -> &'b mut FnvHashMap, + where M: for<'b> Fn(&'b mut Self) -> &'b mut FxHashMap, T: Clone + Eq + Hash, U: Encodable { @@ -1143,7 +1143,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { struct ImplVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - impls: FnvHashMap>, + impls: FxHashMap>, } impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> { @@ -1165,7 +1165,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_impls(&mut self) -> LazySeq { let mut visitor = ImplVisitor { tcx: self.tcx, - impls: FnvHashMap(), + impls: FxHashMap(), }; self.tcx.map.krate().visit_all_items(&mut visitor); diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 0461d7ec061d4..c31b209768c38 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -221,7 +221,7 @@ use rustc::session::Session; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use rustc::session::search_paths::PathKind; use rustc::util::common; -use rustc::util::nodemap::FnvHashMap; +use rustc::util::nodemap::FxHashMap; use rustc_llvm as llvm; use rustc_llvm::{False, ObjectFile, mk_section_iter}; @@ -430,7 +430,7 @@ impl<'a> Context<'a> { let rlib_prefix = format!("lib{}", self.crate_name); let staticlib_prefix = format!("{}{}", staticpair.0, self.crate_name); - let mut candidates = FnvHashMap(); + let mut candidates = FxHashMap(); let mut staticlibs = vec![]; // First, find all possible candidate rlibs and dylibs purely based on @@ -469,7 +469,7 @@ impl<'a> Context<'a> { let hash_str = hash.to_string(); let slot = candidates.entry(hash_str) - .or_insert_with(|| (FnvHashMap(), FnvHashMap())); + .or_insert_with(|| (FxHashMap(), FxHashMap())); let (ref mut rlibs, ref mut dylibs) = *slot; fs::canonicalize(path) .map(|p| { @@ -492,7 +492,7 @@ impl<'a> Context<'a> { // A Library candidate is created if the metadata for the set of // libraries corresponds to the crate id and hash criteria that this // search is being performed for. - let mut libraries = FnvHashMap(); + let mut libraries = FxHashMap(); for (_hash, (rlibs, dylibs)) in candidates { let mut slot = None; let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot); @@ -544,7 +544,7 @@ impl<'a> Context<'a> { // be read, it is assumed that the file isn't a valid rust library (no // errors are emitted). fn extract_one(&mut self, - m: FnvHashMap, + m: FxHashMap, flavor: CrateFlavor, slot: &mut Option<(Svh, MetadataBlob)>) -> Option<(PathBuf, PathKind)> { @@ -690,8 +690,8 @@ impl<'a> Context<'a> { // rlibs/dylibs. let sess = self.sess; let dylibname = self.dylibname(); - let mut rlibs = FnvHashMap(); - let mut dylibs = FnvHashMap(); + let mut rlibs = FxHashMap(); + let mut dylibs = FxHashMap(); { let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| { if !loc.exists() { diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 490f675c3d5e3..b75e52fd4b10d 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -13,7 +13,7 @@ use std; use rustc_const_math::{ConstMathErr, Op}; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use build::{BlockAnd, BlockAndExtension, Builder}; @@ -190,7 +190,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // first process the set of fields that were provided // (evaluating them in order given by user) - let fields_map: FnvHashMap<_, _> = + let fields_map: FxHashMap<_, _> = fields.into_iter() .map(|f| (f.name, unpack!(block = this.as_operand(block, f.expr)))) .collect(); diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 727e634ef92db..786299c370d82 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -14,7 +14,7 @@ //! details. use build::{BlockAnd, BlockAndExtension, Builder}; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::bitvec::BitVector; use rustc::middle::const_val::ConstVal; use rustc::ty::{AdtDef, Ty}; @@ -309,7 +309,7 @@ enum TestKind<'tcx> { SwitchInt { switch_ty: Ty<'tcx>, options: Vec, - indices: FnvHashMap, + indices: FxHashMap, }, // test for equality diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 5984b0f7893cd..948ba7338cddb 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -18,7 +18,7 @@ use build::Builder; use build::matches::{Candidate, MatchPair, Test, TestKind}; use hair::*; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::bitvec::BitVector; use rustc::middle::const_val::ConstVal; use rustc::ty::{self, Ty}; @@ -54,7 +54,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // these maps are empty to start; cases are // added below in add_cases_to_switch options: vec![], - indices: FnvHashMap(), + indices: FxHashMap(), } } } @@ -110,7 +110,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { candidate: &Candidate<'pat, 'tcx>, switch_ty: Ty<'tcx>, options: &mut Vec, - indices: &mut FnvHashMap) + indices: &mut FxHashMap) -> bool { let match_pair = match candidate.match_pairs.iter().find(|mp| mp.lvalue == *test_lvalue) { diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index af8170a1b8f55..b5343975a9cdf 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -94,7 +94,7 @@ use rustc::ty::{Ty, TyCtxt}; use rustc::mir::*; use syntax_pos::Span; use rustc_data_structures::indexed_vec::Idx; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; pub struct Scope<'tcx> { /// the scope-id within the scope_auxiliary @@ -140,7 +140,7 @@ pub struct Scope<'tcx> { free: Option>, /// The cache for drop chain on “normal” exit into a particular BasicBlock. - cached_exits: FnvHashMap<(BasicBlock, CodeExtent), BasicBlock>, + cached_exits: FxHashMap<(BasicBlock, CodeExtent), BasicBlock>, } struct DropData<'tcx> { @@ -298,7 +298,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { needs_cleanup: false, drops: vec![], free: None, - cached_exits: FnvHashMap() + cached_exits: FxHashMap() }); self.scope_auxiliary.push(ScopeAuxiliary { extent: extent, diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs index d2fc8aeaa2eea..d6f514cfb9136 100644 --- a/src/librustc_mir/pretty.rs +++ b/src/librustc_mir/pretty.rs @@ -14,7 +14,7 @@ use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::mir::transform::MirSource; use rustc::ty::TyCtxt; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{Idx}; use std::fmt::Display; use std::fs; @@ -122,10 +122,10 @@ enum Annotation { } fn scope_entry_exit_annotations(auxiliary: Option<&ScopeAuxiliaryVec>) - -> FnvHashMap> + -> FxHashMap> { // compute scope/entry exit annotations - let mut annotations = FnvHashMap(); + let mut annotations = FxHashMap(); if let Some(auxiliary) = auxiliary { for (scope_id, auxiliary) in auxiliary.iter_enumerated() { annotations.entry(auxiliary.dom) @@ -166,7 +166,7 @@ fn write_basic_block(tcx: TyCtxt, block: BasicBlock, mir: &Mir, w: &mut Write, - annotations: &FnvHashMap>) + annotations: &FxHashMap>) -> io::Result<()> { let data = &mir[block]; @@ -217,7 +217,7 @@ fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String { /// Returns the total number of variables printed. fn write_scope_tree(tcx: TyCtxt, mir: &Mir, - scope_tree: &FnvHashMap>, + scope_tree: &FxHashMap>, w: &mut Write, parent: VisibilityScope, depth: usize) @@ -283,7 +283,7 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, writeln!(w, " {{")?; // construct a scope tree and write it out - let mut scope_tree: FnvHashMap> = FnvHashMap(); + let mut scope_tree: FxHashMap> = FxHashMap(); for (index, scope_data) in mir.visibility_scopes.iter().enumerate() { if let Some(parent) = scope_data.parent_scope { scope_tree.entry(parent) diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index a01724d6d0e9b..c4a8d34bda008 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -14,7 +14,7 @@ use rustc::mir::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local}; use rustc::mir::transform::{MirPass, MirSource, Pass}; use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::ty::TyCtxt; -use rustc::util::nodemap::FnvHashSet; +use rustc::util::nodemap::FxHashSet; use rustc_data_structures::indexed_vec::Idx; use std::mem; @@ -107,5 +107,5 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> { #[derive(Default)] struct OptimizationList { - and_stars: FnvHashSet, + and_stars: FxHashSet, } diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 18586715894f5..84cf85e2fc4e6 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -15,7 +15,7 @@ use rustc::hir; use rustc::hir::intravisit as hir_visit; use rustc::util::common::to_readable_str; -use rustc::util::nodemap::{FnvHashMap, FnvHashSet}; +use rustc::util::nodemap::{FxHashMap, FxHashSet}; use syntax::ast::{self, NodeId, AttrId}; use syntax::visit as ast_visit; use syntax_pos::Span; @@ -34,15 +34,15 @@ struct NodeData { struct StatCollector<'k> { krate: Option<&'k hir::Crate>, - data: FnvHashMap<&'static str, NodeData>, - seen: FnvHashSet, + data: FxHashMap<&'static str, NodeData>, + seen: FxHashSet, } pub fn print_hir_stats(krate: &hir::Crate) { let mut collector = StatCollector { krate: Some(krate), - data: FnvHashMap(), - seen: FnvHashSet(), + data: FxHashMap(), + seen: FxHashSet(), }; hir_visit::walk_crate(&mut collector, krate); collector.print("HIR STATS"); @@ -51,8 +51,8 @@ pub fn print_hir_stats(krate: &hir::Crate) { pub fn print_ast_stats(krate: &ast::Crate, title: &str) { let mut collector = StatCollector { krate: None, - data: FnvHashMap(), - seen: FnvHashSet(), + data: FxHashMap(), + seen: FxHashSet(), }; ast_visit::walk_crate(&mut collector, krate); collector.print(title); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index d90fe769caf63..1e998a2a4d5b0 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -25,7 +25,7 @@ use rustc::middle::cstore::LoadedMacros; use rustc::hir::def::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::ty; -use rustc::util::nodemap::FnvHashMap; +use rustc::util::nodemap::FxHashMap; use std::cell::Cell; use std::rc::Rc; @@ -539,7 +539,7 @@ impl<'b> Resolver<'b> { self.invocations.insert(mark, invocation); } - let mut macros: FnvHashMap<_, _> = macros.into_iter().map(|mut def| { + let mut macros: FxHashMap<_, _> = macros.into_iter().map(|mut def| { def.body = mark_tts(&def.body, mark); let ext = macro_rules::compile(&self.session.parse_sess, &def); (def.ident.name, (def, Rc::new(ext))) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e7d83a64e03eb..ef14153232b9f 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -51,7 +51,7 @@ use rustc::hir::def::*; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::ty; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; -use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet}; +use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet}; use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::ast::{self, FloatTy}; @@ -498,7 +498,7 @@ struct BindingInfo { } // Map from the name in a pattern to its binding mode. -type BindingMap = FnvHashMap; +type BindingMap = FxHashMap; #[derive(Copy, Clone, PartialEq, Eq, Debug)] enum PatternSource { @@ -703,14 +703,14 @@ enum ModulePrefixResult<'a> { /// One local scope. #[derive(Debug)] struct Rib<'a> { - bindings: FnvHashMap, + bindings: FxHashMap, kind: RibKind<'a>, } impl<'a> Rib<'a> { fn new(kind: RibKind<'a>) -> Rib<'a> { Rib { - bindings: FnvHashMap(), + bindings: FxHashMap(), kind: kind, } } @@ -769,7 +769,7 @@ pub struct ModuleS<'a> { // is the NodeId of the local `extern crate` item (otherwise, `extern_crate_id` is None). extern_crate_id: Option, - resolutions: RefCell>>>, + resolutions: RefCell>>>, no_implicit_prelude: bool, @@ -794,7 +794,7 @@ impl<'a> ModuleS<'a> { kind: kind, normal_ancestor_id: None, extern_crate_id: None, - resolutions: RefCell::new(FnvHashMap()), + resolutions: RefCell::new(FxHashMap()), no_implicit_prelude: false, glob_importers: RefCell::new(Vec::new()), globs: RefCell::new((Vec::new())), @@ -950,12 +950,12 @@ impl<'a> NameBinding<'a> { /// Interns the names of the primitive types. struct PrimitiveTypeTable { - primitive_types: FnvHashMap, + primitive_types: FxHashMap, } impl PrimitiveTypeTable { fn new() -> PrimitiveTypeTable { - let mut table = PrimitiveTypeTable { primitive_types: FnvHashMap() }; + let mut table = PrimitiveTypeTable { primitive_types: FxHashMap() }; table.intern("bool", TyBool); table.intern("char", TyChar); @@ -989,17 +989,17 @@ pub struct Resolver<'a> { // Maps the node id of a statement to the expansions of the `macro_rules!`s // immediately above the statement (if appropriate). - macros_at_scope: FnvHashMap>, + macros_at_scope: FxHashMap>, graph_root: Module<'a>, prelude: Option>, - trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>, + trait_item_map: FxHashMap<(Name, DefId), bool /* is static method? */>, // Names of fields of an item `DefId` accessible with dot syntax. // Used for hints during error reporting. - field_names: FnvHashMap>, + field_names: FxHashMap>, // All imports known to succeed or fail. determined_imports: Vec<&'a ImportDirective<'a>>, @@ -1061,8 +1061,8 @@ pub struct Resolver<'a> { // all imports, but only glob imports are actually interesting). pub glob_map: GlobMap, - used_imports: FnvHashSet<(NodeId, Namespace)>, - used_crates: FnvHashSet, + used_imports: FxHashSet<(NodeId, Namespace)>, + used_crates: FxHashSet, pub maybe_unused_trait_imports: NodeSet, privacy_errors: Vec>, @@ -1075,12 +1075,12 @@ pub struct Resolver<'a> { pub exported_macros: Vec, crate_loader: &'a mut CrateLoader, - macro_names: FnvHashSet, - builtin_macros: FnvHashMap>, + macro_names: FxHashSet, + builtin_macros: FxHashMap>, lexical_macro_resolutions: Vec<(Name, LegacyScope<'a>)>, // Maps the `Mark` of an expansion to its containing module or block. - invocations: FnvHashMap>, + invocations: FxHashMap>, } pub struct ResolverArenas<'a> { @@ -1206,7 +1206,7 @@ impl<'a> Resolver<'a> { let mut definitions = Definitions::new(); DefCollector::new(&mut definitions).collect_root(); - let mut invocations = FnvHashMap(); + let mut invocations = FxHashMap(); invocations.insert(Mark::root(), arenas.alloc_invocation_data(InvocationData::root(graph_root))); @@ -1214,15 +1214,15 @@ impl<'a> Resolver<'a> { session: session, definitions: definitions, - macros_at_scope: FnvHashMap(), + macros_at_scope: FxHashMap(), // The outermost module has def ID 0; this is not reflected in the // AST. graph_root: graph_root, prelude: None, - trait_item_map: FnvHashMap(), - field_names: FnvHashMap(), + trait_item_map: FxHashMap(), + field_names: FxHashMap(), determined_imports: Vec::new(), indeterminate_imports: Vec::new(), @@ -1248,8 +1248,8 @@ impl<'a> Resolver<'a> { make_glob_map: make_glob_map == MakeGlobMap::Yes, glob_map: NodeMap(), - used_imports: FnvHashSet(), - used_crates: FnvHashSet(), + used_imports: FxHashSet(), + used_crates: FxHashSet(), maybe_unused_trait_imports: NodeSet(), privacy_errors: Vec::new(), @@ -1266,8 +1266,8 @@ impl<'a> Resolver<'a> { exported_macros: Vec::new(), crate_loader: crate_loader, - macro_names: FnvHashSet(), - builtin_macros: FnvHashMap(), + macro_names: FxHashSet(), + builtin_macros: FxHashMap(), lexical_macro_resolutions: Vec::new(), invocations: invocations, } @@ -1340,7 +1340,7 @@ impl<'a> Resolver<'a> { fn add_to_glob_map(&mut self, id: NodeId, name: Name) { if self.make_glob_map { - self.glob_map.entry(id).or_insert_with(FnvHashSet).insert(name); + self.glob_map.entry(id).or_insert_with(FxHashSet).insert(name); } } @@ -1803,7 +1803,7 @@ impl<'a> Resolver<'a> { match type_parameters { HasTypeParameters(generics, rib_kind) => { let mut function_type_rib = Rib::new(rib_kind); - let mut seen_bindings = FnvHashMap(); + let mut seen_bindings = FxHashMap(); for type_parameter in &generics.ty_params { let name = type_parameter.ident.name; debug!("with_type_parameter_rib: {}", type_parameter.id); @@ -1867,7 +1867,7 @@ impl<'a> Resolver<'a> { self.label_ribs.push(Rib::new(rib_kind)); // Add each argument to the rib. - let mut bindings_list = FnvHashMap(); + let mut bindings_list = FxHashMap(); for argument in &declaration.inputs { self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list); @@ -2069,7 +2069,7 @@ impl<'a> Resolver<'a> { walk_list!(self, visit_expr, &local.init); // Resolve the pattern. - self.resolve_pattern(&local.pat, PatternSource::Let, &mut FnvHashMap()); + self.resolve_pattern(&local.pat, PatternSource::Let, &mut FxHashMap()); } // build a map from pattern identifiers to binding-info's. @@ -2077,7 +2077,7 @@ impl<'a> Resolver<'a> { // that expands into an or-pattern where one 'x' was from the // user and one 'x' came from the macro. fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap { - let mut binding_map = FnvHashMap(); + let mut binding_map = FxHashMap(); pat.walk(&mut |pat| { if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node { @@ -2137,7 +2137,7 @@ impl<'a> Resolver<'a> { fn resolve_arm(&mut self, arm: &Arm) { self.value_ribs.push(Rib::new(NormalRibKind)); - let mut bindings_list = FnvHashMap(); + let mut bindings_list = FxHashMap(); for pattern in &arm.pats { self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list); } @@ -2278,7 +2278,7 @@ impl<'a> Resolver<'a> { pat_id: NodeId, outer_pat_id: NodeId, pat_src: PatternSource, - bindings: &mut FnvHashMap) + bindings: &mut FxHashMap) -> PathResolution { // Add the binding to the local ribs, if it // doesn't already exist in the bindings map. (We @@ -2391,7 +2391,7 @@ impl<'a> Resolver<'a> { pat_src: PatternSource, // Maps idents to the node ID for the // outermost pattern that binds them. - bindings: &mut FnvHashMap) { + bindings: &mut FxHashMap) { // Visit all direct subpatterns of this pattern. let outer_pat_id = pat.id; pat.walk(&mut |pat| { @@ -3048,7 +3048,7 @@ impl<'a> Resolver<'a> { self.visit_expr(subexpression); self.value_ribs.push(Rib::new(NormalRibKind)); - self.resolve_pattern(pattern, PatternSource::IfLet, &mut FnvHashMap()); + self.resolve_pattern(pattern, PatternSource::IfLet, &mut FxHashMap()); self.visit_block(if_block); self.value_ribs.pop(); @@ -3065,7 +3065,7 @@ impl<'a> Resolver<'a> { ExprKind::WhileLet(ref pattern, ref subexpression, ref block, label) => { self.visit_expr(subexpression); self.value_ribs.push(Rib::new(NormalRibKind)); - self.resolve_pattern(pattern, PatternSource::WhileLet, &mut FnvHashMap()); + self.resolve_pattern(pattern, PatternSource::WhileLet, &mut FxHashMap()); self.resolve_labeled_block(label, expr.id, block); @@ -3075,7 +3075,7 @@ impl<'a> Resolver<'a> { ExprKind::ForLoop(ref pattern, ref subexpression, ref block, label) => { self.visit_expr(subexpression); self.value_ribs.push(Rib::new(NormalRibKind)); - self.resolve_pattern(pattern, PatternSource::For, &mut FnvHashMap()); + self.resolve_pattern(pattern, PatternSource::For, &mut FxHashMap()); self.resolve_labeled_block(label, expr.id, block); @@ -3337,7 +3337,7 @@ impl<'a> Resolver<'a> { fn report_errors(&mut self) { self.report_shadowing_errors(); - let mut reported_spans = FnvHashSet(); + let mut reported_spans = FxHashSet(); for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors { if !reported_spans.insert(span) { continue } @@ -3369,7 +3369,7 @@ impl<'a> Resolver<'a> { self.resolve_macro_name(scope, name); } - let mut reported_errors = FnvHashSet(); + let mut reported_errors = FxHashSet(); for binding in replace(&mut self.disallowed_shadowing, Vec::new()) { if self.resolve_macro_name(binding.parent, binding.name).is_some() && reported_errors.insert((binding.name, binding.span)) { diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index bd15035b8a94e..d50669272f726 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -79,7 +79,7 @@ use type_::Type; use type_of; use value::Value; use Disr; -use util::nodemap::{NodeSet, FnvHashMap, FnvHashSet}; +use util::nodemap::{NodeSet, FxHashMap, FxHashSet}; use arena::TypedArena; use libc::c_uint; @@ -1318,7 +1318,7 @@ fn write_metadata(cx: &SharedCrateContext, fn internalize_symbols<'a, 'tcx>(sess: &Session, ccxs: &CrateContextList<'a, 'tcx>, symbol_map: &SymbolMap<'tcx>, - reachable: &FnvHashSet<&str>) { + reachable: &FxHashSet<&str>) { let scx = ccxs.shared(); let tcx = scx.tcx(); @@ -1332,7 +1332,7 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session, // 'unsafe' because we are holding on to CStr's from the LLVM module within // this block. unsafe { - let mut referenced_somewhere = FnvHashSet(); + let mut referenced_somewhere = FxHashSet(); // Collect all symbols that need to stay externally visible because they // are referenced via a declaration in some other codegen unit. @@ -1353,7 +1353,7 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session, // Also collect all symbols for which we cannot adjust linkage, because // it is fixed by some directive in the source code (e.g. #[no_mangle]). - let linkage_fixed_explicitly: FnvHashSet<_> = scx + let linkage_fixed_explicitly: FxHashSet<_> = scx .translation_items() .borrow() .iter() @@ -1862,7 +1862,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a } if scx.sess().opts.debugging_opts.print_trans_items.is_some() { - let mut item_to_cgus = FnvHashMap(); + let mut item_to_cgus = FxHashMap(); for cgu in &codegen_units { for (&trans_item, &linkage) in cgu.items() { diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 8556e95903c18..0480bb82a998e 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -19,7 +19,7 @@ use common::*; use machine::llalign_of_pref; use type_::Type; use value::Value; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use libc::{c_uint, c_char}; use std::borrow::Cow; @@ -62,7 +62,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Build version of path with cycles removed. // Pass 1: scan table mapping str -> rightmost pos. - let mut mm = FnvHashMap(); + let mut mm = FxHashMap(); let len = v.len(); let mut i = 0; while i < len { diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index a439d415ede15..548554af9727f 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -211,7 +211,7 @@ use context::SharedCrateContext; use common::{fulfill_obligation, type_is_sized}; use glue::{self, DropGlueKind}; use monomorphize::{self, Instance}; -use util::nodemap::{FnvHashSet, FnvHashMap, DefIdMap}; +use util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use trans_item::{TransItem, type_to_string, def_id_to_string}; @@ -228,7 +228,7 @@ pub struct InliningMap<'tcx> { // that are potentially inlined by LLVM into the source. // The two numbers in the tuple are the start (inclusive) and // end index (exclusive) within the `targets` vecs. - index: FnvHashMap, (usize, usize)>, + index: FxHashMap, (usize, usize)>, targets: Vec>, } @@ -236,7 +236,7 @@ impl<'tcx> InliningMap<'tcx> { fn new() -> InliningMap<'tcx> { InliningMap { - index: FnvHashMap(), + index: FxHashMap(), targets: Vec::new(), } } @@ -269,7 +269,7 @@ impl<'tcx> InliningMap<'tcx> { pub fn collect_crate_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, mode: TransItemCollectionMode) - -> (FnvHashSet>, + -> (FxHashSet>, InliningMap<'tcx>) { // We are not tracking dependencies of this pass as it has to be re-executed // every time no matter what. @@ -277,7 +277,7 @@ pub fn collect_crate_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 't let roots = collect_roots(scx, mode); debug!("Building translation item graph, beginning at roots"); - let mut visited = FnvHashSet(); + let mut visited = FxHashSet(); let mut recursion_depths = DefIdMap(); let mut inlining_map = InliningMap::new(); @@ -318,7 +318,7 @@ fn collect_roots<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, // Collect all monomorphized translation items reachable from `starting_point` fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, starting_point: TransItem<'tcx>, - visited: &mut FnvHashSet>, + visited: &mut FxHashSet>, recursion_depths: &mut DefIdMap, inlining_map: &mut InliningMap<'tcx>) { if !visited.insert(starting_point.clone()) { @@ -1179,9 +1179,9 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, ' if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { let callee_substs = tcx.erase_regions(&trait_ref.substs); - let overridden_methods: FnvHashSet<_> = items.iter() - .map(|item| item.name) - .collect(); + let overridden_methods: FxHashSet<_> = items.iter() + .map(|item| item.name) + .collect(); for method in tcx.provided_trait_methods(trait_ref.def_id) { if overridden_methods.contains(&method.name) { continue; diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index fc75b1018ec35..264d4940c17f9 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -32,7 +32,7 @@ use session::config::NoDebugInfo; use session::Session; use session::config; use symbol_map::SymbolMap; -use util::nodemap::{NodeSet, DefIdMap, FnvHashMap, FnvHashSet}; +use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet}; use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; @@ -52,7 +52,7 @@ pub struct Stats { pub n_inlines: Cell, pub n_closures: Cell, pub n_llvm_insns: Cell, - pub llvm_insns: RefCell>, + pub llvm_insns: RefCell>, // (ident, llvm-instructions) pub fn_stats: RefCell >, } @@ -74,7 +74,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> { use_dll_storage_attrs: bool, - translation_items: RefCell>>, + translation_items: RefCell>>, trait_cache: RefCell>>, project_cache: RefCell>>, } @@ -89,15 +89,15 @@ pub struct LocalCrateContext<'tcx> { previous_work_product: Option, tn: TypeNames, // FIXME: This seems to be largely unused. codegen_unit: CodegenUnit<'tcx>, - needs_unwind_cleanup_cache: RefCell, bool>>, - fn_pointer_shims: RefCell, ValueRef>>, - drop_glues: RefCell, (ValueRef, FnType)>>, + needs_unwind_cleanup_cache: RefCell, bool>>, + fn_pointer_shims: RefCell, ValueRef>>, + drop_glues: RefCell, (ValueRef, FnType)>>, /// Cache instances of monomorphic and polymorphic items - instances: RefCell, ValueRef>>, + instances: RefCell, ValueRef>>, /// Cache generated vtables - vtables: RefCell, ValueRef>>, + vtables: RefCell, ValueRef>>, /// Cache of constant strings, - const_cstr_cache: RefCell>, + const_cstr_cache: RefCell>, /// Reverse-direction for const ptrs cast from globals. /// Key is a ValueRef holding a *T, @@ -107,24 +107,24 @@ pub struct LocalCrateContext<'tcx> { /// when we ptrcast, and we have to ptrcast during translation /// of a [T] const because we form a slice, a (*T,usize) pair, not /// a pointer to an LLVM array type. Similar for trait objects. - const_unsized: RefCell>, + const_unsized: RefCell>, /// Cache of emitted const globals (value -> global) - const_globals: RefCell>, + const_globals: RefCell>, /// Cache of emitted const values - const_values: RefCell), ValueRef>>, + const_values: RefCell), ValueRef>>, /// Cache of external const values extern_const_values: RefCell>, /// Mapping from static definitions to their DefId's. - statics: RefCell>, + statics: RefCell>, - impl_method_cache: RefCell>, + impl_method_cache: RefCell>, /// Cache of closure wrappers for bare fn's. - closure_bare_wrapper_cache: RefCell>, + closure_bare_wrapper_cache: RefCell>, /// List of globals for static variables which need to be passed to the /// LLVM function ReplaceAllUsesWith (RAUW) when translation is complete. @@ -132,15 +132,15 @@ pub struct LocalCrateContext<'tcx> { /// to constants.) statics_to_rauw: RefCell>, - lltypes: RefCell, Type>>, - llsizingtypes: RefCell, Type>>, - type_hashcodes: RefCell, String>>, + lltypes: RefCell, Type>>, + llsizingtypes: RefCell, Type>>, + type_hashcodes: RefCell, String>>, int_type: Type, opaque_vec_type: Type, builder: BuilderRef_res, /// Holds the LLVM values for closure IDs. - closure_vals: RefCell, ValueRef>>, + closure_vals: RefCell, ValueRef>>, dbg_cx: Option>, @@ -148,7 +148,7 @@ pub struct LocalCrateContext<'tcx> { eh_unwind_resume: Cell>, rust_try_fn: Cell>, - intrinsics: RefCell>, + intrinsics: RefCell>, /// Number of LLVM instructions translated into this `LocalCrateContext`. /// This is used to perform some basic load-balancing to keep all LLVM @@ -502,12 +502,12 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { n_inlines: Cell::new(0), n_closures: Cell::new(0), n_llvm_insns: Cell::new(0), - llvm_insns: RefCell::new(FnvHashMap()), + llvm_insns: RefCell::new(FxHashMap()), fn_stats: RefCell::new(Vec::new()), }, check_overflow: check_overflow, use_dll_storage_attrs: use_dll_storage_attrs, - translation_items: RefCell::new(FnvHashSet()), + translation_items: RefCell::new(FxHashSet()), trait_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())), project_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())), } @@ -557,7 +557,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { self.use_dll_storage_attrs } - pub fn translation_items(&self) -> &RefCell>> { + pub fn translation_items(&self) -> &RefCell>> { &self.translation_items } @@ -612,32 +612,32 @@ impl<'tcx> LocalCrateContext<'tcx> { previous_work_product: previous_work_product, codegen_unit: codegen_unit, tn: TypeNames::new(), - needs_unwind_cleanup_cache: RefCell::new(FnvHashMap()), - fn_pointer_shims: RefCell::new(FnvHashMap()), - drop_glues: RefCell::new(FnvHashMap()), - instances: RefCell::new(FnvHashMap()), - vtables: RefCell::new(FnvHashMap()), - const_cstr_cache: RefCell::new(FnvHashMap()), - const_unsized: RefCell::new(FnvHashMap()), - const_globals: RefCell::new(FnvHashMap()), - const_values: RefCell::new(FnvHashMap()), + needs_unwind_cleanup_cache: RefCell::new(FxHashMap()), + fn_pointer_shims: RefCell::new(FxHashMap()), + drop_glues: RefCell::new(FxHashMap()), + instances: RefCell::new(FxHashMap()), + vtables: RefCell::new(FxHashMap()), + const_cstr_cache: RefCell::new(FxHashMap()), + const_unsized: RefCell::new(FxHashMap()), + const_globals: RefCell::new(FxHashMap()), + const_values: RefCell::new(FxHashMap()), extern_const_values: RefCell::new(DefIdMap()), - statics: RefCell::new(FnvHashMap()), - impl_method_cache: RefCell::new(FnvHashMap()), - closure_bare_wrapper_cache: RefCell::new(FnvHashMap()), + statics: RefCell::new(FxHashMap()), + impl_method_cache: RefCell::new(FxHashMap()), + closure_bare_wrapper_cache: RefCell::new(FxHashMap()), statics_to_rauw: RefCell::new(Vec::new()), - lltypes: RefCell::new(FnvHashMap()), - llsizingtypes: RefCell::new(FnvHashMap()), - type_hashcodes: RefCell::new(FnvHashMap()), + lltypes: RefCell::new(FxHashMap()), + llsizingtypes: RefCell::new(FxHashMap()), + type_hashcodes: RefCell::new(FxHashMap()), int_type: Type::from_ref(ptr::null_mut()), opaque_vec_type: Type::from_ref(ptr::null_mut()), builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)), - closure_vals: RefCell::new(FnvHashMap()), + closure_vals: RefCell::new(FxHashMap()), dbg_cx: dbg_cx, eh_personality: Cell::new(None), eh_unwind_resume: Cell::new(None), rust_try_fn: Cell::new(None), - intrinsics: RefCell::new(FnvHashMap()), + intrinsics: RefCell::new(FxHashMap()), n_llvm_insns: Cell::new(0), type_of_depth: Cell::new(0), symbol_map: symbol_map, @@ -794,16 +794,16 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.shared.link_meta } - pub fn needs_unwind_cleanup_cache(&self) -> &RefCell, bool>> { + pub fn needs_unwind_cleanup_cache(&self) -> &RefCell, bool>> { &self.local().needs_unwind_cleanup_cache } - pub fn fn_pointer_shims(&self) -> &RefCell, ValueRef>> { + pub fn fn_pointer_shims(&self) -> &RefCell, ValueRef>> { &self.local().fn_pointer_shims } pub fn drop_glues<'a>(&'a self) - -> &'a RefCell, (ValueRef, FnType)>> { + -> &'a RefCell, (ValueRef, FnType)>> { &self.local().drop_glues } @@ -815,28 +815,28 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { self.sess().cstore.defid_for_inlined_node(node_id) } - pub fn instances<'a>(&'a self) -> &'a RefCell, ValueRef>> { + pub fn instances<'a>(&'a self) -> &'a RefCell, ValueRef>> { &self.local().instances } - pub fn vtables<'a>(&'a self) -> &'a RefCell, ValueRef>> { + pub fn vtables<'a>(&'a self) -> &'a RefCell, ValueRef>> { &self.local().vtables } - pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell> { + pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell> { &self.local().const_cstr_cache } - pub fn const_unsized<'a>(&'a self) -> &'a RefCell> { + pub fn const_unsized<'a>(&'a self) -> &'a RefCell> { &self.local().const_unsized } - pub fn const_globals<'a>(&'a self) -> &'a RefCell> { + pub fn const_globals<'a>(&'a self) -> &'a RefCell> { &self.local().const_globals } - pub fn const_values<'a>(&'a self) -> &'a RefCell), - ValueRef>> { + pub fn const_values<'a>(&'a self) -> &'a RefCell), + ValueRef>> { &self.local().const_values } @@ -844,16 +844,16 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local().extern_const_values } - pub fn statics<'a>(&'a self) -> &'a RefCell> { + pub fn statics<'a>(&'a self) -> &'a RefCell> { &self.local().statics } pub fn impl_method_cache<'a>(&'a self) - -> &'a RefCell> { + -> &'a RefCell> { &self.local().impl_method_cache } - pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell> { + pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell> { &self.local().closure_bare_wrapper_cache } @@ -861,15 +861,15 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local().statics_to_rauw } - pub fn lltypes<'a>(&'a self) -> &'a RefCell, Type>> { + pub fn lltypes<'a>(&'a self) -> &'a RefCell, Type>> { &self.local().lltypes } - pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell, Type>> { + pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell, Type>> { &self.local().llsizingtypes } - pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell, String>> { + pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell, String>> { &self.local().type_hashcodes } @@ -885,7 +885,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { self.local().opaque_vec_type } - pub fn closure_vals<'a>(&'a self) -> &'a RefCell, ValueRef>> { + pub fn closure_vals<'a>(&'a self) -> &'a RefCell, ValueRef>> { &self.local().closure_vals } @@ -905,7 +905,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local().rust_try_fn } - fn intrinsics<'a>(&'a self) -> &'a RefCell> { + fn intrinsics<'a>(&'a self) -> &'a RefCell> { &self.local().intrinsics } @@ -958,7 +958,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &*self.local().symbol_map } - pub fn translation_items(&self) -> &RefCell>> { + pub fn translation_items(&self) -> &RefCell>> { &self.shared.translation_items } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 4bb34850e0870..e81461b662172 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -36,7 +36,7 @@ use common::CrateContext; use type_::Type; use rustc::ty::{self, AdtKind, Ty, layout}; use session::config; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use util::common::path2cstr; use libc::{c_uint, c_longlong}; @@ -84,20 +84,20 @@ pub struct TypeMap<'tcx> { // The UniqueTypeIds created so far unique_id_interner: Interner, // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping. - unique_id_to_metadata: FnvHashMap, + unique_id_to_metadata: FxHashMap, // A map from types to debuginfo metadata. This is a N:1 mapping. - type_to_metadata: FnvHashMap, DIType>, + type_to_metadata: FxHashMap, DIType>, // A map from types to UniqueTypeId. This is a N:1 mapping. - type_to_unique_id: FnvHashMap, UniqueTypeId> + type_to_unique_id: FxHashMap, UniqueTypeId> } impl<'tcx> TypeMap<'tcx> { pub fn new() -> TypeMap<'tcx> { TypeMap { unique_id_interner: Interner::new(), - type_to_metadata: FnvHashMap(), - unique_id_to_metadata: FnvHashMap(), - type_to_unique_id: FnvHashMap(), + type_to_metadata: FxHashMap(), + unique_id_to_metadata: FxHashMap(), + type_to_unique_id: FxHashMap(), } } diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 3bc5f4f3dbc4b..62fb40cc389c2 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -34,7 +34,7 @@ use monomorphize::{self, Instance}; use rustc::ty::{self, Ty}; use rustc::mir; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; -use util::nodemap::{DefIdMap, FnvHashMap, FnvHashSet}; +use util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; use libc::c_uint; use std::cell::{Cell, RefCell}; @@ -68,15 +68,15 @@ pub struct CrateDebugContext<'tcx> { llcontext: ContextRef, builder: DIBuilderRef, current_debug_location: Cell, - created_files: RefCell>, - created_enum_disr_types: RefCell>, + created_files: RefCell>, + created_enum_disr_types: RefCell>, type_map: RefCell>, namespace_map: RefCell>, // This collection is used to assert that composite types (structs, enums, // ...) have their members only set once: - composite_types_completed: RefCell>, + composite_types_completed: RefCell>, } impl<'tcx> CrateDebugContext<'tcx> { @@ -89,11 +89,11 @@ impl<'tcx> CrateDebugContext<'tcx> { llcontext: llcontext, builder: builder, current_debug_location: Cell::new(InternalDebugLocation::UnknownLocation), - created_files: RefCell::new(FnvHashMap()), - created_enum_disr_types: RefCell::new(FnvHashMap()), + created_files: RefCell::new(FxHashMap()), + created_enum_disr_types: RefCell::new(FxHashMap()), type_map: RefCell::new(TypeMap::new()), namespace_map: RefCell::new(DefIdMap()), - composite_types_completed: RefCell::new(FnvHashSet()), + composite_types_completed: RefCell::new(FxHashSet()), }; } } diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 8bf27b4babfc2..b22bcf9825a2a 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -29,7 +29,7 @@ use type_of; use glue; use type_::Type; -use rustc_data_structures::fnv::FnvHashMap; +use rustc_data_structures::fx::FxHashMap; use syntax::parse::token; use super::{MirContext, LocalRef}; @@ -144,7 +144,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { adt::trans_get_discr(bcx, ty, discr_lvalue.llval, None, true) ); - let mut bb_hist = FnvHashMap(); + let mut bb_hist = FxHashMap(); for target in targets { *bb_hist.entry(target).or_insert(0) += 1; } diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index 625b43c7d1792..c9c12fb6d4534 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -134,7 +134,7 @@ use symbol_map::SymbolMap; use syntax::ast::NodeId; use syntax::parse::token::{self, InternedString}; use trans_item::TransItem; -use util::nodemap::{FnvHashMap, FnvHashSet}; +use util::nodemap::{FxHashMap, FxHashSet}; pub enum PartitioningStrategy { /// Generate one codegen unit per source-level module. @@ -151,12 +151,12 @@ pub struct CodegenUnit<'tcx> { /// as well as the crate name and disambiguator. name: InternedString, - items: FnvHashMap, llvm::Linkage>, + items: FxHashMap, llvm::Linkage>, } impl<'tcx> CodegenUnit<'tcx> { pub fn new(name: InternedString, - items: FnvHashMap, llvm::Linkage>) + items: FxHashMap, llvm::Linkage>) -> Self { CodegenUnit { name: name, @@ -165,7 +165,7 @@ impl<'tcx> CodegenUnit<'tcx> { } pub fn empty(name: InternedString) -> Self { - Self::new(name, FnvHashMap()) + Self::new(name, FxHashMap()) } pub fn contains_item(&self, item: &TransItem<'tcx>) -> bool { @@ -176,7 +176,7 @@ impl<'tcx> CodegenUnit<'tcx> { &self.name } - pub fn items(&self) -> &FnvHashMap, llvm::Linkage> { + pub fn items(&self) -> &FxHashMap, llvm::Linkage> { &self.items } @@ -297,7 +297,7 @@ pub fn partition<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>, struct PreInliningPartitioning<'tcx> { codegen_units: Vec>, - roots: FnvHashSet>, + roots: FxHashSet>, } struct PostInliningPartitioning<'tcx>(Vec>); @@ -308,8 +308,8 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>, where I: Iterator> { let tcx = scx.tcx(); - let mut roots = FnvHashSet(); - let mut codegen_units = FnvHashMap(); + let mut roots = FxHashSet(); + let mut codegen_units = FxHashMap(); for trans_item in trans_items { let is_root = !trans_item.is_instantiated_only_on_demand(tcx); @@ -419,7 +419,7 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit for codegen_unit in &initial_partitioning.codegen_units[..] { // Collect all items that need to be available in this codegen unit - let mut reachable = FnvHashSet(); + let mut reachable = FxHashSet(); for root in codegen_unit.items.keys() { follow_inlining(*root, inlining_map, &mut reachable); } @@ -465,7 +465,7 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit fn follow_inlining<'tcx>(trans_item: TransItem<'tcx>, inlining_map: &InliningMap<'tcx>, - visited: &mut FnvHashSet>) { + visited: &mut FxHashSet>) { if !visited.insert(trans_item) { return; } diff --git a/src/librustc_trans/symbol_map.rs b/src/librustc_trans/symbol_map.rs index 3faaa085dce14..c3e0ac1fee515 100644 --- a/src/librustc_trans/symbol_map.rs +++ b/src/librustc_trans/symbol_map.rs @@ -14,7 +14,7 @@ use rustc::ty::TyCtxt; use std::borrow::Cow; use syntax::codemap::Span; use trans_item::TransItem; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; // In the SymbolMap we collect the symbol names of all translation items of // the current crate. This map exists as a performance optimization. Symbol @@ -22,7 +22,7 @@ use util::nodemap::FnvHashMap; // Thus they could also always be recomputed if needed. pub struct SymbolMap<'tcx> { - index: FnvHashMap, (usize, usize)>, + index: FxHashMap, (usize, usize)>, arena: String, } @@ -78,7 +78,7 @@ impl<'tcx> SymbolMap<'tcx> { } let mut symbol_map = SymbolMap { - index: FnvHashMap(), + index: FxHashMap(), arena: String::with_capacity(1024), }; diff --git a/src/librustc_trans/type_.rs b/src/librustc_trans/type_.rs index 03a71827b473b..2a6f79d3ed57a 100644 --- a/src/librustc_trans/type_.rs +++ b/src/librustc_trans/type_.rs @@ -15,7 +15,7 @@ use llvm::{TypeRef, Bool, False, True, TypeKind}; use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use context::CrateContext; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use syntax::ast; use rustc::ty::layout; @@ -325,13 +325,13 @@ impl Type { /* Memory-managed object interface to type handles. */ pub struct TypeNames { - named_types: RefCell>, + named_types: RefCell>, } impl TypeNames { pub fn new() -> TypeNames { TypeNames { - named_types: RefCell::new(FnvHashMap()) + named_types: RefCell::new(FxHashMap()) } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c93f1c6c8e610..57936f8a4b3be 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -66,7 +66,7 @@ use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ElisionFailureInfo, ElidedLifetime}; use rscope::{AnonTypeScope, MaybeWithAnonTypes}; use util::common::{ErrorReported, FN_OUTPUT_NAME}; -use util::nodemap::{NodeMap, FnvHashSet}; +use util::nodemap::{NodeMap, FxHashSet}; use std::cell::RefCell; use syntax::{abi, ast}; @@ -569,7 +569,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let mut possible_implied_output_region = None; for input_type in input_tys.iter() { - let mut regions = FnvHashSet(); + let mut regions = FxHashSet(); let have_bound_regions = tcx.collect_regions(input_type, &mut regions); debug!("find_implied_output_regions: collected {:?} from {:?} \ @@ -1142,7 +1142,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { return tcx.types.err; } - let mut associated_types = FnvHashSet::default(); + let mut associated_types = FxHashSet::default(); for tr in traits::supertraits(tcx, principal) { if let Some(trait_id) = tcx.map.as_local_node_id(tr.def_id()) { use collect::trait_associated_type_names; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index c842514227ca0..15b29573ac4e8 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -14,7 +14,7 @@ use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::infer::{self, InferOk, TypeOrigin}; use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference}; use check::{FnCtxt, Expectation}; -use util::nodemap::FnvHashMap; +use util::nodemap::FxHashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::cmp; @@ -633,10 +633,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let field_map = variant.fields .iter() .map(|field| (field.name, field)) - .collect::>(); + .collect::>(); // Keep track of which fields have already appeared in the pattern. - let mut used_fields = FnvHashMap(); + let mut used_fields = FxHashMap(); // Typecheck each field. for &Spanned { node: ref field, span } in fields { diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index e72bcb3079c5c..d28eb85ebb49d 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -18,7 +18,7 @@ use middle::region; use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, AdtKind, Ty, TyCtxt}; use rustc::traits::{self, Reveal}; -use util::nodemap::FnvHashSet; +use util::nodemap::FxHashSet; use syntax::ast; use syntax_pos::{self, Span}; @@ -289,7 +289,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( rcx: rcx, span: span, parent_scope: parent_scope, - breadcrumbs: FnvHashSet() + breadcrumbs: FxHashSet() }, TypeContext::Root, typ, @@ -347,7 +347,7 @@ enum TypeContext { struct DropckContext<'a, 'b: 'a, 'gcx: 'b+'tcx, 'tcx: 'b> { rcx: &'a mut RegionCtxt<'b, 'gcx, 'tcx>, /// types that have already been traversed - breadcrumbs: FnvHashSet>, + breadcrumbs: FxHashSet>, /// span for error reporting span: Span, /// the scope reachable dtorck types must outlive diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 7d2547ec17f3a..95d2b2211f5b4 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -16,7 +16,7 @@ use rustc::infer::TypeOrigin; use rustc::ty::subst::Substs; use rustc::ty::FnSig; use rustc::ty::{self, Ty}; -use rustc::util::nodemap::FnvHashMap; +use rustc::util::nodemap::FxHashMap; use {CrateCtxt, require_same_types}; use syntax::abi::Abi; @@ -372,7 +372,7 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt, return } - let mut structural_to_nomimal = FnvHashMap(); + let mut structural_to_nomimal = FxHashMap(); let sig = tcx.no_late_bound_regions(i_ty.ty.fn_sig()).unwrap(); if intr.inputs.len() != sig.inputs.len() { @@ -412,7 +412,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>( ccx: &CrateCtxt<'a, 'tcx>, position: &str, span: Span, - structural_to_nominal: &mut FnvHashMap<&'a intrinsics::Type, ty::Ty<'tcx>>, + structural_to_nominal: &mut FxHashMap<&'a intrinsics::Type, ty::Ty<'tcx>>, expected: &'a intrinsics::Type, t: ty::Ty<'tcx>) { use intrinsics::Type::*; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 43837de2f345d..54b1b6c6807db 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -20,7 +20,7 @@ use rustc::ty::subst::{Subst, Substs}; use rustc::traits; use rustc::ty::{self, Ty, ToPolyTraitRef, TraitRef, TypeFoldable}; use rustc::infer::{InferOk, TypeOrigin}; -use rustc::util::nodemap::FnvHashSet; +use rustc::util::nodemap::FxHashSet; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; use rustc::hir; @@ -40,7 +40,7 @@ struct ProbeContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { opt_simplified_steps: Option>, inherent_candidates: Vec>, extension_candidates: Vec>, - impl_dups: FnvHashSet, + impl_dups: FxHashSet, import_id: Option, /// Collects near misses when the candidate functions are missing a `self` keyword and is only @@ -263,7 +263,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { item_name: item_name, inherent_candidates: Vec::new(), extension_candidates: Vec::new(), - impl_dups: FnvHashSet(), + impl_dups: FxHashSet(), import_id: None, steps: Rc::new(steps), opt_simplified_steps: opt_simplified_steps, @@ -568,7 +568,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_extension_candidates_for_traits_in_scope(&mut self, expr_id: ast::NodeId) -> Result<(), MethodError<'tcx>> { - let mut duplicates = FnvHashSet(); + let mut duplicates = FxHashSet(); let opt_applicable_traits = self.tcx.trait_map.get(&expr_id); if let Some(applicable_traits) = opt_applicable_traits { for trait_candidate in applicable_traits { @@ -585,7 +585,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { } fn assemble_extension_candidates_for_all_traits(&mut self) -> Result<(), MethodError<'tcx>> { - let mut duplicates = FnvHashSet(); + let mut duplicates = FxHashSet(); for trait_info in suggest::all_traits(self.ccx) { if duplicates.insert(trait_info.def_id) { self.assemble_extension_candidates_for_trait(trait_info.def_id)?; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 32bf839a4ed4e..98d3957db7059 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -20,7 +20,7 @@ use hir::def::Def; use hir::def_id::{CRATE_DEF_INDEX, DefId}; use middle::lang_items::FnOnceTraitLangItem; use rustc::traits::{Obligation, SelectionContext}; -use util::nodemap::FnvHashSet; +use util::nodemap::FxHashSet; use syntax::ast; use errors::DiagnosticBuilder; @@ -470,10 +470,10 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { }); // Cross-crate: - let mut external_mods = FnvHashSet(); + let mut external_mods = FxHashSet(); fn handle_external_def(ccx: &CrateCtxt, traits: &mut AllTraitsVec, - external_mods: &mut FnvHashSet, + external_mods: &mut FxHashSet, def: Def) { let def_id = def.def_id(); match def { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d8314bd6c2aed..10523755277e8 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -103,7 +103,7 @@ use CrateCtxt; use TypeAndSubsts; use lint; use util::common::{block_query, ErrorReported, indenter, loop_query}; -use util::nodemap::{DefIdMap, FnvHashMap, FnvHashSet, NodeMap}; +use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap}; use std::cell::{Cell, Ref, RefCell}; use std::mem::replace; @@ -1975,13 +1975,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // We must collect the defaults *before* we do any unification. Because we have // directly attached defaults to the type variables any unification that occurs // will erase defaults causing conflicting defaults to be completely ignored. - let default_map: FnvHashMap<_, _> = + let default_map: FxHashMap<_, _> = unsolved_variables .iter() .filter_map(|t| self.default(t).map(|d| (t, d))) .collect(); - let mut unbound_tyvars = FnvHashSet(); + let mut unbound_tyvars = FxHashSet(); debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map); @@ -2129,8 +2129,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // table then apply defaults until we find a conflict. That default must be the one // that caused conflict earlier. fn find_conflicting_default(&self, - unbound_vars: &FnvHashSet>, - default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>, + unbound_vars: &FxHashSet>, + default_map: &FxHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>, conflict: Ty<'tcx>) -> Option> { use rustc::ty::error::UnconstrainedNumeric::Neither; @@ -3123,12 +3123,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields") }; - let mut remaining_fields = FnvHashMap(); + let mut remaining_fields = FxHashMap(); for field in &variant.fields { remaining_fields.insert(field.name, field); } - let mut seen_fields = FnvHashMap(); + let mut seen_fields = FxHashMap(); let mut error_happened = false; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index be1f2e35679d7..741f327ac99e1 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -16,7 +16,7 @@ use middle::region::{CodeExtent}; use rustc::infer::TypeOrigin; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::util::nodemap::{FnvHashSet, FnvHashMap}; +use rustc::util::nodemap::{FxHashSet, FxHashMap}; use syntax::ast; use syntax_pos::Span; @@ -529,7 +529,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { assert_eq!(ty_predicates.parent, None); let variances = self.tcx().item_variances(item_def_id); - let mut constrained_parameters: FnvHashSet<_> = + let mut constrained_parameters: FxHashSet<_> = variances.iter().enumerate() .filter(|&(_, &variance)| variance != ty::Bivariant) .map(|(index, _)| Parameter(index as u32)) @@ -580,10 +580,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) { let parent = tcx.lookup_generics(generics.parent.unwrap()); - let impl_params: FnvHashMap<_, _> = parent.types - .iter() - .map(|tp| (tp.name, tp.def_id)) - .collect(); + let impl_params: FxHashMap<_, _> = parent.types + .iter() + .map(|tp| (tp.name, tp.def_id)) + .collect(); for method_param in &generics.types { if impl_params.contains_key(&method_param.name) { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 0e0f5cb1a7e15..5c51877ae743e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -72,7 +72,7 @@ use rustc::ty::util::IntTypeExt; use rscope::*; use rustc::dep_graph::DepNode; use util::common::{ErrorReported, MemoizationMap}; -use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet}; +use util::nodemap::{NodeMap, FxHashMap, FxHashSet}; use {CrateCtxt, write_ty_to_tcx}; use rustc_const_math::ConstInt; @@ -786,8 +786,8 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { // Convert all the associated consts. // Also, check if there are any duplicate associated items - let mut seen_type_items = FnvHashMap(); - let mut seen_value_items = FnvHashMap(); + let mut seen_type_items = FxHashMap(); + let mut seen_value_items = FxHashMap(); for impl_item in impl_items { let seen_items = match impl_item.node { @@ -1038,7 +1038,7 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, disr_val: ty::Disr, def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> { - let mut seen_fields: FnvHashMap = FnvHashMap(); + let mut seen_fields: FxHashMap = FxHashMap(); let node_id = ccx.tcx.map.as_local_node_id(did).unwrap(); let fields = def.fields().iter().map(|f| { let fid = ccx.tcx.map.local_def_id(f.id); @@ -1952,9 +1952,9 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, { let inline_bounds = from_bounds(ccx, param_bounds); let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates); - let all_bounds: FnvHashSet<_> = inline_bounds.into_iter() - .chain(where_bounds) - .collect(); + let all_bounds: FxHashSet<_> = inline_bounds.into_iter() + .chain(where_bounds) + .collect(); return if all_bounds.len() > 1 { ty::ObjectLifetimeDefault::Ambiguous } else if all_bounds.len() == 0 { @@ -2171,7 +2171,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // The trait reference is an input, so find all type parameters // reachable from there, to start (if this is an inherent impl, // then just examine the self type). - let mut input_parameters: FnvHashSet<_> = + let mut input_parameters: FxHashSet<_> = ctp::parameters_for(&impl_scheme.ty, false).into_iter().collect(); if let Some(ref trait_ref) = impl_trait_ref { input_parameters.extend(ctp::parameters_for(trait_ref, false)); @@ -2200,7 +2200,7 @@ fn enforce_impl_lifetimes_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let impl_predicates = ccx.tcx.lookup_predicates(impl_def_id); let impl_trait_ref = ccx.tcx.impl_trait_ref(impl_def_id); - let mut input_parameters: FnvHashSet<_> = + let mut input_parameters: FxHashSet<_> = ctp::parameters_for(&impl_scheme.ty, false).into_iter().collect(); if let Some(ref trait_ref) = impl_trait_ref { input_parameters.extend(ctp::parameters_for(trait_ref, false)); @@ -2208,7 +2208,7 @@ fn enforce_impl_lifetimes_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ctp::identify_constrained_type_params( &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters); - let lifetimes_in_associated_types: FnvHashSet<_> = impl_items.iter() + let lifetimes_in_associated_types: FxHashSet<_> = impl_items.iter() .map(|item| ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(item.id))) .filter_map(|item| match item { ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty, diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 39f9e4316b9c7..7918537a6c08f 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -10,7 +10,7 @@ use rustc::ty::{self, Ty}; use rustc::ty::fold::{TypeFoldable, TypeVisitor}; -use rustc::util::nodemap::FnvHashSet; +use rustc::util::nodemap::FxHashSet; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct Parameter(pub u32); @@ -76,7 +76,7 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { pub fn identify_constrained_type_params<'tcx>(predicates: &[ty::Predicate<'tcx>], impl_trait_ref: Option>, - input_parameters: &mut FnvHashSet) + input_parameters: &mut FxHashSet) { let mut predicates = predicates.to_owned(); setup_constraining_predicates(&mut predicates, impl_trait_ref, input_parameters); @@ -125,7 +125,7 @@ pub fn identify_constrained_type_params<'tcx>(predicates: &[ty::Predicate<'tcx>] /// think of any. pub fn setup_constraining_predicates<'tcx>(predicates: &mut [ty::Predicate<'tcx>], impl_trait_ref: Option>, - input_parameters: &mut FnvHashSet) + input_parameters: &mut FxHashSet) { // The canonical way of doing the needed topological sort // would be a DFS, but getting the graph and its ownership diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 31497b6bd3352..1885b4276cc41 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -19,7 +19,7 @@ use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; use rustc::hir::print as pprust; use rustc::ty::{self, TyCtxt}; -use rustc::util::nodemap::FnvHashSet; +use rustc::util::nodemap::FxHashSet; use rustc_const_eval::lookup_const_by_id; @@ -460,7 +460,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext, .into_iter() .map(|meth| meth.name.to_string()) .collect() - }).unwrap_or(FnvHashSet()); + }).unwrap_or(FxHashSet()); ret.push(clean::Item { inner: clean::ImplItem(clean::Impl { @@ -496,7 +496,7 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, // If we're reexporting a reexport it may actually reexport something in // two namespaces, so the target may be listed twice. Make sure we only // visit each node at most once. - let mut visited = FnvHashSet(); + let mut visited = FxHashSet(); for item in tcx.sess.cstore.item_children(did) { let def_id = item.def.def_id(); if tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 265b66b01ea52..df13e384d9615 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -38,7 +38,7 @@ use rustc::hir::print as pprust; use rustc::ty::subst::Substs; use rustc::ty::{self, AdtKind}; use rustc::middle::stability; -use rustc::util::nodemap::{FnvHashMap, FnvHashSet}; +use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc::hir; @@ -116,7 +116,7 @@ pub struct Crate { pub access_levels: Arc>, // These are later on moved into `CACHEKEY`, leaving the map empty. // Only here so that they can be filtered through the rustdoc passes. - pub external_traits: FnvHashMap, + pub external_traits: FxHashMap, } struct CrateNum(def_id::CrateNum); @@ -993,7 +993,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, // Note that associated types also have a sized bound by default, but we // don't actually know the set of associated types right here so that's // handled in cleaning associated types - let mut sized_params = FnvHashSet(); + let mut sized_params = FxHashSet(); where_predicates.retain(|pred| { match *pred { WP::BoundPredicate { ty: Generic(ref g), ref bounds } => { @@ -1693,8 +1693,8 @@ impl Clean for hir::Ty { }); if let Some((tcx, &hir::ItemTy(ref ty, ref generics))) = tcx_and_alias { let provided_params = &path.segments.last().unwrap().parameters; - let mut ty_substs = FnvHashMap(); - let mut lt_substs = FnvHashMap(); + let mut ty_substs = FxHashMap(); + let mut lt_substs = FxHashMap(); for (i, ty_param) in generics.ty_params.iter().enumerate() { let ty_param_def = tcx.expect_def(ty_param.id); if let Some(ty) = provided_params.types().get(i).cloned() @@ -2368,7 +2368,7 @@ impl Clean for hir::ImplPolarity { pub struct Impl { pub unsafety: hir::Unsafety, pub generics: Generics, - pub provided_trait_methods: FnvHashSet, + pub provided_trait_methods: FxHashSet, pub trait_: Option, pub for_: Type, pub items: Vec, @@ -2394,7 +2394,7 @@ impl Clean> for doctree::Impl { .map(|meth| meth.name.to_string()) .collect() }) - }).unwrap_or(FnvHashSet()); + }).unwrap_or(FxHashSet()); ret.push(Item { name: None, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index f03b6a5ab3f1f..810bea4c5b098 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -19,7 +19,7 @@ use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt}; use rustc::hir::map as hir_map; use rustc::lint; -use rustc::util::nodemap::FnvHashMap; +use rustc::util::nodemap::FxHashMap; use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; @@ -48,7 +48,7 @@ pub enum MaybeTyped<'a, 'tcx: 'a> { NotTyped(&'a session::Session) } -pub type ExternalPaths = FnvHashMap, clean::TypeKind)>; +pub type ExternalPaths = FxHashMap, clean::TypeKind)>; pub struct DocContext<'a, 'tcx: 'a> { pub map: &'a hir_map::Map<'tcx>, @@ -65,15 +65,15 @@ pub struct DocContext<'a, 'tcx: 'a> { /// Later on moved into `html::render::CACHE_KEY` pub renderinfo: RefCell, /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` - pub external_traits: RefCell>, + pub external_traits: RefCell>, // The current set of type and lifetime substitutions, // for expanding type aliases at the HIR level: /// Table type parameter definition -> substituted type - pub ty_substs: RefCell>, + pub ty_substs: RefCell>, /// Table node id of lifetime parameter definition -> substituted lifetime - pub lt_substs: RefCell>, + pub lt_substs: RefCell>, } impl<'b, 'tcx> DocContext<'b, 'tcx> { @@ -99,8 +99,8 @@ impl<'b, 'tcx> DocContext<'b, 'tcx> { /// Call the closure with the given parameters set as /// the substitutions for a type alias' RHS. pub fn enter_alias(&self, - ty_substs: FnvHashMap, - lt_substs: FnvHashMap, + ty_substs: FxHashMap, + lt_substs: FxHashMap, f: F) -> R where F: FnOnce() -> R { let (old_tys, old_lts) = diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a848a011f88db..2078ad3ffbe26 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -59,7 +59,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; use rustc::hir; -use rustc::util::nodemap::{FnvHashMap, FnvHashSet}; +use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::flock; use clean::{self, Attributes, GetDefId, SelfTy, Mutability}; @@ -111,9 +111,9 @@ pub struct SharedContext { /// `true`. pub include_sources: bool, /// The local file sources we've emitted and their respective url-paths. - pub local_sources: FnvHashMap, + pub local_sources: FxHashMap, /// All the passes that were run on this crate. - pub passes: FnvHashSet, + pub passes: FxHashSet, /// The base-URL of the issue tracker for when an item has been tagged with /// an issue number. pub issue_tracker_base_url: Option, @@ -208,7 +208,7 @@ pub struct Cache { /// Mapping of typaram ids to the name of the type parameter. This is used /// when pretty-printing a type (so pretty printing doesn't have to /// painfully maintain a context like this) - pub typarams: FnvHashMap, + pub typarams: FxHashMap, /// Maps a type id to all known implementations for that type. This is only /// recognized for intra-crate `ResolvedPath` types, and is used to print @@ -216,35 +216,35 @@ pub struct Cache { /// /// The values of the map are a list of implementations and documentation /// found on that implementation. - pub impls: FnvHashMap>, + pub impls: FxHashMap>, /// Maintains a mapping of local crate node ids to the fully qualified name /// and "short type description" of that node. This is used when generating /// URLs when a type is being linked to. External paths are not located in /// this map because the `External` type itself has all the information /// necessary. - pub paths: FnvHashMap, ItemType)>, + pub paths: FxHashMap, ItemType)>, /// Similar to `paths`, but only holds external paths. This is only used for /// generating explicit hyperlinks to other crates. - pub external_paths: FnvHashMap, ItemType)>, + pub external_paths: FxHashMap, ItemType)>, /// This map contains information about all known traits of this crate. /// Implementations of a crate should inherit the documentation of the /// parent trait if no extra documentation is specified, and default methods /// should show up in documentation about trait implementations. - pub traits: FnvHashMap, + pub traits: FxHashMap, /// When rendering traits, it's often useful to be able to list all /// implementors of the trait, and this mapping is exactly, that: a mapping /// of trait ids to the list of known implementors of the trait - pub implementors: FnvHashMap>, + pub implementors: FxHashMap>, /// Cache of where external crate documentation can be found. - pub extern_locations: FnvHashMap, + pub extern_locations: FxHashMap, /// Cache of where documentation for primitives can be found. - pub primitive_locations: FnvHashMap, + pub primitive_locations: FxHashMap, // Note that external items for which `doc(hidden)` applies to are shown as // non-reachable while local items aren't. This is because we're reusing @@ -257,7 +257,7 @@ pub struct Cache { parent_stack: Vec, parent_is_trait_impl: bool, search_index: Vec, - seen_modules: FnvHashSet, + seen_modules: FxHashSet, seen_mod: bool, stripped_mod: bool, deref_trait_did: Option, @@ -275,9 +275,9 @@ pub struct Cache { /// Later on moved into `CACHE_KEY`. #[derive(Default)] pub struct RenderInfo { - pub inlined: FnvHashSet, + pub inlined: FxHashSet, pub external_paths: ::core::ExternalPaths, - pub external_typarams: FnvHashMap, + pub external_typarams: FxHashMap, pub deref_trait_did: Option, pub deref_mut_trait_did: Option, } @@ -376,10 +376,10 @@ impl ToJson for IndexItemFunctionType { thread_local!(static CACHE_KEY: RefCell> = Default::default()); thread_local!(pub static CURRENT_LOCATION_KEY: RefCell> = RefCell::new(Vec::new())); -thread_local!(static USED_ID_MAP: RefCell> = +thread_local!(static USED_ID_MAP: RefCell> = RefCell::new(init_ids())); -fn init_ids() -> FnvHashMap { +fn init_ids() -> FxHashMap { [ "main", "search", @@ -406,7 +406,7 @@ pub fn reset_ids(embedded: bool) { *s.borrow_mut() = if embedded { init_ids() } else { - FnvHashMap() + FxHashMap() }; }); } @@ -431,7 +431,7 @@ pub fn derive_id(candidate: String) -> String { pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: PathBuf, - passes: FnvHashSet, + passes: FxHashSet, css_file_extension: Option, renderinfo: RenderInfo) -> Result<(), Error> { let src_root = match krate.src.parent() { @@ -442,7 +442,7 @@ pub fn run(mut krate: clean::Crate, src_root: src_root, passes: passes, include_sources: true, - local_sources: FnvHashMap(), + local_sources: FxHashMap(), issue_tracker_base_url: None, layout: layout::Layout { logo: "".to_string(), @@ -510,22 +510,22 @@ pub fn run(mut krate: clean::Crate, .collect(); let mut cache = Cache { - impls: FnvHashMap(), + impls: FxHashMap(), external_paths: external_paths, - paths: FnvHashMap(), - implementors: FnvHashMap(), + paths: FxHashMap(), + implementors: FxHashMap(), stack: Vec::new(), parent_stack: Vec::new(), search_index: Vec::new(), parent_is_trait_impl: false, - extern_locations: FnvHashMap(), - primitive_locations: FnvHashMap(), - seen_modules: FnvHashSet(), + extern_locations: FxHashMap(), + primitive_locations: FxHashMap(), + seen_modules: FxHashSet(), seen_mod: false, stripped_mod: false, access_levels: krate.access_levels.clone(), orphan_impl_items: Vec::new(), - traits: mem::replace(&mut krate.external_traits, FnvHashMap()), + traits: mem::replace(&mut krate.external_traits, FxHashMap()), deref_trait_did: deref_trait_did, deref_mut_trait_did: deref_mut_trait_did, typarams: external_typarams, @@ -572,7 +572,7 @@ pub fn run(mut krate: clean::Crate, /// Build the search index from the collected metadata fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { - let mut nodeid_to_pathid = FnvHashMap(); + let mut nodeid_to_pathid = FxHashMap(); let mut crate_items = Vec::with_capacity(cache.search_index.len()); let mut crate_paths = Vec::::new(); @@ -2618,7 +2618,7 @@ fn render_union(w: &mut fmt::Formatter, it: &clean::Item, #[derive(Copy, Clone)] enum AssocItemLink<'a> { Anchor(Option<&'a str>), - GotoSource(DefId, &'a FnvHashSet), + GotoSource(DefId, &'a FxHashSet), } impl<'a> AssocItemLink<'a> { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 4d1af1622724a..6e47c037ad3db 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -22,7 +22,7 @@ use rustc::hir::map as hir_map; use rustc::hir::def::Def; use rustc::hir::def_id::LOCAL_CRATE; use rustc::middle::privacy::AccessLevel; -use rustc::util::nodemap::FnvHashSet; +use rustc::util::nodemap::FxHashSet; use rustc::hir; @@ -42,14 +42,14 @@ pub struct RustdocVisitor<'a, 'tcx: 'a> { pub module: Module, pub attrs: hir::HirVec, pub cx: &'a core::DocContext<'a, 'tcx>, - view_item_stack: FnvHashSet, + view_item_stack: FxHashSet, inlining_from_glob: bool, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { pub fn new(cx: &'a core::DocContext<'a, 'tcx>) -> RustdocVisitor<'a, 'tcx> { // If the root is reexported, terminate all recursion. - let mut stack = FnvHashSet(); + let mut stack = FxHashSet(); stack.insert(ast::CRATE_NODE_ID); RustdocVisitor { module: Module::new(None), From 31a508e1185713c6e570bb963dd3e097a228957c Mon Sep 17 00:00:00 2001 From: Josh Driver Date: Tue, 8 Nov 2016 21:45:02 +1030 Subject: [PATCH 12/24] Allow proc_macro functions to whitelist specific attributes By using a second attribute `attributes(Bar)` on proc_macro_derive, whitelist any attributes with the name `Bar` in the deriving item. This allows a proc_macro function to use custom attribtues without a custom attribute error or unused attribute lint. --- src/libproc_macro/lib.rs | 3 +- src/librustc_metadata/creader.rs | 8 ++- src/libsyntax_ext/deriving/custom.rs | 44 +++++++++--- src/libsyntax_ext/proc_macro_registrar.rs | 67 ++++++++++++++----- .../proc-macro/attribute.rs | 22 +++++- .../proc-macro/auxiliary/derive-b.rs | 25 +++++++ .../proc-macro/item-error.rs | 26 +++++++ .../proc-macro/proc-macro-attributes.rs | 26 +++++++ .../proc-macro/auxiliary/add-impl.rs | 5 +- .../proc-macro/auxiliary/append-impl.rs | 11 ++- .../proc-macro/auxiliary/derive-a.rs | 2 +- .../proc-macro/auxiliary/derive-b.rs | 29 ++++++++ .../auxiliary/derive-same-struct.rs | 2 +- .../auxiliary/expand-with-a-macro.rs | 2 - .../run-pass-fulldeps/proc-macro/derive-b.rs | 32 +++++++++ .../proc-macro/derive-same-struct.rs | 2 +- 16 files changed, 260 insertions(+), 46 deletions(-) create mode 100644 src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/item-error.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/derive-b.rs diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 1d2c64d6d938a..5ee9fecfb21b3 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -95,7 +95,8 @@ pub mod __internal { pub trait Registry { fn register_custom_derive(&mut self, trait_name: &str, - expand: fn(TokenStream) -> TokenStream); + expand: fn(TokenStream) -> TokenStream, + attributes: &[&'static str]); } // Emulate scoped_thread_local!() here essentially diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index e72ac8419941c..2f2b7d9188a4a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -624,8 +624,12 @@ impl<'a> CrateLoader<'a> { impl Registry for MyRegistrar { fn register_custom_derive(&mut self, trait_name: &str, - expand: fn(TokenStream) -> TokenStream) { - let derive = SyntaxExtension::CustomDerive(Box::new(CustomDerive::new(expand))); + expand: fn(TokenStream) -> TokenStream, + attributes: &[&'static str]) { + let attrs = attributes.iter().map(|s| InternedString::new(s)).collect(); + let derive = SyntaxExtension::CustomDerive( + Box::new(CustomDerive::new(expand, attrs)) + ); self.0.push((intern(trait_name), derive)); } } diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index f8cb1294a6663..2b80deded0aa8 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -12,20 +12,37 @@ use std::panic; use errors::FatalError; use proc_macro::{TokenStream, __internal}; -use syntax::ast::{self, ItemKind}; +use syntax::ast::{self, ItemKind, Attribute}; +use syntax::attr::{mark_used, mark_known}; use syntax::codemap::{ExpnInfo, MacroAttribute, NameAndSpan, Span}; use syntax::ext::base::*; use syntax::fold::Folder; +use syntax::parse::token::InternedString; use syntax::parse::token::intern; use syntax::print::pprust; +use syntax::visit::Visitor; + +struct MarkAttrs<'a>(&'a [InternedString]); + +impl<'a> Visitor for MarkAttrs<'a> { + fn visit_attribute(&mut self, attr: &Attribute) { + if self.0.contains(&attr.name()) { + mark_used(attr); + mark_known(attr); + } + } +} pub struct CustomDerive { inner: fn(TokenStream) -> TokenStream, + attrs: Vec, } impl CustomDerive { - pub fn new(inner: fn(TokenStream) -> TokenStream) -> CustomDerive { - CustomDerive { inner: inner } + pub fn new(inner: fn(TokenStream) -> TokenStream, + attrs: Vec) + -> CustomDerive { + CustomDerive { inner: inner, attrs: attrs } } } @@ -47,7 +64,7 @@ impl MultiItemModifier for CustomDerive { }; match item.node { ItemKind::Struct(..) | - ItemKind::Enum(..) => {} + ItemKind::Enum(..) => {}, _ => { ecx.span_err(span, "custom derive attributes may only be \ applied to struct/enum items"); @@ -55,6 +72,9 @@ impl MultiItemModifier for CustomDerive { } } + // Mark attributes as known, and used. + MarkAttrs(&self.attrs).visit_item(&item); + let input_span = Span { expn_id: ecx.codemap().record_expansion(ExpnInfo { call_site: span, @@ -66,12 +86,13 @@ impl MultiItemModifier for CustomDerive { }), ..item.span }; - let input = __internal::new_token_stream(item); + + let input = __internal::new_token_stream(item.clone()); let res = __internal::set_parse_sess(&ecx.parse_sess, || { let inner = self.inner; panic::catch_unwind(panic::AssertUnwindSafe(|| inner(input))) }); - let item = match res { + let new_items = match res { Ok(stream) => __internal::token_stream_items(stream), Err(e) => { let msg = "custom derive attribute panicked"; @@ -88,12 +109,13 @@ impl MultiItemModifier for CustomDerive { } }; - // Right now we have no knowledge of spans at all in custom derive - // macros, everything is just parsed as a string. Reassign all spans to - // the input `item` for better errors here. - item.into_iter().flat_map(|item| { + let mut res = vec![Annotatable::Item(item)]; + // Reassign spans of all expanded items to the input `item` + // for better errors here. + res.extend(new_items.into_iter().flat_map(|item| { ChangeSpan { span: input_span }.fold_item(item) - }).map(Annotatable::Item).collect() + }).map(Annotatable::Item)); + res } } diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs index f49a5f0e0706e..5996ba70b190b 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -30,6 +30,7 @@ struct CustomDerive { trait_name: InternedString, function_name: Ident, span: Span, + attrs: Vec, } struct CollectCustomDerives<'a> { @@ -133,7 +134,8 @@ impl<'a> Visitor for CollectCustomDerives<'a> { } // Once we've located the `#[proc_macro_derive]` attribute, verify - // that it's of the form `#[proc_macro_derive(Foo)]` + // that it's of the form `#[proc_macro_derive(Foo)]` or + // `#[proc_macro_derive(Foo, attributes(A, ..))]` let list = match attr.meta_item_list() { Some(list) => list, None => { @@ -143,38 +145,69 @@ impl<'a> Visitor for CollectCustomDerives<'a> { return } }; - if list.len() != 1 { + if list.len() != 1 && list.len() != 2 { self.handler.span_err(attr.span(), - "attribute must only have one argument"); + "attribute must have either one or two arguments"); return } - let attr = &list[0]; - let trait_name = match attr.name() { + let trait_attr = &list[0]; + let attributes_attr = list.get(1); + let trait_name = match trait_attr.name() { Some(name) => name, _ => { - self.handler.span_err(attr.span(), "not a meta item"); + self.handler.span_err(trait_attr.span(), "not a meta item"); return } }; - if !attr.is_word() { - self.handler.span_err(attr.span(), "must only be one word"); + if !trait_attr.is_word() { + self.handler.span_err(trait_attr.span(), "must only be one word"); } if deriving::is_builtin_trait(&trait_name) { - self.handler.span_err(attr.span(), + self.handler.span_err(trait_attr.span(), "cannot override a built-in #[derive] mode"); } if self.derives.iter().any(|d| d.trait_name == trait_name) { - self.handler.span_err(attr.span(), + self.handler.span_err(trait_attr.span(), "derive mode defined twice in this crate"); } + let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { + if !attr.check_name("attributes") { + self.handler.span_err(attr.span(), "second argument must be `attributes`") + } + attr.meta_item_list().unwrap_or_else(|| { + self.handler.span_err(attr.span(), + "attribute must be of form: \ + `attributes(foo, bar)`"); + &[] + }).into_iter().filter_map(|attr| { + let name = match attr.name() { + Some(name) => name, + _ => { + self.handler.span_err(attr.span(), "not a meta item"); + return None; + }, + }; + + if !attr.is_word() { + self.handler.span_err(attr.span(), "must only be one word"); + return None; + } + + Some(name) + }).collect() + } else { + Vec::new() + }; + if self.in_root { self.derives.push(CustomDerive { span: item.span, trait_name: trait_name, function_name: item.ident, + attrs: proc_attrs, }); } else { let msg = "functions tagged with `#[proc_macro_derive]` must \ @@ -208,8 +241,8 @@ impl<'a> Visitor for CollectCustomDerives<'a> { // // #[plugin_registrar] // fn registrar(registrar: &mut Registry) { -// registrar.register_custom_derive($name_trait1, ::$name1); -// registrar.register_custom_derive($name_trait2, ::$name2); +// registrar.register_custom_derive($name_trait1, ::$name1, &[]); +// registrar.register_custom_derive($name_trait2, ::$name2, &["attribute_name"]); // // ... // } // } @@ -238,14 +271,18 @@ fn mk_registrar(cx: &mut ExtCtxt, let stmts = custom_derives.iter().map(|cd| { let path = cx.path_global(cd.span, vec![cd.function_name]); let trait_name = cx.expr_str(cd.span, cd.trait_name.clone()); - (path, trait_name) - }).map(|(path, trait_name)| { + let attrs = cx.expr_vec_slice( + span, + cd.attrs.iter().map(|s| cx.expr_str(cd.span, s.clone())).collect::>() + ); + (path, trait_name, attrs) + }).map(|(path, trait_name, attrs)| { let registrar = cx.expr_ident(span, registrar); let ufcs_path = cx.path(span, vec![proc_macro, __internal, registry, register_custom_derive]); cx.expr_call(span, cx.expr_path(ufcs_path), - vec![registrar, trait_name, cx.expr_path(path)]) + vec![registrar, trait_name, cx.expr_path(path), attrs]) }).map(|expr| { cx.stmt_expr(expr) }).collect::>(); diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute.rs b/src/test/compile-fail-fulldeps/proc-macro/attribute.rs index d1b2aa330ed5a..e22339694f9b0 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attribute.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attribute.rs @@ -33,8 +33,8 @@ pub fn foo3(input: proc_macro::TokenStream) -> proc_macro::TokenStream { input } -#[proc_macro_derive(b, c)] -//~^ ERROR: attribute must only have one argument +#[proc_macro_derive(b, c, d)] +//~^ ERROR: attribute must have either one or two arguments pub fn foo4(input: proc_macro::TokenStream) -> proc_macro::TokenStream { input } @@ -44,3 +44,21 @@ pub fn foo4(input: proc_macro::TokenStream) -> proc_macro::TokenStream { pub fn foo5(input: proc_macro::TokenStream) -> proc_macro::TokenStream { input } + +#[proc_macro_derive(f, attributes(g = "h"))] +//~^ ERROR: must only be one word +pub fn foo6(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} + +#[proc_macro_derive(i, attributes(j(k)))] +//~^ ERROR: must only be one word +pub fn foo7(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} + +#[proc_macro_derive(l, attributes(m), n)] +//~^ ERROR: attribute must have either one or two arguments +pub fn foo8(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs new file mode 100644 index 0000000000000..70b778b1030e7 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs @@ -0,0 +1,25 @@ +// Copyright 2016 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. + +// force-host +// no-prefer-dynamic + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(B, attributes(B))] +pub fn derive_b(input: TokenStream) -> TokenStream { + "".parse().unwrap() +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs b/src/test/compile-fail-fulldeps/proc-macro/item-error.rs new file mode 100644 index 0000000000000..2a68accf91f71 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/item-error.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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. + +// aux-build:derive-b.rs + +#![feature(proc_macro)] +#![allow(warnings)] + +#[macro_use] +extern crate derive_b; + +#[derive(B)] +struct A { + a: &u64 +//~^ ERROR: missing lifetime specifier +} + +fn main() { +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs new file mode 100644 index 0000000000000..651a277d4abd5 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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. + +// aux-build:derive-b.rs + +#![feature(proc_macro)] +#![allow(warnings)] + +#[macro_use] +extern crate derive_b; + +#[derive(B)] +#[B] +#[C] //~ ERROR: The attribute `C` is currently unknown to the compiler +#[B(D)] +#[B(E = "foo")] +struct B; + +fn main() {} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs index 99586b0bb493a..1d34049db249f 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs @@ -21,13 +21,12 @@ use proc_macro::TokenStream; #[proc_macro_derive(AddImpl)] // #[cfg(proc_macro)] pub fn derive(input: TokenStream) -> TokenStream { - (input.to_string() + " - impl B { + "impl B { fn foo(&self) {} } fn foo() {} mod bar { pub fn foo() {} } - ").parse().unwrap() + ".parse().unwrap() } diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs index 27c3d643ca4ff..7260bc4a5e7bb 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs @@ -21,11 +21,8 @@ use proc_macro::TokenStream; #[proc_macro_derive(Append)] pub fn derive_a(input: TokenStream) -> TokenStream { - let mut input = input.to_string(); - input.push_str(" - impl Append for A { - fn foo(&self) {} - } - "); - input.parse().unwrap() + "impl Append for A { + fn foo(&self) {} + } + ".parse().unwrap() } diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs index c2de173568b48..eaada5542274c 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs @@ -23,5 +23,5 @@ pub fn derive(input: TokenStream) -> TokenStream { let input = input.to_string(); assert!(input.contains("struct A;")); assert!(input.contains("#[derive(Debug, PartialEq, Eq, Copy, Clone)]")); - "#[derive(Debug, PartialEq, Eq, Copy, Clone)] struct A;".parse().unwrap() + "".parse().unwrap() } diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs new file mode 100644 index 0000000000000..a02b798c8023e --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs @@ -0,0 +1,29 @@ +// Copyright 2016 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. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] +#![feature(proc_macro_lib)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(B, attributes(B, C))] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert!(input.contains("#[B]")); + assert!(input.contains("struct B {")); + assert!(input.contains("#[C]")); + assert!(input.contains("#[derive(Debug, PartialEq, Eq, Copy, Clone)]")); + "".parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs index bd283ca57ebd9..bc8a0d575913b 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs @@ -21,7 +21,7 @@ use proc_macro::TokenStream; #[proc_macro_derive(AToB)] pub fn derive1(input: TokenStream) -> TokenStream { println!("input1: {:?}", input.to_string()); - assert_eq!(input.to_string(), "#[derive(BToC)]\nstruct A;\n"); + assert_eq!(input.to_string(), "struct A;\n"); "#[derive(BToC)] struct B;".parse().unwrap() } diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs index 155b125690cc1..50eaf035962f1 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs @@ -24,8 +24,6 @@ pub fn derive(input: TokenStream) -> TokenStream { let input = input.to_string(); assert!(input.contains("struct A;")); r#" - struct A; - impl A { fn a(&self) { panic!("hello"); diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs new file mode 100644 index 0000000000000..f5bb93f012490 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs @@ -0,0 +1,32 @@ +// Copyright 2016 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. + +// aux-build:derive-b.rs +// ignore-stage1 + +#![feature(proc_macro)] + +#[macro_use] +extern crate derive_b; + +#[derive(Debug, PartialEq, B, Eq, Copy, Clone)] +#[B] +struct B { + #[C] + a: u64 +} + +fn main() { + B { a: 3 }; + assert_eq!(B { a: 3 }, B { a: 3 }); + let b = B { a: 3 }; + let _d = b; + let _e = b; +} diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs index b3edc8f1c310d..608f86bca5768 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs @@ -15,7 +15,7 @@ #[macro_use] extern crate derive_same_struct; -#[derive(AToB, BToC)] +#[derive(AToB)] struct A; fn main() { From 134ef4f7933b87efdc04eac3e8d9a530d56d9cfe Mon Sep 17 00:00:00 2001 From: Josh Driver Date: Tue, 8 Nov 2016 23:03:33 +1030 Subject: [PATCH 13/24] Revert "Point macros 1.1 errors to the input item" This reverts commit 3784067edcbcd0614f6c4c88f6445ca17ae27ff6. Any errors in the derived output now point at the derive attribute instead of the item. --- src/libsyntax_ext/deriving/custom.rs | 20 +++---------------- .../proc-macro/expand-to-unstable-2.rs | 2 +- .../proc-macro/expand-to-unstable.rs | 2 +- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 2b80deded0aa8..3305c1eae2b00 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -14,12 +14,10 @@ use errors::FatalError; use proc_macro::{TokenStream, __internal}; use syntax::ast::{self, ItemKind, Attribute}; use syntax::attr::{mark_used, mark_known}; -use syntax::codemap::{ExpnInfo, MacroAttribute, NameAndSpan, Span}; +use syntax::codemap::Span; use syntax::ext::base::*; use syntax::fold::Folder; use syntax::parse::token::InternedString; -use syntax::parse::token::intern; -use syntax::print::pprust; use syntax::visit::Visitor; struct MarkAttrs<'a>(&'a [InternedString]); @@ -50,7 +48,7 @@ impl MultiItemModifier for CustomDerive { fn expand(&self, ecx: &mut ExtCtxt, span: Span, - meta_item: &ast::MetaItem, + _meta_item: &ast::MetaItem, item: Annotatable) -> Vec { let item = match item { @@ -75,18 +73,6 @@ impl MultiItemModifier for CustomDerive { // Mark attributes as known, and used. MarkAttrs(&self.attrs).visit_item(&item); - let input_span = Span { - expn_id: ecx.codemap().record_expansion(ExpnInfo { - call_site: span, - callee: NameAndSpan { - format: MacroAttribute(intern(&pprust::meta_item_to_string(meta_item))), - span: Some(span), - allow_internal_unstable: true, - }, - }), - ..item.span - }; - let input = __internal::new_token_stream(item.clone()); let res = __internal::set_parse_sess(&ecx.parse_sess, || { let inner = self.inner; @@ -113,7 +99,7 @@ impl MultiItemModifier for CustomDerive { // Reassign spans of all expanded items to the input `item` // for better errors here. res.extend(new_items.into_iter().flat_map(|item| { - ChangeSpan { span: input_span }.fold_item(item) + ChangeSpan { span: span }.fold_item(item) }).map(Annotatable::Item)); res } diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs index 23dcbe03b5fee..4f4ed90f8fca2 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs @@ -17,8 +17,8 @@ extern crate derive_unstable_2; #[derive(Unstable)] -struct A; //~^ ERROR: reserved for internal compiler +struct A; fn main() { foo(); diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs index fb86f6f1b6574..84ac776a765a2 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs @@ -17,8 +17,8 @@ extern crate derive_unstable; #[derive(Unstable)] -struct A; //~^ ERROR: use of unstable library feature +struct A; fn main() { unsafe { foo(); } From c2a1c7f44f1d922812f5e91347f478ad79004b3c Mon Sep 17 00:00:00 2001 From: abhijeetbhagat Date: Mon, 1 Aug 2016 13:11:53 +0530 Subject: [PATCH 14/24] Change description of no-stack-check (#34915) --- src/librustc/session/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 63eabd5212fd0..fd63f7398d202 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -793,7 +793,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, remark: Passes = (SomePasses(Vec::new()), parse_passes, [UNTRACKED], "print remarks for these optimization passes (space separated, or \"all\")"), no_stack_check: bool = (false, parse_bool, [UNTRACKED], - "disable checks for stack exhaustion (a memory-safety hazard!)"), + "the --no-stack-check flag is deprecated and does nothing"), debuginfo: Option = (None, parse_opt_uint, [TRACKED], "debug info emission level, 0 = no debug info, 1 = line tables only, \ 2 = full debug info with variable and type information"), @@ -2444,4 +2444,4 @@ mod tests { opts.debugging_opts.mir_opt_level = Some(1); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } -} +} \ No newline at end of file From c670293630611cdf677cfc5bc9a17ba378f78b84 Mon Sep 17 00:00:00 2001 From: karpinski Date: Mon, 7 Nov 2016 18:38:47 +0100 Subject: [PATCH 15/24] Adding a deprecation warning for no-stack-check codegen option. --- src/librustc/session/config.rs | 2 +- src/librustc_driver/lib.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index fd63f7398d202..16522a73f56a5 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -2444,4 +2444,4 @@ mod tests { opts.debugging_opts.mir_opt_level = Some(1); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } -} \ No newline at end of file +} diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index cb78baa12a6ad..2699682fb3023 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -75,7 +75,7 @@ use rustc::dep_graph::DepGraph; use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType}; use rustc::session::config::nightly_options; -use rustc::session::early_error; +use rustc::session::{early_error, early_warn}; use rustc::lint::Lint; use rustc::lint; use rustc_metadata::locator; @@ -1011,6 +1011,11 @@ pub fn handle_options(args: &[String]) -> Option { return None; } + if cg_flags.iter().any(|x| *x == "no-stack-check") { + early_warn(ErrorOutputType::default(), + "the --no-stack-check flag is deprecated and does nothing"); + } + if cg_flags.contains(&"passes=list".to_string()) { unsafe { ::llvm::LLVMRustPrintPasses(); From 319f46fba306f9e3dbe09e48044f941e74406ed6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 1 Nov 2016 14:58:36 -0700 Subject: [PATCH 16/24] rustbuild: Vendor all dependencies This commit vendors all dependencies when using rustbuild to ensure that we don't hit the network during a build and can build as a self-contained unit. --- src/vendor/cmake/.cargo-checksum.json | 1 + src/vendor/cmake/.cargo-ok | 0 src/vendor/cmake/.gitignore | 2 + src/vendor/cmake/.travis.yml | 19 + src/vendor/cmake/Cargo.toml | 17 + src/vendor/cmake/LICENSE-APACHE | 201 + src/vendor/cmake/LICENSE-MIT | 25 + src/vendor/cmake/README.md | 22 + src/vendor/cmake/src/lib.rs | 522 +++ src/vendor/cmake/src/registry.rs | 84 + src/vendor/env_logger/.cargo-checksum.json | 1 + src/vendor/env_logger/.cargo-ok | 0 src/vendor/env_logger/Cargo.toml | 23 + src/vendor/env_logger/src/lib.rs | 623 +++ src/vendor/env_logger/src/regex.rs | 28 + src/vendor/env_logger/src/string.rs | 21 + src/vendor/env_logger/tests/regexp_filter.rs | 51 + src/vendor/filetime/.cargo-checksum.json | 1 + src/vendor/filetime/.cargo-ok | 0 src/vendor/filetime/.gitignore | 2 + src/vendor/filetime/.travis.yml | 26 + src/vendor/filetime/Cargo.toml | 19 + src/vendor/filetime/LICENSE-APACHE | 201 + src/vendor/filetime/LICENSE-MIT | 25 + src/vendor/filetime/README.md | 25 + src/vendor/filetime/appveyor.yml | 17 + src/vendor/filetime/src/lib.rs | 305 ++ src/vendor/gcc/.cargo-checksum.json | 1 + src/vendor/gcc/.cargo-ok | 0 src/vendor/gcc/.gitignore | 2 + src/vendor/gcc/.travis.yml | 40 + src/vendor/gcc/Cargo.toml | 23 + src/vendor/gcc/LICENSE-APACHE | 201 + src/vendor/gcc/LICENSE-MIT | 25 + src/vendor/gcc/README.md | 161 + src/vendor/gcc/appveyor.yml | 35 + src/vendor/gcc/src/bin/gcc-shim.rs | 23 + src/vendor/gcc/src/lib.rs | 959 ++++ src/vendor/gcc/src/registry.rs | 169 + src/vendor/gcc/src/windows_registry.rs | 425 ++ src/vendor/gcc/tests/cc_env.rs | 49 + src/vendor/gcc/tests/support/mod.rs | 111 + src/vendor/gcc/tests/test.rs | 207 + src/vendor/getopts/.cargo-checksum.json | 1 + src/vendor/getopts/.cargo-ok | 0 src/vendor/getopts/.gitignore | 2 + src/vendor/getopts/.travis.yml | 20 + src/vendor/getopts/Cargo.toml | 16 + src/vendor/getopts/LICENSE-APACHE | 201 + src/vendor/getopts/LICENSE-MIT | 25 + src/vendor/getopts/README.md | 23 + src/vendor/getopts/appveyor.yml | 17 + src/vendor/getopts/src/lib.rs | 1831 ++++++++ src/vendor/getopts/tests/smoke.rs | 8 + src/vendor/libc/.cargo-checksum.json | 1 + src/vendor/libc/.cargo-ok | 0 src/vendor/libc/.gitignore | 3 + src/vendor/libc/.travis.yml | 125 + src/vendor/libc/Cargo.toml | 21 + src/vendor/libc/LICENSE-APACHE | 201 + src/vendor/libc/LICENSE-MIT | 25 + src/vendor/libc/README.md | 137 + src/vendor/libc/appveyor.yml | 25 + src/vendor/libc/ci/README.md | 203 + .../aarch64-unknown-linux-gnu/Dockerfile | 7 + .../docker/arm-linux-androideabi/Dockerfile | 4 + .../arm-unknown-linux-gnueabihf/Dockerfile | 7 + .../docker/i686-unknown-linux-gnu/Dockerfile | 5 + .../docker/i686-unknown-linux-musl/Dockerfile | 22 + .../docker/mips-unknown-linux-gnu/Dockerfile | 10 + .../docker/mips-unknown-linux-musl/Dockerfile | 14 + .../mips64-unknown-linux-gnuabi64/Dockerfile | 11 + .../mipsel-unknown-linux-musl/Dockerfile | 14 + .../powerpc-unknown-linux-gnu/Dockerfile | 10 + .../powerpc64-unknown-linux-gnu/Dockerfile | 11 + .../docker/x86_64-rumprun-netbsd/Dockerfile | 6 + .../docker/x86_64-unknown-freebsd/Dockerfile | 13 + .../x86_64-unknown-linux-gnu/Dockerfile | 5 + .../x86_64-unknown-linux-musl/Dockerfile | 13 + .../docker/x86_64-unknown-openbsd/Dockerfile | 8 + src/vendor/libc/ci/dox.sh | 33 + src/vendor/libc/ci/landing-page-footer.html | 3 + src/vendor/libc/ci/landing-page-head.html | 7 + src/vendor/libc/ci/run-docker.sh | 26 + src/vendor/libc/ci/run-qemu.sh | 32 + src/vendor/libc/ci/run.sh | 160 + src/vendor/libc/ci/style.rs | 204 + src/vendor/libc/src/dox.rs | 134 + src/vendor/libc/src/lib.rs | 274 ++ src/vendor/libc/src/macros.rs | 108 + src/vendor/libc/src/unix/bsd/apple/b32.rs | 19 + src/vendor/libc/src/unix/bsd/apple/b64.rs | 19 + src/vendor/libc/src/unix/bsd/apple/mod.rs | 1500 +++++++ .../src/unix/bsd/freebsdlike/dragonfly/mod.rs | 303 ++ .../src/unix/bsd/freebsdlike/freebsd/mod.rs | 306 ++ .../src/unix/bsd/freebsdlike/freebsd/x86.rs | 31 + .../unix/bsd/freebsdlike/freebsd/x86_64.rs | 30 + .../libc/src/unix/bsd/freebsdlike/mod.rs | 879 ++++ src/vendor/libc/src/unix/bsd/mod.rs | 368 ++ .../libc/src/unix/bsd/netbsdlike/mod.rs | 547 +++ .../src/unix/bsd/netbsdlike/netbsd/mod.rs | 618 +++ .../bsd/netbsdlike/netbsd/other/b32/mod.rs | 2 + .../bsd/netbsdlike/netbsd/other/b64/mod.rs | 2 + .../unix/bsd/netbsdlike/netbsd/other/mod.rs | 13 + .../unix/bsd/netbsdlike/openbsdlike/bitrig.rs | 75 + .../unix/bsd/netbsdlike/openbsdlike/mod.rs | 448 ++ .../bsd/netbsdlike/openbsdlike/openbsd.rs | 28 + src/vendor/libc/src/unix/haiku/b32.rs | 2 + src/vendor/libc/src/unix/haiku/b64.rs | 2 + src/vendor/libc/src/unix/haiku/mod.rs | 748 ++++ src/vendor/libc/src/unix/mod.rs | 862 ++++ .../libc/src/unix/notbsd/android/b32.rs | 151 + .../libc/src/unix/notbsd/android/b64.rs | 161 + .../libc/src/unix/notbsd/android/mod.rs | 779 ++++ src/vendor/libc/src/unix/notbsd/linux/mips.rs | 651 +++ .../libc/src/unix/notbsd/linux/mips64.rs | 240 + src/vendor/libc/src/unix/notbsd/linux/mod.rs | 747 ++++ .../src/unix/notbsd/linux/musl/b32/arm.rs | 336 ++ .../src/unix/notbsd/linux/musl/b32/asmjs.rs | 335 ++ .../src/unix/notbsd/linux/musl/b32/mips.rs | 344 ++ .../src/unix/notbsd/linux/musl/b32/mod.rs | 50 + .../src/unix/notbsd/linux/musl/b32/x86.rs | 350 ++ .../src/unix/notbsd/linux/musl/b64/aarch64.rs | 3 + .../src/unix/notbsd/linux/musl/b64/mod.rs | 370 ++ .../unix/notbsd/linux/musl/b64/powerpc64.rs | 3 + .../src/unix/notbsd/linux/musl/b64/x86_64.rs | 20 + .../libc/src/unix/notbsd/linux/musl/mod.rs | 245 + .../src/unix/notbsd/linux/other/b32/arm.rs | 168 + .../src/unix/notbsd/linux/other/b32/mod.rs | 89 + .../unix/notbsd/linux/other/b32/powerpc.rs | 165 + .../src/unix/notbsd/linux/other/b32/x86.rs | 213 + .../unix/notbsd/linux/other/b64/aarch64.rs | 178 + .../src/unix/notbsd/linux/other/b64/mod.rs | 65 + .../unix/notbsd/linux/other/b64/powerpc64.rs | 176 + .../src/unix/notbsd/linux/other/b64/x86_64.rs | 246 + .../libc/src/unix/notbsd/linux/other/mod.rs | 620 +++ .../libc/src/unix/notbsd/linux/s390x.rs | 679 +++ src/vendor/libc/src/unix/notbsd/mod.rs | 867 ++++ src/vendor/libc/src/unix/solaris/mod.rs | 1047 +++++ src/vendor/libc/src/windows.rs | 234 + src/vendor/log/.cargo-checksum.json | 1 + src/vendor/log/.cargo-ok | 0 src/vendor/log/.gitignore | 2 + src/vendor/log/.travis.yml | 31 + src/vendor/log/Cargo.toml | 36 + src/vendor/log/LICENSE-APACHE | 201 + src/vendor/log/LICENSE-MIT | 25 + src/vendor/log/README.md | 160 + src/vendor/log/appveyor.yml | 18 + src/vendor/log/src/lib.rs | 1013 +++++ src/vendor/log/src/macros.rs | 155 + src/vendor/log/tests/filters.rs | 76 + src/vendor/md5/.cargo-checksum.json | 1 + src/vendor/md5/.cargo-ok | 0 src/vendor/md5/.gitignore | 2 + src/vendor/md5/.travis.yml | 11 + src/vendor/md5/Cargo.toml | 9 + src/vendor/md5/LICENSE.txt | 21 + src/vendor/md5/README.md | 19 + src/vendor/md5/benches/lib.rs | 16 + src/vendor/md5/src/lib.rs | 340 ++ src/vendor/num_cpus/.cargo-checksum.json | 1 + src/vendor/num_cpus/.cargo-ok | 0 src/vendor/num_cpus/.gitignore | 2 + src/vendor/num_cpus/Cargo.toml | 12 + src/vendor/num_cpus/LICENSE-APACHE | 201 + src/vendor/num_cpus/LICENSE-MIT | 20 + src/vendor/num_cpus/README.md | 36 + src/vendor/num_cpus/src/lib.rs | 116 + .../rustc-serialize/.cargo-checksum.json | 1 + src/vendor/rustc-serialize/.cargo-ok | 0 src/vendor/rustc-serialize/.gitignore | 2 + src/vendor/rustc-serialize/.travis.yml | 26 + src/vendor/rustc-serialize/Cargo.toml | 18 + src/vendor/rustc-serialize/LICENSE-APACHE | 201 + src/vendor/rustc-serialize/LICENSE-MIT | 25 + src/vendor/rustc-serialize/README.md | 24 + src/vendor/rustc-serialize/appveyor.yml | 17 + src/vendor/rustc-serialize/benches/base64.rs | 48 + src/vendor/rustc-serialize/benches/hex.rs | 28 + src/vendor/rustc-serialize/benches/json.rs | 84 + src/vendor/rustc-serialize/src/base64.rs | 476 ++ .../rustc-serialize/src/collection_impls.rs | 186 + src/vendor/rustc-serialize/src/hex.rs | 209 + src/vendor/rustc-serialize/src/json.rs | 3955 +++++++++++++++++ src/vendor/rustc-serialize/src/lib.rs | 69 + src/vendor/rustc-serialize/src/serialize.rs | 843 ++++ src/vendor/toml/.cargo-checksum.json | 1 + src/vendor/toml/.cargo-ok | 0 src/vendor/toml/.gitignore | 2 + src/vendor/toml/.travis.yml | 31 + src/vendor/toml/Cargo.toml | 26 + src/vendor/toml/LICENSE-APACHE | 201 + src/vendor/toml/LICENSE-MIT | 25 + src/vendor/toml/README.md | 26 + src/vendor/toml/examples/toml2json.rs | 57 + src/vendor/toml/src/decoder/mod.rs | 235 + .../toml/src/decoder/rustc_serialize.rs | 371 ++ src/vendor/toml/src/decoder/serde.rs | 544 +++ src/vendor/toml/src/display.rs | 201 + src/vendor/toml/src/encoder/mod.rs | 214 + .../toml/src/encoder/rustc_serialize.rs | 716 +++ src/vendor/toml/src/encoder/serde.rs | 108 + src/vendor/toml/src/lib.rs | 492 ++ src/vendor/toml/src/parser.rs | 1581 +++++++ src/vendor/toml/tests/README.md | 1 + .../array-mixed-types-ints-and-floats.json | 15 + src/vendor/toml/tests/invalid.rs | 108 + .../array-mixed-types-arrays-and-ints.toml | 1 + .../array-mixed-types-ints-and-floats.toml | 1 + .../array-mixed-types-strings-and-ints.toml | 1 + .../invalid/datetime-malformed-no-leads.toml | 1 + .../invalid/datetime-malformed-no-secs.toml | 1 + .../invalid/datetime-malformed-no-t.toml | 1 + .../invalid/datetime-malformed-no-z.toml | 1 + .../datetime-malformed-with-milli.toml | 1 + .../tests/invalid/duplicate-key-table.toml | 5 + .../toml/tests/invalid/duplicate-keys.toml | 2 + .../toml/tests/invalid/duplicate-tables.toml | 2 + .../tests/invalid/empty-implicit-table.toml | 1 + .../toml/tests/invalid/empty-table.toml | 1 + .../tests/invalid/float-no-leading-zero.toml | 2 + .../invalid/float-no-trailing-digits.toml | 2 + .../toml/tests/invalid/key-after-array.toml | 1 + .../toml/tests/invalid/key-after-table.toml | 1 + src/vendor/toml/tests/invalid/key-empty.toml | 1 + src/vendor/toml/tests/invalid/key-hash.toml | 1 + .../toml/tests/invalid/key-newline.toml | 2 + .../toml/tests/invalid/key-open-bracket.toml | 1 + .../invalid/key-single-open-bracket.toml | 1 + src/vendor/toml/tests/invalid/key-space.toml | 1 + .../toml/tests/invalid/key-start-bracket.toml | 3 + .../toml/tests/invalid/key-two-equals.toml | 1 + .../tests/invalid/string-bad-byte-escape.toml | 1 + .../toml/tests/invalid/string-bad-escape.toml | 1 + .../tests/invalid/string-byte-escapes.toml | 1 + .../toml/tests/invalid/string-no-close.toml | 1 + .../tests/invalid/table-array-implicit.toml | 14 + .../table-array-malformed-bracket.toml | 2 + .../invalid/table-array-malformed-empty.toml | 2 + .../toml/tests/invalid/table-empty.toml | 1 + .../invalid/table-nested-brackets-close.toml | 2 + .../invalid/table-nested-brackets-open.toml | 2 + .../toml/tests/invalid/table-whitespace.toml | 1 + .../toml/tests/invalid/table-with-pound.toml | 2 + .../invalid/text-after-array-entries.toml | 4 + .../tests/invalid/text-after-integer.toml | 1 + .../toml/tests/invalid/text-after-string.toml | 1 + .../toml/tests/invalid/text-after-table.toml | 1 + .../invalid/text-before-array-separator.toml | 4 + .../toml/tests/invalid/text-in-array.toml | 5 + src/vendor/toml/tests/valid.rs | 195 + src/vendor/toml/tests/valid/array-empty.json | 11 + src/vendor/toml/tests/valid/array-empty.toml | 1 + .../toml/tests/valid/array-nospaces.json | 10 + .../toml/tests/valid/array-nospaces.toml | 1 + .../toml/tests/valid/arrays-hetergeneous.json | 19 + .../toml/tests/valid/arrays-hetergeneous.toml | 1 + .../toml/tests/valid/arrays-nested.json | 13 + .../toml/tests/valid/arrays-nested.toml | 1 + src/vendor/toml/tests/valid/arrays.json | 34 + src/vendor/toml/tests/valid/arrays.toml | 8 + src/vendor/toml/tests/valid/bool.json | 4 + src/vendor/toml/tests/valid/bool.toml | 2 + .../toml/tests/valid/comments-everywhere.json | 12 + .../toml/tests/valid/comments-everywhere.toml | 24 + src/vendor/toml/tests/valid/datetime.json | 3 + src/vendor/toml/tests/valid/datetime.toml | 1 + src/vendor/toml/tests/valid/empty.json | 1 + src/vendor/toml/tests/valid/empty.toml | 0 src/vendor/toml/tests/valid/example-bom.toml | 5 + .../toml/tests/valid/example-v0.3.0.json | 1 + .../toml/tests/valid/example-v0.3.0.toml | 182 + .../toml/tests/valid/example-v0.4.0.json | 1 + .../toml/tests/valid/example-v0.4.0.toml | 235 + src/vendor/toml/tests/valid/example.json | 14 + src/vendor/toml/tests/valid/example.toml | 5 + src/vendor/toml/tests/valid/example2.json | 1 + src/vendor/toml/tests/valid/example2.toml | 47 + src/vendor/toml/tests/valid/float.json | 4 + src/vendor/toml/tests/valid/float.toml | 2 + src/vendor/toml/tests/valid/hard_example.json | 1 + src/vendor/toml/tests/valid/hard_example.toml | 33 + .../valid/implicit-and-explicit-after.json | 10 + .../valid/implicit-and-explicit-after.toml | 5 + .../valid/implicit-and-explicit-before.json | 10 + .../valid/implicit-and-explicit-before.toml | 5 + .../toml/tests/valid/implicit-groups.json | 9 + .../toml/tests/valid/implicit-groups.toml | 2 + src/vendor/toml/tests/valid/integer.json | 4 + src/vendor/toml/tests/valid/integer.toml | 2 + .../toml/tests/valid/key-equals-nospace.json | 3 + .../toml/tests/valid/key-equals-nospace.toml | 1 + src/vendor/toml/tests/valid/key-space.json | 3 + src/vendor/toml/tests/valid/key-space.toml | 1 + .../toml/tests/valid/key-special-chars.json | 5 + .../toml/tests/valid/key-special-chars.toml | 1 + .../toml/tests/valid/key-with-pound.json | 3 + .../toml/tests/valid/key-with-pound.toml | 1 + src/vendor/toml/tests/valid/long-float.json | 4 + src/vendor/toml/tests/valid/long-float.toml | 2 + src/vendor/toml/tests/valid/long-integer.json | 4 + src/vendor/toml/tests/valid/long-integer.toml | 2 + .../toml/tests/valid/multiline-string.json | 30 + .../toml/tests/valid/multiline-string.toml | 23 + .../tests/valid/raw-multiline-string.json | 14 + .../tests/valid/raw-multiline-string.toml | 9 + src/vendor/toml/tests/valid/raw-string.json | 30 + src/vendor/toml/tests/valid/raw-string.toml | 7 + src/vendor/toml/tests/valid/string-empty.json | 6 + src/vendor/toml/tests/valid/string-empty.toml | 1 + .../toml/tests/valid/string-escapes.json | 50 + .../toml/tests/valid/string-escapes.toml | 12 + .../toml/tests/valid/string-simple.json | 6 + .../toml/tests/valid/string-simple.toml | 1 + .../toml/tests/valid/string-with-pound.json | 7 + .../toml/tests/valid/string-with-pound.toml | 2 + .../tests/valid/table-array-implicit.json | 7 + .../tests/valid/table-array-implicit.toml | 2 + .../toml/tests/valid/table-array-many.json | 16 + .../toml/tests/valid/table-array-many.toml | 11 + .../toml/tests/valid/table-array-nest.json | 18 + .../toml/tests/valid/table-array-nest.toml | 17 + .../toml/tests/valid/table-array-one.json | 8 + .../toml/tests/valid/table-array-one.toml | 3 + src/vendor/toml/tests/valid/table-empty.json | 3 + src/vendor/toml/tests/valid/table-empty.toml | 1 + .../toml/tests/valid/table-sub-empty.json | 3 + .../toml/tests/valid/table-sub-empty.toml | 2 + .../toml/tests/valid/table-whitespace.json | 3 + .../toml/tests/valid/table-whitespace.toml | 1 + .../toml/tests/valid/table-with-pound.json | 5 + .../toml/tests/valid/table-with-pound.toml | 2 + .../toml/tests/valid/unicode-escape.json | 4 + .../toml/tests/valid/unicode-escape.toml | 2 + .../toml/tests/valid/unicode-literal.json | 3 + .../toml/tests/valid/unicode-literal.toml | 1 + 337 files changed, 40085 insertions(+) create mode 100644 src/vendor/cmake/.cargo-checksum.json create mode 100644 src/vendor/cmake/.cargo-ok create mode 100644 src/vendor/cmake/.gitignore create mode 100644 src/vendor/cmake/.travis.yml create mode 100644 src/vendor/cmake/Cargo.toml create mode 100644 src/vendor/cmake/LICENSE-APACHE create mode 100644 src/vendor/cmake/LICENSE-MIT create mode 100644 src/vendor/cmake/README.md create mode 100644 src/vendor/cmake/src/lib.rs create mode 100644 src/vendor/cmake/src/registry.rs create mode 100644 src/vendor/env_logger/.cargo-checksum.json create mode 100644 src/vendor/env_logger/.cargo-ok create mode 100644 src/vendor/env_logger/Cargo.toml create mode 100644 src/vendor/env_logger/src/lib.rs create mode 100644 src/vendor/env_logger/src/regex.rs create mode 100644 src/vendor/env_logger/src/string.rs create mode 100644 src/vendor/env_logger/tests/regexp_filter.rs create mode 100644 src/vendor/filetime/.cargo-checksum.json create mode 100644 src/vendor/filetime/.cargo-ok create mode 100644 src/vendor/filetime/.gitignore create mode 100644 src/vendor/filetime/.travis.yml create mode 100644 src/vendor/filetime/Cargo.toml create mode 100644 src/vendor/filetime/LICENSE-APACHE create mode 100644 src/vendor/filetime/LICENSE-MIT create mode 100644 src/vendor/filetime/README.md create mode 100644 src/vendor/filetime/appveyor.yml create mode 100644 src/vendor/filetime/src/lib.rs create mode 100644 src/vendor/gcc/.cargo-checksum.json create mode 100644 src/vendor/gcc/.cargo-ok create mode 100644 src/vendor/gcc/.gitignore create mode 100644 src/vendor/gcc/.travis.yml create mode 100644 src/vendor/gcc/Cargo.toml create mode 100644 src/vendor/gcc/LICENSE-APACHE create mode 100644 src/vendor/gcc/LICENSE-MIT create mode 100644 src/vendor/gcc/README.md create mode 100644 src/vendor/gcc/appveyor.yml create mode 100644 src/vendor/gcc/src/bin/gcc-shim.rs create mode 100644 src/vendor/gcc/src/lib.rs create mode 100644 src/vendor/gcc/src/registry.rs create mode 100644 src/vendor/gcc/src/windows_registry.rs create mode 100644 src/vendor/gcc/tests/cc_env.rs create mode 100644 src/vendor/gcc/tests/support/mod.rs create mode 100644 src/vendor/gcc/tests/test.rs create mode 100644 src/vendor/getopts/.cargo-checksum.json create mode 100644 src/vendor/getopts/.cargo-ok create mode 100644 src/vendor/getopts/.gitignore create mode 100644 src/vendor/getopts/.travis.yml create mode 100644 src/vendor/getopts/Cargo.toml create mode 100644 src/vendor/getopts/LICENSE-APACHE create mode 100644 src/vendor/getopts/LICENSE-MIT create mode 100644 src/vendor/getopts/README.md create mode 100644 src/vendor/getopts/appveyor.yml create mode 100644 src/vendor/getopts/src/lib.rs create mode 100644 src/vendor/getopts/tests/smoke.rs create mode 100644 src/vendor/libc/.cargo-checksum.json create mode 100644 src/vendor/libc/.cargo-ok create mode 100644 src/vendor/libc/.gitignore create mode 100644 src/vendor/libc/.travis.yml create mode 100644 src/vendor/libc/Cargo.toml create mode 100644 src/vendor/libc/LICENSE-APACHE create mode 100644 src/vendor/libc/LICENSE-MIT create mode 100644 src/vendor/libc/README.md create mode 100644 src/vendor/libc/appveyor.yml create mode 100644 src/vendor/libc/ci/README.md create mode 100644 src/vendor/libc/ci/docker/aarch64-unknown-linux-gnu/Dockerfile create mode 100644 src/vendor/libc/ci/docker/arm-linux-androideabi/Dockerfile create mode 100644 src/vendor/libc/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile create mode 100644 src/vendor/libc/ci/docker/i686-unknown-linux-gnu/Dockerfile create mode 100644 src/vendor/libc/ci/docker/i686-unknown-linux-musl/Dockerfile create mode 100644 src/vendor/libc/ci/docker/mips-unknown-linux-gnu/Dockerfile create mode 100644 src/vendor/libc/ci/docker/mips-unknown-linux-musl/Dockerfile create mode 100644 src/vendor/libc/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile create mode 100644 src/vendor/libc/ci/docker/mipsel-unknown-linux-musl/Dockerfile create mode 100644 src/vendor/libc/ci/docker/powerpc-unknown-linux-gnu/Dockerfile create mode 100644 src/vendor/libc/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile create mode 100644 src/vendor/libc/ci/docker/x86_64-rumprun-netbsd/Dockerfile create mode 100644 src/vendor/libc/ci/docker/x86_64-unknown-freebsd/Dockerfile create mode 100644 src/vendor/libc/ci/docker/x86_64-unknown-linux-gnu/Dockerfile create mode 100644 src/vendor/libc/ci/docker/x86_64-unknown-linux-musl/Dockerfile create mode 100644 src/vendor/libc/ci/docker/x86_64-unknown-openbsd/Dockerfile create mode 100644 src/vendor/libc/ci/dox.sh create mode 100644 src/vendor/libc/ci/landing-page-footer.html create mode 100644 src/vendor/libc/ci/landing-page-head.html create mode 100644 src/vendor/libc/ci/run-docker.sh create mode 100644 src/vendor/libc/ci/run-qemu.sh create mode 100755 src/vendor/libc/ci/run.sh create mode 100644 src/vendor/libc/ci/style.rs create mode 100644 src/vendor/libc/src/dox.rs create mode 100644 src/vendor/libc/src/lib.rs create mode 100644 src/vendor/libc/src/macros.rs create mode 100644 src/vendor/libc/src/unix/bsd/apple/b32.rs create mode 100644 src/vendor/libc/src/unix/bsd/apple/b64.rs create mode 100644 src/vendor/libc/src/unix/bsd/apple/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs create mode 100644 src/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64.rs create mode 100644 src/vendor/libc/src/unix/bsd/freebsdlike/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/netbsdlike/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/netbsdlike/netbsd/other/b32/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/netbsdlike/netbsd/other/b64/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/netbsdlike/netbsd/other/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/bitrig.rs create mode 100644 src/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/mod.rs create mode 100644 src/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd.rs create mode 100644 src/vendor/libc/src/unix/haiku/b32.rs create mode 100644 src/vendor/libc/src/unix/haiku/b64.rs create mode 100644 src/vendor/libc/src/unix/haiku/mod.rs create mode 100644 src/vendor/libc/src/unix/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/android/b32.rs create mode 100644 src/vendor/libc/src/unix/notbsd/android/b64.rs create mode 100644 src/vendor/libc/src/unix/notbsd/android/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/mips.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/mips64.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b32/arm.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b32/asmjs.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b32/mips.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b32/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b32/x86.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b64/aarch64.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b64/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b64/powerpc64.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/b64/x86_64.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/musl/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/b32/arm.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/b32/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/b32/powerpc.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/b32/x86.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/b64/aarch64.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/b64/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/b64/powerpc64.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/b64/x86_64.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/other/mod.rs create mode 100644 src/vendor/libc/src/unix/notbsd/linux/s390x.rs create mode 100644 src/vendor/libc/src/unix/notbsd/mod.rs create mode 100644 src/vendor/libc/src/unix/solaris/mod.rs create mode 100644 src/vendor/libc/src/windows.rs create mode 100644 src/vendor/log/.cargo-checksum.json create mode 100644 src/vendor/log/.cargo-ok create mode 100644 src/vendor/log/.gitignore create mode 100644 src/vendor/log/.travis.yml create mode 100644 src/vendor/log/Cargo.toml create mode 100644 src/vendor/log/LICENSE-APACHE create mode 100644 src/vendor/log/LICENSE-MIT create mode 100644 src/vendor/log/README.md create mode 100644 src/vendor/log/appveyor.yml create mode 100644 src/vendor/log/src/lib.rs create mode 100644 src/vendor/log/src/macros.rs create mode 100644 src/vendor/log/tests/filters.rs create mode 100644 src/vendor/md5/.cargo-checksum.json create mode 100644 src/vendor/md5/.cargo-ok create mode 100644 src/vendor/md5/.gitignore create mode 100644 src/vendor/md5/.travis.yml create mode 100644 src/vendor/md5/Cargo.toml create mode 100644 src/vendor/md5/LICENSE.txt create mode 100644 src/vendor/md5/README.md create mode 100644 src/vendor/md5/benches/lib.rs create mode 100644 src/vendor/md5/src/lib.rs create mode 100644 src/vendor/num_cpus/.cargo-checksum.json create mode 100644 src/vendor/num_cpus/.cargo-ok create mode 100644 src/vendor/num_cpus/.gitignore create mode 100644 src/vendor/num_cpus/Cargo.toml create mode 100644 src/vendor/num_cpus/LICENSE-APACHE create mode 100644 src/vendor/num_cpus/LICENSE-MIT create mode 100644 src/vendor/num_cpus/README.md create mode 100644 src/vendor/num_cpus/src/lib.rs create mode 100644 src/vendor/rustc-serialize/.cargo-checksum.json create mode 100644 src/vendor/rustc-serialize/.cargo-ok create mode 100644 src/vendor/rustc-serialize/.gitignore create mode 100644 src/vendor/rustc-serialize/.travis.yml create mode 100644 src/vendor/rustc-serialize/Cargo.toml create mode 100644 src/vendor/rustc-serialize/LICENSE-APACHE create mode 100644 src/vendor/rustc-serialize/LICENSE-MIT create mode 100644 src/vendor/rustc-serialize/README.md create mode 100644 src/vendor/rustc-serialize/appveyor.yml create mode 100644 src/vendor/rustc-serialize/benches/base64.rs create mode 100644 src/vendor/rustc-serialize/benches/hex.rs create mode 100644 src/vendor/rustc-serialize/benches/json.rs create mode 100644 src/vendor/rustc-serialize/src/base64.rs create mode 100644 src/vendor/rustc-serialize/src/collection_impls.rs create mode 100644 src/vendor/rustc-serialize/src/hex.rs create mode 100644 src/vendor/rustc-serialize/src/json.rs create mode 100644 src/vendor/rustc-serialize/src/lib.rs create mode 100644 src/vendor/rustc-serialize/src/serialize.rs create mode 100644 src/vendor/toml/.cargo-checksum.json create mode 100644 src/vendor/toml/.cargo-ok create mode 100644 src/vendor/toml/.gitignore create mode 100644 src/vendor/toml/.travis.yml create mode 100644 src/vendor/toml/Cargo.toml create mode 100644 src/vendor/toml/LICENSE-APACHE create mode 100644 src/vendor/toml/LICENSE-MIT create mode 100644 src/vendor/toml/README.md create mode 100644 src/vendor/toml/examples/toml2json.rs create mode 100644 src/vendor/toml/src/decoder/mod.rs create mode 100644 src/vendor/toml/src/decoder/rustc_serialize.rs create mode 100644 src/vendor/toml/src/decoder/serde.rs create mode 100644 src/vendor/toml/src/display.rs create mode 100644 src/vendor/toml/src/encoder/mod.rs create mode 100644 src/vendor/toml/src/encoder/rustc_serialize.rs create mode 100644 src/vendor/toml/src/encoder/serde.rs create mode 100644 src/vendor/toml/src/lib.rs create mode 100644 src/vendor/toml/src/parser.rs create mode 100644 src/vendor/toml/tests/README.md create mode 100644 src/vendor/toml/tests/invalid-encoder/array-mixed-types-ints-and-floats.json create mode 100644 src/vendor/toml/tests/invalid.rs create mode 100644 src/vendor/toml/tests/invalid/array-mixed-types-arrays-and-ints.toml create mode 100644 src/vendor/toml/tests/invalid/array-mixed-types-ints-and-floats.toml create mode 100644 src/vendor/toml/tests/invalid/array-mixed-types-strings-and-ints.toml create mode 100644 src/vendor/toml/tests/invalid/datetime-malformed-no-leads.toml create mode 100644 src/vendor/toml/tests/invalid/datetime-malformed-no-secs.toml create mode 100644 src/vendor/toml/tests/invalid/datetime-malformed-no-t.toml create mode 100644 src/vendor/toml/tests/invalid/datetime-malformed-no-z.toml create mode 100644 src/vendor/toml/tests/invalid/datetime-malformed-with-milli.toml create mode 100644 src/vendor/toml/tests/invalid/duplicate-key-table.toml create mode 100644 src/vendor/toml/tests/invalid/duplicate-keys.toml create mode 100644 src/vendor/toml/tests/invalid/duplicate-tables.toml create mode 100644 src/vendor/toml/tests/invalid/empty-implicit-table.toml create mode 100644 src/vendor/toml/tests/invalid/empty-table.toml create mode 100644 src/vendor/toml/tests/invalid/float-no-leading-zero.toml create mode 100644 src/vendor/toml/tests/invalid/float-no-trailing-digits.toml create mode 100644 src/vendor/toml/tests/invalid/key-after-array.toml create mode 100644 src/vendor/toml/tests/invalid/key-after-table.toml create mode 100644 src/vendor/toml/tests/invalid/key-empty.toml create mode 100644 src/vendor/toml/tests/invalid/key-hash.toml create mode 100644 src/vendor/toml/tests/invalid/key-newline.toml create mode 100644 src/vendor/toml/tests/invalid/key-open-bracket.toml create mode 100644 src/vendor/toml/tests/invalid/key-single-open-bracket.toml create mode 100644 src/vendor/toml/tests/invalid/key-space.toml create mode 100644 src/vendor/toml/tests/invalid/key-start-bracket.toml create mode 100644 src/vendor/toml/tests/invalid/key-two-equals.toml create mode 100644 src/vendor/toml/tests/invalid/string-bad-byte-escape.toml create mode 100644 src/vendor/toml/tests/invalid/string-bad-escape.toml create mode 100644 src/vendor/toml/tests/invalid/string-byte-escapes.toml create mode 100644 src/vendor/toml/tests/invalid/string-no-close.toml create mode 100644 src/vendor/toml/tests/invalid/table-array-implicit.toml create mode 100644 src/vendor/toml/tests/invalid/table-array-malformed-bracket.toml create mode 100644 src/vendor/toml/tests/invalid/table-array-malformed-empty.toml create mode 100644 src/vendor/toml/tests/invalid/table-empty.toml create mode 100644 src/vendor/toml/tests/invalid/table-nested-brackets-close.toml create mode 100644 src/vendor/toml/tests/invalid/table-nested-brackets-open.toml create mode 100644 src/vendor/toml/tests/invalid/table-whitespace.toml create mode 100644 src/vendor/toml/tests/invalid/table-with-pound.toml create mode 100644 src/vendor/toml/tests/invalid/text-after-array-entries.toml create mode 100644 src/vendor/toml/tests/invalid/text-after-integer.toml create mode 100644 src/vendor/toml/tests/invalid/text-after-string.toml create mode 100644 src/vendor/toml/tests/invalid/text-after-table.toml create mode 100644 src/vendor/toml/tests/invalid/text-before-array-separator.toml create mode 100644 src/vendor/toml/tests/invalid/text-in-array.toml create mode 100644 src/vendor/toml/tests/valid.rs create mode 100644 src/vendor/toml/tests/valid/array-empty.json create mode 100644 src/vendor/toml/tests/valid/array-empty.toml create mode 100644 src/vendor/toml/tests/valid/array-nospaces.json create mode 100644 src/vendor/toml/tests/valid/array-nospaces.toml create mode 100644 src/vendor/toml/tests/valid/arrays-hetergeneous.json create mode 100644 src/vendor/toml/tests/valid/arrays-hetergeneous.toml create mode 100644 src/vendor/toml/tests/valid/arrays-nested.json create mode 100644 src/vendor/toml/tests/valid/arrays-nested.toml create mode 100644 src/vendor/toml/tests/valid/arrays.json create mode 100644 src/vendor/toml/tests/valid/arrays.toml create mode 100644 src/vendor/toml/tests/valid/bool.json create mode 100644 src/vendor/toml/tests/valid/bool.toml create mode 100644 src/vendor/toml/tests/valid/comments-everywhere.json create mode 100644 src/vendor/toml/tests/valid/comments-everywhere.toml create mode 100644 src/vendor/toml/tests/valid/datetime.json create mode 100644 src/vendor/toml/tests/valid/datetime.toml create mode 100644 src/vendor/toml/tests/valid/empty.json create mode 100644 src/vendor/toml/tests/valid/empty.toml create mode 100644 src/vendor/toml/tests/valid/example-bom.toml create mode 100644 src/vendor/toml/tests/valid/example-v0.3.0.json create mode 100644 src/vendor/toml/tests/valid/example-v0.3.0.toml create mode 100644 src/vendor/toml/tests/valid/example-v0.4.0.json create mode 100644 src/vendor/toml/tests/valid/example-v0.4.0.toml create mode 100644 src/vendor/toml/tests/valid/example.json create mode 100644 src/vendor/toml/tests/valid/example.toml create mode 100644 src/vendor/toml/tests/valid/example2.json create mode 100644 src/vendor/toml/tests/valid/example2.toml create mode 100644 src/vendor/toml/tests/valid/float.json create mode 100644 src/vendor/toml/tests/valid/float.toml create mode 100644 src/vendor/toml/tests/valid/hard_example.json create mode 100644 src/vendor/toml/tests/valid/hard_example.toml create mode 100644 src/vendor/toml/tests/valid/implicit-and-explicit-after.json create mode 100644 src/vendor/toml/tests/valid/implicit-and-explicit-after.toml create mode 100644 src/vendor/toml/tests/valid/implicit-and-explicit-before.json create mode 100644 src/vendor/toml/tests/valid/implicit-and-explicit-before.toml create mode 100644 src/vendor/toml/tests/valid/implicit-groups.json create mode 100644 src/vendor/toml/tests/valid/implicit-groups.toml create mode 100644 src/vendor/toml/tests/valid/integer.json create mode 100644 src/vendor/toml/tests/valid/integer.toml create mode 100644 src/vendor/toml/tests/valid/key-equals-nospace.json create mode 100644 src/vendor/toml/tests/valid/key-equals-nospace.toml create mode 100644 src/vendor/toml/tests/valid/key-space.json create mode 100644 src/vendor/toml/tests/valid/key-space.toml create mode 100644 src/vendor/toml/tests/valid/key-special-chars.json create mode 100644 src/vendor/toml/tests/valid/key-special-chars.toml create mode 100644 src/vendor/toml/tests/valid/key-with-pound.json create mode 100644 src/vendor/toml/tests/valid/key-with-pound.toml create mode 100644 src/vendor/toml/tests/valid/long-float.json create mode 100644 src/vendor/toml/tests/valid/long-float.toml create mode 100644 src/vendor/toml/tests/valid/long-integer.json create mode 100644 src/vendor/toml/tests/valid/long-integer.toml create mode 100644 src/vendor/toml/tests/valid/multiline-string.json create mode 100644 src/vendor/toml/tests/valid/multiline-string.toml create mode 100644 src/vendor/toml/tests/valid/raw-multiline-string.json create mode 100644 src/vendor/toml/tests/valid/raw-multiline-string.toml create mode 100644 src/vendor/toml/tests/valid/raw-string.json create mode 100644 src/vendor/toml/tests/valid/raw-string.toml create mode 100644 src/vendor/toml/tests/valid/string-empty.json create mode 100644 src/vendor/toml/tests/valid/string-empty.toml create mode 100644 src/vendor/toml/tests/valid/string-escapes.json create mode 100644 src/vendor/toml/tests/valid/string-escapes.toml create mode 100644 src/vendor/toml/tests/valid/string-simple.json create mode 100644 src/vendor/toml/tests/valid/string-simple.toml create mode 100644 src/vendor/toml/tests/valid/string-with-pound.json create mode 100644 src/vendor/toml/tests/valid/string-with-pound.toml create mode 100644 src/vendor/toml/tests/valid/table-array-implicit.json create mode 100644 src/vendor/toml/tests/valid/table-array-implicit.toml create mode 100644 src/vendor/toml/tests/valid/table-array-many.json create mode 100644 src/vendor/toml/tests/valid/table-array-many.toml create mode 100644 src/vendor/toml/tests/valid/table-array-nest.json create mode 100644 src/vendor/toml/tests/valid/table-array-nest.toml create mode 100644 src/vendor/toml/tests/valid/table-array-one.json create mode 100644 src/vendor/toml/tests/valid/table-array-one.toml create mode 100644 src/vendor/toml/tests/valid/table-empty.json create mode 100644 src/vendor/toml/tests/valid/table-empty.toml create mode 100644 src/vendor/toml/tests/valid/table-sub-empty.json create mode 100644 src/vendor/toml/tests/valid/table-sub-empty.toml create mode 100644 src/vendor/toml/tests/valid/table-whitespace.json create mode 100644 src/vendor/toml/tests/valid/table-whitespace.toml create mode 100644 src/vendor/toml/tests/valid/table-with-pound.json create mode 100644 src/vendor/toml/tests/valid/table-with-pound.toml create mode 100644 src/vendor/toml/tests/valid/unicode-escape.json create mode 100644 src/vendor/toml/tests/valid/unicode-escape.toml create mode 100644 src/vendor/toml/tests/valid/unicode-literal.json create mode 100644 src/vendor/toml/tests/valid/unicode-literal.toml diff --git a/src/vendor/cmake/.cargo-checksum.json b/src/vendor/cmake/.cargo-checksum.json new file mode 100644 index 0000000000000..b81d7d2fa04ea --- /dev/null +++ b/src/vendor/cmake/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"5d83ed1ae0b80cd6cebfc6a25b1fdb58c893ead400f0f84cd0ebf08d9ad48b28","Cargo.toml":"2266412ecb4504137a90d378ebdbf3a41f0e8b7188858cfb149da54792f7f8d9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"8ca528d20639506546044c676ff9069e3e850937b02bff4194dcf9e5c3c50d64","src/lib.rs":"dae5d93c005bf8d16427e29eb3bfb50c5527a1ec7c39a383d0694a8e8e38af90","src/registry.rs":"ca16433f51b5e3aedb0560bba41370b0c42de9238926a5118d1c0a3a072b64b2"},"package":"0e5bcf27e097a184c1df4437654ed98df3d7a516e8508a6ba45d8b092bbdf283"} \ No newline at end of file diff --git a/src/vendor/cmake/.cargo-ok b/src/vendor/cmake/.cargo-ok new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/vendor/cmake/.gitignore b/src/vendor/cmake/.gitignore new file mode 100644 index 0000000000000..4fffb2f89cbd8 --- /dev/null +++ b/src/vendor/cmake/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/src/vendor/cmake/.travis.yml b/src/vendor/cmake/.travis.yml new file mode 100644 index 0000000000000..3ac040c5c0949 --- /dev/null +++ b/src/vendor/cmake/.travis.yml @@ -0,0 +1,19 @@ +language: rust +rust: + - stable + - beta + - nightly +sudo: false +before_script: + - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH +script: + - cargo test --verbose + - cargo doc --no-deps +after_success: + - travis-cargo --only nightly doc-upload +env: + global: + secure: WSQJRyheeMf7eRdivHextSEQzyFnTIw2yeemO2+ZkHVftp0XYsTXQVca3RGlQNsVmjI0RP8lbDVe7HG23uwbTMeRgm+9hzSwNMa0ndJZ06TNMpPM6nqcXFUaNGeuf7EqU370xcgVBO+ZA0cSh55pJkOBg5ALd9bfRWbjEAjHkx8= +notifications: + email: + on_success: never diff --git a/src/vendor/cmake/Cargo.toml b/src/vendor/cmake/Cargo.toml new file mode 100644 index 0000000000000..c17bbff922582 --- /dev/null +++ b/src/vendor/cmake/Cargo.toml @@ -0,0 +1,17 @@ +[package] + +name = "cmake" +version = "0.1.18" +authors = ["Alex Crichton "] +license = "MIT/Apache-2.0" +readme = "README.md" +keywords = ["build-dependencies"] +repository = "https://github.com/alexcrichton/cmake-rs" +homepage = "https://github.com/alexcrichton/cmake-rs" +documentation = "http://alexcrichton.com/cmake-rs" +description = """ +A build dependency for running `cmake` to build a native library +""" + +[dependencies] +gcc = "0.3.17" diff --git a/src/vendor/cmake/LICENSE-APACHE b/src/vendor/cmake/LICENSE-APACHE new file mode 100644 index 0000000000000..16fe87b06e802 --- /dev/null +++ b/src/vendor/cmake/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/src/vendor/cmake/LICENSE-MIT b/src/vendor/cmake/LICENSE-MIT new file mode 100644 index 0000000000000..39e0ed6602151 --- /dev/null +++ b/src/vendor/cmake/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/vendor/cmake/README.md b/src/vendor/cmake/README.md new file mode 100644 index 0000000000000..8b2586eb01e25 --- /dev/null +++ b/src/vendor/cmake/README.md @@ -0,0 +1,22 @@ +# cmake + +[![Build Status](https://travis-ci.org/alexcrichton/cmake-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/cmake-rs) + +[Documentation](http://alexcrichton.com/cmake-rs) + +A build dependency for running the `cmake` build tool to compile a native +library. + +```toml +# Cargo.toml +[build-dependencies] +cmake = "0.2" +``` + +# License + +`cmake-rs` is primarily distributed under the terms of both the MIT license and +the Apache License (Version 2.0), with portions covered by various BSD-like +licenses. + +See LICENSE-APACHE, and LICENSE-MIT for details. diff --git a/src/vendor/cmake/src/lib.rs b/src/vendor/cmake/src/lib.rs new file mode 100644 index 0000000000000..3607d29026a03 --- /dev/null +++ b/src/vendor/cmake/src/lib.rs @@ -0,0 +1,522 @@ +//! A build dependency for running `cmake` to build a native library +//! +//! This crate provides some necessary boilerplate and shim support for running +//! the system `cmake` command to build a native library. It will add +//! appropriate cflags for building code to link into Rust, handle cross +//! compilation, and use the necessary generator for the platform being +//! targeted. +//! +//! The builder-style configuration allows for various variables and such to be +//! passed down into the build as well. +//! +//! ## Installation +//! +//! Add this to your `Cargo.toml`: +//! +//! ```toml +//! [build-dependencies] +//! cmake = "0.1" +//! ``` +//! +//! ## Examples +//! +//! ```no_run +//! use cmake; +//! +//! // Builds the project in the directory located in `libfoo`, installing it +//! // into $OUT_DIR +//! let dst = cmake::build("libfoo"); +//! +//! println!("cargo:rustc-link-search=native={}", dst.display()); +//! println!("cargo:rustc-link-lib=static=foo"); +//! ``` +//! +//! ```no_run +//! use cmake::Config; +//! +//! let dst = Config::new("libfoo") +//! .define("FOO", "BAR") +//! .cflag("-foo") +//! .build(); +//! println!("cargo:rustc-link-search=native={}", dst.display()); +//! println!("cargo:rustc-link-lib=static=foo"); +//! ``` + +#![deny(missing_docs)] + +extern crate gcc; + +use std::env; +use std::ffi::{OsString, OsStr}; +use std::fs::{self, File}; +use std::io::ErrorKind; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; +use std::process::Command; + +#[cfg(windows)] +mod registry; + +/// Builder style configuration for a pending CMake build. +pub struct Config { + path: PathBuf, + generator: Option, + cflags: OsString, + cxxflags: OsString, + defines: Vec<(OsString, OsString)>, + deps: Vec, + target: Option, + host: Option, + out_dir: Option, + profile: Option, + build_args: Vec, + cmake_target: Option, +} + +/// Builds the native library rooted at `path` with the default cmake options. +/// This will return the directory in which the library was installed. +/// +/// # Examples +/// +/// ```no_run +/// use cmake; +/// +/// // Builds the project in the directory located in `libfoo`, installing it +/// // into $OUT_DIR +/// let dst = cmake::build("libfoo"); +/// +/// println!("cargo:rustc-link-search=native={}", dst.display()); +/// println!("cargo:rustc-link-lib=static=foo"); +/// ``` +/// +pub fn build>(path: P) -> PathBuf { + Config::new(path.as_ref()).build() +} + +impl Config { + /// Creates a new blank set of configuration to build the project specified + /// at the path `path`. + pub fn new>(path: P) -> Config { + Config { + path: env::current_dir().unwrap().join(path), + generator: None, + cflags: OsString::new(), + cxxflags: OsString::new(), + defines: Vec::new(), + deps: Vec::new(), + profile: None, + out_dir: None, + target: None, + host: None, + build_args: Vec::new(), + cmake_target: None, + } + } + + /// Sets the build-tool generator (`-G`) for this compilation. + pub fn generator>(&mut self, generator: T) -> &mut Config { + self.generator = Some(generator.as_ref().to_owned()); + self + } + + /// Adds a custom flag to pass down to the C compiler, supplementing those + /// that this library already passes. + pub fn cflag>(&mut self, flag: P) -> &mut Config { + self.cflags.push(" "); + self.cflags.push(flag.as_ref()); + self + } + + /// Adds a custom flag to pass down to the C++ compiler, supplementing those + /// that this library already passes. + pub fn cxxflag>(&mut self, flag: P) -> &mut Config { + self.cxxflags.push(" "); + self.cxxflags.push(flag.as_ref()); + self + } + + /// Adds a new `-D` flag to pass to cmake during the generation step. + pub fn define(&mut self, k: K, v: V) -> &mut Config + where K: AsRef, V: AsRef + { + self.defines.push((k.as_ref().to_owned(), v.as_ref().to_owned())); + self + } + + /// Registers a dependency for this compilation on the native library built + /// by Cargo previously. + /// + /// This registration will modify the `CMAKE_PREFIX_PATH` environment + /// variable for the build system generation step. + pub fn register_dep(&mut self, dep: &str) -> &mut Config { + self.deps.push(dep.to_string()); + self + } + + /// Sets the target triple for this compilation. + /// + /// This is automatically scraped from `$TARGET` which is set for Cargo + /// build scripts so it's not necessary to call this from a build script. + pub fn target(&mut self, target: &str) -> &mut Config { + self.target = Some(target.to_string()); + self + } + + /// Sets the host triple for this compilation. + /// + /// This is automatically scraped from `$HOST` which is set for Cargo + /// build scripts so it's not necessary to call this from a build script. + pub fn host(&mut self, host: &str) -> &mut Config { + self.host = Some(host.to_string()); + self + } + + /// Sets the output directory for this compilation. + /// + /// This is automatically scraped from `$OUT_DIR` which is set for Cargo + /// build scripts so it's not necessary to call this from a build script. + pub fn out_dir>(&mut self, out: P) -> &mut Config { + self.out_dir = Some(out.as_ref().to_path_buf()); + self + } + + /// Sets the profile for this compilation. + /// + /// This is automatically scraped from `$PROFILE` which is set for Cargo + /// build scripts so it's not necessary to call this from a build script. + pub fn profile(&mut self, profile: &str) -> &mut Config { + self.profile = Some(profile.to_string()); + self + } + + /// Add an argument to the final `cmake` build step + pub fn build_arg>(&mut self, arg: A) -> &mut Config { + self.build_args.push(arg.as_ref().to_owned()); + self + } + + /// Sets the build target for the final `cmake` build step, this will + /// default to "install" if not specified. + pub fn build_target(&mut self, target: &str) -> &mut Config { + self.cmake_target = Some(target.to_string()); + self + } + + /// Run this configuration, compiling the library with all the configured + /// options. + /// + /// This will run both the build system generator command as well as the + /// command to build the library. + pub fn build(&mut self) -> PathBuf { + let target = self.target.clone().unwrap_or_else(|| { + getenv_unwrap("TARGET") + }); + let host = self.host.clone().unwrap_or_else(|| { + getenv_unwrap("HOST") + }); + let msvc = target.contains("msvc"); + let c_compiler = gcc::Config::new().cargo_metadata(false) + .opt_level(0) + .debug(false) + .target(&target) + .host(&host) + .get_compiler(); + let cxx_compiler = gcc::Config::new().cargo_metadata(false) + .cpp(true) + .opt_level(0) + .debug(false) + .target(&target) + .host(&host) + .get_compiler(); + + let dst = self.out_dir.clone().unwrap_or_else(|| { + PathBuf::from(getenv_unwrap("OUT_DIR")) + }); + let build = dst.join("build"); + self.maybe_clear(&build); + let _ = fs::create_dir(&build); + + // Add all our dependencies to our cmake paths + let mut cmake_prefix_path = Vec::new(); + for dep in &self.deps { + if let Some(root) = env::var_os(&format!("DEP_{}_ROOT", dep)) { + cmake_prefix_path.push(PathBuf::from(root)); + } + } + let system_prefix = env::var_os("CMAKE_PREFIX_PATH") + .unwrap_or(OsString::new()); + cmake_prefix_path.extend(env::split_paths(&system_prefix) + .map(|s| s.to_owned())); + let cmake_prefix_path = env::join_paths(&cmake_prefix_path).unwrap(); + + // Build up the first cmake command to build the build system. + let mut cmd = Command::new("cmake"); + cmd.arg(&self.path) + .current_dir(&build); + if target.contains("windows-gnu") { + if host.contains("windows") { + // On MinGW we need to coerce cmake to not generate a visual + // studio build system but instead use makefiles that MinGW can + // use to build. + if self.generator.is_none() { + cmd.arg("-G").arg("MSYS Makefiles"); + } + } else { + // If we're cross compiling onto windows, then set some + // variables which will hopefully get things to succeed. Some + // systems may need the `windres` or `dlltool` variables set, so + // set them if possible. + if !self.defined("CMAKE_SYSTEM_NAME") { + cmd.arg("-DCMAKE_SYSTEM_NAME=Windows"); + } + if !self.defined("CMAKE_RC_COMPILER") { + let exe = find_exe(c_compiler.path()); + if let Some(name) = exe.file_name().unwrap().to_str() { + let name = name.replace("gcc", "windres"); + let windres = exe.with_file_name(name); + if windres.is_file() { + let mut arg = OsString::from("-DCMAKE_RC_COMPILER="); + arg.push(&windres); + cmd.arg(arg); + } + } + } + } + } else if msvc { + // If we're on MSVC we need to be sure to use the right generator or + // otherwise we won't get 32/64 bit correct automatically. + if self.generator.is_none() { + cmd.arg("-G").arg(self.visual_studio_generator(&target)); + } + } + if let Some(ref generator) = self.generator { + cmd.arg("-G").arg(generator); + } + let profile = self.profile.clone().unwrap_or_else(|| { + match &getenv_unwrap("PROFILE")[..] { + "bench" | "release" => "Release", + // currently we need to always use the same CRT for MSVC + _ if msvc => "Release", + _ => "Debug", + }.to_string() + }); + for &(ref k, ref v) in &self.defines { + let mut os = OsString::from("-D"); + os.push(k); + os.push("="); + os.push(v); + cmd.arg(os); + } + + if !self.defined("CMAKE_INSTALL_PREFIX") { + let mut dstflag = OsString::from("-DCMAKE_INSTALL_PREFIX="); + dstflag.push(&dst); + cmd.arg(dstflag); + } + + { + let mut set_compiler = |kind: &str, + compiler: &gcc::Tool, + extra: &OsString| { + let flag_var = format!("CMAKE_{}_FLAGS", kind); + let tool_var = format!("CMAKE_{}_COMPILER", kind); + if !self.defined(&flag_var) { + let mut flagsflag = OsString::from("-D"); + flagsflag.push(&flag_var); + flagsflag.push("="); + flagsflag.push(extra); + for arg in compiler.args() { + flagsflag.push(" "); + flagsflag.push(arg); + } + cmd.arg(flagsflag); + } + + // Apparently cmake likes to have an absolute path to the + // compiler as otherwise it sometimes thinks that this variable + // changed as it thinks the found compiler, /usr/bin/cc, + // differs from the specified compiler, cc. Not entirely sure + // what's up, but at least this means cmake doesn't get + // confused? + // + // Also don't specify this on Windows as it's not needed for + // MSVC and for MinGW it doesn't really vary. + if !self.defined("CMAKE_TOOLCHAIN_FILE") + && !self.defined(&tool_var) + && env::consts::FAMILY != "windows" { + let mut ccompiler = OsString::from("-D"); + ccompiler.push(&tool_var); + ccompiler.push("="); + ccompiler.push(find_exe(compiler.path())); + cmd.arg(ccompiler); + } + }; + + set_compiler("C", &c_compiler, &self.cflags); + set_compiler("CXX", &cxx_compiler, &self.cxxflags); + } + + if !self.defined("CMAKE_BUILD_TYPE") { + cmd.arg(&format!("-DCMAKE_BUILD_TYPE={}", profile)); + } + + if !self.defined("CMAKE_TOOLCHAIN_FILE") { + if let Ok(s) = env::var("CMAKE_TOOLCHAIN_FILE") { + cmd.arg(&format!("-DCMAKE_TOOLCHAIN_FILE={}", s)); + } + } + + run(cmd.env("CMAKE_PREFIX_PATH", cmake_prefix_path), "cmake"); + + let mut parallel_args = Vec::new(); + if fs::metadata(&dst.join("build/Makefile")).is_ok() { + if let Ok(s) = env::var("NUM_JOBS") { + parallel_args.push(format!("-j{}", s)); + } + } + + // And build! + let target = self.cmake_target.clone().unwrap_or("install".to_string()); + run(Command::new("cmake") + .arg("--build").arg(".") + .arg("--target").arg(target) + .arg("--config").arg(profile) + .arg("--").args(&self.build_args) + .args(¶llel_args) + .current_dir(&build), "cmake"); + + println!("cargo:root={}", dst.display()); + return dst + } + + fn visual_studio_generator(&self, target: &str) -> String { + let base = match std::env::var("VisualStudioVersion") { + Ok(version) => { + match &version[..] { + "15.0" => "Visual Studio 15", + "14.0" => "Visual Studio 14 2015", + "12.0" => "Visual Studio 12 2013", + vers => panic!("\n\n\ + unsupported or unknown VisualStudio version: {}\n\ + if another version is installed consider running \ + the appropriate vcvars script before building this \ + crate\n\ + ", vers), + } + } + _ => { + // Check for the presense of a specific registry key + // that indicates visual studio is installed. + if self.has_msbuild_version("15.0") { + "Visual Studio 15" + } else if self.has_msbuild_version("14.0") { + "Visual Studio 14 2015" + } else if self.has_msbuild_version("12.0") { + "Visual Studio 12 2013" + } else { + panic!("\n\n\ + couldn't determine visual studio generator\n\ + if VisualStudio is installed, however, consider \ + running the appropriate vcvars script before building \ + this crate\n\ + "); + } + } + }; + + if target.contains("i686") { + base.to_string() + } else if target.contains("x86_64") { + format!("{} Win64", base) + } else { + panic!("unsupported msvc target: {}", target); + } + } + + #[cfg(not(windows))] + fn has_msbuild_version(&self, _version: &str) -> bool { + false + } + + #[cfg(windows)] + fn has_msbuild_version(&self, version: &str) -> bool { + let key = format!("SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\{}", + version); + registry::LOCAL_MACHINE.open(key.as_ref()).is_ok() + } + + fn defined(&self, var: &str) -> bool { + self.defines.iter().any(|&(ref a, _)| a == var) + } + + // If a cmake project has previously been built (e.g. CMakeCache.txt already + // exists), then cmake will choke if the source directory for the original + // project being built has changed. Detect this situation through the + // `CMAKE_HOME_DIRECTORY` variable that cmake emits and if it doesn't match + // we blow away the build directory and start from scratch (the recommended + // solution apparently [1]). + // + // [1]: https://cmake.org/pipermail/cmake/2012-August/051545.html + fn maybe_clear(&self, dir: &Path) { + // CMake will apparently store canonicalized paths which normally + // isn't relevant to us but we canonicalize it here to ensure + // we're both checking the same thing. + let path = fs::canonicalize(&self.path).unwrap_or(self.path.clone()); + let src = match path.to_str() { + Some(src) => src, + None => return, + }; + let mut f = match File::open(dir.join("CMakeCache.txt")) { + Ok(f) => f, + Err(..) => return, + }; + let mut u8contents = Vec::new(); + match f.read_to_end(&mut u8contents) { + Ok(f) => f, + Err(..) => return, + }; + let contents = String::from_utf8_lossy(&u8contents); + drop(f); + for line in contents.lines() { + if line.contains("CMAKE_HOME_DIRECTORY") && !line.contains(src) { + println!("detected home dir change, cleaning out entire build \ + directory"); + fs::remove_dir_all(dir).unwrap(); + break + } + } + } +} + +fn run(cmd: &mut Command, program: &str) { + println!("running: {:?}", cmd); + let status = match cmd.status() { + Ok(status) => status, + Err(ref e) if e.kind() == ErrorKind::NotFound => { + fail(&format!("failed to execute command: {}\nis `{}` not installed?", + e, program)); + } + Err(e) => fail(&format!("failed to execute command: {}", e)), + }; + if !status.success() { + fail(&format!("command did not execute successfully, got: {}", status)); + } +} + +fn find_exe(path: &Path) -> PathBuf { + env::split_paths(&env::var_os("PATH").unwrap_or(OsString::new())) + .map(|p| p.join(path)) + .find(|p| fs::metadata(p).is_ok()) + .unwrap_or(path.to_owned()) +} + +fn getenv_unwrap(v: &str) -> String { + match env::var(v) { + Ok(s) => s, + Err(..) => fail(&format!("environment variable `{}` not defined", v)), + } +} + +fn fail(s: &str) -> ! { + panic!("\n{}\n\nbuild script failed, must exit now", s) +} diff --git a/src/vendor/cmake/src/registry.rs b/src/vendor/cmake/src/registry.rs new file mode 100644 index 0000000000000..8819b094151e7 --- /dev/null +++ b/src/vendor/cmake/src/registry.rs @@ -0,0 +1,84 @@ +// Copyright 2015 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. + +use std::ffi::OsStr; +use std::io; +use std::os::raw; +use std::os::windows::prelude::*; + +pub struct RegistryKey(Repr); + +type HKEY = *mut u8; +type DWORD = u32; +type LPDWORD = *mut DWORD; +type LPCWSTR = *const u16; +type LPWSTR = *mut u16; +type LONG = raw::c_long; +type PHKEY = *mut HKEY; +type PFILETIME = *mut u8; +type LPBYTE = *mut u8; +type REGSAM = u32; + +const ERROR_SUCCESS: DWORD = 0; +const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY; +const KEY_READ: DWORD = 0x20019; +const KEY_WOW64_32KEY: DWORD = 0x200; + +#[link(name = "advapi32")] +extern "system" { + fn RegOpenKeyExW(key: HKEY, + lpSubKey: LPCWSTR, + ulOptions: DWORD, + samDesired: REGSAM, + phkResult: PHKEY) -> LONG; + fn RegCloseKey(hKey: HKEY) -> LONG; +} + +struct OwnedKey(HKEY); + +enum Repr { + Const(HKEY), + Owned(OwnedKey), +} + +unsafe impl Sync for Repr {} +unsafe impl Send for Repr {} + +pub static LOCAL_MACHINE: RegistryKey = + RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE)); + +impl RegistryKey { + fn raw(&self) -> HKEY { + match self.0 { + Repr::Const(val) => val, + Repr::Owned(ref val) => val.0, + } + } + + pub fn open(&self, key: &OsStr) -> io::Result { + let key = key.encode_wide().chain(Some(0)).collect::>(); + let mut ret = 0 as *mut _; + let err = unsafe { + RegOpenKeyExW(self.raw(), key.as_ptr(), 0, + KEY_READ | KEY_WOW64_32KEY, &mut ret) + }; + if err == ERROR_SUCCESS as LONG { + Ok(RegistryKey(Repr::Owned(OwnedKey(ret)))) + } else { + Err(io::Error::from_raw_os_error(err as i32)) + } + } +} + +impl Drop for OwnedKey { + fn drop(&mut self) { + unsafe { RegCloseKey(self.0); } + } +} diff --git a/src/vendor/env_logger/.cargo-checksum.json b/src/vendor/env_logger/.cargo-checksum.json new file mode 100644 index 0000000000000..e3d83501ad079 --- /dev/null +++ b/src/vendor/env_logger/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"4af0565a97a599bba727315d9aff1f57a350dcfee7d9f00986c851e54a24b4ca","src/lib.rs":"484cec14a5f18a25b71d7b1842f7b184f0530165021b71b36dde9fc57b7fc15a","src/regex.rs":"d8e2a6958d4ed8084867063aae4b5c77ffc5d271dc2e17909d56c5a5e1552034","src/string.rs":"26ede9ab41a2673c3ad6001bc1802c005ce9a4f190f55860a24aa66b6b71bbc7","tests/regexp_filter.rs":"a3f9c01623e90e54b247a62c53b25caf5f502d054f28c0bdf92abbea486a95b5"},"package":"15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"} \ No newline at end of file diff --git a/src/vendor/env_logger/.cargo-ok b/src/vendor/env_logger/.cargo-ok new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/vendor/env_logger/Cargo.toml b/src/vendor/env_logger/Cargo.toml new file mode 100644 index 0000000000000..5efadbf0d6293 --- /dev/null +++ b/src/vendor/env_logger/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "env_logger" +version = "0.3.5" +authors = ["The Rust Project Developers"] +license = "MIT/Apache-2.0" +repository = "https://github.com/rust-lang/log" +documentation = "http://doc.rust-lang.org/log/env_logger" +homepage = "https://github.com/rust-lang/log" +description = """ +An logging implementation for `log` which is configured via an environment +variable. +""" + +[dependencies] +log = { version = "0.3", path = ".." } +regex = { version = "0.1", optional = true } + +[[test]] +name = "regexp_filter" +harness = false + +[features] +default = ["regex"] diff --git a/src/vendor/env_logger/src/lib.rs b/src/vendor/env_logger/src/lib.rs new file mode 100644 index 0000000000000..9105c19c65cd4 --- /dev/null +++ b/src/vendor/env_logger/src/lib.rs @@ -0,0 +1,623 @@ +// Copyright 2014-2015 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. + +//! A logger configured via an environment variable which writes to standard +//! error. +//! +//! ## Example +//! +//! ``` +//! #[macro_use] extern crate log; +//! extern crate env_logger; +//! +//! use log::LogLevel; +//! +//! fn main() { +//! env_logger::init().unwrap(); +//! +//! debug!("this is a debug {}", "message"); +//! error!("this is printed by default"); +//! +//! if log_enabled!(LogLevel::Info) { +//! let x = 3 * 4; // expensive computation +//! info!("the answer was: {}", x); +//! } +//! } +//! ``` +//! +//! Assumes the binary is `main`: +//! +//! ```{.bash} +//! $ RUST_LOG=error ./main +//! ERROR:main: this is printed by default +//! ``` +//! +//! ```{.bash} +//! $ RUST_LOG=info ./main +//! ERROR:main: this is printed by default +//! INFO:main: the answer was: 12 +//! ``` +//! +//! ```{.bash} +//! $ RUST_LOG=debug ./main +//! DEBUG:main: this is a debug message +//! ERROR:main: this is printed by default +//! INFO:main: the answer was: 12 +//! ``` +//! +//! You can also set the log level on a per module basis: +//! +//! ```{.bash} +//! $ RUST_LOG=main=info ./main +//! ERROR:main: this is printed by default +//! INFO:main: the answer was: 12 +//! ``` +//! +//! And enable all logging: +//! +//! ```{.bash} +//! $ RUST_LOG=main ./main +//! DEBUG:main: this is a debug message +//! ERROR:main: this is printed by default +//! INFO:main: the answer was: 12 +//! ``` +//! +//! See the documentation for the log crate for more information about its API. +//! +//! ## Enabling logging +//! +//! Log levels are controlled on a per-module basis, and by default all logging +//! is disabled except for `error!`. Logging is controlled via the `RUST_LOG` +//! environment variable. The value of this environment variable is a +//! comma-separated list of logging directives. A logging directive is of the +//! form: +//! +//! ```text +//! path::to::module=log_level +//! ``` +//! +//! The path to the module is rooted in the name of the crate it was compiled +//! for, so if your program is contained in a file `hello.rs`, for example, to +//! turn on logging for this file you would use a value of `RUST_LOG=hello`. +//! Furthermore, this path is a prefix-search, so all modules nested in the +//! specified module will also have logging enabled. +//! +//! The actual `log_level` is optional to specify. If omitted, all logging will +//! be enabled. If specified, it must be one of the strings `debug`, `error`, +//! `info`, `warn`, or `trace`. +//! +//! As the log level for a module is optional, the module to enable logging for +//! is also optional. If only a `log_level` is provided, then the global log +//! level for all modules is set to this value. +//! +//! Some examples of valid values of `RUST_LOG` are: +//! +//! * `hello` turns on all logging for the 'hello' module +//! * `info` turns on all info logging +//! * `hello=debug` turns on debug logging for 'hello' +//! * `hello,std::option` turns on hello, and std's option logging +//! * `error,hello=warn` turn on global error logging and also warn for hello +//! +//! ## Filtering results +//! +//! A RUST_LOG directive may include a regex filter. The syntax is to append `/` +//! followed by a regex. Each message is checked against the regex, and is only +//! logged if it matches. Note that the matching is done after formatting the +//! log string but before adding any logging meta-data. There is a single filter +//! for all modules. +//! +//! Some examples: +//! +//! * `hello/foo` turns on all logging for the 'hello' module where the log +//! message includes 'foo'. +//! * `info/f.o` turns on all info logging where the log message includes 'foo', +//! 'f1o', 'fao', etc. +//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log +//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc. +//! * `error,hello=warn/[0-9] scopes` turn on global error logging and also +//! warn for hello. In both cases the log message must include a single digit +//! number followed by 'scopes'. + +#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://doc.rust-lang.org/env_logger/")] +#![cfg_attr(test, deny(warnings))] + +extern crate log; + +use std::env; +use std::io::prelude::*; +use std::io; +use std::mem; + +use log::{Log, LogLevel, LogLevelFilter, LogRecord, SetLoggerError, LogMetadata}; + +#[cfg(feature = "regex")] +#[path = "regex.rs"] +mod filter; + +#[cfg(not(feature = "regex"))] +#[path = "string.rs"] +mod filter; + +/// The logger. +pub struct Logger { + directives: Vec, + filter: Option, + format: Box String + Sync + Send>, +} + +/// LogBuilder acts as builder for initializing the Logger. +/// It can be used to customize the log format, change the enviromental variable used +/// to provide the logging directives and also set the default log level filter. +/// +/// ## Example +/// +/// ``` +/// #[macro_use] +/// extern crate log; +/// extern crate env_logger; +/// +/// use std::env; +/// use log::{LogRecord, LogLevelFilter}; +/// use env_logger::LogBuilder; +/// +/// fn main() { +/// let format = |record: &LogRecord| { +/// format!("{} - {}", record.level(), record.args()) +/// }; +/// +/// let mut builder = LogBuilder::new(); +/// builder.format(format).filter(None, LogLevelFilter::Info); +/// +/// if env::var("RUST_LOG").is_ok() { +/// builder.parse(&env::var("RUST_LOG").unwrap()); +/// } +/// +/// builder.init().unwrap(); +/// +/// error!("error message"); +/// info!("info message"); +/// } +/// ``` +pub struct LogBuilder { + directives: Vec, + filter: Option, + format: Box String + Sync + Send>, +} + +impl LogBuilder { + /// Initializes the log builder with defaults + pub fn new() -> LogBuilder { + LogBuilder { + directives: Vec::new(), + filter: None, + format: Box::new(|record: &LogRecord| { + format!("{}:{}: {}", record.level(), + record.location().module_path(), record.args()) + }), + } + } + + /// Adds filters to the logger + /// + /// The given module (if any) will log at most the specified level provided. + /// If no module is provided then the filter will apply to all log messages. + pub fn filter(&mut self, + module: Option<&str>, + level: LogLevelFilter) -> &mut Self { + self.directives.push(LogDirective { + name: module.map(|s| s.to_string()), + level: level, + }); + self + } + + /// Sets the format function for formatting the log output. + /// + /// This function is called on each record logged to produce a string which + /// is actually printed out. + pub fn format(&mut self, format: F) -> &mut Self + where F: Fn(&LogRecord) -> String + Sync + Send + { + self.format = Box::new(format); + self + } + + /// Parses the directives string in the same form as the RUST_LOG + /// environment variable. + /// + /// See the module documentation for more details. + pub fn parse(&mut self, filters: &str) -> &mut Self { + let (directives, filter) = parse_logging_spec(filters); + + self.filter = filter; + + for directive in directives { + self.directives.push(directive); + } + self + } + + /// Initializes the global logger with an env logger. + /// + /// This should be called early in the execution of a Rust program, and the + /// global logger may only be initialized once. Future initialization + /// attempts will return an error. + pub fn init(&mut self) -> Result<(), SetLoggerError> { + log::set_logger(|max_level| { + let logger = self.build(); + max_level.set(logger.filter()); + Box::new(logger) + }) + } + + /// Build an env logger. + pub fn build(&mut self) -> Logger { + if self.directives.is_empty() { + // Adds the default filter if none exist + self.directives.push(LogDirective { + name: None, + level: LogLevelFilter::Error, + }); + } else { + // Sort the directives by length of their name, this allows a + // little more efficient lookup at runtime. + self.directives.sort_by(|a, b| { + let alen = a.name.as_ref().map(|a| a.len()).unwrap_or(0); + let blen = b.name.as_ref().map(|b| b.len()).unwrap_or(0); + alen.cmp(&blen) + }); + } + + Logger { + directives: mem::replace(&mut self.directives, Vec::new()), + filter: mem::replace(&mut self.filter, None), + format: mem::replace(&mut self.format, Box::new(|_| String::new())), + } + } +} + +impl Logger { + pub fn new() -> Logger { + let mut builder = LogBuilder::new(); + + if let Ok(s) = env::var("RUST_LOG") { + builder.parse(&s); + } + + builder.build() + } + + pub fn filter(&self) -> LogLevelFilter { + self.directives.iter() + .map(|d| d.level).max() + .unwrap_or(LogLevelFilter::Off) + } + + fn enabled(&self, level: LogLevel, target: &str) -> bool { + // Search for the longest match, the vector is assumed to be pre-sorted. + for directive in self.directives.iter().rev() { + match directive.name { + Some(ref name) if !target.starts_with(&**name) => {}, + Some(..) | None => { + return level <= directive.level + } + } + } + false + } +} + +impl Log for Logger { + fn enabled(&self, metadata: &LogMetadata) -> bool { + self.enabled(metadata.level(), metadata.target()) + } + + fn log(&self, record: &LogRecord) { + if !Log::enabled(self, record.metadata()) { + return; + } + + if let Some(filter) = self.filter.as_ref() { + if !filter.is_match(&*record.args().to_string()) { + return; + } + } + + let _ = writeln!(&mut io::stderr(), "{}", (self.format)(record)); + } +} + +struct LogDirective { + name: Option, + level: LogLevelFilter, +} + +/// Initializes the global logger with an env logger. +/// +/// This should be called early in the execution of a Rust program, and the +/// global logger may only be initialized once. Future initialization attempts +/// will return an error. +pub fn init() -> Result<(), SetLoggerError> { + let mut builder = LogBuilder::new(); + + if let Ok(s) = env::var("RUST_LOG") { + builder.parse(&s); + } + + builder.init() +} + +/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=error/foo") +/// and return a vector with log directives. +fn parse_logging_spec(spec: &str) -> (Vec, Option) { + let mut dirs = Vec::new(); + + let mut parts = spec.split('/'); + let mods = parts.next(); + let filter = parts.next(); + if parts.next().is_some() { + println!("warning: invalid logging spec '{}', \ + ignoring it (too many '/'s)", spec); + return (dirs, None); + } + mods.map(|m| { for s in m.split(',') { + if s.len() == 0 { continue } + let mut parts = s.split('='); + let (log_level, name) = match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) { + (Some(part0), None, None) => { + // if the single argument is a log-level string or number, + // treat that as a global fallback + match part0.parse() { + Ok(num) => (num, None), + Err(_) => (LogLevelFilter::max(), Some(part0)), + } + } + (Some(part0), Some(""), None) => (LogLevelFilter::max(), Some(part0)), + (Some(part0), Some(part1), None) => { + match part1.parse() { + Ok(num) => (num, Some(part0)), + _ => { + println!("warning: invalid logging spec '{}', \ + ignoring it", part1); + continue + } + } + }, + _ => { + println!("warning: invalid logging spec '{}', \ + ignoring it", s); + continue + } + }; + dirs.push(LogDirective { + name: name.map(|s| s.to_string()), + level: log_level, + }); + }}); + + let filter = filter.map_or(None, |filter| { + match filter::Filter::new(filter) { + Ok(re) => Some(re), + Err(e) => { + println!("warning: invalid regex filter - {}", e); + None + } + } + }); + + return (dirs, filter); +} + +#[cfg(test)] +mod tests { + use log::{LogLevel, LogLevelFilter}; + + use super::{LogBuilder, Logger, LogDirective, parse_logging_spec}; + + fn make_logger(dirs: Vec) -> Logger { + let mut logger = LogBuilder::new().build(); + logger.directives = dirs; + logger + } + + #[test] + fn filter_info() { + let logger = LogBuilder::new().filter(None, LogLevelFilter::Info).build(); + assert!(logger.enabled(LogLevel::Info, "crate1")); + assert!(!logger.enabled(LogLevel::Debug, "crate1")); + } + + #[test] + fn filter_beginning_longest_match() { + let logger = LogBuilder::new() + .filter(Some("crate2"), LogLevelFilter::Info) + .filter(Some("crate2::mod"), LogLevelFilter::Debug) + .filter(Some("crate1::mod1"), LogLevelFilter::Warn) + .build(); + assert!(logger.enabled(LogLevel::Debug, "crate2::mod1")); + assert!(!logger.enabled(LogLevel::Debug, "crate2")); + } + + #[test] + fn parse_default() { + let logger = LogBuilder::new().parse("info,crate1::mod1=warn").build(); + assert!(logger.enabled(LogLevel::Warn, "crate1::mod1")); + assert!(logger.enabled(LogLevel::Info, "crate2::mod2")); + } + + #[test] + fn match_full_path() { + let logger = make_logger(vec![ + LogDirective { + name: Some("crate2".to_string()), + level: LogLevelFilter::Info + }, + LogDirective { + name: Some("crate1::mod1".to_string()), + level: LogLevelFilter::Warn + } + ]); + assert!(logger.enabled(LogLevel::Warn, "crate1::mod1")); + assert!(!logger.enabled(LogLevel::Info, "crate1::mod1")); + assert!(logger.enabled(LogLevel::Info, "crate2")); + assert!(!logger.enabled(LogLevel::Debug, "crate2")); + } + + #[test] + fn no_match() { + let logger = make_logger(vec![ + LogDirective { name: Some("crate2".to_string()), level: LogLevelFilter::Info }, + LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Warn } + ]); + assert!(!logger.enabled(LogLevel::Warn, "crate3")); + } + + #[test] + fn match_beginning() { + let logger = make_logger(vec![ + LogDirective { name: Some("crate2".to_string()), level: LogLevelFilter::Info }, + LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Warn } + ]); + assert!(logger.enabled(LogLevel::Info, "crate2::mod1")); + } + + #[test] + fn match_beginning_longest_match() { + let logger = make_logger(vec![ + LogDirective { name: Some("crate2".to_string()), level: LogLevelFilter::Info }, + LogDirective { name: Some("crate2::mod".to_string()), level: LogLevelFilter::Debug }, + LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Warn } + ]); + assert!(logger.enabled(LogLevel::Debug, "crate2::mod1")); + assert!(!logger.enabled(LogLevel::Debug, "crate2")); + } + + #[test] + fn match_default() { + let logger = make_logger(vec![ + LogDirective { name: None, level: LogLevelFilter::Info }, + LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Warn } + ]); + assert!(logger.enabled(LogLevel::Warn, "crate1::mod1")); + assert!(logger.enabled(LogLevel::Info, "crate2::mod2")); + } + + #[test] + fn zero_level() { + let logger = make_logger(vec![ + LogDirective { name: None, level: LogLevelFilter::Info }, + LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Off } + ]); + assert!(!logger.enabled(LogLevel::Error, "crate1::mod1")); + assert!(logger.enabled(LogLevel::Info, "crate2::mod2")); + } + + #[test] + fn parse_logging_spec_valid() { + let (dirs, filter) = parse_logging_spec("crate1::mod1=error,crate1::mod2,crate2=debug"); + assert_eq!(dirs.len(), 3); + assert_eq!(dirs[0].name, Some("crate1::mod1".to_string())); + assert_eq!(dirs[0].level, LogLevelFilter::Error); + + assert_eq!(dirs[1].name, Some("crate1::mod2".to_string())); + assert_eq!(dirs[1].level, LogLevelFilter::max()); + + assert_eq!(dirs[2].name, Some("crate2".to_string())); + assert_eq!(dirs[2].level, LogLevelFilter::Debug); + assert!(filter.is_none()); + } + + #[test] + fn parse_logging_spec_invalid_crate() { + // test parse_logging_spec with multiple = in specification + let (dirs, filter) = parse_logging_spec("crate1::mod1=warn=info,crate2=debug"); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LogLevelFilter::Debug); + assert!(filter.is_none()); + } + + #[test] + fn parse_logging_spec_invalid_log_level() { + // test parse_logging_spec with 'noNumber' as log level + let (dirs, filter) = parse_logging_spec("crate1::mod1=noNumber,crate2=debug"); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LogLevelFilter::Debug); + assert!(filter.is_none()); + } + + #[test] + fn parse_logging_spec_string_log_level() { + // test parse_logging_spec with 'warn' as log level + let (dirs, filter) = parse_logging_spec("crate1::mod1=wrong,crate2=warn"); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LogLevelFilter::Warn); + assert!(filter.is_none()); + } + + #[test] + fn parse_logging_spec_empty_log_level() { + // test parse_logging_spec with '' as log level + let (dirs, filter) = parse_logging_spec("crate1::mod1=wrong,crate2="); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LogLevelFilter::max()); + assert!(filter.is_none()); + } + + #[test] + fn parse_logging_spec_global() { + // test parse_logging_spec with no crate + let (dirs, filter) = parse_logging_spec("warn,crate2=debug"); + assert_eq!(dirs.len(), 2); + assert_eq!(dirs[0].name, None); + assert_eq!(dirs[0].level, LogLevelFilter::Warn); + assert_eq!(dirs[1].name, Some("crate2".to_string())); + assert_eq!(dirs[1].level, LogLevelFilter::Debug); + assert!(filter.is_none()); + } + + #[test] + fn parse_logging_spec_valid_filter() { + let (dirs, filter) = parse_logging_spec("crate1::mod1=error,crate1::mod2,crate2=debug/abc"); + assert_eq!(dirs.len(), 3); + assert_eq!(dirs[0].name, Some("crate1::mod1".to_string())); + assert_eq!(dirs[0].level, LogLevelFilter::Error); + + assert_eq!(dirs[1].name, Some("crate1::mod2".to_string())); + assert_eq!(dirs[1].level, LogLevelFilter::max()); + + assert_eq!(dirs[2].name, Some("crate2".to_string())); + assert_eq!(dirs[2].level, LogLevelFilter::Debug); + assert!(filter.is_some() && filter.unwrap().to_string() == "abc"); + } + + #[test] + fn parse_logging_spec_invalid_crate_filter() { + let (dirs, filter) = parse_logging_spec("crate1::mod1=error=warn,crate2=debug/a.c"); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LogLevelFilter::Debug); + assert!(filter.is_some() && filter.unwrap().to_string() == "a.c"); + } + + #[test] + fn parse_logging_spec_empty_with_filter() { + let (dirs, filter) = parse_logging_spec("crate1/a*c"); + assert_eq!(dirs.len(), 1); + assert_eq!(dirs[0].name, Some("crate1".to_string())); + assert_eq!(dirs[0].level, LogLevelFilter::max()); + assert!(filter.is_some() && filter.unwrap().to_string() == "a*c"); + } +} diff --git a/src/vendor/env_logger/src/regex.rs b/src/vendor/env_logger/src/regex.rs new file mode 100644 index 0000000000000..0df03e673304d --- /dev/null +++ b/src/vendor/env_logger/src/regex.rs @@ -0,0 +1,28 @@ +extern crate regex; + +use std::fmt; + +use self::regex::Regex; + +pub struct Filter { + inner: Regex, +} + +impl Filter { + pub fn new(spec: &str) -> Result { + match Regex::new(spec){ + Ok(r) => Ok(Filter { inner: r }), + Err(e) => Err(e.to_string()), + } + } + + pub fn is_match(&self, s: &str) -> bool { + self.inner.is_match(s) + } +} + +impl fmt::Display for Filter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.inner.fmt(f) + } +} diff --git a/src/vendor/env_logger/src/string.rs b/src/vendor/env_logger/src/string.rs new file mode 100644 index 0000000000000..74d0e04dbd6ed --- /dev/null +++ b/src/vendor/env_logger/src/string.rs @@ -0,0 +1,21 @@ +use std::fmt; + +pub struct Filter { + inner: String, +} + +impl Filter { + pub fn new(spec: &str) -> Result { + Ok(Filter { inner: spec.to_string() }) + } + + pub fn is_match(&self, s: &str) -> bool { + s.contains(&self.inner) + } +} + +impl fmt::Display for Filter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.inner.fmt(f) + } +} diff --git a/src/vendor/env_logger/tests/regexp_filter.rs b/src/vendor/env_logger/tests/regexp_filter.rs new file mode 100644 index 0000000000000..5036fb8e3c9c3 --- /dev/null +++ b/src/vendor/env_logger/tests/regexp_filter.rs @@ -0,0 +1,51 @@ +#[macro_use] extern crate log; +extern crate env_logger; + +use std::process; +use std::env; +use std::str; + +fn main() { + if env::var("LOG_REGEXP_TEST").ok() == Some(String::from("1")) { + child_main(); + } else { + parent_main() + } +} + +fn child_main() { + env_logger::init().unwrap(); + info!("XYZ Message"); +} + +fn run_child(rust_log: String) -> bool { + let exe = env::current_exe().unwrap(); + let out = process::Command::new(exe) + .env("LOG_REGEXP_TEST", "1") + .env("RUST_LOG", rust_log) + .output() + .unwrap_or_else(|e| panic!("Unable to start child process: {}", e)); + str::from_utf8(out.stderr.as_ref()).unwrap().contains("XYZ Message") +} + +fn assert_message_printed(rust_log: &str) { + if !run_child(rust_log.to_string()) { + panic!("RUST_LOG={} should allow the test log message", rust_log) + } +} + +fn assert_message_not_printed(rust_log: &str) { + if run_child(rust_log.to_string()) { + panic!("RUST_LOG={} should not allow the test log message", rust_log) + } +} + +fn parent_main() { + // test normal log severity levels + assert_message_printed("info"); + assert_message_not_printed("warn"); + + // test of regular expression filters + assert_message_printed("info/XYZ"); + assert_message_not_printed("info/XXX"); +} diff --git a/src/vendor/filetime/.cargo-checksum.json b/src/vendor/filetime/.cargo-checksum.json new file mode 100644 index 0000000000000..674ae31b296ba --- /dev/null +++ b/src/vendor/filetime/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"c8cfe2c700e7b1d6500d0ad8084694be7009095e9572aaf54bf695c1fe7822d6","Cargo.toml":"4e414fe72ef2afcae81fb5a89f39e59ec40844272b589381746623f612333305","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"fef1998633eb2f460e6b12bc1133a21f5674e0b53ae5914ba1e53f1b63a185c3","appveyor.yml":"da991211b72fa6f231af7adb84c9fb72f5a9131d1c0a3d47b8ceffe5a82c8542","src/lib.rs":"8fa03e69ab113e5a30c742f60b6beddc0b77ef41a1eb45e82f9df867c9265815"},"package":"5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"} \ No newline at end of file diff --git a/src/vendor/filetime/.cargo-ok b/src/vendor/filetime/.cargo-ok new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/vendor/filetime/.gitignore b/src/vendor/filetime/.gitignore new file mode 100644 index 0000000000000..a9d37c560c6ab --- /dev/null +++ b/src/vendor/filetime/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/src/vendor/filetime/.travis.yml b/src/vendor/filetime/.travis.yml new file mode 100644 index 0000000000000..001cdd259ecf3 --- /dev/null +++ b/src/vendor/filetime/.travis.yml @@ -0,0 +1,26 @@ +language: rust +rust: + - stable + - beta + - nightly +sudo: false +script: + - cargo build --verbose + - cargo test --verbose + - cargo doc --no-deps +after_success: | + [ $TRAVIS_BRANCH = master ] && + [ $TRAVIS_PULL_REQUEST = false ] && + echo '' > target/doc/index.html && + pip install ghp-import --user $USER && + $HOME/.local/bin/ghp-import -n target/doc && + git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages +notifications: + email: + on_success: never +env: + global: + secure: dsIj09BQvGF872zKmqzG+WwCl7gfqwsnxcm3GZlAMgyLYm4juvHOwCRhIERCN3BCxPvdlSRKhe9Rwmp1RkiKuqTK3ITUTAy29Maf2vuL1T+zcdpZE0t6JSCU1gbEwzCA2foB1jzgy7Q47EzeJusmGNwibscjYmXKlH6JCFwTobM= +os: + - linux + - osx diff --git a/src/vendor/filetime/Cargo.toml b/src/vendor/filetime/Cargo.toml new file mode 100644 index 0000000000000..971eaf601469d --- /dev/null +++ b/src/vendor/filetime/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "filetime" +authors = ["Alex Crichton "] +version = "0.1.10" +license = "MIT/Apache-2.0" +readme = "README.md" +keywords = ["timestamp", "mtime"] +repository = "https://github.com/alexcrichton/filetime" +homepage = "https://github.com/alexcrichton/filetime" +documentation = "http://alexcrichton.com/filetime" +description = """ +Platform-agnostic accessors of timestamps in File metadata +""" + +[dependencies] +libc = "0.2" + +[dev-dependencies] +tempdir = "0.3" diff --git a/src/vendor/filetime/LICENSE-APACHE b/src/vendor/filetime/LICENSE-APACHE new file mode 100644 index 0000000000000..16fe87b06e802 --- /dev/null +++ b/src/vendor/filetime/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/src/vendor/filetime/LICENSE-MIT b/src/vendor/filetime/LICENSE-MIT new file mode 100644 index 0000000000000..39e0ed6602151 --- /dev/null +++ b/src/vendor/filetime/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/vendor/filetime/README.md b/src/vendor/filetime/README.md new file mode 100644 index 0000000000000..0422084e7e206 --- /dev/null +++ b/src/vendor/filetime/README.md @@ -0,0 +1,25 @@ +# filetime + +[![Build Status](https://travis-ci.org/alexcrichton/filetime.svg?branch=master)](https://travis-ci.org/alexcrichton/filetime) +[![Build status](https://ci.appveyor.com/api/projects/status/9tatexq47i3ee13k?svg=true)](https://ci.appveyor.com/project/alexcrichton/filetime) + +[Documentation](http://alexcrichton.com/filetime/filetime/index.html) + +A helper library for inspecting the various timestamps of files in Rust. This +library takes into account cross-platform differences in terms of where the +timestamps are located, what they are called, and how to convert them into a +platform-independent representation. + +```toml +# Cargo.toml +[dependencies] +filetime = "0.1" +``` + +# License + +`filetime` is primarily distributed under the terms of both the MIT license and +the Apache License (Version 2.0), with portions covered by various BSD-like +licenses. + +See LICENSE-APACHE, and LICENSE-MIT for details. diff --git a/src/vendor/filetime/appveyor.yml b/src/vendor/filetime/appveyor.yml new file mode 100644 index 0000000000000..6a1b8dc19c039 --- /dev/null +++ b/src/vendor/filetime/appveyor.yml @@ -0,0 +1,17 @@ +environment: + matrix: + - TARGET: x86_64-pc-windows-msvc + - TARGET: i686-pc-windows-msvc + - TARGET: i686-pc-windows-gnu +install: + - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" + - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" + - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin + - SET PATH=%PATH%;C:\MinGW\bin + - rustc -V + - cargo -V + +build: false + +test_script: + - cargo test --verbose diff --git a/src/vendor/filetime/src/lib.rs b/src/vendor/filetime/src/lib.rs new file mode 100644 index 0000000000000..aa6bec1dfefe3 --- /dev/null +++ b/src/vendor/filetime/src/lib.rs @@ -0,0 +1,305 @@ +//! Timestamps for files in Rust +//! +//! This library provides platform-agnostic inspection of the various timestamps +//! present in the standard `fs::Metadata` structure. +//! +//! # Installation +//! +//! Add this to you `Cargo.toml`: +//! +//! ```toml +//! [dependencies] +//! filetime = "0.1" +//! ``` +//! +//! # Usage +//! +//! ```no_run +//! use std::fs; +//! use filetime::FileTime; +//! +//! let metadata = fs::metadata("foo.txt").unwrap(); +//! +//! let mtime = FileTime::from_last_modification_time(&metadata); +//! println!("{}", mtime); +//! +//! let atime = FileTime::from_last_access_time(&metadata); +//! assert!(mtime < atime); +//! +//! // Inspect values that can be interpreted across platforms +//! println!("{}", mtime.seconds_relative_to_1970()); +//! println!("{}", mtime.nanoseconds()); +//! +//! // Print the platform-specific value of seconds +//! println!("{}", mtime.seconds()); +//! ``` + +extern crate libc; + +#[cfg(unix)] use std::os::unix::prelude::*; +#[cfg(windows)] use std::os::windows::prelude::*; + +use std::fmt; +use std::fs; +use std::io; +use std::path::Path; + +/// A helper structure to represent a timestamp for a file. +/// +/// The actual value contined within is platform-specific and does not have the +/// same meaning across platforms, but comparisons and stringification can be +/// significant among the same platform. +#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone, Hash)] +pub struct FileTime { + seconds: u64, + nanos: u32, +} + +impl FileTime { + /// Creates a new timestamp representing a 0 time. + /// + /// Useful for creating the base of a cmp::max chain of times. + pub fn zero() -> FileTime { + FileTime { seconds: 0, nanos: 0 } + } + + /// Creates a new instance of `FileTime` with a number of seconds and + /// nanoseconds relative to January 1, 1970. + /// + /// Note that this is typically the relative point that Unix time stamps are + /// from, but on Windows the native time stamp is relative to January 1, + /// 1601 so the return value of `seconds` from the returned `FileTime` + /// instance may not be the same as that passed in. + pub fn from_seconds_since_1970(seconds: u64, nanos: u32) -> FileTime { + FileTime { + seconds: seconds + if cfg!(windows) {11644473600} else {0}, + nanos: nanos, + } + } + + /// Creates a new timestamp from the last modification time listed in the + /// specified metadata. + /// + /// The returned value corresponds to the `mtime` field of `stat` on Unix + /// platforms and the `ftLastWriteTime` field on Windows platforms. + pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime { + #[cfg(unix)] + fn imp(meta: &fs::Metadata) -> FileTime { + FileTime::from_os_repr(meta.mtime() as u64, meta.mtime_nsec() as u32) + } + #[cfg(windows)] + fn imp(meta: &fs::Metadata) -> FileTime { + FileTime::from_os_repr(meta.last_write_time()) + } + imp(meta) + } + + /// Creates a new timestamp from the last access time listed in the + /// specified metadata. + /// + /// The returned value corresponds to the `atime` field of `stat` on Unix + /// platforms and the `ftLastAccessTime` field on Windows platforms. + pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime { + #[cfg(unix)] + fn imp(meta: &fs::Metadata) -> FileTime { + FileTime::from_os_repr(meta.atime() as u64, meta.atime_nsec() as u32) + } + #[cfg(windows)] + fn imp(meta: &fs::Metadata) -> FileTime { + FileTime::from_os_repr(meta.last_access_time()) + } + imp(meta) + } + + /// Creates a new timestamp from the creation time listed in the specified + /// metadata. + /// + /// The returned value corresponds to the `birthtime` field of `stat` on + /// Unix platforms and the `ftCreationTime` field on Windows platforms. Note + /// that not all Unix platforms have this field available and may return + /// `None` in some circumstances. + pub fn from_creation_time(meta: &fs::Metadata) -> Option { + macro_rules! birthtim { + ($(($e:expr, $i:ident)),*) => { + #[cfg(any($(target_os = $e),*))] + fn imp(meta: &fs::Metadata) -> Option { + $( + #[cfg(target_os = $e)] + use std::os::$i::fs::MetadataExt; + )* + let raw = meta.as_raw_stat(); + Some(FileTime::from_os_repr(raw.st_birthtime as u64, + raw.st_birthtime_nsec as u32)) + } + + #[cfg(all(not(windows), + $(not(target_os = $e)),*))] + fn imp(_meta: &fs::Metadata) -> Option { + None + } + } + } + + birthtim! { + ("bitrig", bitrig), + ("freebsd", freebsd), + ("ios", ios), + ("macos", macos), + ("openbsd", openbsd) + } + + #[cfg(windows)] + fn imp(meta: &fs::Metadata) -> Option { + Some(FileTime::from_os_repr(meta.last_access_time())) + } + imp(meta) + } + + #[cfg(windows)] + fn from_os_repr(time: u64) -> FileTime { + // Windows write times are in 100ns intervals, so do a little math to + // get it into the right representation. + FileTime { + seconds: time / (1_000_000_000 / 100), + nanos: ((time % (1_000_000_000 / 100)) * 100) as u32, + } + } + + #[cfg(unix)] + fn from_os_repr(seconds: u64, nanos: u32) -> FileTime { + FileTime { seconds: seconds, nanos: nanos } + } + + /// Returns the whole number of seconds represented by this timestamp. + /// + /// Note that this value's meaning is **platform specific**. On Unix + /// platform time stamps are typically relative to January 1, 1970, but on + /// Windows platforms time stamps are relative to January 1, 1601. + pub fn seconds(&self) -> u64 { self.seconds } + + /// Returns the whole number of seconds represented by this timestamp, + /// relative to the Unix epoch start of January 1, 1970. + /// + /// Note that this does not return the same value as `seconds` for Windows + /// platforms as seconds are relative to a different date there. + pub fn seconds_relative_to_1970(&self) -> u64 { + self.seconds - if cfg!(windows) {11644473600} else {0} + } + + /// Returns the nanosecond precision of this timestamp. + /// + /// The returned value is always less than one billion and represents a + /// portion of a second forward from the seconds returned by the `seconds` + /// method. + pub fn nanoseconds(&self) -> u32 { self.nanos } +} + +impl fmt::Display for FileTime { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}.{:09}s", self.seconds, self.nanos) + } +} + +/// Set the last access and modification times for a file on the filesystem. +/// +/// This function will set the `atime` and `mtime` metadata fields for a file +/// on the local filesystem, returning any error encountered. +pub fn set_file_times

(p: P, atime: FileTime, mtime: FileTime) + -> io::Result<()> where P: AsRef { + set_file_times_(p.as_ref(), atime, mtime) +} + +#[cfg(unix)] +fn set_file_times_(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> { + use std::ffi::CString; + use libc::{timeval, time_t, suseconds_t, utimes}; + + let times = [to_timeval(&atime), to_timeval(&mtime)]; + let p = try!(CString::new(p.as_os_str().as_bytes())); + return unsafe { + if utimes(p.as_ptr() as *const _, times.as_ptr()) == 0 { + Ok(()) + } else { + Err(io::Error::last_os_error()) + } + }; + + fn to_timeval(ft: &FileTime) -> timeval { + timeval { + tv_sec: ft.seconds() as time_t, + tv_usec: (ft.nanoseconds() / 1000) as suseconds_t, + } + } +} + +#[cfg(windows)] +#[allow(bad_style)] +fn set_file_times_(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> { + use std::fs::OpenOptions; + + type BOOL = i32; + type HANDLE = *mut u8; + type DWORD = u32; + #[repr(C)] + struct FILETIME { + dwLowDateTime: u32, + dwHighDateTime: u32, + } + extern "system" { + fn SetFileTime(hFile: HANDLE, + lpCreationTime: *const FILETIME, + lpLastAccessTime: *const FILETIME, + lpLastWriteTime: *const FILETIME) -> BOOL; + } + + let f = try!(OpenOptions::new().write(true).open(p)); + let atime = to_filetime(&atime); + let mtime = to_filetime(&mtime); + return unsafe { + let ret = SetFileTime(f.as_raw_handle() as *mut _, + 0 as *const _, + &atime, &mtime); + if ret != 0 { + Ok(()) + } else { + Err(io::Error::last_os_error()) + } + }; + + fn to_filetime(ft: &FileTime) -> FILETIME { + let intervals = ft.seconds() * (1_000_000_000 / 100) + + ((ft.nanoseconds() as u64) / 100); + FILETIME { + dwLowDateTime: intervals as DWORD, + dwHighDateTime: (intervals >> 32) as DWORD, + } + } +} + +#[cfg(test)] +mod tests { + extern crate tempdir; + + use std::fs::{self, File}; + use self::tempdir::TempDir; + use super::{FileTime, set_file_times}; + + #[test] + fn set_file_times_test() { + let td = TempDir::new("filetime").unwrap(); + let path = td.path().join("foo.txt"); + File::create(&path).unwrap(); + + let metadata = fs::metadata(&path).unwrap(); + let mtime = FileTime::from_last_modification_time(&metadata); + let atime = FileTime::from_last_access_time(&metadata); + set_file_times(&path, atime, mtime).unwrap(); + + let new_mtime = FileTime::from_seconds_since_1970(10_000, 0); + set_file_times(&path, atime, new_mtime).unwrap(); + + let metadata = fs::metadata(&path).unwrap(); + let mtime = FileTime::from_last_modification_time(&metadata); + assert_eq!(mtime, new_mtime); + } +} diff --git a/src/vendor/gcc/.cargo-checksum.json b/src/vendor/gcc/.cargo-checksum.json new file mode 100644 index 0000000000000..efe1ebb7d44c3 --- /dev/null +++ b/src/vendor/gcc/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"5cee7774cf6d876246a0ae0f8362cceeecec5924b751049c945faac9342565ff","Cargo.toml":"2634dedd87889b33a794e31b41a8d8d4713ef40382be3d464229707679bd83da","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ecb2d93f4c81edbd48d8742ff7887dc0a4530a5890967839090bbc972d49bebe","appveyor.yml":"46c77d913eaa45871296942c2cd96ef092c9dcaf19201cb5c500a5107faeb06f","src/bin/gcc-shim.rs":"11edfe1fc6f932bd42ffffda5145833302bc163e0b87dc0d54f4bd0997ad4708","src/lib.rs":"5eb0e311367226ed0420f5e2dac10cc35fc0a3be639a612b6e8ea6d24f646634","src/registry.rs":"3e2a42581ebb82e325dd5600c6571cef937b35003b2927dc618967f5238a2058","src/windows_registry.rs":"906653c020ffe9d572e435f3fc3a8892d9e0a13240ba297db01ce0a288e08cdb","tests/cc_env.rs":"d92c5e3d3d43ac244e63b2cd2c93a521fcf124bf1ccf8d4c6bfa7f8333d88976","tests/support/mod.rs":"d11ed0db4dda5ecf5fb970c9b0c56428cd47421a2742f07032e2cc6b0a0f07e2","tests/test.rs":"164220f11be2eebc20315826513999970660a82feff8cc4b15b4e9d73d98324e"},"package":"553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"} \ No newline at end of file diff --git a/src/vendor/gcc/.cargo-ok b/src/vendor/gcc/.cargo-ok new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/vendor/gcc/.gitignore b/src/vendor/gcc/.gitignore new file mode 100644 index 0000000000000..a9d37c560c6ab --- /dev/null +++ b/src/vendor/gcc/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/src/vendor/gcc/.travis.yml b/src/vendor/gcc/.travis.yml new file mode 100644 index 0000000000000..6b508b9d8bc97 --- /dev/null +++ b/src/vendor/gcc/.travis.yml @@ -0,0 +1,40 @@ +language: rust +rust: + - stable + - beta + - nightly +sudo: false +install: + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then OS=unknown-linux-gnu; else OS=apple-darwin; fi + - export TARGET=$ARCH-$OS + - curl https://static.rust-lang.org/rustup.sh | + sh -s -- --add-target=$TARGET --disable-sudo -y --prefix=`rustc --print sysroot` +before_script: + - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH +script: + - cargo build --verbose + - cargo test --verbose + - cargo test --verbose --features parallel + - cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET + - cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET --features parallel + - cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET --release + - cargo doc + - rustdoc --test README.md -L target/debug -L target/debug/deps +after_success: + - travis-cargo --only nightly doc-upload +env: + global: + secure: ilbcq9zX+UaiBcwqkBGldeanbEQus9npLsi0/nF1PUxKbQsoWSVtVOehAD8Hy92D3hX2npIRyNL8GxBn85XEcBYc1h7DiWUhLcXfZie79v8Ly/qboHCfZLXlB1ofbypbyQfouEdOE9zHf0ZILYVpAgUkliv6KuVShsrKNlbn4QE= + matrix: + - ARCH=x86_64 + - ARCH=i686 +notifications: + email: + on_success: never +os: + - linux + - osx +addons: + apt: + packages: + - g++-multilib diff --git a/src/vendor/gcc/Cargo.toml b/src/vendor/gcc/Cargo.toml new file mode 100644 index 0000000000000..fd51ce0e9f457 --- /dev/null +++ b/src/vendor/gcc/Cargo.toml @@ -0,0 +1,23 @@ +[package] + +name = "gcc" +version = "0.3.38" +authors = ["Alex Crichton "] +license = "MIT/Apache-2.0" +repository = "https://github.com/alexcrichton/gcc-rs" +documentation = "http://alexcrichton.com/gcc-rs" +description = """ +A build-time dependency for Cargo build scripts to assist in invoking the native +C compiler to compile native C code into a static archive to be linked into Rust +code. +""" +keywords = ["build-dependencies"] + +[dependencies] +rayon = { version = "0.4", optional = true } + +[features] +parallel = ["rayon"] + +[dev-dependencies] +tempdir = "0.3" diff --git a/src/vendor/gcc/LICENSE-APACHE b/src/vendor/gcc/LICENSE-APACHE new file mode 100644 index 0000000000000..16fe87b06e802 --- /dev/null +++ b/src/vendor/gcc/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/src/vendor/gcc/LICENSE-MIT b/src/vendor/gcc/LICENSE-MIT new file mode 100644 index 0000000000000..39e0ed6602151 --- /dev/null +++ b/src/vendor/gcc/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/vendor/gcc/README.md b/src/vendor/gcc/README.md new file mode 100644 index 0000000000000..ecc79c6735266 --- /dev/null +++ b/src/vendor/gcc/README.md @@ -0,0 +1,161 @@ +# gcc-rs + +A library to compile C/C++ code into a Rust library/application. + +[![Build Status](https://travis-ci.org/alexcrichton/gcc-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/gcc-rs) +[![Build status](https://ci.appveyor.com/api/projects/status/onu270iw98h81nwv?svg=true)](https://ci.appveyor.com/project/alexcrichton/gcc-rs) + +[Documentation](http://alexcrichton.com/gcc-rs) + +A simple library meant to be used as a build dependency with Cargo packages in +order to build a set of C/C++ files into a static archive. Note that while this +crate is called "gcc", it actually calls out to the most relevant compile for +a platform, for example using `cl` on MSVC. That is, this crate does indeed work +on MSVC! + +## Using gcc-rs + +First, you'll want to both add a build script for your crate (`build.rs`) and +also add this crate to your `Cargo.toml` via: + +```toml +[package] +# ... +build = "build.rs" + +[build-dependencies] +gcc = "0.3" +``` + +Next up, you'll want to write a build script like so: + +```rust,no_run +// build.rs + +extern crate gcc; + +fn main() { + gcc::compile_library("libfoo.a", &["foo.c", "bar.c"]); +} +``` + +And that's it! Running `cargo build` should take care of the rest and your Rust +application will now have the C files `foo.c` and `bar.c` compiled into it. You +can call the functions in Rust by declaring functions in your Rust code like so: + +``` +extern { + fn foo_function(); + fn bar_function(); +} + +pub fn call() { + unsafe { + foo_function(); + bar_function(); + } +} + +fn main() { + // ... +} +``` + +## External configuration via environment variables + +To control the programs and flags used for building, the builder can set a +number of different environment variables. + +* `CFLAGS` - a series of space separated flags passed to "gcc". Note that + individual flags cannot currently contain spaces, so doing + something like: "-L=foo\ bar" is not possible. +* `CC` - the actual C compiler used. Note that this is used as an exact + executable name, so (for example) no extra flags can be passed inside + this variable, and the builder must ensure that there aren't any + trailing spaces. This compiler must understand the `-c` flag. For + certain `TARGET`s, it also is assumed to know about other flags (most + common is `-fPIC`). +* `AR` - the `ar` (archiver) executable to use to build the static library. + +Each of these variables can also be supplied with certain prefixes and suffixes, +in the following prioritized order: + +1. `_` - for example, `CC_x86_64-unknown-linux-gnu` +2. `_` - for example, `CC_x86_64_unknown_linux_gnu` +3. `_` - for example, `HOST_CC` or `TARGET_CFLAGS` +4. `` - a plain `CC`, `AR` as above. + +If none of these variables exist, gcc-rs uses built-in defaults + +In addition to the the above optional environment variables, `gcc-rs` has some +functions with hard requirements on some variables supplied by [cargo's +build-script driver][cargo] that it has the `TARGET`, `OUT_DIR`, `OPT_LEVEL`, +and `HOST` variables. + +[cargo]: http://doc.crates.io/build-script.html#inputs-to-the-build-script + +## Optional features + +Currently gcc-rs supports parallel compilation (think `make -jN`) but this +feature is turned off by default. To enable gcc-rs to compile C/C++ in parallel, +you can change your dependency to: + +```toml +[build-dependencies] +gcc = { version = "0.3", features = ["parallel"] } +``` + +By default gcc-rs will limit parallelism to `$NUM_JOBS`, or if not present it +will limit it to the number of cpus on the machine. + +## Compile-time Requirements + +To work properly this crate needs access to a C compiler when the build script +is being run. This crate does not ship a C compiler with it. The compiler +required varies per platform, but there are three broad categories: + +* Unix platforms require `cc` to be the C compiler. This can be found by + installing gcc/clang on Linux distributions and Xcode on OSX, for example. +* Windows platforms targeting MSVC (e.g. your target triple ends in `-msvc`) + require `cl.exe` to be available and in `PATH`. This is typically found in + standard Visual Studio installations and the `PATH` can be set up by running + the appropriate developer tools shell. +* Windows platforms targeting MinGW (e.g. your target triple ends in `-gnu`) + require `gcc` to be available in `PATH`. We recommend the + [MinGW-w64](http://mingw-w64.org) distribution, which is using the + [Win-builds](http://win-builds.org) installation system. + You may also acquire it via + [MSYS2](http://msys2.github.io), as explained [here][msys2-help]. Make sure + to install the appropriate architecture corresponding to your installation of + rustc. GCC from older [MinGW](http://www.mingw.org) project is compatible + only with 32-bit rust compiler. + +[msys2-help]: http://github.com/rust-lang/rust#building-on-windows + +## C++ support + +`gcc-rs` supports C++ libraries compilation by using the `cpp` method on +`Config`: + +```rust,no_run +extern crate gcc; + +fn main() { + gcc::Config::new() + .cpp(true) // Switch to C++ library compilation. + .file("foo.cpp") + .compile("libfoo.a"); +} +``` + +When using C++ library compilation switch, the `CXX` and `CXXFLAGS` env +variables are used instead of `CC` and `CFLAGS` and the C++ standard library is +linked to the crate target. + +## License + +`gcc-rs` is primarily distributed under the terms of both the MIT license and +the Apache License (Version 2.0), with portions covered by various BSD-like +licenses. + +See LICENSE-APACHE, and LICENSE-MIT for details. diff --git a/src/vendor/gcc/appveyor.yml b/src/vendor/gcc/appveyor.yml new file mode 100644 index 0000000000000..f6108c66514e9 --- /dev/null +++ b/src/vendor/gcc/appveyor.yml @@ -0,0 +1,35 @@ +environment: + matrix: + - TARGET: x86_64-pc-windows-msvc + ARCH: amd64 + VS: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat + - TARGET: x86_64-pc-windows-msvc + ARCH: amd64 + VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat + - TARGET: i686-pc-windows-msvc + ARCH: x86 + VS: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat + - TARGET: i686-pc-windows-msvc + ARCH: x86 + VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat + - TARGET: x86_64-pc-windows-gnu + MSYS_BITS: 64 + - TARGET: i686-pc-windows-gnu + MSYS_BITS: 32 +install: + - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" + - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" + - if defined VS call "%VS%" %ARCH% + - set PATH=%PATH%;C:\Program Files (x86)\Rust\bin + - if defined MSYS_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS_BITS%\bin + - rustc -V + - cargo -V + +build: false + +test_script: + - cargo test --target %TARGET% + - cargo test --features parallel --target %TARGET% + - cargo test --manifest-path gcc-test/Cargo.toml --target %TARGET% + - cargo test --manifest-path gcc-test/Cargo.toml --features parallel --target %TARGET% + - cargo test --manifest-path gcc-test/Cargo.toml --release --target %TARGET% diff --git a/src/vendor/gcc/src/bin/gcc-shim.rs b/src/vendor/gcc/src/bin/gcc-shim.rs new file mode 100644 index 0000000000000..43fd811d3615b --- /dev/null +++ b/src/vendor/gcc/src/bin/gcc-shim.rs @@ -0,0 +1,23 @@ +#![cfg_attr(test, allow(dead_code))] + +use std::env; +use std::fs::File; +use std::io::prelude::*; +use std::path::PathBuf; + +fn main() { + let out_dir = PathBuf::from(env::var_os("GCCTEST_OUT_DIR").unwrap()); + for i in 0.. { + let candidate = out_dir.join(format!("out{}", i)); + if candidate.exists() { + continue + } + let mut f = File::create(candidate).unwrap(); + for arg in env::args().skip(1) { + writeln!(f, "{}", arg).unwrap(); + } + + File::create(out_dir.join("libfoo.a")).unwrap(); + break + } +} diff --git a/src/vendor/gcc/src/lib.rs b/src/vendor/gcc/src/lib.rs new file mode 100644 index 0000000000000..f319e9313ad7b --- /dev/null +++ b/src/vendor/gcc/src/lib.rs @@ -0,0 +1,959 @@ +//! A library for build scripts to compile custom C code +//! +//! This library is intended to be used as a `build-dependencies` entry in +//! `Cargo.toml`: +//! +//! ```toml +//! [build-dependencies] +//! gcc = "0.3" +//! ``` +//! +//! The purpose of this crate is to provide the utility functions necessary to +//! compile C code into a static archive which is then linked into a Rust crate. +//! The top-level `compile_library` function serves as a convenience and more +//! advanced configuration is available through the `Config` builder. +//! +//! This crate will automatically detect situations such as cross compilation or +//! other environment variables set by Cargo and will build code appropriately. +//! +//! # Examples +//! +//! Use the default configuration: +//! +//! ```no_run +//! extern crate gcc; +//! +//! fn main() { +//! gcc::compile_library("libfoo.a", &["src/foo.c"]); +//! } +//! ``` +//! +//! Use more advanced configuration: +//! +//! ```no_run +//! extern crate gcc; +//! +//! fn main() { +//! gcc::Config::new() +//! .file("src/foo.c") +//! .define("FOO", Some("bar")) +//! .include("src") +//! .compile("libfoo.a"); +//! } +//! ``` + +#![doc(html_root_url = "http://alexcrichton.com/gcc-rs")] +#![cfg_attr(test, deny(warnings))] +#![deny(missing_docs)] + +#[cfg(feature = "parallel")] +extern crate rayon; + +use std::env; +use std::ffi::{OsString, OsStr}; +use std::fs; +use std::io; +use std::path::{PathBuf, Path}; +use std::process::{Command, Stdio}; +use std::io::{BufReader, BufRead, Write}; + +#[cfg(windows)] +mod registry; +pub mod windows_registry; + +/// Extra configuration to pass to gcc. +pub struct Config { + include_directories: Vec, + definitions: Vec<(String, Option)>, + objects: Vec, + flags: Vec, + files: Vec, + cpp: bool, + cpp_link_stdlib: Option>, + cpp_set_stdlib: Option, + target: Option, + host: Option, + out_dir: Option, + opt_level: Option, + debug: Option, + env: Vec<(OsString, OsString)>, + compiler: Option, + archiver: Option, + cargo_metadata: bool, + pic: Option, +} + +/// Configuration used to represent an invocation of a C compiler. +/// +/// This can be used to figure out what compiler is in use, what the arguments +/// to it are, and what the environment variables look like for the compiler. +/// This can be used to further configure other build systems (e.g. forward +/// along CC and/or CFLAGS) or the `to_command` method can be used to run the +/// compiler itself. +pub struct Tool { + path: PathBuf, + args: Vec, + env: Vec<(OsString, OsString)>, +} + +/// Compile a library from the given set of input C files. +/// +/// This will simply compile all files into object files and then assemble them +/// into the output. This will read the standard environment variables to detect +/// cross compilations and such. +/// +/// This function will also print all metadata on standard output for Cargo. +/// +/// # Example +/// +/// ```no_run +/// gcc::compile_library("libfoo.a", &["foo.c", "bar.c"]); +/// ``` +pub fn compile_library(output: &str, files: &[&str]) { + let mut c = Config::new(); + for f in files.iter() { + c.file(*f); + } + c.compile(output) +} + +impl Config { + /// Construct a new instance of a blank set of configuration. + /// + /// This builder is finished with the `compile` function. + pub fn new() -> Config { + Config { + include_directories: Vec::new(), + definitions: Vec::new(), + objects: Vec::new(), + flags: Vec::new(), + files: Vec::new(), + cpp: false, + cpp_link_stdlib: None, + cpp_set_stdlib: None, + target: None, + host: None, + out_dir: None, + opt_level: None, + debug: None, + env: Vec::new(), + compiler: None, + archiver: None, + cargo_metadata: true, + pic: None, + } + } + + /// Add a directory to the `-I` or include path for headers + pub fn include>(&mut self, dir: P) -> &mut Config { + self.include_directories.push(dir.as_ref().to_path_buf()); + self + } + + /// Specify a `-D` variable with an optional value. + pub fn define(&mut self, var: &str, val: Option<&str>) -> &mut Config { + self.definitions.push((var.to_string(), val.map(|s| s.to_string()))); + self + } + + /// Add an arbitrary object file to link in + pub fn object>(&mut self, obj: P) -> &mut Config { + self.objects.push(obj.as_ref().to_path_buf()); + self + } + + /// Add an arbitrary flag to the invocation of the compiler + pub fn flag(&mut self, flag: &str) -> &mut Config { + self.flags.push(flag.to_string()); + self + } + + /// Add a file which will be compiled + pub fn file>(&mut self, p: P) -> &mut Config { + self.files.push(p.as_ref().to_path_buf()); + self + } + + /// Set C++ support. + /// + /// The other `cpp_*` options will only become active if this is set to + /// `true`. + pub fn cpp(&mut self, cpp: bool) -> &mut Config { + self.cpp = cpp; + self + } + + /// Set the standard library to link against when compiling with C++ + /// support. + /// + /// The default value of this property depends on the current target: On + /// OS X `Some("c++")` is used, when compiling for a Visual Studio based + /// target `None` is used and for other targets `Some("stdc++")` is used. + /// + /// A value of `None` indicates that no automatic linking should happen, + /// otherwise cargo will link against the specified library. + /// + /// The given library name must not contain the `lib` prefix. + pub fn cpp_link_stdlib(&mut self, cpp_link_stdlib: Option<&str>) + -> &mut Config { + self.cpp_link_stdlib = Some(cpp_link_stdlib.map(|s| s.into())); + self + } + + /// Force the C++ compiler to use the specified standard library. + /// + /// Setting this option will automatically set `cpp_link_stdlib` to the same + /// value. + /// + /// The default value of this option is always `None`. + /// + /// This option has no effect when compiling for a Visual Studio based + /// target. + /// + /// This option sets the `-stdlib` flag, which is only supported by some + /// compilers (clang, icc) but not by others (gcc). The library will not + /// detect which compiler is used, as such it is the responsibility of the + /// caller to ensure that this option is only used in conjuction with a + /// compiler which supports the `-stdlib` flag. + /// + /// A value of `None` indicates that no specific C++ standard library should + /// be used, otherwise `-stdlib` is added to the compile invocation. + /// + /// The given library name must not contain the `lib` prefix. + pub fn cpp_set_stdlib(&mut self, cpp_set_stdlib: Option<&str>) + -> &mut Config { + self.cpp_set_stdlib = cpp_set_stdlib.map(|s| s.into()); + self.cpp_link_stdlib(cpp_set_stdlib); + self + } + + /// Configures the target this configuration will be compiling for. + /// + /// This option is automatically scraped from the `TARGET` environment + /// variable by build scripts, so it's not required to call this function. + pub fn target(&mut self, target: &str) -> &mut Config { + self.target = Some(target.to_string()); + self + } + + /// Configures the host assumed by this configuration. + /// + /// This option is automatically scraped from the `HOST` environment + /// variable by build scripts, so it's not required to call this function. + pub fn host(&mut self, host: &str) -> &mut Config { + self.host = Some(host.to_string()); + self + } + + /// Configures the optimization level of the generated object files. + /// + /// This option is automatically scraped from the `OPT_LEVEL` environment + /// variable by build scripts, so it's not required to call this function. + pub fn opt_level(&mut self, opt_level: u32) -> &mut Config { + self.opt_level = Some(opt_level.to_string()); + self + } + + /// Configures the optimization level of the generated object files. + /// + /// This option is automatically scraped from the `OPT_LEVEL` environment + /// variable by build scripts, so it's not required to call this function. + pub fn opt_level_str(&mut self, opt_level: &str) -> &mut Config { + self.opt_level = Some(opt_level.to_string()); + self + } + + /// Configures whether the compiler will emit debug information when + /// generating object files. + /// + /// This option is automatically scraped from the `PROFILE` environment + /// variable by build scripts (only enabled when the profile is "debug"), so + /// it's not required to call this function. + pub fn debug(&mut self, debug: bool) -> &mut Config { + self.debug = Some(debug); + self + } + + /// Configures the output directory where all object files and static + /// libraries will be located. + /// + /// This option is automatically scraped from the `OUT_DIR` environment + /// variable by build scripts, so it's not required to call this function. + pub fn out_dir>(&mut self, out_dir: P) -> &mut Config { + self.out_dir = Some(out_dir.as_ref().to_owned()); + self + } + + /// Configures the compiler to be used to produce output. + /// + /// This option is automatically determined from the target platform or a + /// number of environment variables, so it's not required to call this + /// function. + pub fn compiler>(&mut self, compiler: P) -> &mut Config { + self.compiler = Some(compiler.as_ref().to_owned()); + self + } + + /// Configures the tool used to assemble archives. + /// + /// This option is automatically determined from the target platform or a + /// number of environment variables, so it's not required to call this + /// function. + pub fn archiver>(&mut self, archiver: P) -> &mut Config { + self.archiver = Some(archiver.as_ref().to_owned()); + self + } + /// Define whether metadata should be emitted for cargo allowing it to + /// automatically link the binary. Defaults to `true`. + pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Config { + self.cargo_metadata = cargo_metadata; + self + } + + /// Configures whether the compiler will emit position independent code. + /// + /// This option defaults to `false` for `i686` and `windows-gnu` targets and to `true` for all + /// other targets. + pub fn pic(&mut self, pic: bool) -> &mut Config { + self.pic = Some(pic); + self + } + + + #[doc(hidden)] + pub fn __set_env(&mut self, a: A, b: B) -> &mut Config + where A: AsRef, B: AsRef + { + self.env.push((a.as_ref().to_owned(), b.as_ref().to_owned())); + self + } + + /// Run the compiler, generating the file `output` + /// + /// The name `output` must begin with `lib` and end with `.a` + pub fn compile(&self, output: &str) { + assert!(output.starts_with("lib")); + assert!(output.ends_with(".a")); + let lib_name = &output[3..output.len() - 2]; + let dst = self.get_out_dir(); + + let mut objects = Vec::new(); + let mut src_dst = Vec::new(); + for file in self.files.iter() { + let obj = dst.join(file).with_extension("o"); + let obj = if !obj.starts_with(&dst) { + dst.join(obj.file_name().unwrap()) + } else { + obj + }; + fs::create_dir_all(&obj.parent().unwrap()).unwrap(); + src_dst.push((file.to_path_buf(), obj.clone())); + objects.push(obj); + } + self.compile_objects(&src_dst); + self.assemble(lib_name, &dst.join(output), &objects); + + self.print(&format!("cargo:rustc-link-lib=static={}", + &output[3..output.len() - 2])); + self.print(&format!("cargo:rustc-link-search=native={}", dst.display())); + + // Add specific C++ libraries, if enabled. + if self.cpp { + if let Some(stdlib) = self.get_cpp_link_stdlib() { + self.print(&format!("cargo:rustc-link-lib={}", stdlib)); + } + } + } + + #[cfg(feature = "parallel")] + fn compile_objects(&self, objs: &[(PathBuf, PathBuf)]) { + use self::rayon::prelude::*; + + let mut cfg = rayon::Configuration::new(); + if let Ok(amt) = env::var("NUM_JOBS") { + if let Ok(amt) = amt.parse() { + cfg = cfg.set_num_threads(amt); + } + } + drop(rayon::initialize(cfg)); + + objs.par_iter().weight_max().for_each(|&(ref src, ref dst)| { + self.compile_object(src, dst) + }) + } + + #[cfg(not(feature = "parallel"))] + fn compile_objects(&self, objs: &[(PathBuf, PathBuf)]) { + for &(ref src, ref dst) in objs { + self.compile_object(src, dst); + } + } + + fn compile_object(&self, file: &Path, dst: &Path) { + let is_asm = file.extension().and_then(|s| s.to_str()) == Some("asm"); + let msvc = self.get_target().contains("msvc"); + let (mut cmd, name) = if msvc && is_asm { + self.msvc_macro_assembler() + } else { + let compiler = self.get_compiler(); + let mut cmd = compiler.to_command(); + for &(ref a, ref b) in self.env.iter() { + cmd.env(a, b); + } + (cmd, compiler.path.file_name().unwrap() + .to_string_lossy().into_owned()) + }; + if msvc && is_asm { + cmd.arg("/Fo").arg(dst); + } else if msvc { + let mut s = OsString::from("/Fo"); + s.push(&dst); + cmd.arg(s); + } else { + cmd.arg("-o").arg(&dst); + } + cmd.arg(if msvc {"/c"} else {"-c"}); + cmd.arg(file); + + run(&mut cmd, &name); + } + + /// Get the compiler that's in use for this configuration. + /// + /// This function will return a `Tool` which represents the culmination + /// of this configuration at a snapshot in time. The returned compiler can + /// be inspected (e.g. the path, arguments, environment) to forward along to + /// other tools, or the `to_command` method can be used to invoke the + /// compiler itself. + /// + /// This method will take into account all configuration such as debug + /// information, optimization level, include directories, defines, etc. + /// Additionally, the compiler binary in use follows the standard + /// conventions for this path, e.g. looking at the explicitly set compiler, + /// environment variables (a number of which are inspected here), and then + /// falling back to the default configuration. + pub fn get_compiler(&self) -> Tool { + let opt_level = self.get_opt_level(); + let debug = self.get_debug(); + let target = self.get_target(); + let msvc = target.contains("msvc"); + self.print(&format!("debug={} opt-level={}", debug, opt_level)); + + let mut cmd = self.get_base_compiler(); + let nvcc = cmd.path.to_str() + .map(|path| path.contains("nvcc")) + .unwrap_or(false); + + if msvc { + cmd.args.push("/nologo".into()); + cmd.args.push("/MD".into()); // link against msvcrt.dll for now + match &opt_level[..] { + "z" | "s" => cmd.args.push("/Os".into()), + "2" => cmd.args.push("/O2".into()), + "1" => cmd.args.push("/O1".into()), + _ => {} + } + if target.contains("i686") { + cmd.args.push("/SAFESEH".into()); + } else if target.contains("i586") { + cmd.args.push("/SAFESEH".into()); + cmd.args.push("/ARCH:IA32".into()); + } + } else if nvcc { + cmd.args.push(format!("-O{}", opt_level).into()); + } else { + cmd.args.push(format!("-O{}", opt_level).into()); + cmd.args.push("-ffunction-sections".into()); + cmd.args.push("-fdata-sections".into()); + } + for arg in self.envflags(if self.cpp {"CXXFLAGS"} else {"CFLAGS"}) { + cmd.args.push(arg.into()); + } + + if debug { + cmd.args.push(if msvc {"/Z7"} else {"-g"}.into()); + } + + if target.contains("-ios") { + self.ios_flags(&mut cmd); + } else if !msvc { + if target.contains("i686") || target.contains("i586") { + cmd.args.push("-m32".into()); + } else if target.contains("x86_64") || target.contains("powerpc64") { + cmd.args.push("-m64".into()); + } + + if !nvcc && self.pic.unwrap_or(!target.contains("i686") && !target.contains("windows-gnu")) { + cmd.args.push("-fPIC".into()); + } else if nvcc && self.pic.unwrap_or(false) { + cmd.args.push("-Xcompiler".into()); + cmd.args.push("\'-fPIC\'".into()); + } + if target.contains("musl") { + cmd.args.push("-static".into()); + } + + if target.starts_with("armv7-unknown-linux-") { + cmd.args.push("-march=armv7-a".into()); + } + if target.starts_with("armv7-linux-androideabi") { + cmd.args.push("-march=armv7-a".into()); + cmd.args.push("-mfpu=vfpv3-d16".into()); + } + if target.starts_with("arm-unknown-linux-") { + cmd.args.push("-march=armv6".into()); + cmd.args.push("-marm".into()); + } + if target.starts_with("i586-unknown-linux-") { + cmd.args.push("-march=pentium".into()); + } + if target.starts_with("i686-unknown-linux-") { + cmd.args.push("-march=i686".into()); + } + if target.starts_with("thumb") { + cmd.args.push("-mthumb".into()); + + if target.ends_with("eabihf") { + cmd.args.push("-mfloat-abi=hard".into()) + } + } + if target.starts_with("thumbv6m") { + cmd.args.push("-march=armv6-m".into()); + } + if target.starts_with("thumbv7em") { + cmd.args.push("-march=armv7e-m".into()); + } + if target.starts_with("thumbv7m") { + cmd.args.push("-march=armv7-m".into()); + } + } + + if self.cpp && !msvc { + if let Some(ref stdlib) = self.cpp_set_stdlib { + cmd.args.push(format!("-stdlib=lib{}", stdlib).into()); + } + } + + for directory in self.include_directories.iter() { + cmd.args.push(if msvc {"/I"} else {"-I"}.into()); + cmd.args.push(directory.into()); + } + + for flag in self.flags.iter() { + cmd.args.push(flag.into()); + } + + for &(ref key, ref value) in self.definitions.iter() { + let lead = if msvc {"/"} else {"-"}; + if let &Some(ref value) = value { + cmd.args.push(format!("{}D{}={}", lead, key, value).into()); + } else { + cmd.args.push(format!("{}D{}", lead, key).into()); + } + } + cmd + } + + fn msvc_macro_assembler(&self) -> (Command, String) { + let target = self.get_target(); + let tool = if target.contains("x86_64") {"ml64.exe"} else {"ml.exe"}; + let mut cmd = windows_registry::find(&target, tool).unwrap_or_else(|| { + self.cmd(tool) + }); + for directory in self.include_directories.iter() { + cmd.arg("/I").arg(directory); + } + for &(ref key, ref value) in self.definitions.iter() { + if let &Some(ref value) = value { + cmd.arg(&format!("/D{}={}", key, value)); + } else { + cmd.arg(&format!("/D{}", key)); + } + } + + if target.contains("i686") || target.contains("i586") { + cmd.arg("/safeseh"); + } + for flag in self.flags.iter() { + cmd.arg(flag); + } + + (cmd, tool.to_string()) + } + + fn assemble(&self, lib_name: &str, dst: &Path, objects: &[PathBuf]) { + // Delete the destination if it exists as the `ar` tool at least on Unix + // appends to it, which we don't want. + let _ = fs::remove_file(&dst); + + let target = self.get_target(); + if target.contains("msvc") { + let mut cmd = match self.archiver { + Some(ref s) => self.cmd(s), + None => windows_registry::find(&target, "lib.exe") + .unwrap_or(self.cmd("lib.exe")), + }; + let mut out = OsString::from("/OUT:"); + out.push(dst); + run(cmd.arg(out).arg("/nologo") + .args(objects) + .args(&self.objects), "lib.exe"); + + // The Rust compiler will look for libfoo.a and foo.lib, but the + // MSVC linker will also be passed foo.lib, so be sure that both + // exist for now. + let lib_dst = dst.with_file_name(format!("{}.lib", lib_name)); + let _ = fs::remove_file(&lib_dst); + fs::hard_link(&dst, &lib_dst).or_else(|_| { + //if hard-link fails, just copy (ignoring the number of bytes written) + fs::copy(&dst, &lib_dst).map(|_| ()) + }).ok().expect("Copying from {:?} to {:?} failed.");; + } else { + let ar = self.get_ar(); + let cmd = ar.file_name().unwrap().to_string_lossy(); + run(self.cmd(&ar).arg("crs") + .arg(dst) + .args(objects) + .args(&self.objects), &cmd); + } + } + + fn ios_flags(&self, cmd: &mut Tool) { + enum ArchSpec { + Device(&'static str), + Simulator(&'static str), + } + + let target = self.get_target(); + let arch = target.split('-').nth(0).unwrap(); + let arch = match arch { + "arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"), + "armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"), + "arm64" | "aarch64" => ArchSpec::Device("arm64"), + "i386" | "i686" => ArchSpec::Simulator("-m32"), + "x86_64" => ArchSpec::Simulator("-m64"), + _ => fail("Unknown arch for iOS target") + }; + + let sdk = match arch { + ArchSpec::Device(arch) => { + cmd.args.push("-arch".into()); + cmd.args.push(arch.into()); + cmd.args.push("-miphoneos-version-min=7.0".into()); + "iphoneos" + }, + ArchSpec::Simulator(arch) => { + cmd.args.push(arch.into()); + cmd.args.push("-mios-simulator-version-min=7.0".into()); + "iphonesimulator" + } + }; + + self.print(&format!("Detecting iOS SDK path for {}", sdk)); + let sdk_path = self.cmd("xcrun") + .arg("--show-sdk-path") + .arg("--sdk") + .arg(sdk) + .stderr(Stdio::inherit()) + .output() + .unwrap() + .stdout; + + let sdk_path = String::from_utf8(sdk_path).unwrap(); + + cmd.args.push("-isysroot".into()); + cmd.args.push(sdk_path.trim().into()); + } + + fn cmd>(&self, prog: P) -> Command { + let mut cmd = Command::new(prog); + for &(ref a, ref b) in self.env.iter() { + cmd.env(a, b); + } + return cmd + } + + fn get_base_compiler(&self) -> Tool { + if let Some(ref c) = self.compiler { + return Tool::new(c.clone()) + } + let host = self.get_host(); + let target = self.get_target(); + let (env, msvc, gnu, default) = if self.cpp { + ("CXX", "cl.exe", "g++", "c++") + } else { + ("CC", "cl.exe", "gcc", "cc") + }; + self.env_tool(env).map(|(tool, args)| { + let mut t = Tool::new(PathBuf::from(tool)); + for arg in args { + t.args.push(arg.into()); + } + return t + }).or_else(|| { + if target.contains("emscripten") { + if self.cpp { + Some(Tool::new(PathBuf::from("em++"))) + } else { + Some(Tool::new(PathBuf::from("emcc"))) + } + } else { + None + } + }).or_else(|| { + windows_registry::find_tool(&target, "cl.exe") + }).unwrap_or_else(|| { + let compiler = if host.contains("windows") && + target.contains("windows") { + if target.contains("msvc") { + msvc.to_string() + } else { + format!("{}.exe", gnu) + } + } else if target.contains("android") { + format!("{}-{}", target, gnu) + } else if self.get_host() != target { + // CROSS_COMPILE is of the form: "arm-linux-gnueabi-" + let cc_env = self.getenv("CROSS_COMPILE"); + let cross_compile = cc_env.as_ref().map(|s| s.trim_right_matches('-')); + let prefix = cross_compile.or(match &target[..] { + "aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu"), + "arm-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"), + "arm-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"), + "arm-unknown-linux-musleabi" => Some("arm-linux-musleabi"), + "arm-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"), + "arm-unknown-netbsdelf-eabi" => Some("arm--netbsdelf-eabi"), + "armv6-unknown-netbsdelf-eabihf" => Some("armv6--netbsdelf-eabihf"), + "armv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"), + "armv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"), + "armv7-unknown-netbsdelf-eabihf" => Some("armv7--netbsdelf-eabihf"), + "i686-pc-windows-gnu" => Some("i686-w64-mingw32"), + "i686-unknown-linux-musl" => Some("musl"), + "i686-unknown-netbsdelf" => Some("i486--netbsdelf"), + "mips-unknown-linux-gnu" => Some("mips-linux-gnu"), + "mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"), + "mips64-unknown-linux-gnuabi64" => Some("mips64-linux-gnuabi64"), + "mips64el-unknown-linux-gnuabi64" => Some("mips64el-linux-gnuabi64"), + "powerpc-unknown-linux-gnu" => Some("powerpc-linux-gnu"), + "powerpc-unknown-netbsd" => Some("powerpc--netbsd"), + "powerpc64-unknown-linux-gnu" => Some("powerpc-linux-gnu"), + "powerpc64le-unknown-linux-gnu" => Some("powerpc64le-linux-gnu"), + "s390x-unknown-linux-gnu" => Some("s390x-linux-gnu"), + "thumbv6m-none-eabi" => Some("arm-none-eabi"), + "thumbv7em-none-eabi" => Some("arm-none-eabi"), + "thumbv7em-none-eabihf" => Some("arm-none-eabi"), + "thumbv7m-none-eabi" => Some("arm-none-eabi"), + "x86_64-pc-windows-gnu" => Some("x86_64-w64-mingw32"), + "x86_64-rumprun-netbsd" => Some("x86_64-rumprun-netbsd"), + "x86_64-unknown-linux-musl" => Some("musl"), + "x86_64-unknown-netbsd" => Some("x86_64--netbsd"), + _ => None, + }); + match prefix { + Some(prefix) => format!("{}-{}", prefix, gnu), + None => default.to_string(), + } + } else { + default.to_string() + }; + Tool::new(PathBuf::from(compiler)) + }) + } + + fn get_var(&self, var_base: &str) -> Result { + let target = self.get_target(); + let host = self.get_host(); + let kind = if host == target {"HOST"} else {"TARGET"}; + let target_u = target.replace("-", "_"); + let res = self.getenv(&format!("{}_{}", var_base, target)) + .or_else(|| self.getenv(&format!("{}_{}", var_base, target_u))) + .or_else(|| self.getenv(&format!("{}_{}", kind, var_base))) + .or_else(|| self.getenv(var_base)); + + match res { + Some(res) => Ok(res), + None => Err("could not get environment variable".to_string()), + } + } + + fn envflags(&self, name: &str) -> Vec { + self.get_var(name).unwrap_or(String::new()) + .split(|c: char| c.is_whitespace()).filter(|s| !s.is_empty()) + .map(|s| s.to_string()) + .collect() + } + + fn env_tool(&self, name: &str) -> Option<(String, Vec)> { + self.get_var(name).ok().map(|tool| { + let whitelist = ["ccache", "distcc"]; + for t in whitelist.iter() { + if tool.starts_with(t) && tool[t.len()..].starts_with(" ") { + return (t.to_string(), + vec![tool[t.len()..].trim_left().to_string()]) + } + } + (tool, Vec::new()) + }) + } + + /// Returns the default C++ standard library for the current target: `libc++` + /// for OS X and `libstdc++` for anything else. + fn get_cpp_link_stdlib(&self) -> Option { + self.cpp_link_stdlib.clone().unwrap_or_else(|| { + let target = self.get_target(); + if target.contains("msvc") { + None + } else if target.contains("darwin") { + Some("c++".to_string()) + } else { + Some("stdc++".to_string()) + } + }) + } + + fn get_ar(&self) -> PathBuf { + self.archiver.clone().or_else(|| { + self.get_var("AR").map(PathBuf::from).ok() + }).unwrap_or_else(|| { + if self.get_target().contains("android") { + PathBuf::from(format!("{}-ar", self.get_target())) + } else if self.get_target().contains("emscripten") { + PathBuf::from("emar") + } else { + PathBuf::from("ar") + } + }) + } + + fn get_target(&self) -> String { + self.target.clone().unwrap_or_else(|| self.getenv_unwrap("TARGET")) + } + + fn get_host(&self) -> String { + self.host.clone().unwrap_or_else(|| self.getenv_unwrap("HOST")) + } + + fn get_opt_level(&self) -> String { + self.opt_level.as_ref().cloned().unwrap_or_else(|| { + self.getenv_unwrap("OPT_LEVEL") + }) + } + + fn get_debug(&self) -> bool { + self.debug.unwrap_or_else(|| self.getenv_unwrap("PROFILE") == "debug") + } + + fn get_out_dir(&self) -> PathBuf { + self.out_dir.clone().unwrap_or_else(|| { + env::var_os("OUT_DIR").map(PathBuf::from).unwrap() + }) + } + + fn getenv(&self, v: &str) -> Option { + let r = env::var(v).ok(); + self.print(&format!("{} = {:?}", v, r)); + r + } + + fn getenv_unwrap(&self, v: &str) -> String { + match self.getenv(v) { + Some(s) => s, + None => fail(&format!("environment variable `{}` not defined", v)), + } + } + + fn print(&self, s: &str) { + if self.cargo_metadata { + println!("{}", s); + } + } +} + +impl Tool { + fn new(path: PathBuf) -> Tool { + Tool { + path: path, + args: Vec::new(), + env: Vec::new(), + } + } + + /// Converts this compiler into a `Command` that's ready to be run. + /// + /// This is useful for when the compiler needs to be executed and the + /// command returned will already have the initial arguments and environment + /// variables configured. + pub fn to_command(&self) -> Command { + let mut cmd = Command::new(&self.path); + cmd.args(&self.args); + for &(ref k, ref v) in self.env.iter() { + cmd.env(k, v); + } + return cmd + } + + /// Returns the path for this compiler. + /// + /// Note that this may not be a path to a file on the filesystem, e.g. "cc", + /// but rather something which will be resolved when a process is spawned. + pub fn path(&self) -> &Path { + &self.path + } + + /// Returns the default set of arguments to the compiler needed to produce + /// executables for the target this compiler generates. + pub fn args(&self) -> &[OsString] { + &self.args + } + + /// Returns the set of environment variables needed for this compiler to + /// operate. + /// + /// This is typically only used for MSVC compilers currently. + pub fn env(&self) -> &[(OsString, OsString)] { + &self.env + } +} + +fn run(cmd: &mut Command, program: &str) { + println!("running: {:?}", cmd); + // Capture the standard error coming from these programs, and write it out + // with cargo:warning= prefixes. Note that this is a bit wonky to avoid + // requiring the output to be UTF-8, we instead just ship bytes from one + // location to another. + let spawn_result = match cmd.stderr(Stdio::piped()).spawn() { + Ok(mut child) => { + let stderr = BufReader::new(child.stderr.take().unwrap()); + for line in stderr.split(b'\n').filter_map(|l| l.ok()) { + print!("cargo:warning="); + std::io::stdout().write_all(&line).unwrap(); + println!(""); + } + child.wait() + } + Err(e) => Err(e), + }; + let status = match spawn_result { + Ok(status) => status, + Err(ref e) if e.kind() == io::ErrorKind::NotFound => { + let extra = if cfg!(windows) { + " (see https://github.com/alexcrichton/gcc-rs#compile-time-requirements \ + for help)" + } else { + "" + }; + fail(&format!("failed to execute command: {}\nIs `{}` \ + not installed?{}", e, program, extra)); + } + Err(e) => fail(&format!("failed to execute command: {}", e)), + }; + println!("{:?}", status); + if !status.success() { + fail(&format!("command did not execute successfully, got: {}", status)); + } +} + +fn fail(s: &str) -> ! { + println!("\n\n{}\n\n", s); + panic!() +} diff --git a/src/vendor/gcc/src/registry.rs b/src/vendor/gcc/src/registry.rs new file mode 100644 index 0000000000000..d871cd21f3c06 --- /dev/null +++ b/src/vendor/gcc/src/registry.rs @@ -0,0 +1,169 @@ +// Copyright 2015 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. + +use std::ffi::{OsString, OsStr}; +use std::io; +use std::ops::RangeFrom; +use std::os::raw; +use std::os::windows::prelude::*; + +pub struct RegistryKey(Repr); + +type HKEY = *mut u8; +type DWORD = u32; +type LPDWORD = *mut DWORD; +type LPCWSTR = *const u16; +type LPWSTR = *mut u16; +type LONG = raw::c_long; +type PHKEY = *mut HKEY; +type PFILETIME = *mut u8; +type LPBYTE = *mut u8; +type REGSAM = u32; + +const ERROR_SUCCESS: DWORD = 0; +const ERROR_NO_MORE_ITEMS: DWORD = 259; +const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY; +const REG_SZ: DWORD = 1; +const KEY_READ: DWORD = 0x20019; +const KEY_WOW64_32KEY: DWORD = 0x200; + +#[link(name = "advapi32")] +extern "system" { + fn RegOpenKeyExW(key: HKEY, + lpSubKey: LPCWSTR, + ulOptions: DWORD, + samDesired: REGSAM, + phkResult: PHKEY) -> LONG; + fn RegEnumKeyExW(key: HKEY, + dwIndex: DWORD, + lpName: LPWSTR, + lpcName: LPDWORD, + lpReserved: LPDWORD, + lpClass: LPWSTR, + lpcClass: LPDWORD, + lpftLastWriteTime: PFILETIME) -> LONG; + fn RegQueryValueExW(hKey: HKEY, + lpValueName: LPCWSTR, + lpReserved: LPDWORD, + lpType: LPDWORD, + lpData: LPBYTE, + lpcbData: LPDWORD) -> LONG; + fn RegCloseKey(hKey: HKEY) -> LONG; +} + +struct OwnedKey(HKEY); + +enum Repr { + Const(HKEY), + Owned(OwnedKey), +} + +pub struct Iter<'a> { + idx: RangeFrom, + key: &'a RegistryKey, +} + +unsafe impl Sync for Repr {} +unsafe impl Send for Repr {} + +pub static LOCAL_MACHINE: RegistryKey = + RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE)); + +impl RegistryKey { + fn raw(&self) -> HKEY { + match self.0 { + Repr::Const(val) => val, + Repr::Owned(ref val) => val.0, + } + } + + pub fn open(&self, key: &OsStr) -> io::Result { + let key = key.encode_wide().chain(Some(0)).collect::>(); + let mut ret = 0 as *mut _; + let err = unsafe { + RegOpenKeyExW(self.raw(), key.as_ptr(), 0, + KEY_READ | KEY_WOW64_32KEY, &mut ret) + }; + if err == ERROR_SUCCESS as LONG { + Ok(RegistryKey(Repr::Owned(OwnedKey(ret)))) + } else { + Err(io::Error::from_raw_os_error(err as i32)) + } + } + + pub fn iter(&self) -> Iter { + Iter { idx: 0.., key: self } + } + + pub fn query_str(&self, name: &str) -> io::Result { + let name: &OsStr = name.as_ref(); + let name = name.encode_wide().chain(Some(0)).collect::>(); + let mut len = 0; + let mut kind = 0; + unsafe { + let err = RegQueryValueExW(self.raw(), name.as_ptr(), 0 as *mut _, + &mut kind, 0 as *mut _, &mut len); + if err != ERROR_SUCCESS as LONG { + return Err(io::Error::from_raw_os_error(err as i32)) + } + if kind != REG_SZ { + return Err(io::Error::new(io::ErrorKind::Other, + "registry key wasn't a string")) + } + + // The length here is the length in bytes, but we're using wide + // characters so we need to be sure to halve it for the capacity + // passed in. + let mut v = Vec::with_capacity(len as usize / 2); + let err = RegQueryValueExW(self.raw(), name.as_ptr(), 0 as *mut _, + 0 as *mut _, v.as_mut_ptr() as *mut _, + &mut len); + if err != ERROR_SUCCESS as LONG { + return Err(io::Error::from_raw_os_error(err as i32)) + } + v.set_len(len as usize / 2); + + // Some registry keys may have a terminating nul character, but + // we're not interested in that, so chop it off if it's there. + if v[v.len() - 1] == 0 { + v.pop(); + } + Ok(OsString::from_wide(&v)) + } + } +} + +impl Drop for OwnedKey { + fn drop(&mut self) { + unsafe { RegCloseKey(self.0); } + } +} + +impl<'a> Iterator for Iter<'a> { + type Item = io::Result; + + fn next(&mut self) -> Option> { + self.idx.next().and_then(|i| unsafe { + let mut v = Vec::with_capacity(256); + let mut len = v.capacity() as DWORD; + let ret = RegEnumKeyExW(self.key.raw(), i, v.as_mut_ptr(), &mut len, + 0 as *mut _, 0 as *mut _, 0 as *mut _, + 0 as *mut _); + if ret == ERROR_NO_MORE_ITEMS as LONG { + None + } else if ret != ERROR_SUCCESS as LONG { + Some(Err(io::Error::from_raw_os_error(ret as i32))) + } else { + v.set_len(len as usize); + Some(Ok(OsString::from_wide(&v))) + } + }) + } +} diff --git a/src/vendor/gcc/src/windows_registry.rs b/src/vendor/gcc/src/windows_registry.rs new file mode 100644 index 0000000000000..b2c719d27ffdc --- /dev/null +++ b/src/vendor/gcc/src/windows_registry.rs @@ -0,0 +1,425 @@ +// Copyright 2015 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. + +//! A helper module to probe the Windows Registry when looking for +//! windows-specific tools. + +use std::process::Command; + +use Tool; + +macro_rules! otry { + ($expr:expr) => (match $expr { + Some(val) => val, + None => return None, + }) +} + +/// Attempts to find a tool within an MSVC installation using the Windows +/// registry as a point to search from. +/// +/// The `target` argument is the target that the tool should work for (e.g. +/// compile or link for) and the `tool` argument is the tool to find (e.g. +/// `cl.exe` or `link.exe`). +/// +/// This function will return `None` if the tool could not be found, or it will +/// return `Some(cmd)` which represents a command that's ready to execute the +/// tool with the appropriate environment variables set. +/// +/// Note that this function always returns `None` for non-MSVC targets. +pub fn find(target: &str, tool: &str) -> Option { + find_tool(target, tool).map(|c| c.to_command()) +} + +/// Similar to the `find` function above, this function will attempt the same +/// operation (finding a MSVC tool in a local install) but instead returns a +/// `Tool` which may be introspected. +#[cfg(not(windows))] +pub fn find_tool(_target: &str, _tool: &str) -> Option { + None +} + +/// Documented above. +#[cfg(windows)] +pub fn find_tool(target: &str, tool: &str) -> Option { + use std::env; + use std::ffi::OsString; + use std::mem; + use std::path::{Path, PathBuf}; + use registry::{RegistryKey, LOCAL_MACHINE}; + + struct MsvcTool { + tool: PathBuf, + libs: Vec, + path: Vec, + include: Vec, + } + + impl MsvcTool { + fn new(tool: PathBuf) -> MsvcTool { + MsvcTool { + tool: tool, + libs: Vec::new(), + path: Vec::new(), + include: Vec::new(), + } + } + + fn into_tool(self) -> Tool { + let MsvcTool { tool, libs, path, include } = self; + let mut tool = Tool::new(tool.into()); + add_env(&mut tool, "LIB", libs); + add_env(&mut tool, "PATH", path); + add_env(&mut tool, "INCLUDE", include); + return tool + } + } + + // This logic is all tailored for MSVC, if we're not that then bail out + // early. + if !target.contains("msvc") { + return None + } + + // Looks like msbuild isn't located in the same location as other tools like + // cl.exe and lib.exe. To handle this we probe for it manually with + // dedicated registry keys. + if tool.contains("msbuild") { + return find_msbuild(target) + } + + // If VCINSTALLDIR is set, then someone's probably already run vcvars and we + // should just find whatever that indicates. + if env::var_os("VCINSTALLDIR").is_some() { + return env::var_os("PATH").and_then(|path| { + env::split_paths(&path).map(|p| p.join(tool)).find(|p| p.exists()) + }).map(|path| { + Tool::new(path.into()) + }) + } + + // Ok, if we're here, now comes the fun part of the probing. Default shells + // or shells like MSYS aren't really configured to execute `cl.exe` and the + // various compiler tools shipped as part of Visual Studio. Here we try to + // first find the relevant tool, then we also have to be sure to fill in + // environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that + // the tool is actually usable. + + return find_msvc_latest(tool, target, "15.0").or_else(|| { + find_msvc_latest(tool, target, "14.0") + }).or_else(|| { + find_msvc_12(tool, target) + }).or_else(|| { + find_msvc_11(tool, target) + }); + + // For MSVC 14 or newer we need to find the Universal CRT as well as either + // the Windows 10 SDK or Windows 8.1 SDK. + fn find_msvc_latest(tool: &str, target: &str, ver: &str) -> Option { + let vcdir = otry!(get_vc_dir(ver)); + let mut tool = otry!(get_tool(tool, &vcdir, target)); + let sub = otry!(lib_subdir(target)); + let (ucrt, ucrt_version) = otry!(get_ucrt_dir()); + + let ucrt_include = ucrt.join("include").join(&ucrt_version); + tool.include.push(ucrt_include.join("ucrt")); + + let ucrt_lib = ucrt.join("lib").join(&ucrt_version); + tool.libs.push(ucrt_lib.join("ucrt").join(sub)); + + if let Some((sdk, version)) = get_sdk10_dir() { + tool.path.push(sdk.join("bin").join(sub)); + let sdk_lib = sdk.join("lib").join(&version); + tool.libs.push(sdk_lib.join("um").join(sub)); + let sdk_include = sdk.join("include").join(&version); + tool.include.push(sdk_include.join("um")); + tool.include.push(sdk_include.join("winrt")); + tool.include.push(sdk_include.join("shared")); + } else if let Some(sdk) = get_sdk81_dir() { + tool.path.push(sdk.join("bin").join(sub)); + let sdk_lib = sdk.join("lib").join("winv6.3"); + tool.libs.push(sdk_lib.join("um").join(sub)); + let sdk_include = sdk.join("include"); + tool.include.push(sdk_include.join("um")); + tool.include.push(sdk_include.join("winrt")); + tool.include.push(sdk_include.join("shared")); + } else { + return None + } + Some(tool.into_tool()) + } + + // For MSVC 12 we need to find the Windows 8.1 SDK. + fn find_msvc_12(tool: &str, target: &str) -> Option { + let vcdir = otry!(get_vc_dir("12.0")); + let mut tool = otry!(get_tool(tool, &vcdir, target)); + let sub = otry!(lib_subdir(target)); + let sdk81 = otry!(get_sdk81_dir()); + tool.path.push(sdk81.join("bin").join(sub)); + let sdk_lib = sdk81.join("lib").join("winv6.3"); + tool.libs.push(sdk_lib.join("um").join(sub)); + let sdk_include = sdk81.join("include"); + tool.include.push(sdk_include.join("shared")); + tool.include.push(sdk_include.join("um")); + tool.include.push(sdk_include.join("winrt")); + Some(tool.into_tool()) + } + + // For MSVC 11 we need to find the Windows 8 SDK. + fn find_msvc_11(tool: &str, target: &str) -> Option { + let vcdir = otry!(get_vc_dir("11.0")); + let mut tool = otry!(get_tool(tool, &vcdir, target)); + let sub = otry!(lib_subdir(target)); + let sdk8 = otry!(get_sdk8_dir()); + tool.path.push(sdk8.join("bin").join(sub)); + let sdk_lib = sdk8.join("lib").join("win8"); + tool.libs.push(sdk_lib.join("um").join(sub)); + let sdk_include = sdk8.join("include"); + tool.include.push(sdk_include.join("shared")); + tool.include.push(sdk_include.join("um")); + tool.include.push(sdk_include.join("winrt")); + Some(tool.into_tool()) + } + + fn add_env(tool: &mut Tool, env: &str, paths: Vec) { + let prev = env::var_os(env).unwrap_or(OsString::new()); + let prev = env::split_paths(&prev); + let new = paths.into_iter().chain(prev); + tool.env.push((env.to_string().into(), env::join_paths(new).unwrap())); + } + + // Given a possible MSVC installation directory, we look for the linker and + // then add the MSVC library path. + fn get_tool(tool: &str, path: &Path, target: &str) -> Option { + bin_subdir(target).into_iter().map(|(sub, host)| { + (path.join("bin").join(sub).join(tool), + path.join("bin").join(host)) + }).filter(|&(ref path, _)| { + path.is_file() + }).map(|(path, host)| { + let mut tool = MsvcTool::new(path); + tool.path.push(host); + tool + }).filter_map(|mut tool| { + let sub = otry!(vc_lib_subdir(target)); + tool.libs.push(path.join("lib").join(sub)); + tool.include.push(path.join("include")); + Some(tool) + }).next() + } + + // To find MSVC we look in a specific registry key for the version we are + // trying to find. + fn get_vc_dir(ver: &str) -> Option { + let key = r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7"; + let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); + let path = otry!(key.query_str(ver).ok()); + Some(path.into()) + } + + // To find the Universal CRT we look in a specific registry key for where + // all the Universal CRTs are located and then sort them asciibetically to + // find the newest version. While this sort of sorting isn't ideal, it is + // what vcvars does so that's good enough for us. + // + // Returns a pair of (root, version) for the ucrt dir if found + fn get_ucrt_dir() -> Option<(PathBuf, String)> { + let key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots"; + let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); + let root = otry!(key.query_str("KitsRoot10").ok()); + let readdir = otry!(Path::new(&root).join("lib").read_dir().ok()); + let max_libdir = otry!(readdir.filter_map(|dir| { + dir.ok() + }).map(|dir| { + dir.path() + }).filter(|dir| { + dir.components().last().and_then(|c| { + c.as_os_str().to_str() + }).map(|c| { + c.starts_with("10.") && dir.join("ucrt").is_dir() + }).unwrap_or(false) + }).max()); + let version = max_libdir.components().last().unwrap(); + let version = version.as_os_str().to_str().unwrap().to_string(); + Some((root.into(), version)) + } + + // Vcvars finds the correct version of the Windows 10 SDK by looking + // for the include `um\Windows.h` because sometimes a given version will + // only have UCRT bits without the rest of the SDK. Since we only care about + // libraries and not includes, we instead look for `um\x64\kernel32.lib`. + // Since the 32-bit and 64-bit libraries are always installed together we + // only need to bother checking x64, making this code a tiny bit simpler. + // Like we do for the Universal CRT, we sort the possibilities + // asciibetically to find the newest one as that is what vcvars does. + fn get_sdk10_dir() -> Option<(PathBuf, String)> { + let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0"; + let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); + let root = otry!(key.query_str("InstallationFolder").ok()); + let readdir = otry!(Path::new(&root).join("lib").read_dir().ok()); + let mut dirs = readdir.filter_map(|dir| dir.ok()) + .map(|dir| dir.path()) + .collect::>(); + dirs.sort(); + let dir = otry!(dirs.into_iter().rev().filter(|dir| { + dir.join("um").join("x64").join("kernel32.lib").is_file() + }).next()); + let version = dir.components().last().unwrap(); + let version = version.as_os_str().to_str().unwrap().to_string(); + Some((root.into(), version)) + } + + // Interestingly there are several subdirectories, `win7` `win8` and + // `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same + // applies to us. Note that if we were targetting kernel mode drivers + // instead of user mode applications, we would care. + fn get_sdk81_dir() -> Option { + let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1"; + let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); + let root = otry!(key.query_str("InstallationFolder").ok()); + Some(root.into()) + } + + fn get_sdk8_dir() -> Option { + let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0"; + let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); + let root = otry!(key.query_str("InstallationFolder").ok()); + Some(root.into()) + } + + const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0; + const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9; + const X86: u16 = PROCESSOR_ARCHITECTURE_INTEL; + const X86_64: u16 = PROCESSOR_ARCHITECTURE_AMD64; + + // When choosing the tool to use, we have to choose the one which matches + // the target architecture. Otherwise we end up in situations where someone + // on 32-bit Windows is trying to cross compile to 64-bit and it tries to + // invoke the native 64-bit compiler which won't work. + // + // For the return value of this function, the first member of the tuple is + // the folder of the tool we will be invoking, while the second member is + // the folder of the host toolchain for that tool which is essential when + // using a cross linker. We return a Vec since on x64 there are often two + // linkers that can target the architecture we desire. The 64-bit host + // linker is preferred, and hence first, due to 64-bit allowing it more + // address space to work with and potentially being faster. + fn bin_subdir(target: &str) -> Vec<(&'static str, &'static str)> { + let arch = target.split('-').next().unwrap(); + match (arch, host_arch()) { + ("i586", X86) | + ("i686", X86) => vec![("", "")], + ("i586", X86_64) | + ("i686", X86_64) => vec![("amd64_x86", "amd64"), ("", "")], + ("x86_64", X86) => vec![("x86_amd64", "")], + ("x86_64", X86_64) => vec![("amd64", "amd64"), ("x86_amd64", "")], + ("arm", X86) => vec![("x86_arm", "")], + ("arm", X86_64) => vec![("amd64_arm", "amd64"), ("x86_arm", "")], + _ => vec![], + } + } + + fn lib_subdir(target: &str) -> Option<&'static str> { + let arch = target.split('-').next().unwrap(); + match arch { + "i586" | "i686" => Some("x86"), + "x86_64" => Some("x64"), + "arm" => Some("arm"), + _ => None, + } + } + + // MSVC's x86 libraries are not in a subfolder + fn vc_lib_subdir(target: &str) -> Option<&'static str> { + let arch = target.split('-').next().unwrap(); + match arch { + "i586" | "i686" => Some(""), + "x86_64" => Some("amd64"), + "arm" => Some("arm"), + _ => None, + } + } + + #[allow(bad_style)] + fn host_arch() -> u16 { + type DWORD = u32; + type WORD = u16; + type LPVOID = *mut u8; + type DWORD_PTR = usize; + + #[repr(C)] + struct SYSTEM_INFO { + wProcessorArchitecture: WORD, + _wReserved: WORD, + _dwPageSize: DWORD, + _lpMinimumApplicationAddress: LPVOID, + _lpMaximumApplicationAddress: LPVOID, + _dwActiveProcessorMask: DWORD_PTR, + _dwNumberOfProcessors: DWORD, + _dwProcessorType: DWORD, + _dwAllocationGranularity: DWORD, + _wProcessorLevel: WORD, + _wProcessorRevision: WORD, + } + + extern "system" { + fn GetNativeSystemInfo(lpSystemInfo: *mut SYSTEM_INFO); + } + + unsafe { + let mut info = mem::zeroed(); + GetNativeSystemInfo(&mut info); + info.wProcessorArchitecture + } + } + + // Given a registry key, look at all the sub keys and find the one which has + // the maximal numeric value. + // + // Returns the name of the maximal key as well as the opened maximal key. + fn max_version(key: &RegistryKey) -> Option<(OsString, RegistryKey)> { + let mut max_vers = 0; + let mut max_key = None; + for subkey in key.iter().filter_map(|k| k.ok()) { + let val = subkey.to_str().and_then(|s| { + s.trim_left_matches("v").replace(".", "").parse().ok() + }); + let val = match val { + Some(s) => s, + None => continue, + }; + if val > max_vers { + if let Ok(k) = key.open(&subkey) { + max_vers = val; + max_key = Some((subkey, k)); + } + } + } + return max_key + } + + // see http://stackoverflow.com/questions/328017/path-to-msbuild + fn find_msbuild(target: &str) -> Option { + let key = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions"; + LOCAL_MACHINE.open(key.as_ref()).ok().and_then(|key| { + max_version(&key).and_then(|(_vers, key)| { + key.query_str("MSBuildToolsPath").ok() + }) + }).map(|path| { + let mut path = PathBuf::from(path); + path.push("MSBuild.exe"); + let mut tool = Tool::new(path); + if target.contains("x86_64") { + tool.env.push(("Platform".into(), "X64".into())); + } + tool + }) + } +} diff --git a/src/vendor/gcc/tests/cc_env.rs b/src/vendor/gcc/tests/cc_env.rs new file mode 100644 index 0000000000000..559dbe8ad4e50 --- /dev/null +++ b/src/vendor/gcc/tests/cc_env.rs @@ -0,0 +1,49 @@ +extern crate tempdir; +extern crate gcc; + +use std::env; + +mod support; +use support::Test; + +#[test] +fn main() { + ccache(); + distcc(); + ccache_spaces(); +} + +fn ccache() { + let test = Test::gnu(); + test.shim("ccache"); + + env::set_var("CC", "ccache lol-this-is-not-a-compiler foo"); + test.gcc().file("foo.c").compile("libfoo.a"); + + test.cmd(0) + .must_have("lol-this-is-not-a-compiler foo") + .must_have("foo.c") + .must_not_have("ccache"); +} + +fn ccache_spaces() { + let test = Test::gnu(); + test.shim("ccache"); + + env::set_var("CC", "ccache lol-this-is-not-a-compiler foo"); + test.gcc().file("foo.c").compile("libfoo.a"); + test.cmd(0).must_have("lol-this-is-not-a-compiler foo"); +} + +fn distcc() { + let test = Test::gnu(); + test.shim("distcc"); + + env::set_var("CC", "distcc lol-this-is-not-a-compiler foo"); + test.gcc().file("foo.c").compile("libfoo.a"); + + test.cmd(0) + .must_have("lol-this-is-not-a-compiler foo") + .must_have("foo.c") + .must_not_have("distcc"); +} diff --git a/src/vendor/gcc/tests/support/mod.rs b/src/vendor/gcc/tests/support/mod.rs new file mode 100644 index 0000000000000..b5703d2fd8b1a --- /dev/null +++ b/src/vendor/gcc/tests/support/mod.rs @@ -0,0 +1,111 @@ +#![allow(dead_code)] + +use std::env; +use std::ffi::OsStr; +use std::fs::{self, File}; +use std::io::prelude::*; +use std::path::PathBuf; + +use gcc; +use tempdir::TempDir; + +pub struct Test { + pub td: TempDir, + pub gcc: PathBuf, + pub msvc: bool, +} + +pub struct Execution { + args: Vec, +} + +impl Test { + pub fn new() -> Test { + let mut gcc = PathBuf::from(env::current_exe().unwrap()); + gcc.pop(); + gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX)); + Test { + td: TempDir::new("gcc-test").unwrap(), + gcc: gcc, + msvc: false, + } + } + + pub fn gnu() -> Test { + let t = Test::new(); + t.shim("cc").shim("ar"); + return t + } + + pub fn msvc() -> Test { + let mut t = Test::new(); + t.shim("cl").shim("lib.exe"); + t.msvc = true; + return t + } + + pub fn shim(&self, name: &str) -> &Test { + let fname = format!("{}{}", name, env::consts::EXE_SUFFIX); + fs::hard_link(&self.gcc, self.td.path().join(&fname)).or_else(|_| { + fs::copy(&self.gcc, self.td.path().join(&fname)).map(|_| ()) + }).unwrap(); + self + } + + pub fn gcc(&self) -> gcc::Config { + let mut cfg = gcc::Config::new(); + let mut path = env::split_paths(&env::var_os("PATH").unwrap()) + .collect::>(); + path.insert(0, self.td.path().to_owned()); + let target = if self.msvc { + "x86_64-pc-windows-msvc" + } else { + "x86_64-unknown-linux-gnu" + }; + + cfg.target(target).host(target) + .opt_level(2) + .debug(false) + .out_dir(self.td.path()) + .__set_env("PATH", env::join_paths(path).unwrap()) + .__set_env("GCCTEST_OUT_DIR", self.td.path()); + if self.msvc { + cfg.compiler(self.td.path().join("cl")); + cfg.archiver(self.td.path().join("lib.exe")); + } + return cfg + } + + pub fn cmd(&self, i: u32) -> Execution { + let mut s = String::new(); + File::open(self.td.path().join(format!("out{}", i))).unwrap() + .read_to_string(&mut s).unwrap(); + Execution { + args: s.lines().map(|s| s.to_string()).collect(), + } + } +} + +impl Execution { + pub fn must_have>(&self, p: P) -> &Execution { + if !self.has(p.as_ref()) { + panic!("didn't find {:?} in {:?}", p.as_ref(), self.args); + } else { + self + } + } + + pub fn must_not_have>(&self, p: P) -> &Execution { + if self.has(p.as_ref()) { + panic!("found {:?}", p.as_ref()); + } else { + self + } + } + + pub fn has(&self, p: &OsStr) -> bool { + self.args.iter().any(|arg| { + OsStr::new(arg) == p + }) + } +} diff --git a/src/vendor/gcc/tests/test.rs b/src/vendor/gcc/tests/test.rs new file mode 100644 index 0000000000000..1b6a0bd0d10a6 --- /dev/null +++ b/src/vendor/gcc/tests/test.rs @@ -0,0 +1,207 @@ +extern crate gcc; +extern crate tempdir; + +use support::Test; + +mod support; + +#[test] +fn gnu_smoke() { + let test = Test::gnu(); + test.gcc() + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("-O2") + .must_have("foo.c") + .must_not_have("-g") + .must_have("-c") + .must_have("-ffunction-sections") + .must_have("-fdata-sections"); + test.cmd(1).must_have(test.td.path().join("foo.o")); +} + +#[test] +fn gnu_opt_level_1() { + let test = Test::gnu(); + test.gcc() + .opt_level(1) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("-O1") + .must_not_have("-O2"); +} + +#[test] +fn gnu_opt_level_s() { + let test = Test::gnu(); + test.gcc() + .opt_level_str("s") + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("-Os") + .must_not_have("-O1") + .must_not_have("-O2") + .must_not_have("-O3") + .must_not_have("-Oz"); +} + +#[test] +fn gnu_debug() { + let test = Test::gnu(); + test.gcc() + .debug(true) + .file("foo.c").compile("libfoo.a"); + test.cmd(0).must_have("-g"); +} + +#[test] +fn gnu_x86_64() { + for vendor in &["unknown-linux-gnu", "apple-darwin"] { + let target = format!("x86_64-{}", vendor); + let test = Test::gnu(); + test.gcc() + .target(&target) + .host(&target) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("-fPIC") + .must_have("-m64"); + } +} + +#[test] +fn gnu_x86_64_no_pic() { + for vendor in &["unknown-linux-gnu", "apple-darwin"] { + let target = format!("x86_64-{}", vendor); + let test = Test::gnu(); + test.gcc() + .pic(false) + .target(&target) + .host(&target) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_not_have("-fPIC"); + } +} + +#[test] +fn gnu_i686() { + for vendor in &["unknown-linux-gnu", "apple-darwin"] { + let target = format!("i686-{}", vendor); + let test = Test::gnu(); + test.gcc() + .target(&target) + .host(&target) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_not_have("-fPIC") + .must_have("-m32"); + } +} + +#[test] +fn gnu_i686_pic() { + for vendor in &["unknown-linux-gnu", "apple-darwin"] { + let target = format!("i686-{}", vendor); + let test = Test::gnu(); + test.gcc() + .pic(true) + .target(&target) + .host(&target) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("-fPIC"); + } +} + +#[test] +fn gnu_set_stdlib() { + let test = Test::gnu(); + test.gcc() + .cpp_set_stdlib(Some("foo")) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_not_have("-stdlib=foo"); +} + +#[test] +fn gnu_include() { + let test = Test::gnu(); + test.gcc() + .include("foo/bar") + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("-I").must_have("foo/bar"); +} + +#[test] +fn gnu_define() { + let test = Test::gnu(); + test.gcc() + .define("FOO", Some("bar")) + .define("BAR", None) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR"); +} + +#[test] +fn gnu_compile_assembly() { + let test = Test::gnu(); + test.gcc() + .file("foo.S").compile("libfoo.a"); + test.cmd(0).must_have("foo.S"); +} + +#[test] +fn msvc_smoke() { + let test = Test::msvc(); + test.gcc() + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("/O2") + .must_have("foo.c") + .must_not_have("/Z7") + .must_have("/c"); + test.cmd(1).must_have(test.td.path().join("foo.o")); +} + +#[test] +fn msvc_opt_level_0() { + let test = Test::msvc(); + test.gcc() + .opt_level(0) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_not_have("/O2"); +} + +#[test] +fn msvc_debug() { + let test = Test::msvc(); + test.gcc() + .debug(true) + .file("foo.c").compile("libfoo.a"); + test.cmd(0).must_have("/Z7"); +} + +#[test] +fn msvc_include() { + let test = Test::msvc(); + test.gcc() + .include("foo/bar") + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("/I").must_have("foo/bar"); +} + +#[test] +fn msvc_define() { + let test = Test::msvc(); + test.gcc() + .define("FOO", Some("bar")) + .define("BAR", None) + .file("foo.c").compile("libfoo.a"); + + test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR"); +} diff --git a/src/vendor/getopts/.cargo-checksum.json b/src/vendor/getopts/.cargo-checksum.json new file mode 100644 index 0000000000000..0c13fda1c1168 --- /dev/null +++ b/src/vendor/getopts/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"f01015154ac55bebd8ff25742496135c40395959f772005bdf7c63bc9b373c12","Cargo.toml":"a027aa6d21622b42c545707ba04f78341cc28079b46da775827ab1ec37fe3ca7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"4002d78e71c4e1fb82c77590eddb999371f40dce037d895f96e6d6df42c728d3","appveyor.yml":"da991211b72fa6f231af7adb84c9fb72f5a9131d1c0a3d47b8ceffe5a82c8542","src/lib.rs":"9512dd4ec1053c9fc61f630d869053ca50c55e0839e3ab7091246a8654423bf0","tests/smoke.rs":"26a95ac42e42b766ae752fe8531fb740fd147d5cdff352dec0763d175ce91806"},"package":"d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"} \ No newline at end of file diff --git a/src/vendor/getopts/.cargo-ok b/src/vendor/getopts/.cargo-ok new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/vendor/getopts/.gitignore b/src/vendor/getopts/.gitignore new file mode 100644 index 0000000000000..4fffb2f89cbd8 --- /dev/null +++ b/src/vendor/getopts/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/src/vendor/getopts/.travis.yml b/src/vendor/getopts/.travis.yml new file mode 100644 index 0000000000000..d7e3f4787aea5 --- /dev/null +++ b/src/vendor/getopts/.travis.yml @@ -0,0 +1,20 @@ +language: rust +rust: + - 1.0.0 + - beta + - nightly +sudo: false +before_script: + - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH +script: + - cargo build --verbose + - cargo test --verbose + - cargo doc --no-deps +after_success: + - travis-cargo --only nightly doc-upload +env: + global: + secure: by+Jo/boBPbcF5c1N6RNCA008oJm2aRFE5T0SUc3OIfTXxY08dZc0WCBJCHrplp44VjpeKRp/89Y+k1CKncIeU8LiS6ZgsKqaQcCglE2O1KS90B6FYB7+rBqT3ib25taq1nW38clnBHYHV9nz4gOElSdKGRxCcBy+efQ5ZXr2tY= +notifications: + email: + on_success: never diff --git a/src/vendor/getopts/Cargo.toml b/src/vendor/getopts/Cargo.toml new file mode 100644 index 0000000000000..f84899fe8120e --- /dev/null +++ b/src/vendor/getopts/Cargo.toml @@ -0,0 +1,16 @@ +[package] + +name = "getopts" +version = "0.2.14" +authors = ["The Rust Project Developers"] +license = "MIT/Apache-2.0" +readme = "README.md" +repository = "https://github.com/rust-lang/getopts" +documentation = "http://doc.rust-lang.org/getopts" +homepage = "https://github.com/rust-lang/getopts" +description = """ +getopts-like option parsing. +""" + +[dev-dependencies] +log = "0.3" diff --git a/src/vendor/getopts/LICENSE-APACHE b/src/vendor/getopts/LICENSE-APACHE new file mode 100644 index 0000000000000..16fe87b06e802 --- /dev/null +++ b/src/vendor/getopts/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/src/vendor/getopts/LICENSE-MIT b/src/vendor/getopts/LICENSE-MIT new file mode 100644 index 0000000000000..39d4bdb5acd31 --- /dev/null +++ b/src/vendor/getopts/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/vendor/getopts/README.md b/src/vendor/getopts/README.md new file mode 100644 index 0000000000000..c19f48fb06b5c --- /dev/null +++ b/src/vendor/getopts/README.md @@ -0,0 +1,23 @@ +getopts +=== + +A Rust library for option parsing for CLI utilities. + +[![Build Status](https://travis-ci.org/rust-lang/getopts.svg?branch=master)](https://travis-ci.org/rust-lang/getopts) + +[Documentation](http://doc.rust-lang.org/getopts) + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +getopts = "0.2.4" +``` + +and this to your crate root: + +```rust +extern crate getopts; +``` diff --git a/src/vendor/getopts/appveyor.yml b/src/vendor/getopts/appveyor.yml new file mode 100644 index 0000000000000..6a1b8dc19c039 --- /dev/null +++ b/src/vendor/getopts/appveyor.yml @@ -0,0 +1,17 @@ +environment: + matrix: + - TARGET: x86_64-pc-windows-msvc + - TARGET: i686-pc-windows-msvc + - TARGET: i686-pc-windows-gnu +install: + - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" + - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" + - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin + - SET PATH=%PATH%;C:\MinGW\bin + - rustc -V + - cargo -V + +build: false + +test_script: + - cargo test --verbose diff --git a/src/vendor/getopts/src/lib.rs b/src/vendor/getopts/src/lib.rs new file mode 100644 index 0000000000000..8f0c866fae906 --- /dev/null +++ b/src/vendor/getopts/src/lib.rs @@ -0,0 +1,1831 @@ +// Copyright 2012-2014 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. +// +// ignore-lexer-test FIXME #15677 + +//! Simple getopt alternative. +//! +//! Construct a vector of options, either by using `reqopt`, `optopt`, and +//! `optflag` or by building them from components yourself, and pass them to +//! `getopts`, along with a vector of actual arguments (not including +//! `argv[0]`). You'll either get a failure code back, or a match. You'll have +//! to verify whether the amount of 'free' arguments in the match is what you +//! expect. Use `opt_*` accessors to get argument values out of the matches +//! object. +//! +//! Single-character options are expected to appear on the command line with a +//! single preceding dash; multiple-character options are expected to be +//! proceeded by two dashes. Options that expect an argument accept their +//! argument following either a space or an equals sign. Single-character +//! options don't require the space. +//! +//! # Usage +//! +//! This crate is [on crates.io](https://crates.io/crates/getopts) and can be +//! used by adding `getopts` to the dependencies in your project's `Cargo.toml`. +//! +//! ```toml +//! [dependencies] +//! getopts = "0.2" +//! ``` +//! +//! and this to your crate root: +//! +//! ```rust +//! extern crate getopts; +//! ``` +//! +//! # Example +//! +//! The following example shows simple command line parsing for an application +//! that requires an input file to be specified, accepts an optional output file +//! name following `-o`, and accepts both `-h` and `--help` as optional flags. +//! +//! ```{.rust} +//! extern crate getopts; +//! use getopts::Options; +//! use std::env; +//! +//! fn do_work(inp: &str, out: Option) { +//! println!("{}", inp); +//! match out { +//! Some(x) => println!("{}", x), +//! None => println!("No Output"), +//! } +//! } +//! +//! fn print_usage(program: &str, opts: Options) { +//! let brief = format!("Usage: {} FILE [options]", program); +//! print!("{}", opts.usage(&brief)); +//! } +//! +//! fn main() { +//! let args: Vec = env::args().collect(); +//! let program = args[0].clone(); +//! +//! let mut opts = Options::new(); +//! opts.optopt("o", "", "set output file name", "NAME"); +//! opts.optflag("h", "help", "print this help menu"); +//! let matches = match opts.parse(&args[1..]) { +//! Ok(m) => { m } +//! Err(f) => { panic!(f.to_string()) } +//! }; +//! if matches.opt_present("h") { +//! print_usage(&program, opts); +//! return; +//! } +//! let output = matches.opt_str("o"); +//! let input = if !matches.free.is_empty() { +//! matches.free[0].clone() +//! } else { +//! print_usage(&program, opts); +//! return; +//! }; +//! do_work(&input, output); +//! } +//! ``` + +#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://doc.rust-lang.org/getopts/")] +#![deny(missing_docs)] +#![cfg_attr(test, deny(warnings))] +#![cfg_attr(rust_build, feature(staged_api))] +#![cfg_attr(rust_build, staged_api)] +#![cfg_attr(rust_build, + unstable(feature = "rustc_private", + reason = "use the crates.io `getopts` library instead"))] + +#[cfg(test)] #[macro_use] extern crate log; + +use self::Name::*; +use self::HasArg::*; +use self::Occur::*; +use self::Fail::*; +use self::Optval::*; +use self::SplitWithinState::*; +use self::Whitespace::*; +use self::LengthLimit::*; + +use std::error::Error; +use std::ffi::OsStr; +use std::fmt; +use std::iter::{repeat, IntoIterator}; +use std::result; + +/// A description of the options that a program can handle. +pub struct Options { + grps: Vec, + parsing_style : ParsingStyle +} + +impl Options { + /// Create a blank set of options. + pub fn new() -> Options { + Options { + grps: Vec::new(), + parsing_style: ParsingStyle::FloatingFrees + } + } + + /// Set the parsing style. + pub fn parsing_style(&mut self, style: ParsingStyle) -> &mut Options { + self.parsing_style = style; + self + } + + /// Create a generic option group, stating all parameters explicitly. + pub fn opt(&mut self, short_name: &str, long_name: &str, desc: &str, + hint: &str, hasarg: HasArg, occur: Occur) -> &mut Options { + let len = short_name.len(); + assert!(len == 1 || len == 0); + self.grps.push(OptGroup { + short_name: short_name.to_string(), + long_name: long_name.to_string(), + hint: hint.to_string(), + desc: desc.to_string(), + hasarg: hasarg, + occur: occur + }); + self + } + + /// Create a long option that is optional and does not take an argument. + /// + /// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none + /// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none + /// * `desc` - Description for usage help + pub fn optflag(&mut self, short_name: &str, long_name: &str, desc: &str) + -> &mut Options { + let len = short_name.len(); + assert!(len == 1 || len == 0); + self.grps.push(OptGroup { + short_name: short_name.to_string(), + long_name: long_name.to_string(), + hint: "".to_string(), + desc: desc.to_string(), + hasarg: No, + occur: Optional + }); + self + } + + /// Create a long option that can occur more than once and does not + /// take an argument. + /// + /// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none + /// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none + /// * `desc` - Description for usage help + pub fn optflagmulti(&mut self, short_name: &str, long_name: &str, desc: &str) + -> &mut Options { + let len = short_name.len(); + assert!(len == 1 || len == 0); + self.grps.push(OptGroup { + short_name: short_name.to_string(), + long_name: long_name.to_string(), + hint: "".to_string(), + desc: desc.to_string(), + hasarg: No, + occur: Multi + }); + self + } + + /// Create a long option that is optional and takes an optional argument. + /// + /// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none + /// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none + /// * `desc` - Description for usage help + /// * `hint` - Hint that is used in place of the argument in the usage help, + /// e.g. `"FILE"` for a `-o FILE` option + pub fn optflagopt(&mut self, short_name: &str, long_name: &str, desc: &str, + hint: &str) -> &mut Options { + let len = short_name.len(); + assert!(len == 1 || len == 0); + self.grps.push(OptGroup { + short_name: short_name.to_string(), + long_name: long_name.to_string(), + hint: hint.to_string(), + desc: desc.to_string(), + hasarg: Maybe, + occur: Optional + }); + self + } + + /// Create a long option that is optional, takes an argument, and may occur + /// multiple times. + /// + /// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none + /// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none + /// * `desc` - Description for usage help + /// * `hint` - Hint that is used in place of the argument in the usage help, + /// e.g. `"FILE"` for a `-o FILE` option + pub fn optmulti(&mut self, short_name: &str, long_name: &str, desc: &str, hint: &str) + -> &mut Options { + let len = short_name.len(); + assert!(len == 1 || len == 0); + self.grps.push(OptGroup { + short_name: short_name.to_string(), + long_name: long_name.to_string(), + hint: hint.to_string(), + desc: desc.to_string(), + hasarg: Yes, + occur: Multi + }); + self + } + + /// Create a long option that is optional and takes an argument. + /// + /// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none + /// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none + /// * `desc` - Description for usage help + /// * `hint` - Hint that is used in place of the argument in the usage help, + /// e.g. `"FILE"` for a `-o FILE` option + pub fn optopt(&mut self, short_name: &str, long_name: &str, desc: &str, hint: &str) + -> &mut Options { + let len = short_name.len(); + assert!(len == 1 || len == 0); + self.grps.push(OptGroup { + short_name: short_name.to_string(), + long_name: long_name.to_string(), + hint: hint.to_string(), + desc: desc.to_string(), + hasarg: Yes, + occur: Optional + }); + self + } + + /// Create a long option that is required and takes an argument. + /// + /// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none + /// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none + /// * `desc` - Description for usage help + /// * `hint` - Hint that is used in place of the argument in the usage help, + /// e.g. `"FILE"` for a `-o FILE` option + pub fn reqopt(&mut self, short_name: &str, long_name: &str, desc: &str, hint: &str) + -> &mut Options { + let len = short_name.len(); + assert!(len == 1 || len == 0); + self.grps.push(OptGroup { + short_name: short_name.to_string(), + long_name: long_name.to_string(), + hint: hint.to_string(), + desc: desc.to_string(), + hasarg: Yes, + occur: Req + }); + self + } + + /// Parse command line arguments according to the provided options. + /// + /// On success returns `Ok(Matches)`. Use methods such as `opt_present` + /// `opt_str`, etc. to interrogate results. + /// # Panics + /// + /// Returns `Err(Fail)` on failure: use the `Debug` implementation of `Fail` + /// to display information about it. + pub fn parse(&self, args: C) -> Result + where C::Item: AsRef + { + let opts: Vec = self.grps.iter().map(|x| x.long_to_short()).collect(); + let n_opts = opts.len(); + + fn f(_x: usize) -> Vec { return Vec::new(); } + + let mut vals = (0 .. n_opts).map(f).collect::>(); + let mut free: Vec = Vec::new(); + let args = try!(args.into_iter().map(|i| { + i.as_ref().to_str().ok_or_else(|| { + Fail::UnrecognizedOption(format!("{:?}", i.as_ref())) + }).map(|s| s.to_owned()) + }).collect::<::std::result::Result, _>>()); + let l = args.len(); + let mut i = 0; + while i < l { + let cur = args[i].clone(); + let curlen = cur.len(); + if !is_arg(&cur) { + match self.parsing_style { + ParsingStyle::FloatingFrees => free.push(cur), + ParsingStyle::StopAtFirstFree => { + while i < l { + free.push(args[i].clone()); + i += 1; + } + break; + } + } + } else if cur == "--" { + let mut j = i + 1; + while j < l { free.push(args[j].clone()); j += 1; } + break; + } else { + let mut names; + let mut i_arg = None; + if cur.as_bytes()[1] == b'-' { + let tail = &cur[2..curlen]; + let tail_eq: Vec<&str> = tail.splitn(2, '=').collect(); + if tail_eq.len() <= 1 { + names = vec!(Long(tail.to_string())); + } else { + names = + vec!(Long(tail_eq[0].to_string())); + i_arg = Some(tail_eq[1].to_string()); + } + } else { + names = Vec::new(); + for (j, ch) in cur.char_indices().skip(1) { + let opt = Short(ch); + + /* In a series of potential options (eg. -aheJ), if we + see one which takes an argument, we assume all + subsequent characters make up the argument. This + allows options such as -L/usr/local/lib/foo to be + interpreted correctly + */ + + let opt_id = match find_opt(&opts, opt.clone()) { + Some(id) => id, + None => return Err(UnrecognizedOption(opt.to_string())) + }; + + names.push(opt); + + let arg_follows = match opts[opt_id].hasarg { + Yes | Maybe => true, + No => false + }; + + if arg_follows { + let next = j + ch.len_utf8(); + if next < curlen { + i_arg = Some(cur[next..curlen].to_string()); + break; + } + } + } + } + let mut name_pos = 0; + for nm in names.iter() { + name_pos += 1; + let optid = match find_opt(&opts, (*nm).clone()) { + Some(id) => id, + None => return Err(UnrecognizedOption(nm.to_string())) + }; + match opts[optid].hasarg { + No => { + if name_pos == names.len() && !i_arg.is_none() { + return Err(UnexpectedArgument(nm.to_string())); + } + vals[optid].push(Given); + } + Maybe => { + if !i_arg.is_none() { + vals[optid] + .push(Val((i_arg.clone()) + .unwrap())); + } else if name_pos < names.len() || i + 1 == l || + is_arg(&args[i + 1]) { + vals[optid].push(Given); + } else { + i += 1; + vals[optid].push(Val(args[i].clone())); + } + } + Yes => { + if !i_arg.is_none() { + vals[optid].push(Val(i_arg.clone().unwrap())); + } else if i + 1 == l { + return Err(ArgumentMissing(nm.to_string())); + } else { + i += 1; + vals[optid].push(Val(args[i].clone())); + } + } + } + } + } + i += 1; + } + for i in 0 .. n_opts { + let n = vals[i].len(); + let occ = opts[i].occur; + if occ == Req && n == 0 { + return Err(OptionMissing(opts[i].name.to_string())); + } + if occ != Multi && n > 1 { + return Err(OptionDuplicated(opts[i].name.to_string())); + } + } + Ok(Matches { + opts: opts, + vals: vals, + free: free + }) + } + + /// Derive a short one-line usage summary from a set of long options. + #[allow(deprecated)] // connect => join in 1.3 + pub fn short_usage(&self, program_name: &str) -> String { + let mut line = format!("Usage: {} ", program_name); + line.push_str(&self.grps.iter() + .map(format_option) + .collect::>() + .connect(" ")); + line + } + + /// Derive a usage message from a set of options. + #[allow(deprecated)] // connect => join in 1.3 + pub fn usage(&self, brief: &str) -> String { + let desc_sep = format!("\n{}", repeat(" ").take(24).collect::()); + + let any_short = self.grps.iter().any(|optref| { + optref.short_name.len() > 0 + }); + + let rows = self.grps.iter().map(|optref| { + let OptGroup{short_name, + long_name, + hint, + desc, + hasarg, + ..} = (*optref).clone(); + + let mut row = " ".to_string(); + + // short option + match short_name.len() { + 0 => { + if any_short { + row.push_str(" "); + } + } + 1 => { + row.push('-'); + row.push_str(&short_name); + if long_name.len() > 0 { + row.push_str(", "); + } else { + // Only a single space here, so that any + // argument is printed in the correct spot. + row.push(' '); + } + } + _ => panic!("the short name should only be 1 ascii char long"), + } + + // long option + match long_name.len() { + 0 => {} + _ => { + row.push_str("--"); + row.push_str(&long_name); + row.push(' '); + } + } + + // arg + match hasarg { + No => {} + Yes => row.push_str(&hint), + Maybe => { + row.push('['); + row.push_str(&hint); + row.push(']'); + } + } + + // FIXME: #5516 should be graphemes not codepoints + // here we just need to indent the start of the description + let rowlen = row.chars().count(); + if rowlen < 24 { + for _ in 0 .. 24 - rowlen { + row.push(' '); + } + } else { + row.push_str(&desc_sep) + } + + // Normalize desc to contain words separated by one space character + let mut desc_normalized_whitespace = String::new(); + for word in desc.split(|c: char| c.is_whitespace()) + .filter(|s| !s.is_empty()) { + desc_normalized_whitespace.push_str(word); + desc_normalized_whitespace.push(' '); + } + + // FIXME: #5516 should be graphemes not codepoints + let mut desc_rows = Vec::new(); + each_split_within(&desc_normalized_whitespace, + 54, + |substr| { + desc_rows.push(substr.to_string()); + true + }); + + // FIXME: #5516 should be graphemes not codepoints + // wrapped description + row.push_str(&desc_rows.connect(&desc_sep)); + + row + }); + + format!("{}\n\nOptions:\n{}\n", brief, + rows.collect::>().connect("\n")) + } +} + +/// What parsing style to use when parsing arguments. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum ParsingStyle { + /// Flags and "free" arguments can be freely inter-mixed. + FloatingFrees, + /// As soon as a "free" argument (i.e. non-flag) is encountered, stop + /// considering any remaining arguments as flags. + StopAtFirstFree +} + +/// Name of an option. Either a string or a single char. +#[derive(Clone, PartialEq, Eq)] +enum Name { + /// A string representing the long name of an option. + /// For example: "help" + Long(String), + /// A char representing the short name of an option. + /// For example: 'h' + Short(char), +} + +/// Describes whether an option has an argument. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum HasArg { + /// The option requires an argument. + Yes, + /// The option takes no argument. + No, + /// The option argument is optional. + Maybe, +} + +/// Describes how often an option may occur. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum Occur { + /// The option occurs once. + Req, + /// The option occurs at most once. + Optional, + /// The option occurs zero or more times. + Multi, +} + +/// A description of a possible option. +#[derive(Clone, PartialEq, Eq)] +struct Opt { + /// Name of the option + name: Name, + /// Whether it has an argument + hasarg: HasArg, + /// How often it can occur + occur: Occur, + /// Which options it aliases + aliases: Vec, +} + +/// One group of options, e.g., both `-h` and `--help`, along with +/// their shared description and properties. +#[derive(Clone, PartialEq, Eq)] +struct OptGroup { + /// Short name of the option, e.g. `h` for a `-h` option + short_name: String, + /// Long name of the option, e.g. `help` for a `--help` option + long_name: String, + /// Hint for argument, e.g. `FILE` for a `-o FILE` option + hint: String, + /// Description for usage help text + desc: String, + /// Whether option has an argument + hasarg: HasArg, + /// How often it can occur + occur: Occur +} + +/// Describes whether an option is given at all or has a value. +#[derive(Clone, PartialEq, Eq)] +enum Optval { + Val(String), + Given, +} + +/// The result of checking command line arguments. Contains a vector +/// of matches and a vector of free strings. +#[derive(Clone, PartialEq, Eq)] +pub struct Matches { + /// Options that matched + opts: Vec, + /// Values of the Options that matched + vals: Vec>, + /// Free string fragments + pub free: Vec, +} + +/// The type returned when the command line does not conform to the +/// expected format. Use the `Debug` implementation to output detailed +/// information. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Fail { + /// The option requires an argument but none was passed. + ArgumentMissing(String), + /// The passed option is not declared among the possible options. + UnrecognizedOption(String), + /// A required option is not present. + OptionMissing(String), + /// A single occurrence option is being used multiple times. + OptionDuplicated(String), + /// There's an argument being passed to a non-argument option. + UnexpectedArgument(String), +} + +impl Error for Fail { + fn description(&self) -> &str { + match *self { + ArgumentMissing(_) => "missing argument", + UnrecognizedOption(_) => "unrecognized option", + OptionMissing(_) => "missing option", + OptionDuplicated(_) => "duplicated option", + UnexpectedArgument(_) => "unexpected argument", + } + } +} + +/// The type of failure that occurred. +#[derive(Clone, Copy, PartialEq, Eq)] +#[allow(missing_docs)] +pub enum FailType { + ArgumentMissing_, + UnrecognizedOption_, + OptionMissing_, + OptionDuplicated_, + UnexpectedArgument_, +} + +/// The result of parsing a command line with a set of options. +pub type Result = result::Result; + +impl Name { + fn from_str(nm: &str) -> Name { + if nm.len() == 1 { + Short(nm.as_bytes()[0] as char) + } else { + Long(nm.to_string()) + } + } + + fn to_string(&self) -> String { + match *self { + Short(ch) => ch.to_string(), + Long(ref s) => s.to_string() + } + } +} + +impl OptGroup { + /// Translate OptGroup into Opt. + /// (Both short and long names correspond to different Opts). + fn long_to_short(&self) -> Opt { + let OptGroup { + short_name, + long_name, + hasarg, + occur, + .. + } = (*self).clone(); + + match (short_name.len(), long_name.len()) { + (0,0) => panic!("this long-format option was given no name"), + (0,_) => Opt { + name: Long((long_name)), + hasarg: hasarg, + occur: occur, + aliases: Vec::new() + }, + (1,0) => Opt { + name: Short(short_name.as_bytes()[0] as char), + hasarg: hasarg, + occur: occur, + aliases: Vec::new() + }, + (1,_) => Opt { + name: Long((long_name)), + hasarg: hasarg, + occur: occur, + aliases: vec!( + Opt { + name: Short(short_name.as_bytes()[0] as char), + hasarg: hasarg, + occur: occur, + aliases: Vec::new() + } + ) + }, + (_,_) => panic!("something is wrong with the long-form opt") + } + } +} + +impl Matches { + fn opt_vals(&self, nm: &str) -> Vec { + match find_opt(&self.opts, Name::from_str(nm)) { + Some(id) => self.vals[id].clone(), + None => panic!("No option '{}' defined", nm) + } + } + + fn opt_val(&self, nm: &str) -> Option { + self.opt_vals(nm).into_iter().next() + } + + /// Returns true if an option was matched. + pub fn opt_present(&self, nm: &str) -> bool { + !self.opt_vals(nm).is_empty() + } + + /// Returns the number of times an option was matched. + pub fn opt_count(&self, nm: &str) -> usize { + self.opt_vals(nm).len() + } + + /// Returns true if any of several options were matched. + pub fn opts_present(&self, names: &[String]) -> bool { + names.iter().any(|nm| { + match find_opt(&self.opts, Name::from_str(&nm)) { + Some(id) if !self.vals[id].is_empty() => true, + _ => false, + } + }) + } + + /// Returns the string argument supplied to one of several matching options or `None`. + pub fn opts_str(&self, names: &[String]) -> Option { + names.iter().filter_map(|nm| { + match self.opt_val(&nm) { + Some(Val(s)) => Some(s), + _ => None, + } + }).next() + } + + /// Returns a vector of the arguments provided to all matches of the given + /// option. + /// + /// Used when an option accepts multiple values. + pub fn opt_strs(&self, nm: &str) -> Vec { + self.opt_vals(nm).into_iter().filter_map(|v| { + match v { + Val(s) => Some(s), + _ => None, + } + }).collect() + } + + /// Returns the string argument supplied to a matching option or `None`. + pub fn opt_str(&self, nm: &str) -> Option { + match self.opt_val(nm) { + Some(Val(s)) => Some(s), + _ => None, + } + } + + + /// Returns the matching string, a default, or `None`. + /// + /// Returns `None` if the option was not present, `def` if the option was + /// present but no argument was provided, and the argument if the option was + /// present and an argument was provided. + pub fn opt_default(&self, nm: &str, def: &str) -> Option { + match self.opt_val(nm) { + Some(Val(s)) => Some(s), + Some(_) => Some(def.to_string()), + None => None, + } + } + +} + +fn is_arg(arg: &str) -> bool { + arg.as_bytes().get(0) == Some(&b'-') && arg.len() > 1 +} + +fn find_opt(opts: &[Opt], nm: Name) -> Option { + // Search main options. + let pos = opts.iter().position(|opt| opt.name == nm); + if pos.is_some() { + return pos + } + + // Search in aliases. + for candidate in opts.iter() { + if candidate.aliases.iter().position(|opt| opt.name == nm).is_some() { + return opts.iter().position(|opt| opt.name == candidate.name); + } + } + + None +} + +impl fmt::Display for Fail { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ArgumentMissing(ref nm) => { + write!(f, "Argument to option '{}' missing.", *nm) + } + UnrecognizedOption(ref nm) => { + write!(f, "Unrecognized option: '{}'.", *nm) + } + OptionMissing(ref nm) => { + write!(f, "Required option '{}' missing.", *nm) + } + OptionDuplicated(ref nm) => { + write!(f, "Option '{}' given more than once.", *nm) + } + UnexpectedArgument(ref nm) => { + write!(f, "Option '{}' does not take an argument.", *nm) + } + } + } +} + +fn format_option(opt: &OptGroup) -> String { + let mut line = String::new(); + + if opt.occur != Req { + line.push('['); + } + + // Use short_name if possible, but fall back to long_name. + if opt.short_name.len() > 0 { + line.push('-'); + line.push_str(&opt.short_name); + } else { + line.push_str("--"); + line.push_str(&opt.long_name); + } + + if opt.hasarg != No { + line.push(' '); + if opt.hasarg == Maybe { + line.push('['); + } + line.push_str(&opt.hint); + if opt.hasarg == Maybe { + line.push(']'); + } + } + + if opt.occur != Req { + line.push(']'); + } + if opt.occur == Multi { + line.push_str(".."); + } + + line +} + +#[derive(Clone, Copy)] +enum SplitWithinState { + A, // leading whitespace, initial state + B, // words + C, // internal and trailing whitespace +} + +#[derive(Clone, Copy)] +enum Whitespace { + Ws, // current char is whitespace + Cr // current char is not whitespace +} + +#[derive(Clone, Copy)] +enum LengthLimit { + UnderLim, // current char makes current substring still fit in limit + OverLim // current char makes current substring no longer fit in limit +} + + +/// Splits a string into substrings with possibly internal whitespace, +/// each of them at most `lim` bytes long. The substrings have leading and trailing +/// whitespace removed, and are only cut at whitespace boundaries. +/// +/// Note: Function was moved here from `std::str` because this module is the only place that +/// uses it, and because it was too specific for a general string function. +/// +/// # Panics +/// +/// Panics during iteration if the string contains a non-whitespace +/// sequence longer than the limit. +fn each_split_within<'a, F>(ss: &'a str, lim: usize, mut it: F) + -> bool where F: FnMut(&'a str) -> bool { + // Just for fun, let's write this as a state machine: + + let mut slice_start = 0; + let mut last_start = 0; + let mut last_end = 0; + let mut state = A; + let mut fake_i = ss.len(); + let mut lim = lim; + + let mut cont = true; + + // if the limit is larger than the string, lower it to save cycles + if lim >= fake_i { + lim = fake_i; + } + + let mut machine = |cont: &mut bool, (i, c): (usize, char)| { + let whitespace = if c.is_whitespace() { Ws } else { Cr }; + let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim }; + + state = match (state, whitespace, limit) { + (A, Ws, _) => { A } + (A, Cr, _) => { slice_start = i; last_start = i; B } + + (B, Cr, UnderLim) => { B } + (B, Cr, OverLim) if (i - last_start + 1) > lim + => panic!("word starting with {} longer than limit!", + &ss[last_start..i + 1]), + (B, Cr, OverLim) => { + *cont = it(&ss[slice_start..last_end]); + slice_start = last_start; + B + } + (B, Ws, UnderLim) => { + last_end = i; + C + } + (B, Ws, OverLim) => { + last_end = i; + *cont = it(&ss[slice_start..last_end]); + A + } + + (C, Cr, UnderLim) => { + last_start = i; + B + } + (C, Cr, OverLim) => { + *cont = it(&ss[slice_start..last_end]); + slice_start = i; + last_start = i; + last_end = i; + B + } + (C, Ws, OverLim) => { + *cont = it(&ss[slice_start..last_end]); + A + } + (C, Ws, UnderLim) => { + C + } + }; + + *cont + }; + + ss.char_indices().all(|x| machine(&mut cont, x)); + + // Let the automaton 'run out' by supplying trailing whitespace + while cont && match state { B | C => true, A => false } { + machine(&mut cont, (fake_i, ' ')); + fake_i += 1; + } + return cont; +} + +#[test] +fn test_split_within() { + fn t(s: &str, i: usize, u: &[String]) { + let mut v = Vec::new(); + each_split_within(s, i, |s| { v.push(s.to_string()); true }); + assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b)); + } + t("", 0, &[]); + t("", 15, &[]); + t("hello", 15, &["hello".to_string()]); + t("\nMary had a little lamb\nLittle lamb\n", 15, &[ + "Mary had a".to_string(), + "little lamb".to_string(), + "Little lamb".to_string() + ]); + t("\nMary had a little lamb\nLittle lamb\n", ::std::usize::MAX, + &["Mary had a little lamb\nLittle lamb".to_string()]); +} + +#[cfg(test)] +mod tests { + use super::{HasArg, Name, Occur, Opt, Options, ParsingStyle}; + use super::Fail::*; + + // Tests for reqopt + #[test] + fn test_reqopt() { + let long_args = vec!("--test=20".to_string()); + let mut opts = Options::new(); + opts.reqopt("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!(m.opt_present("t")); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => { panic!("test_reqopt failed (long arg)"); } + } + let short_args = vec!("-t".to_string(), "20".to_string()); + match opts.parse(&short_args) { + Ok(ref m) => { + assert!((m.opt_present("test"))); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => { panic!("test_reqopt failed (short arg)"); } + } + } + + #[test] + fn test_reqopt_missing() { + let args = vec!("blah".to_string()); + match Options::new() + .reqopt("t", "test", "testing", "TEST") + .parse(&args) { + Err(OptionMissing(_)) => {}, + _ => panic!() + } + } + + #[test] + fn test_reqopt_no_arg() { + let long_args = vec!("--test".to_string()); + let mut opts = Options::new(); + opts.reqopt("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Err(ArgumentMissing(_)) => {}, + _ => panic!() + } + let short_args = vec!("-t".to_string()); + match opts.parse(&short_args) { + Err(ArgumentMissing(_)) => {}, + _ => panic!() + } + } + + #[test] + fn test_reqopt_multi() { + let args = vec!("--test=20".to_string(), "-t".to_string(), "30".to_string()); + match Options::new() + .reqopt("t", "test", "testing", "TEST") + .parse(&args) { + Err(OptionDuplicated(_)) => {}, + _ => panic!() + } + } + + // Tests for optopt + #[test] + fn test_optopt() { + let long_args = vec!("--test=20".to_string()); + let mut opts = Options::new(); + opts.optopt("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => panic!() + } + let short_args = vec!("-t".to_string(), "20".to_string()); + match opts.parse(&short_args) { + Ok(ref m) => { + assert!((m.opt_present("test"))); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => panic!() + } + } + + #[test] + fn test_optopt_missing() { + let args = vec!("blah".to_string()); + match Options::new() + .optopt("t", "test", "testing", "TEST") + .parse(&args) { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + } + _ => panic!() + } + } + + #[test] + fn test_optopt_no_arg() { + let long_args = vec!("--test".to_string()); + let mut opts = Options::new(); + opts.optopt("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Err(ArgumentMissing(_)) => {}, + _ => panic!() + } + let short_args = vec!("-t".to_string()); + match opts.parse(&short_args) { + Err(ArgumentMissing(_)) => {}, + _ => panic!() + } + } + + #[test] + fn test_optopt_multi() { + let args = vec!("--test=20".to_string(), "-t".to_string(), "30".to_string()); + match Options::new() + .optopt("t", "test", "testing", "TEST") + .parse(&args) { + Err(OptionDuplicated(_)) => {}, + _ => panic!() + } + } + + // Tests for optflag + #[test] + fn test_optflag() { + let long_args = vec!("--test".to_string()); + let mut opts = Options::new(); + opts.optflag("t", "test", "testing"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert!(m.opt_present("t")); + } + _ => panic!() + } + let short_args = vec!("-t".to_string()); + match opts.parse(&short_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert!(m.opt_present("t")); + } + _ => panic!() + } + } + + #[test] + fn test_optflag_missing() { + let args = vec!("blah".to_string()); + match Options::new() + .optflag("t", "test", "testing") + .parse(&args) { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + } + _ => panic!() + } + } + + #[test] + fn test_optflag_long_arg() { + let args = vec!("--test=20".to_string()); + match Options::new() + .optflag("t", "test", "testing") + .parse(&args) { + Err(UnexpectedArgument(_)) => {}, + _ => panic!() + } + } + + #[test] + fn test_optflag_multi() { + let args = vec!("--test".to_string(), "-t".to_string()); + match Options::new() + .optflag("t", "test", "testing") + .parse(&args) { + Err(OptionDuplicated(_)) => {}, + _ => panic!() + } + } + + #[test] + fn test_optflag_short_arg() { + let args = vec!("-t".to_string(), "20".to_string()); + match Options::new() + .optflag("t", "test", "testing") + .parse(&args) { + Ok(ref m) => { + // The next variable after the flag is just a free argument + + assert!(m.free[0] == "20"); + } + _ => panic!() + } + } + + // Tests for optflagmulti + #[test] + fn test_optflagmulti_short1() { + let args = vec!("-v".to_string()); + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) { + Ok(ref m) => { + assert_eq!(m.opt_count("v"), 1); + } + _ => panic!() + } + } + + #[test] + fn test_optflagmulti_short2a() { + let args = vec!("-v".to_string(), "-v".to_string()); + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) { + Ok(ref m) => { + assert_eq!(m.opt_count("v"), 2); + } + _ => panic!() + } + } + + #[test] + fn test_optflagmulti_short2b() { + let args = vec!("-vv".to_string()); + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) { + Ok(ref m) => { + assert_eq!(m.opt_count("v"), 2); + } + _ => panic!() + } + } + + #[test] + fn test_optflagmulti_long1() { + let args = vec!("--verbose".to_string()); + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) { + Ok(ref m) => { + assert_eq!(m.opt_count("verbose"), 1); + } + _ => panic!() + } + } + + #[test] + fn test_optflagmulti_long2() { + let args = vec!("--verbose".to_string(), "--verbose".to_string()); + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) { + Ok(ref m) => { + assert_eq!(m.opt_count("verbose"), 2); + } + _ => panic!() + } + } + + #[test] + fn test_optflagmulti_mix() { + let args = vec!("--verbose".to_string(), "-v".to_string(), + "-vv".to_string(), "verbose".to_string()); + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) { + Ok(ref m) => { + assert_eq!(m.opt_count("verbose"), 4); + assert_eq!(m.opt_count("v"), 4); + } + _ => panic!() + } + } + + // Tests for optflagopt + #[test] + fn test_optflagopt() { + let long_args = vec!("--test".to_string()); + let mut opts = Options::new(); + opts.optflag("t", "test", "testing"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert!(m.opt_present("t")); + } + _ => panic!() + } + let short_args = vec!("-t".to_string()); + match opts.parse(&short_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert!(m.opt_present("t")); + } + _ => panic!() + } + let no_args: Vec = vec!(); + match opts.parse(&no_args) { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + } + _ => panic!() + } + } + + // Tests for optmulti + #[test] + fn test_optmulti() { + let long_args = vec!("--test=20".to_string()); + let mut opts = Options::new(); + opts.optmulti("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!((m.opt_present("test"))); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => panic!() + } + let short_args = vec!("-t".to_string(), "20".to_string()); + match opts.parse(&short_args) { + Ok(ref m) => { + assert!((m.opt_present("test"))); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => panic!() + } + } + + #[test] + fn test_optmulti_missing() { + let args = vec!("blah".to_string()); + match Options::new() + .optmulti("t", "test", "testing", "TEST") + .parse(&args) { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + } + _ => panic!() + } + } + + #[test] + fn test_optmulti_no_arg() { + let long_args = vec!("--test".to_string()); + let mut opts = Options::new(); + opts.optmulti("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Err(ArgumentMissing(_)) => {}, + _ => panic!() + } + let short_args = vec!("-t".to_string()); + match opts.parse(&short_args) { + Err(ArgumentMissing(_)) => {}, + _ => panic!() + } + } + + #[test] + fn test_optmulti_multi() { + let args = vec!("--test=20".to_string(), "-t".to_string(), "30".to_string()); + match Options::new() + .optmulti("t", "test", "testing", "TEST") + .parse(&args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!(m.opt_present("t")); + assert_eq!(m.opt_str("t").unwrap(), "20"); + let pair = m.opt_strs("test"); + assert!(pair[0] == "20"); + assert!(pair[1] == "30"); + } + _ => panic!() + } + } + + #[test] + fn test_free_argument_is_hyphen() { + let args = vec!("-".to_string()); + match Options::new().parse(&args) { + Ok(ref m) => { + assert_eq!(m.free.len(), 1); + assert_eq!(m.free[0], "-"); + } + _ => panic!() + } + } + + #[test] + fn test_unrecognized_option() { + let long_args = vec!("--untest".to_string()); + let mut opts = Options::new(); + opts.optmulti("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Err(UnrecognizedOption(_)) => {}, + _ => panic!() + } + let short_args = vec!("-u".to_string()); + match opts.parse(&short_args) { + Err(UnrecognizedOption(_)) => {}, + _ => panic!() + } + } + + #[test] + fn test_combined() { + let args = + vec!("prog".to_string(), + "free1".to_string(), + "-s".to_string(), + "20".to_string(), + "free2".to_string(), + "--flag".to_string(), + "--long=30".to_string(), + "-f".to_string(), + "-m".to_string(), + "40".to_string(), + "-m".to_string(), + "50".to_string(), + "-n".to_string(), + "-A B".to_string(), + "-n".to_string(), + "-60 70".to_string()); + match Options::new() + .optopt("s", "something", "something", "SOMETHING") + .optflag("", "flag", "a flag") + .reqopt("", "long", "hi", "LONG") + .optflag("f", "", "another flag") + .optmulti("m", "", "mmmmmm", "YUM") + .optmulti("n", "", "nothing", "NOTHING") + .optopt("", "notpresent", "nothing to see here", "NOPE") + .parse(&args) { + Ok(ref m) => { + assert!(m.free[0] == "prog"); + assert!(m.free[1] == "free1"); + assert_eq!(m.opt_str("s").unwrap(), "20"); + assert!(m.free[2] == "free2"); + assert!((m.opt_present("flag"))); + assert_eq!(m.opt_str("long").unwrap(), "30"); + assert!((m.opt_present("f"))); + let pair = m.opt_strs("m"); + assert!(pair[0] == "40"); + assert!(pair[1] == "50"); + let pair = m.opt_strs("n"); + assert!(pair[0] == "-A B"); + assert!(pair[1] == "-60 70"); + assert!((!m.opt_present("notpresent"))); + } + _ => panic!() + } + } + + #[test] + fn test_mixed_stop() { + let args = + vec!("-a".to_string(), + "b".to_string(), + "-c".to_string(), + "d".to_string()); + match Options::new() + .parsing_style(ParsingStyle::StopAtFirstFree) + .optflag("a", "", "") + .optopt("c", "", "", "") + .parse(&args) { + Ok(ref m) => { + println!("{}", m.opt_present("c")); + assert!(m.opt_present("a")); + assert!(!m.opt_present("c")); + assert_eq!(m.free.len(), 3); + assert_eq!(m.free[0], "b"); + assert_eq!(m.free[1], "-c"); + assert_eq!(m.free[2], "d"); + } + _ => panic!() + } + } + + #[test] + fn test_mixed_stop_hyphen() { + let args = + vec!("-a".to_string(), + "-".to_string(), + "-c".to_string(), + "d".to_string()); + match Options::new() + .parsing_style(ParsingStyle::StopAtFirstFree) + .optflag("a", "", "") + .optopt("c", "", "", "") + .parse(&args) { + Ok(ref m) => { + println!("{}", m.opt_present("c")); + assert!(m.opt_present("a")); + assert!(!m.opt_present("c")); + assert_eq!(m.free.len(), 3); + assert_eq!(m.free[0], "-"); + assert_eq!(m.free[1], "-c"); + assert_eq!(m.free[2], "d"); + } + _ => panic!() + } + } + + #[test] + fn test_multi() { + let mut opts = Options::new(); + opts.optopt("e", "", "encrypt", "ENCRYPT"); + opts.optopt("", "encrypt", "encrypt", "ENCRYPT"); + opts.optopt("f", "", "flag", "FLAG"); + + let args_single = vec!("-e".to_string(), "foo".to_string()); + let matches_single = &match opts.parse(&args_single) { + Ok(m) => m, + Err(_) => panic!() + }; + assert!(matches_single.opts_present(&["e".to_string()])); + assert!(matches_single.opts_present(&["encrypt".to_string(), "e".to_string()])); + assert!(matches_single.opts_present(&["e".to_string(), "encrypt".to_string()])); + assert!(!matches_single.opts_present(&["encrypt".to_string()])); + assert!(!matches_single.opts_present(&["thing".to_string()])); + assert!(!matches_single.opts_present(&[])); + + assert_eq!(matches_single.opts_str(&["e".to_string()]).unwrap(), "foo"); + assert_eq!(matches_single.opts_str(&["e".to_string(), "encrypt".to_string()]).unwrap(), + "foo"); + assert_eq!(matches_single.opts_str(&["encrypt".to_string(), "e".to_string()]).unwrap(), + "foo"); + + let args_both = vec!("-e".to_string(), "foo".to_string(), "--encrypt".to_string(), + "foo".to_string()); + let matches_both = &match opts.parse(&args_both) { + Ok(m) => m, + Err(_) => panic!() + }; + assert!(matches_both.opts_present(&["e".to_string()])); + assert!(matches_both.opts_present(&["encrypt".to_string()])); + assert!(matches_both.opts_present(&["encrypt".to_string(), "e".to_string()])); + assert!(matches_both.opts_present(&["e".to_string(), "encrypt".to_string()])); + assert!(!matches_both.opts_present(&["f".to_string()])); + assert!(!matches_both.opts_present(&["thing".to_string()])); + assert!(!matches_both.opts_present(&[])); + + assert_eq!(matches_both.opts_str(&["e".to_string()]).unwrap(), "foo"); + assert_eq!(matches_both.opts_str(&["encrypt".to_string()]).unwrap(), "foo"); + assert_eq!(matches_both.opts_str(&["e".to_string(), "encrypt".to_string()]).unwrap(), + "foo"); + assert_eq!(matches_both.opts_str(&["encrypt".to_string(), "e".to_string()]).unwrap(), + "foo"); + } + + #[test] + fn test_nospace() { + let args = vec!("-Lfoo".to_string(), "-M.".to_string()); + let matches = &match Options::new() + .optmulti("L", "", "library directory", "LIB") + .optmulti("M", "", "something", "MMMM") + .parse(&args) { + Ok(m) => m, + Err(_) => panic!() + }; + assert!(matches.opts_present(&["L".to_string()])); + assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "foo"); + assert!(matches.opts_present(&["M".to_string()])); + assert_eq!(matches.opts_str(&["M".to_string()]).unwrap(), "."); + + } + + #[test] + fn test_nospace_conflict() { + let args = vec!("-vvLverbose".to_string(), "-v".to_string() ); + let matches = &match Options::new() + .optmulti("L", "", "library directory", "LIB") + .optflagmulti("v", "verbose", "Verbose") + .parse(&args) { + Ok(m) => m, + Err(e) => panic!( "{}", e ) + }; + assert!(matches.opts_present(&["L".to_string()])); + assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "verbose"); + assert!(matches.opts_present(&["v".to_string()])); + assert_eq!(3, matches.opt_count("v")); + } + + #[test] + fn test_long_to_short() { + let mut short = Opt { + name: Name::Long("banana".to_string()), + hasarg: HasArg::Yes, + occur: Occur::Req, + aliases: Vec::new(), + }; + short.aliases = vec!(Opt { name: Name::Short('b'), + hasarg: HasArg::Yes, + occur: Occur::Req, + aliases: Vec::new() }); + let mut opts = Options::new(); + opts.reqopt("b", "banana", "some bananas", "VAL"); + let ref verbose = opts.grps[0]; + assert!(verbose.long_to_short() == short); + } + + #[test] + fn test_aliases_long_and_short() { + let args = vec!("-a".to_string(), "--apple".to_string(), "-a".to_string()); + + let matches = Options::new() + .optflagmulti("a", "apple", "Desc") + .parse(&args) + .unwrap(); + assert_eq!(3, matches.opt_count("a")); + assert_eq!(3, matches.opt_count("apple")); + } + + #[test] + fn test_usage() { + let mut opts = Options::new(); + opts.reqopt("b", "banana", "Desc", "VAL"); + opts.optopt("a", "012345678901234567890123456789", + "Desc", "VAL"); + opts.optflag("k", "kiwi", "Desc"); + opts.optflagopt("p", "", "Desc", "VAL"); + opts.optmulti("l", "", "Desc", "VAL"); + opts.optflag("", "starfruit", "Starfruit"); + + let expected = +"Usage: fruits + +Options: + -b, --banana VAL Desc + -a, --012345678901234567890123456789 VAL + Desc + -k, --kiwi Desc + -p [VAL] Desc + -l VAL Desc + --starfruit Starfruit +"; + + let generated_usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", generated_usage); + assert_eq!(generated_usage, expected); + } + + #[test] + fn test_usage_description_wrapping() { + // indentation should be 24 spaces + // lines wrap after 78: or rather descriptions wrap after 54 + + let mut opts = Options::new(); + opts.optflag("k", "kiwi", + "This is a long description which won't be wrapped..+.."); // 54 + opts.optflag("a", "apple", + "This is a long description which _will_ be wrapped..+.."); + + let expected = +"Usage: fruits + +Options: + -k, --kiwi This is a long description which won't be wrapped..+.. + -a, --apple This is a long description which _will_ be + wrapped..+.. +"; + + let usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) + } + + #[test] + fn test_usage_description_multibyte_handling() { + let mut opts = Options::new(); + opts.optflag("k", "k\u{2013}w\u{2013}", + "The word kiwi is normally spelled with two i's"); + opts.optflag("a", "apple", + "This \u{201C}description\u{201D} has some characters that could \ +confuse the line wrapping; an apple costs 0.51€ in some parts of Europe."); + + let expected = +"Usage: fruits + +Options: + -k, --k–w– The word kiwi is normally spelled with two i's + -a, --apple This “description” has some characters that could + confuse the line wrapping; an apple costs 0.51€ in + some parts of Europe. +"; + + let usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) + } + + #[test] + fn test_usage_short_only() { + let mut opts = Options::new(); + opts.optopt("k", "", "Kiwi", "VAL"); + opts.optflag("s", "", "Starfruit"); + opts.optflagopt("a", "", "Apple", "TYPE"); + + let expected = +"Usage: fruits + +Options: + -k VAL Kiwi + -s Starfruit + -a [TYPE] Apple +"; + + let usage = opts.usage("Usage: fruits"); + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) + } + + #[test] + fn test_usage_long_only() { + let mut opts = Options::new(); + opts.optopt("", "kiwi", "Kiwi", "VAL"); + opts.optflag("", "starfruit", "Starfruit"); + opts.optflagopt("", "apple", "Apple", "TYPE"); + + let expected = +"Usage: fruits + +Options: + --kiwi VAL Kiwi + --starfruit Starfruit + --apple [TYPE] Apple +"; + + let usage = opts.usage("Usage: fruits"); + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) + } + + #[test] + fn test_short_usage() { + let mut opts = Options::new(); + opts.reqopt("b", "banana", "Desc", "VAL"); + opts.optopt("a", "012345678901234567890123456789", + "Desc", "VAL"); + opts.optflag("k", "kiwi", "Desc"); + opts.optflagopt("p", "", "Desc", "VAL"); + opts.optmulti("l", "", "Desc", "VAL"); + + let expected = "Usage: fruits -b VAL [-a VAL] [-k] [-p [VAL]] [-l VAL]..".to_string(); + let generated_usage = opts.short_usage("fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", generated_usage); + assert_eq!(generated_usage, expected); + } + + #[test] + fn test_args_with_equals() { + let mut opts = Options::new(); + opts.optopt("o", "one", "One", "INFO"); + opts.optopt("t", "two", "Two", "INFO"); + + let args = vec!("--one".to_string(), "A=B".to_string(), + "--two=C=D".to_string()); + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e) + }; + assert_eq!(matches.opts_str(&["o".to_string()]).unwrap(), "A=B"); + assert_eq!(matches.opts_str(&["t".to_string()]).unwrap(), "C=D"); + } +} diff --git a/src/vendor/getopts/tests/smoke.rs b/src/vendor/getopts/tests/smoke.rs new file mode 100644 index 0000000000000..a46f9c0167ab3 --- /dev/null +++ b/src/vendor/getopts/tests/smoke.rs @@ -0,0 +1,8 @@ +extern crate getopts; + +use std::env; + +#[test] +fn main() { + getopts::Options::new().parse(env::args()).unwrap(); +} diff --git a/src/vendor/libc/.cargo-checksum.json b/src/vendor/libc/.cargo-checksum.json new file mode 100644 index 0000000000000..56c0bb8d2559c --- /dev/null +++ b/src/vendor/libc/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"7150ee9391a955b2ef7e0762fc61c0c1aab167620ca36d88d78062d93b8334ba",".travis.yml":"ca5e05b688a8c9a3215de3b38f22f4b468f73d26738a80bd939af503ddb222e1","Cargo.toml":"4b1f0d59b5fb939877a639d1d4cac5a12440c6e2d366edf2abcb45c46e3dcd3e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"c1f46480074340f17f1c3ea989b28e6b632b9d324e57792293a60399b90bfda0","appveyor.yml":"c0d70c650b6231e6ff78a352224f1a522a9be69d9da4251adbaddb3f0393294d","ci/README.md":"be804f15e2128e5fd4b160cb0b13cff5f19e7d77b55ec5254aa6fd8731c84f0d","ci/docker/aarch64-unknown-linux-gnu/Dockerfile":"62ca7317439f9c303990e897450a91cd467be05eb75dfc01456d417932ac8672","ci/docker/arm-linux-androideabi/Dockerfile":"c3d60f2ba389e60e59cb6973542751c66a0e7bd484e11589c8ee7346e9ff2bab","ci/docker/arm-unknown-linux-gnueabihf/Dockerfile":"e349f7caa463adbde8d6ec4d2b9f7720ed81c77f48d75bbfb78c89751f55c2dc","ci/docker/i686-unknown-linux-gnu/Dockerfile":"07e9df6ba91025cbec7ae81ade63f8cfb8a54c5e1e5a8f8def0617e17bd59db0","ci/docker/i686-unknown-linux-musl/Dockerfile":"1a4d064adff4a8f58773305567cfe5d915bcd0762bcb0e101cf6f4ca628a96da","ci/docker/mips-unknown-linux-gnu/Dockerfile":"860299d96ee50ebdbd788e65eb6ba1f561ef66107647bddffcb2567ac350896b","ci/docker/mips-unknown-linux-musl/Dockerfile":"b5917a15c0998adb79ebfdb8aff9ab0e5c4098c4bd5ca78e90ee05859dcfbda3","ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile":"163776e0fd38f66df7415421202ac29efc7d345a628947434e573c3885594ab5","ci/docker/mipsel-unknown-linux-musl/Dockerfile":"b2dd4c26890c1070228df9694adde8fdb1fe78d7d5a71a8cb5c1b54835f93c46","ci/docker/powerpc-unknown-linux-gnu/Dockerfile":"08b846a338c2ee70100f4e80db812668dc58bfb536c44a95cd1cf004d965186b","ci/docker/powerpc64-unknown-linux-gnu/Dockerfile":"4da285ffd035d16f5da9e3701841eb86049c8cfa417fa81e53da4ef74152eac0","ci/docker/x86_64-rumprun-netbsd/Dockerfile":"44c3107fb30380785aaed6ff73fa334017a5bb4e3b5c7d4876154f09023a2b99","ci/docker/x86_64-unknown-freebsd/Dockerfile":"56fce89ceb70792be9005425f3e896361f5ba8a0553db659da87daced93f9785","ci/docker/x86_64-unknown-linux-gnu/Dockerfile":"67fabbc8c6ac02376cf9344251ad49ecdac396b71accb572fd1ae65225325bc0","ci/docker/x86_64-unknown-linux-musl/Dockerfile":"f71019fed5204b950843ef5e56144161fda7e27fad68ed0e8bc4353c388c7bcf","ci/docker/x86_64-unknown-openbsd/Dockerfile":"4a5583797a613056d87f6ae0b1d7a3d3a55552efa7c30e1e0aa67e34d69b4d9c","ci/dox.sh":"2161cb17ee0d6a2279a64149c6b7c73a5b2eab344f248ea1fa0e6c8f6335ec5f","ci/landing-page-footer.html":"b70b3112c2147f5c967e7481061ef38bc2d79a28dd55a16fb916d9c9426da2c4","ci/landing-page-head.html":"ad69663fac7924f27d0209bc519d55838e86edfc4133713a6fd08caadac1b142","ci/run-docker.sh":"325648a92ff4d74f18fdf3d190a5cd483306ed2a98479c0742ca7284acd6b948","ci/run-qemu.sh":"bb859421170871ef23a8940c5e150efec0c01b95e32d2ce2d37b79a45d9d346c","ci/run.sh":"3bb839c2d28986c6915b8f11ed820ff6c62e755fb96bd921a18899ee5f7efd32","ci/style.rs":"60564abc1d5197ed1598426dd0d6ee9939a16d2875b03373538f58843bb616c4","src/dox.rs":"eb6fbcc0b8b59430271bb71ee023961fd165337fc5fd6ca433882457a3c735bd","src/lib.rs":"4cece0e880ec8731913e5110b58d1b134148b0a43e72d6b990c1d999916fc706","src/macros.rs":"bd9802772b0e5c8b3c550d1c24307f06c0d1e4ce656b4ae1cf092142bbe5412c","src/unix/bsd/apple/b32.rs":"110ecff78da0e8d405d861447904da403d8b3f6da1f0f9dc9987633f3f04fe46","src/unix/bsd/apple/b64.rs":"e6808081c0b276cca3189628716f507c7c0d00b62417cd44addbdaefe848cec7","src/unix/bsd/apple/mod.rs":"6691f81221d455b882d68d1102de049d5b9729bb4b59050c1d62c835dcaddafb","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"d87f02c64649ce63367d9f0e39de7213bd30366bbd5e497f7d88f0dc3c319294","src/unix/bsd/freebsdlike/freebsd/mod.rs":"0a675c4b7f54b410547e10e433503487eb1e738394ab81cac82112a96d275bdc","src/unix/bsd/freebsdlike/freebsd/x86.rs":"54311d3ebf2bb091ab22361e377e6ef9224aec2ecfe459fbfcedde4932db9c58","src/unix/bsd/freebsdlike/freebsd/x86_64.rs":"c7f46b9ae23fde5a9e245a28ed1380066e67f081323b4d253a18e9da3b97b860","src/unix/bsd/freebsdlike/mod.rs":"574f7a1368058fad551cdebea4f576fe672f9bbe95a85468c91f9ff5661908c3","src/unix/bsd/mod.rs":"bd422d4bca87a3e8ea4bd78b9ae019643399807d036913f42fdd7476f260297d","src/unix/bsd/netbsdlike/mod.rs":"7b62b89c6ba0d5a8e0cf0937587a81e0314f9c5dabb0c9a9164106b677cf4dd8","src/unix/bsd/netbsdlike/netbsd/mod.rs":"d62a02a78275ed705b2080cae452eb8954ef0f66ac9acb0f44c819d453904c5c","src/unix/bsd/netbsdlike/netbsd/other/b32/mod.rs":"bd251a102bed65d5cb3459275f6ec3310fe5803ff4c9651212115548f86256d0","src/unix/bsd/netbsdlike/netbsd/other/b64/mod.rs":"927eeccaf3269d299db4c2a55f8010807bf43dfa894aea6a783215f5d3560baa","src/unix/bsd/netbsdlike/netbsd/other/mod.rs":"8ce39030f3e4fb45a3d676ade97da8f6d1b3d5f6d8d141224d341c993c57e090","src/unix/bsd/netbsdlike/openbsdlike/bitrig.rs":"f8cd05dacd3a3136c58da5a2fbe26f703767823b28e74fe8a2b57a7bd98d6d5c","src/unix/bsd/netbsdlike/openbsdlike/mod.rs":"769647209be7b8fc5b7e5c1970f16d5cf9cc3fba04bb456c9584f19a5c406e08","src/unix/bsd/netbsdlike/openbsdlike/openbsd.rs":"b1b9cf7be9f0e4d294a57092594074ad03a65fe0eeac9d1104fa874c313e7900","src/unix/haiku/b32.rs":"bd251a102bed65d5cb3459275f6ec3310fe5803ff4c9651212115548f86256d0","src/unix/haiku/b64.rs":"b422430c550c0ba833c9206d1350861e344e3a2eb33d7d58693efb35044be1cc","src/unix/haiku/mod.rs":"d14c45d536f24cd9cd8d5170b9829026da4c782ff2d5855644cc217553e309cf","src/unix/mod.rs":"82952d405742b8b21bfbc29648115b3909d9c64422ad04fb6aca443c16ddaa99","src/unix/notbsd/android/b32.rs":"148e1b4ed8b4f700d5aa24178af925164176e1c18b54db877ced4b55ba9f03d4","src/unix/notbsd/android/b64.rs":"302caf0aa95fa022030717c58de17d85d814b04350eca081a722ec435bc4f217","src/unix/notbsd/android/mod.rs":"f7c0145110a406c5cb14243dc71b98af8971674aa7620e5f55dabfa5c8b344c8","src/unix/notbsd/linux/mips.rs":"7736e565499b04560bc7e6f8636fd39c74f4a588c671ece931d27de8ca263963","src/unix/notbsd/linux/mips64.rs":"f269d516e0f5203fbfd18ff6b22ff33f206be1584d9df03c35743f5e80127d8b","src/unix/notbsd/linux/mod.rs":"81dbebd7dd798dc57e5b5b84cec69af2b6027a415262f4ad07b8c609ad2c95ee","src/unix/notbsd/linux/musl/b32/arm.rs":"a8416bc6e36460f3c60e2f7730dad7c43466790d11214441ef227ffb05ea450f","src/unix/notbsd/linux/musl/b32/asmjs.rs":"c660c5eef21a5f7580e9258eb44881014d2aeba5928af431dfc782b6c4393f33","src/unix/notbsd/linux/musl/b32/mips.rs":"76d835acd06c7bcd07a293a6f141b715ac88b959b633df9af3610e8d6eeb1ab4","src/unix/notbsd/linux/musl/b32/mod.rs":"bd29a02c67b69791e7cabd7666503c35ed5322d244a005b9cc7fd0cb28b552a8","src/unix/notbsd/linux/musl/b32/x86.rs":"da2e557a6afa9d15649d8862a5d17032597c924cd8bb290105500905fe975133","src/unix/notbsd/linux/musl/b64/aarch64.rs":"4009c7eaf703472daef2a70bdac910d9fc395a33689ef2e8cf1c4e692445d3f0","src/unix/notbsd/linux/musl/b64/mod.rs":"20f34e48124d8ca2a08cc0d28353b310238d37a345dfa0d58993e2e930a1ae23","src/unix/notbsd/linux/musl/b64/powerpc64.rs":"dc28f5b7284235d6cf5519053cac59a1c16dc39223b71cca0871e4880755f852","src/unix/notbsd/linux/musl/b64/x86_64.rs":"43291acc0dfc92c2fec8ba6ce77ee9ca3c20bcdccec18e149f95ba911cee704b","src/unix/notbsd/linux/musl/mod.rs":"c195e04167d26f82885f9157e32a28caccfd4eabe807af683708f33e28562021","src/unix/notbsd/linux/other/b32/arm.rs":"f5cb989075fa3b5f997e7101495532c8d5c9f3577412d4c07e4c8c1a16f7b43c","src/unix/notbsd/linux/other/b32/mod.rs":"8b774feb5510b963ed031db7ab3d7e24f1ba5524a6396db0b851d237ccc16fd3","src/unix/notbsd/linux/other/b32/powerpc.rs":"3b62052bb9741afa5349098e6e9c675b60e822e41fed6b5e1b694be1872097b1","src/unix/notbsd/linux/other/b32/x86.rs":"1eda37736f5966c7968b594f74f5018f56b6b8c67bbdeb31fc3db1b6e4ac31b4","src/unix/notbsd/linux/other/b64/aarch64.rs":"a978e82d037a9c8127b2f704323864aff42ac910e721ecc69c255671ca96b950","src/unix/notbsd/linux/other/b64/mod.rs":"efb7740c2fb925ea98977a6a3ff52bc0b72205c1f88a9ba281a939b66b7f0efe","src/unix/notbsd/linux/other/b64/powerpc64.rs":"06a795bca8e91a0143ef1787b034201ed7a21d01960ce9fe869d18c274d5bdb4","src/unix/notbsd/linux/other/b64/x86_64.rs":"0ed128e93f212c0d65660bd95e29190a2dae7c9d15d6fa0d3c4c6656f89e9bdc","src/unix/notbsd/linux/other/mod.rs":"0f7b29425273101ce90a9565637e5f7f61905db2a1e8f5360b285c73b1287da1","src/unix/notbsd/linux/s390x.rs":"6eddef139e18191bc3894f759ca8bd83c59b547bc572ad8938dc61fb5a97d2e9","src/unix/notbsd/mod.rs":"6ba17e2e9a6d05d4470ba595fd38dc55f70fea874a46425a4733ae52d93ee8ff","src/unix/solaris/mod.rs":"6d1f023b637467fe26385d23b32219dbb4573ea177d159e32dad75e4a6ff95de","src/windows.rs":"08f351462388566dcdc6566fb183a467942db63a1caa1bc97f85284fb7a74063"},"package":"044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"} \ No newline at end of file diff --git a/src/vendor/libc/.cargo-ok b/src/vendor/libc/.cargo-ok new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/vendor/libc/.gitignore b/src/vendor/libc/.gitignore new file mode 100644 index 0000000000000..f0ff2599d09b5 --- /dev/null +++ b/src/vendor/libc/.gitignore @@ -0,0 +1,3 @@ +target +Cargo.lock +*~ diff --git a/src/vendor/libc/.travis.yml b/src/vendor/libc/.travis.yml new file mode 100644 index 0000000000000..703329b705727 --- /dev/null +++ b/src/vendor/libc/.travis.yml @@ -0,0 +1,125 @@ +language: rust +sudo: required +dist: trusty +services: + - docker +install: + - curl https://static.rust-lang.org/rustup.sh | + sh -s -- --add-target=$TARGET --disable-sudo -y --prefix=`rustc --print sysroot` +script: + - cargo build + - cargo build --no-default-features + - cargo generate-lockfile --manifest-path libc-test/Cargo.toml + - if [[ $TRAVIS_OS_NAME = "linux" ]]; then + sh ci/run-docker.sh $TARGET; + else + export CARGO_TARGET_DIR=`pwd`/target; + sh ci/run.sh $TARGET; + fi + - rustc ci/style.rs && ./style src +osx_image: xcode7.3 +env: + global: + secure: eIDEoQdTyglcsTD13zSGotAX2HDhRSXIaaTnVZTThqLSrySOc3/6KY3qmOc2Msf7XaBqfFy9QA+alk7OwfePp253eiy1Kced67ffjjFOytEcRT7FlQiYpcYQD6WNHZEj62/bJBO4LTM9sGtWNCTJVEDKW0WM8mUK7qNuC+honPM= +matrix: + include: + # 1.0.0 compat + - os: linux + env: TARGET=x86_64-unknown-linux-gnu + rust: 1.0.0 + script: cargo build + install: + + # build documentation + - os: linux + env: TARGET=x86_64-unknown-linux-gnu + rust: stable + script: sh ci/dox.sh + + # stable compat + - os: linux + env: TARGET=x86_64-unknown-linux-gnu + rust: stable + - os: linux + env: TARGET=i686-unknown-linux-gnu + rust: stable + - os: osx + env: TARGET=x86_64-apple-darwin + rust: stable + - os: osx + env: TARGET=i686-apple-darwin + rust: stable + - os: linux + env: TARGET=arm-linux-androideabi + rust: stable + - os: linux + env: TARGET=x86_64-unknown-linux-musl + rust: stable + - os: linux + env: TARGET=i686-unknown-linux-musl + rust: stable + - os: linux + env: TARGET=arm-unknown-linux-gnueabihf + rust: stable + - os: linux + env: TARGET=aarch64-unknown-linux-gnu + rust: stable + - os: osx + env: TARGET=i386-apple-ios + rust: stable + - os: osx + env: TARGET=x86_64-apple-ios + rust: stable + - os: linux + env: TARGET=x86_64-rumprun-netbsd + rust: stable + - os: linux + env: TARGET=powerpc-unknown-linux-gnu + rust: stable + - os: linux + env: TARGET=powerpc64-unknown-linux-gnu + rust: stable + - os: linux + env: TARGET=mips-unknown-linux-musl + rust: stable + - os: linux + env: TARGET=mipsel-unknown-linux-musl + rust: stable + - os: linux + env: TARGET=mips64-unknown-linux-gnuabi64 + rust: nightly + + # beta + - os: linux + env: TARGET=x86_64-unknown-linux-gnu + rust: beta + - os: osx + env: TARGET=x86_64-apple-darwin + rust: beta + + # nightly + - os: linux + env: TARGET=x86_64-unknown-linux-gnu + rust: nightly + - os: osx + env: TARGET=x86_64-apple-darwin + rust: nightly + - os: linux + env: TARGET=mips-unknown-linux-gnu + # not sure why this has to be nightly... + rust: nightly + + # QEMU based targets that compile in an emulator + - os: linux + env: TARGET=x86_64-unknown-freebsd + rust: stable + - os: linux + env: TARGET=x86_64-unknown-openbsd QEMU=openbsd.qcow2 + rust: stable + script: sh ci/run-docker.sh $TARGET + install: + +notifications: + email: + on_success: never + webhooks: https://buildbot.rust-lang.org/homu/travis diff --git a/src/vendor/libc/Cargo.toml b/src/vendor/libc/Cargo.toml new file mode 100644 index 0000000000000..c08ab3aab9da4 --- /dev/null +++ b/src/vendor/libc/Cargo.toml @@ -0,0 +1,21 @@ +[package] + +name = "libc" +version = "0.2.17" +authors = ["The Rust Project Developers"] +license = "MIT/Apache-2.0" +readme = "README.md" +repository = "https://github.com/rust-lang/libc" +homepage = "https://github.com/rust-lang/libc" +documentation = "http://doc.rust-lang.org/libc" +description = """ +A library for types and bindings to native C functions often found in libc or +other common platform libraries. +""" + +[features] +default = ["use_std"] +use_std = [] + +[workspace] +members = ["libc-test", "libc-test/generate-files"] diff --git a/src/vendor/libc/LICENSE-APACHE b/src/vendor/libc/LICENSE-APACHE new file mode 100644 index 0000000000000..16fe87b06e802 --- /dev/null +++ b/src/vendor/libc/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/src/vendor/libc/LICENSE-MIT b/src/vendor/libc/LICENSE-MIT new file mode 100644 index 0000000000000..39d4bdb5acd31 --- /dev/null +++ b/src/vendor/libc/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/vendor/libc/README.md b/src/vendor/libc/README.md new file mode 100644 index 0000000000000..5ea812320f05f --- /dev/null +++ b/src/vendor/libc/README.md @@ -0,0 +1,137 @@ +libc +==== + +A Rust library with native bindings to the types and functions commonly found on +various systems, including libc. + +[![Build Status](https://travis-ci.org/rust-lang/libc.svg?branch=master)](https://travis-ci.org/rust-lang/libc) +[![Build status](https://ci.appveyor.com/api/projects/status/34csq3uurnw7c0rl?svg=true)](https://ci.appveyor.com/project/alexcrichton/libc) + +[Documentation](#platforms-and-documentation) + +## Usage + +First, add the following to your `Cargo.toml`: + +```toml +[dependencies] +libc = "0.2" +``` + +Next, add this to your crate root: + +```rust +extern crate libc; +``` + +Currently libc by default links to the standard library, but if you would +instead like to use libc in a `#![no_std]` situation or crate you can request +this via: + +```toml +[dependencies] +libc = { version = "0.2", default-features = false } +``` + +## What is libc? + +The primary purpose of this crate is to provide all of the definitions necessary +to easily interoperate with C code (or "C-like" code) on each of the platforms +that Rust supports. This includes type definitions (e.g. `c_int`), constants +(e.g. `EINVAL`) as well as function headers (e.g. `malloc`). + +This crate does not strive to have any form of compatibility across platforms, +but rather it is simply a straight binding to the system libraries on the +platform in question. + +## Public API + +This crate exports all underlying platform types, functions, and constants under +the crate root, so all items are accessible as `libc::foo`. The types and values +of all the exported APIs match the platform that libc is compiled for. + +More detailed information about the design of this library can be found in its +[associated RFC][rfc]. + +[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1291-promote-libc.md + +## Adding an API + +Want to use an API which currently isn't bound in `libc`? It's quite easy to add +one! + +The internal structure of this crate is designed to minimize the number of +`#[cfg]` attributes in order to easily be able to add new items which apply +to all platforms in the future. As a result, the crate is organized +hierarchically based on platform. Each module has a number of `#[cfg]`'d +children, but only one is ever actually compiled. Each module then reexports all +the contents of its children. + +This means that for each platform that libc supports, the path from a +leaf module to the root will contain all bindings for the platform in question. +Consequently, this indicates where an API should be added! Adding an API at a +particular level in the hierarchy means that it is supported on all the child +platforms of that level. For example, when adding a Unix API it should be added +to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to +`src/unix/notbsd/linux/mod.rs`. + +If you're not 100% sure at what level of the hierarchy an API should be added +at, fear not! This crate has CI support which tests any binding against all +platforms supported, so you'll see failures if an API is added at the wrong +level or has different signatures across platforms. + +With that in mind, the steps for adding a new API are: + +1. Determine where in the module hierarchy your API should be added. +2. Add the API. +3. Send a PR to this repo. +4. Wait for CI to pass, fixing errors. +5. Wait for a merge! + +### Test before you commit + +We have two automated tests running on [Travis](https://travis-ci.org/rust-lang/libc): + +1. [`libc-test`](https://github.com/alexcrichton/ctest) + - `cd libc-test && cargo run` + - Use the `skip_*()` functions in `build.rs` if you really need a workaround. +2. Style checker + - `rustc ci/style.rs && ./style src` + +## Platforms and Documentation + +The following platforms are currently tested and have documentation available: + +Tested: + * [`i686-pc-windows-msvc`](https://doc.rust-lang.org/libc/i686-pc-windows-msvc/libc/) + * [`x86_64-pc-windows-msvc`](https://doc.rust-lang.org/libc/x86_64-pc-windows-msvc/libc/) + (Windows) + * [`i686-pc-windows-gnu`](https://doc.rust-lang.org/libc/i686-pc-windows-gnu/libc/) + * [`x86_64-pc-windows-gnu`](https://doc.rust-lang.org/libc/x86_64-pc-windows-gnu/libc/) + * [`i686-apple-darwin`](https://doc.rust-lang.org/libc/i686-apple-darwin/libc/) + * [`x86_64-apple-darwin`](https://doc.rust-lang.org/libc/x86_64-apple-darwin/libc/) + (OSX) + * `i686-apple-ios` + * `x86_64-apple-ios` + * [`i686-unknown-linux-gnu`](https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/) + * [`x86_64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/) + (Linux) + * [`x86_64-unknown-linux-musl`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-musl/libc/) + (Linux MUSL) + * [`aarch64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/aarch64-unknown-linux-gnu/libc/) + * [`mips-unknown-linux-gnu`](https://doc.rust-lang.org/libc/mips-unknown-linux-gnu/libc/) + * [`arm-unknown-linux-gnueabihf`](https://doc.rust-lang.org/libc/arm-unknown-linux-gnueabihf/libc/) + * [`arm-linux-androideabi`](https://doc.rust-lang.org/libc/arm-linux-androideabi/libc/) + (Android) + * [`x86_64-unknown-freebsd`](https://doc.rust-lang.org/libc/x86_64-unknown-freebsd/libc/) + * [`x86_64-unknown-openbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-openbsd/libc/) + * [`x86_64-rumprun-netbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-netbsd/libc/) + +The following may be supported, but are not guaranteed to always work: + + * `i686-unknown-freebsd` + * [`x86_64-unknown-bitrig`](https://doc.rust-lang.org/libc/x86_64-unknown-bitrig/libc/) + * [`x86_64-unknown-dragonfly`](https://doc.rust-lang.org/libc/x86_64-unknown-dragonfly/libc/) + * `i686-unknown-haiku` + * `x86_64-unknown-haiku` + * [`x86_64-unknown-netbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-netbsd/libc/) diff --git a/src/vendor/libc/appveyor.yml b/src/vendor/libc/appveyor.yml new file mode 100644 index 0000000000000..a851bb87b6c3b --- /dev/null +++ b/src/vendor/libc/appveyor.yml @@ -0,0 +1,25 @@ +environment: + matrix: + - TARGET: x86_64-pc-windows-gnu + MSYS2_BITS: 64 + - TARGET: i686-pc-windows-gnu + MSYS2_BITS: 32 + - TARGET: x86_64-pc-windows-msvc + - TARGET: i686-pc-windows-msvc +install: + - curl -sSf -o rustup-init.exe https://win.rustup.rs/ + - rustup-init.exe -y --default-host %TARGET% + - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin + - if defined MSYS2_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS2_BITS%\bin + - rustc -V + - cargo -V + +build: false + +test_script: + - cargo test --target %TARGET% + - cargo run --manifest-path libc-test/Cargo.toml --target %TARGET% + +cache: + - target + - C:\Users\appveyor\.cargo\registry diff --git a/src/vendor/libc/ci/README.md b/src/vendor/libc/ci/README.md new file mode 100644 index 0000000000000..13c7c8da52fc5 --- /dev/null +++ b/src/vendor/libc/ci/README.md @@ -0,0 +1,203 @@ +The goal of the libc crate is to have CI running everywhere to have the +strongest guarantees about the definitions that this library contains, and as a +result the CI is pretty complicated and also pretty large! Hopefully this can +serve as a guide through the sea of scripts in this directory and elsewhere in +this project. + +# Files + +First up, let's talk about the files in this directory: + +* `run-travis.sh` - a shell script run by all Travis builders, this is + responsible for setting up the rest of the environment such as installing new + packages, downloading Rust target libraries, etc. + +* `run.sh` - the actual script which runs tests for a particular architecture. + Called from the `run-travis.sh` script this will run all tests for the target + specified. + +* `cargo-config` - Cargo configuration of linkers to use copied into place by + the `run-travis.sh` script before builds are run. + +* `dox.sh` - script called from `run-travis.sh` on only the linux 64-bit nightly + Travis bots to build documentation for this crate. + +* `landing-page-*.html` - used by `dox.sh` to generate a landing page for all + architectures' documentation. + +* `run-qemu.sh` - see discussion about QEMU below + +* `mips`, `rumprun` - instructions to build the docker image for each respective + CI target + +# CI Systems + +Currently this repository leverages a combination of Travis CI and AppVeyor for +running tests. The triples tested are: + +* AppVeyor + * `{i686,x86_64}-pc-windows-{msvc,gnu}` +* Travis + * `{i686,x86_64,mips,aarch64}-unknown-linux-gnu` + * `x86_64-unknown-linux-musl` + * `arm-unknown-linux-gnueabihf` + * `arm-linux-androideabi` + * `{i686,x86_64}-apple-{darwin,ios}` + * `x86_64-rumprun-netbsd` + * `x86_64-unknown-freebsd` + * `x86_64-unknown-openbsd` + +The Windows triples are all pretty standard, they just set up their environment +then run tests, no need for downloading any extra target libs (we just download +the right installer). The Intel Linux/OSX builds are similar in that we just +download the right target libs and run tests. Note that the Intel Linux/OSX +builds are run on stable/beta/nightly, but are the only ones that do so. + +The remaining architectures look like: + +* Android runs in a [docker image][android-docker] with an emulator, the NDK, + and the SDK already set up. The entire build happens within the docker image. +* The MIPS, ARM, and AArch64 builds all use the QEMU userspace emulator to run + the generated binary to actually verify the tests pass. +* The MUSL build just has to download a MUSL compiler and target libraries and + then otherwise runs tests normally. +* iOS builds need an extra linker flag currently, but beyond that they're built + as standard as everything else. +* The rumprun target builds an entire kernel from the test suite and then runs + it inside QEMU using the serial console to test whether it succeeded or + failed. +* The BSD builds, currently OpenBSD and FreeBSD, use QEMU to boot up a system + and compile/run tests. More information on that below. + +[android-docker]: https://github.com/rust-lang/rust-buildbot/blob/master/slaves/android/Dockerfile + +## QEMU + +Lots of the architectures tested here use QEMU in the tests, so it's worth going +over all the crazy capabilities QEMU has and the various flavors in which we use +it! + +First up, QEMU has userspace emulation where it doesn't boot a full kernel, it +just runs a binary from another architecture (using the `qemu-` wrappers). +We provide it the runtime path for the dynamically loaded system libraries, +however. This strategy is used for all Linux architectures that aren't intel. +Note that one downside of this QEMU system is that threads are barely +implemented, so we're careful to not spawn many threads. + +For the rumprun target the only output is a kernel image, so we just use that +plus the `rumpbake` command to create a full kernel image which is then run from +within QEMU. + +Finally, the fun part, the BSDs. Quite a few hoops are jumped through to get CI +working for these platforms, but the gist of it looks like: + +* Cross compiling from Linux to any of the BSDs seems to be quite non-standard. + We may be able to get it working but it might be difficult at that point to + ensure that the libc definitions align with what you'd get on the BSD itself. + As a result, we try to do compiles within the BSD distro. +* On Travis we can't run a VM-in-a-VM, so we resort to userspace emulation + (QEMU). +* Unfortunately on Travis we also can't use KVM, so the emulation is super slow. + +With all that in mind, the way BSD is tested looks like: + +1. Download a pre-prepared image for the OS being tested. +2. Generate the tests for the OS being tested. This involves running the `ctest` + library over libc to generate a Rust file and a C file which will then be + compiled into the final test. +3. Generate a disk image which will later be mounted by the OS being tested. + This image is mostly just the libc directory, but some modifications are made + to compile the generated files from step 2. +4. The kernel is booted in QEMU, and it is configured to detect the libc-test + image being available, run the test script, and then shut down afterwards. +5. Look for whether the tests passed in the serial console output of the kernel. + +There's some pretty specific instructions for setting up each image (detailed +below), but the main gist of this is that we must avoid a vanilla `cargo run` +inside of the `libc-test` directory (which is what it's intended for) because +that would compile `syntex_syntax`, a large library, with userspace emulation. +This invariably times out on Travis, so we can't do that. + +Once all those hoops are jumped through, however, we can be happy that we're +testing almost everything! + +Below are some details of how to set up the initial OS images which are +downloaded. Each image must be enabled have input/output over the serial +console, log in automatically at the serial console, detect if a second drive in +QEMU is available, and if so mount it, run a script (it'll specifically be +`run-qemu.sh` in this folder which is copied into the generated image talked +about above), and then shut down. + +### QEMU setup - FreeBSD + +1. Download CD installer (most minimal is fine) +2. `qemu-img create -f qcow2 foo.qcow2 2G` +3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user` +4. run installer +5. `echo 'console="comconsole"' >> /boot/loader.conf` +6. `echo 'autoboot_delay="0"' >> /boot/loader.conf` +7. look at /etc/ttys, see what getty argument is for ttyu0 +8. edit /etc/gettytab, look for ttyu0 argument, prepend `:al=root` to line + beneath + +(note that the current image has a `freebsd` user, but this isn't really +necessary) + +Once that's done, arrange for this script to run at login: + +``` +#!/bin/sh + +sudo kldload ext2fs +[ -e /dev/vtbd1 ] || exit 0 +sudo mount -t ext2fs /dev/vtbd1 /mnt +sh /mnt/run.sh /mnt +sudo poweroff +``` + +Helpful links + +* https://en.wikibooks.org/wiki/QEMU/Images +* https://blog.nekoconeko.nl/blog/2015/06/04/creating-an-openstack-freebsd-image.html +* https://www.freebsd.org/doc/handbook/serialconsole-setup.html + + +### QEMU setup - OpenBSD + +1. Download CD installer +2. `qemu-img create -f qcow2 foo.qcow2 2G` +3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user` +4. run installer +5. `echo 'set tty com0' >> /etc/boot.conf` +6. `echo 'boot' >> /etc/boot.conf` +7. Modify /etc/ttys, change the `tty00` at the end from 'unknown off' to + 'vt220 on secure' +8. Modify same line in /etc/ttys to have `"/root/foo.sh"` as the shell +9. Add this script to `/root/foo.sh` + +``` +#!/bin/sh +exec 1>/dev/tty00 +exec 2>&1 + +if mount -t ext2fs /dev/sd1c /mnt; then + sh /mnt/run.sh /mnt + shutdown -ph now +fi + +# limited shell... +exec /bin/sh < /dev/tty00 +``` + +10. `chmod +x /root/foo.sh` + +Helpful links: + +* https://en.wikibooks.org/wiki/QEMU/Images +* http://www.openbsd.org/faq/faq7.html#SerCon + +# Questions? + +Hopefully that's at least somewhat of an introduction to everything going on +here, and feel free to ping @alexcrichton with questions! + diff --git a/src/vendor/libc/ci/docker/aarch64-unknown-linux-gnu/Dockerfile b/src/vendor/libc/ci/docker/aarch64-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000000000..2ba69e15442f3 --- /dev/null +++ b/src/vendor/libc/ci/docker/aarch64-unknown-linux-gnu/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:16.10 +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev ca-certificates \ + gcc-aarch64-linux-gnu libc6-dev-arm64-cross qemu-user +ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ + PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/arm-linux-androideabi/Dockerfile b/src/vendor/libc/ci/docker/arm-linux-androideabi/Dockerfile new file mode 100644 index 0000000000000..0e41ba6dbee66 --- /dev/null +++ b/src/vendor/libc/ci/docker/arm-linux-androideabi/Dockerfile @@ -0,0 +1,4 @@ +FROM alexcrichton/rust-slave-android:2015-11-22 +ENV CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \ + PATH=$PATH:/rust/bin +ENTRYPOINT ["sh"] diff --git a/src/vendor/libc/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile b/src/vendor/libc/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile new file mode 100644 index 0000000000000..3824c0466401f --- /dev/null +++ b/src/vendor/libc/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:16.10 +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev ca-certificates \ + gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user +ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \ + PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/i686-unknown-linux-gnu/Dockerfile b/src/vendor/libc/ci/docker/i686-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000000000..c149d84072912 --- /dev/null +++ b/src/vendor/libc/ci/docker/i686-unknown-linux-gnu/Dockerfile @@ -0,0 +1,5 @@ +FROM ubuntu:16.10 +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc-multilib libc6-dev ca-certificates +ENV PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/i686-unknown-linux-musl/Dockerfile b/src/vendor/libc/ci/docker/i686-unknown-linux-musl/Dockerfile new file mode 100644 index 0000000000000..87459a1672bdc --- /dev/null +++ b/src/vendor/libc/ci/docker/i686-unknown-linux-musl/Dockerfile @@ -0,0 +1,22 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc make libc6-dev git curl ca-certificates +# Below we're cross-compiling musl for i686 using the system compiler on an +# x86_64 system. This is an awkward thing to be doing and so we have to jump +# through a couple hoops to get musl to be happy. In particular: +# +# * We specifically pass -m32 in CFLAGS and override CC when running ./configure, +# since otherwise the script will fail to find a compiler. +# * We manually unset CROSS_COMPILE when running make; otherwise the makefile +# will call the non-existent binary 'i686-ar'. +RUN curl https://www.musl-libc.org/releases/musl-1.1.15.tar.gz | \ + tar xzf - && \ + cd musl-1.1.15 && \ + CC=gcc CFLAGS=-m32 ./configure --prefix=/musl-i686 --disable-shared --target=i686 && \ + make CROSS_COMPILE= install -j4 && \ + cd .. && \ + rm -rf musl-1.1.15 +ENV PATH=$PATH:/musl-i686/bin:/rust/bin \ + CC_i686_unknown_linux_musl=musl-gcc diff --git a/src/vendor/libc/ci/docker/mips-unknown-linux-gnu/Dockerfile b/src/vendor/libc/ci/docker/mips-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000000000..eea1f652c3cbd --- /dev/null +++ b/src/vendor/libc/ci/docker/mips-unknown-linux-gnu/Dockerfile @@ -0,0 +1,10 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev qemu-user ca-certificates \ + gcc-mips-linux-gnu libc6-dev-mips-cross \ + qemu-system-mips + +ENV CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER=mips-linux-gnu-gcc \ + PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/mips-unknown-linux-musl/Dockerfile b/src/vendor/libc/ci/docker/mips-unknown-linux-musl/Dockerfile new file mode 100644 index 0000000000000..77c6adb435f1d --- /dev/null +++ b/src/vendor/libc/ci/docker/mips-unknown-linux-musl/Dockerfile @@ -0,0 +1,14 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev qemu-user ca-certificates qemu-system-mips curl \ + bzip2 + +RUN mkdir /toolchain +RUN curl -L https://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/OpenWrt-SDK-ar71xx-generic_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 | \ + tar xjf - -C /toolchain --strip-components=1 + +ENV PATH=$PATH:/rust/bin:/toolchain/staging_dir/toolchain-mips_34kc_gcc-5.3.0_musl-1.1.15/bin \ + CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \ + CARGO_TARGET_MIPS_UNKNOWN_LINUX_MUSL_LINKER=mips-openwrt-linux-gcc diff --git a/src/vendor/libc/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile b/src/vendor/libc/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile new file mode 100644 index 0000000000000..2eb5de2453800 --- /dev/null +++ b/src/vendor/libc/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev qemu-user ca-certificates \ + gcc-mips64-linux-gnuabi64 libc6-dev-mips64-cross \ + qemu-system-mips64 + +ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER=mips64-linux-gnuabi64-gcc \ + CC_mips64_unknown_linux_gnuabi64=mips64-linux-gnuabi64-gcc \ + PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/mipsel-unknown-linux-musl/Dockerfile b/src/vendor/libc/ci/docker/mipsel-unknown-linux-musl/Dockerfile new file mode 100644 index 0000000000000..36c4d90ef68f6 --- /dev/null +++ b/src/vendor/libc/ci/docker/mipsel-unknown-linux-musl/Dockerfile @@ -0,0 +1,14 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev qemu-user ca-certificates qemu-system-mips curl \ + bzip2 + +RUN mkdir /toolchain +RUN curl -L https://downloads.openwrt.org/snapshots/trunk/malta/generic/OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 | \ + tar xjf - -C /toolchain --strip-components=2 + +ENV PATH=$PATH:/rust/bin:/toolchain/bin \ + CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ + CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_MUSL_LINKER=mipsel-openwrt-linux-gcc diff --git a/src/vendor/libc/ci/docker/powerpc-unknown-linux-gnu/Dockerfile b/src/vendor/libc/ci/docker/powerpc-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000000000..d9d7db0f41dd2 --- /dev/null +++ b/src/vendor/libc/ci/docker/powerpc-unknown-linux-gnu/Dockerfile @@ -0,0 +1,10 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev qemu-user ca-certificates \ + gcc-powerpc-linux-gnu libc6-dev-powerpc-cross \ + qemu-system-ppc + +ENV CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_LINKER=powerpc-linux-gnu-gcc \ + PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile b/src/vendor/libc/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000000000..df0e6057b4f7f --- /dev/null +++ b/src/vendor/libc/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev qemu-user ca-certificates \ + gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross \ + qemu-system-ppc + +ENV CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_LINKER=powerpc64-linux-gnu-gcc \ + CC=powerpc64-linux-gnu-gcc \ + PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/x86_64-rumprun-netbsd/Dockerfile b/src/vendor/libc/ci/docker/x86_64-rumprun-netbsd/Dockerfile new file mode 100644 index 0000000000000..129771e76b74d --- /dev/null +++ b/src/vendor/libc/ci/docker/x86_64-rumprun-netbsd/Dockerfile @@ -0,0 +1,6 @@ +FROM mato/rumprun-toolchain-hw-x86_64 +USER root +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + qemu +ENV PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/x86_64-unknown-freebsd/Dockerfile b/src/vendor/libc/ci/docker/x86_64-unknown-freebsd/Dockerfile new file mode 100644 index 0000000000000..b127338222363 --- /dev/null +++ b/src/vendor/libc/ci/docker/x86_64-unknown-freebsd/Dockerfile @@ -0,0 +1,13 @@ +FROM alexcrichton/rust-slave-linux-cross:2016-04-15 +USER root + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + qemu genext2fs + +ENTRYPOINT ["sh"] + +ENV PATH=$PATH:/rust/bin \ + QEMU=freebsd.qcow2.gz \ + CAN_CROSS=1 \ + CARGO_TARGET_X86_64_UNKNOWN_FREEBSD_LINKER=x86_64-unknown-freebsd10-gcc diff --git a/src/vendor/libc/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/src/vendor/libc/ci/docker/x86_64-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000000000..4af3f834cbe6e --- /dev/null +++ b/src/vendor/libc/ci/docker/x86_64-unknown-linux-gnu/Dockerfile @@ -0,0 +1,5 @@ +FROM ubuntu:16.10 +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev ca-certificates +ENV PATH=$PATH:/rust/bin diff --git a/src/vendor/libc/ci/docker/x86_64-unknown-linux-musl/Dockerfile b/src/vendor/libc/ci/docker/x86_64-unknown-linux-musl/Dockerfile new file mode 100644 index 0000000000000..9c2499948a287 --- /dev/null +++ b/src/vendor/libc/ci/docker/x86_64-unknown-linux-musl/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc make libc6-dev git curl ca-certificates +RUN curl https://www.musl-libc.org/releases/musl-1.1.15.tar.gz | \ + tar xzf - && \ + cd musl-1.1.15 && \ + ./configure --prefix=/musl-x86_64 && \ + make install -j4 && \ + cd .. && \ + rm -rf musl-1.1.15 +ENV PATH=$PATH:/musl-x86_64/bin:/rust/bin diff --git a/src/vendor/libc/ci/docker/x86_64-unknown-openbsd/Dockerfile b/src/vendor/libc/ci/docker/x86_64-unknown-openbsd/Dockerfile new file mode 100644 index 0000000000000..26340a5ed1eca --- /dev/null +++ b/src/vendor/libc/ci/docker/x86_64-unknown-openbsd/Dockerfile @@ -0,0 +1,8 @@ +FROM ubuntu:16.10 + +RUN apt-get update +RUN apt-get install -y --no-install-recommends \ + gcc libc6-dev qemu curl ca-certificates \ + genext2fs +ENV PATH=$PATH:/rust/bin \ + QEMU=2016-09-07/openbsd-6.0-without-pkgs.qcow2 diff --git a/src/vendor/libc/ci/dox.sh b/src/vendor/libc/ci/dox.sh new file mode 100644 index 0000000000000..88d882dcacdd3 --- /dev/null +++ b/src/vendor/libc/ci/dox.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# Builds documentation for all target triples that we have a registered URL for +# in liblibc. This scrapes the list of triples to document from `src/lib.rs` +# which has a bunch of `html_root_url` directives we pick up. + +set -e + +TARGETS=`grep html_root_url src/lib.rs | sed 's/.*".*\/\(.*\)"/\1/'` + +rm -rf target/doc +mkdir -p target/doc + +cp ci/landing-page-head.html target/doc/index.html + +for target in $TARGETS; do + echo documenting $target + + rustdoc -o target/doc/$target --target $target src/lib.rs --cfg dox \ + --crate-name libc + + echo "

  • $target
  • " \ + >> target/doc/index.html +done + +cat ci/landing-page-footer.html >> target/doc/index.html + +# If we're on travis, not a PR, and on the right branch, publish! +if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_BRANCH" = "master" ]; then + pip install ghp-import --user $USER + $HOME/.local/bin/ghp-import -n target/doc + git push -qf https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages +fi diff --git a/src/vendor/libc/ci/landing-page-footer.html b/src/vendor/libc/ci/landing-page-footer.html new file mode 100644 index 0000000000000..941cc8d2b4030 --- /dev/null +++ b/src/vendor/libc/ci/landing-page-footer.html @@ -0,0 +1,3 @@ + + + diff --git a/src/vendor/libc/ci/landing-page-head.html b/src/vendor/libc/ci/landing-page-head.html new file mode 100644 index 0000000000000..fc69fa88eb5ce --- /dev/null +++ b/src/vendor/libc/ci/landing-page-head.html @@ -0,0 +1,7 @@ + + + + + + +