Auto merge of #42381 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 10 pull requests - Successful merges: #41981, #42225, #42310, #42319, #42335, #42343, #42355, #42360, #42370, #42372 - Failed merges:
This commit is contained in:
commit
bb907adbbd
29 changed files with 184 additions and 614 deletions
45
src/Cargo.lock
generated
45
src/Cargo.lock
generated
|
@ -44,7 +44,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"build_helper 0.1.0",
|
||||
"core 0.0.0",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.0.0",
|
||||
]
|
||||
|
||||
|
@ -84,7 +84,7 @@ name = "backtrace-sys"
|
|||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -110,7 +110,7 @@ dependencies = [
|
|||
"build_helper 0.1.0",
|
||||
"cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -178,7 +178,7 @@ dependencies = [
|
|||
"serde_ignored 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -202,7 +202,7 @@ dependencies = [
|
|||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -239,7 +239,7 @@ name = "cmake"
|
|||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -257,7 +257,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"build_helper 0.1.0",
|
||||
"core 0.0.0",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -308,7 +308,7 @@ name = "curl-sys"
|
|||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -411,7 +411,7 @@ name = "flate"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"build_helper 0.1.0",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -444,7 +444,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.46"
|
||||
version = "0.3.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -540,7 +540,7 @@ dependencies = [
|
|||
"flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -605,7 +605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"curl-sys 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -630,7 +630,7 @@ name = "libz-sys"
|
|||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -650,7 +650,7 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -697,7 +697,7 @@ name = "miniz-sys"
|
|||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -830,7 +830,7 @@ name = "openssl-sys"
|
|||
version = "0.9.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1248,7 +1248,7 @@ name = "rustc_llvm"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"build_helper 0.1.0",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_bitflags 0.0.0",
|
||||
]
|
||||
|
||||
|
@ -1375,6 +1375,7 @@ name = "rustc_trans"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"flate 0.0.0",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc 0.0.0",
|
||||
|
@ -1425,7 +1426,7 @@ dependencies = [
|
|||
"arena 0.0.0",
|
||||
"build_helper 0.1.0",
|
||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc 0.0.0",
|
||||
|
@ -1577,7 +1578,7 @@ dependencies = [
|
|||
"collections 0.0.0",
|
||||
"compiler_builtins 0.0.0",
|
||||
"core 0.0.0",
|
||||
"gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.0.0",
|
||||
"panic_abort 0.0.0",
|
||||
"panic_unwind 0.0.0",
|
||||
|
@ -1744,7 +1745,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.12"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2042,7 +2043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c"
|
||||
"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d"
|
||||
"checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf"
|
||||
"checksum gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "181e3cebba1d663bd92eb90e2da787e10597e027eb00de8d742b260a7850948f"
|
||||
"checksum gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)" = "5f837c392f2ea61cb1576eac188653df828c861b7137d74ea4a5caa89621f9e6"
|
||||
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
|
||||
"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
|
||||
"checksum git2 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9de9df4358c17e448a778d90cd0272e1dab5eae30244502333fa2001c4e24357"
|
||||
|
@ -2128,7 +2129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13ad4762fe52abc9f4008e85c4fb1b1fe3aa91ccb99ff4826a439c7c598e1047"
|
||||
"checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde"
|
||||
"checksum syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6e0e4dbae163dd98989464c23dd503161b338790640e11537686f2ef0f25c791"
|
||||
"checksum tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0ef9ead2fe0aa9e18475a96a207bfd5143f4124779ef7429503a8665416ce8"
|
||||
"checksum tar 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "281285b717926caa919ad905ef89c63d75805c7d89437fb873100925a53f2b1b"
|
||||
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
||||
"checksum term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d168af3930b369cfe245132550579d47dfd873d69470755a19c2c6568dbbd989"
|
||||
"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
|
||||
|
|
|
@ -36,5 +36,5 @@ num_cpus = "1.0"
|
|||
toml = "0.1"
|
||||
getopts = "0.2"
|
||||
rustc-serialize = "0.3"
|
||||
gcc = "0.3.46"
|
||||
gcc = "0.3.50"
|
||||
libc = "0.2"
|
||||
|
|
|
@ -17,7 +17,7 @@ libc = { path = "../rustc/libc_shim" }
|
|||
|
||||
[build-dependencies]
|
||||
build_helper = { path = "../build_helper" }
|
||||
gcc = "0.3.27"
|
||||
gcc = "0.3.50"
|
||||
|
||||
[features]
|
||||
debug = []
|
||||
|
|
|
@ -1515,6 +1515,7 @@ pub trait SliceConcatExt<T: ?Sized> {
|
|||
///
|
||||
/// ```
|
||||
/// assert_eq!(["hello", "world"].concat(), "helloworld");
|
||||
/// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn concat(&self) -> Self::Output;
|
||||
|
@ -1526,6 +1527,7 @@ pub trait SliceConcatExt<T: ?Sized> {
|
|||
///
|
||||
/// ```
|
||||
/// assert_eq!(["hello", "world"].join(" "), "hello world");
|
||||
/// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
|
||||
/// ```
|
||||
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
|
||||
fn join(&self, sep: &T) -> Self::Output;
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
#![feature(collections)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(iterator_step_by)]
|
||||
#![feature(pattern)]
|
||||
#![feature(placement_in_syntax)]
|
||||
#![feature(rand)]
|
||||
#![feature(slice_rotate)]
|
||||
#![feature(splice)]
|
||||
#![feature(step_by)]
|
||||
#![feature(str_escape)]
|
||||
#![feature(test)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
|
|
@ -510,7 +510,8 @@ fn test_from_iter() {
|
|||
let u: Vec<_> = deq.iter().cloned().collect();
|
||||
assert_eq!(u, v);
|
||||
|
||||
let seq = (0..).step_by(2).take(256);
|
||||
// FIXME #27741: Remove `.skip(0)` when Range::step_by is fully removed
|
||||
let seq = (0..).skip(0).step_by(2).take(256);
|
||||
let deq: VecDeque<_> = seq.collect();
|
||||
for (i, &x) in deq.iter().enumerate() {
|
||||
assert_eq!(2 * i, x);
|
||||
|
|
|
@ -16,4 +16,4 @@ core = { path = "../libcore" }
|
|||
|
||||
[build-dependencies]
|
||||
build_helper = { path = "../build_helper" }
|
||||
gcc = "0.3.27"
|
||||
gcc = "0.3.50"
|
||||
|
|
|
@ -313,6 +313,9 @@ pub use self::iterator::Iterator;
|
|||
pub use self::range::Step;
|
||||
#[unstable(feature = "step_by", reason = "recent addition",
|
||||
issue = "27741")]
|
||||
#[rustc_deprecated(since = "1.19.0",
|
||||
reason = "replaced by `iter::StepBy`")]
|
||||
#[allow(deprecated)]
|
||||
pub use self::range::StepBy as DeprecatedStepBy;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
|
@ -252,6 +252,9 @@ step_impl_no_between!(u128 i128);
|
|||
#[derive(Clone, Debug)]
|
||||
#[unstable(feature = "step_by", reason = "recent addition",
|
||||
issue = "27741")]
|
||||
#[rustc_deprecated(since = "1.19.0",
|
||||
reason = "replaced by `iter::StepBy`")]
|
||||
#[allow(deprecated)]
|
||||
pub struct StepBy<A, R> {
|
||||
step_by: A,
|
||||
range: R,
|
||||
|
@ -272,6 +275,9 @@ impl<A: Step> ops::RangeFrom<A> {
|
|||
/// ```
|
||||
#[unstable(feature = "step_by", reason = "recent addition",
|
||||
issue = "27741")]
|
||||
#[rustc_deprecated(since = "1.19.0",
|
||||
reason = "replaced by `Iterator::step_by`")]
|
||||
#[allow(deprecated)]
|
||||
pub fn step_by(self, by: A) -> StepBy<A, Self> {
|
||||
StepBy {
|
||||
step_by: by,
|
||||
|
@ -297,6 +303,9 @@ impl<A: Step> ops::Range<A> {
|
|||
/// ```
|
||||
#[unstable(feature = "step_by", reason = "recent addition",
|
||||
issue = "27741")]
|
||||
#[rustc_deprecated(since = "1.19.0",
|
||||
reason = "replaced by `Iterator::step_by`")]
|
||||
#[allow(deprecated)]
|
||||
pub fn step_by(self, by: A) -> StepBy<A, Self> {
|
||||
StepBy {
|
||||
step_by: by,
|
||||
|
@ -321,6 +330,9 @@ impl<A: Step> ops::RangeInclusive<A> {
|
|||
/// ```
|
||||
#[unstable(feature = "step_by", reason = "recent addition",
|
||||
issue = "27741")]
|
||||
#[rustc_deprecated(since = "1.19.0",
|
||||
reason = "replaced by `Iterator::step_by`")]
|
||||
#[allow(deprecated)]
|
||||
pub fn step_by(self, by: A) -> StepBy<A, Self> {
|
||||
StepBy {
|
||||
step_by: by,
|
||||
|
@ -331,6 +343,7 @@ impl<A: Step> ops::RangeInclusive<A> {
|
|||
|
||||
#[unstable(feature = "step_by", reason = "recent addition",
|
||||
issue = "27741")]
|
||||
#[allow(deprecated)]
|
||||
impl<A> Iterator for StepBy<A, ops::RangeFrom<A>> where
|
||||
A: Clone,
|
||||
for<'a> &'a A: Add<&'a A, Output = A>
|
||||
|
@ -351,11 +364,13 @@ impl<A> Iterator for StepBy<A, ops::RangeFrom<A>> where
|
|||
}
|
||||
|
||||
#[unstable(feature = "fused", issue = "35602")]
|
||||
#[allow(deprecated)]
|
||||
impl<A> FusedIterator for StepBy<A, ops::RangeFrom<A>>
|
||||
where A: Clone, for<'a> &'a A: Add<&'a A, Output = A> {}
|
||||
|
||||
#[unstable(feature = "step_by", reason = "recent addition",
|
||||
issue = "27741")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
|
||||
type Item = A;
|
||||
|
||||
|
@ -393,11 +408,13 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "fused", issue = "35602")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step + Clone> FusedIterator for StepBy<A, ops::Range<A>> {}
|
||||
|
||||
#[unstable(feature = "inclusive_range",
|
||||
reason = "recently added, follows RFC",
|
||||
issue = "28237")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
|
||||
type Item = A;
|
||||
|
||||
|
@ -437,6 +454,7 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "fused", issue = "35602")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step + Clone> FusedIterator for StepBy<A, ops::RangeInclusive<A>> {}
|
||||
|
||||
macro_rules! range_exact_iter_impl {
|
||||
|
|
|
@ -12,6 +12,15 @@ use core::iter::*;
|
|||
use core::{i8, i16, isize};
|
||||
use core::usize;
|
||||
|
||||
// FIXME #27741: This is here to simplify calling Iterator::step_by. Remove
|
||||
// once Range::step_by is completely gone (not just deprecated).
|
||||
trait IterEx: Sized {
|
||||
fn iter_step_by(self, n: usize) -> StepBy<Self>;
|
||||
}
|
||||
impl<I:Iterator> IterEx for I {
|
||||
fn iter_step_by(self, n: usize) -> StepBy<Self> { self.step_by(n) }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lt() {
|
||||
let empty: [isize; 0] = [];
|
||||
|
@ -67,7 +76,7 @@ fn test_multi_iter() {
|
|||
|
||||
#[test]
|
||||
fn test_counter_from_iter() {
|
||||
let it = (0..).step_by(5).take(10);
|
||||
let it = (0..).iter_step_by(5).take(10);
|
||||
let xs: Vec<isize> = FromIterator::from_iter(it);
|
||||
assert_eq!(xs, [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
|
||||
}
|
||||
|
@ -85,7 +94,7 @@ fn test_iterator_chain() {
|
|||
}
|
||||
assert_eq!(i, expected.len());
|
||||
|
||||
let ys = (30..).step_by(10).take(4);
|
||||
let ys = (30..).iter_step_by(10).take(4);
|
||||
let it = xs.iter().cloned().chain(ys);
|
||||
let mut i = 0;
|
||||
for x in it {
|
||||
|
@ -147,15 +156,13 @@ fn test_iterator_chain_find() {
|
|||
#[test]
|
||||
fn test_iterator_step_by() {
|
||||
// Identity
|
||||
// Replace with (0..).step_by(1) after Range::step_by gets removed
|
||||
let mut it = Iterator::step_by((0..), 1).take(3);
|
||||
let mut it = (0..).iter_step_by(1).take(3);
|
||||
assert_eq!(it.next(), Some(0));
|
||||
assert_eq!(it.next(), Some(1));
|
||||
assert_eq!(it.next(), Some(2));
|
||||
assert_eq!(it.next(), None);
|
||||
|
||||
// Replace with (0..).step_by(3) after Range::step_by gets removed
|
||||
let mut it = Iterator::step_by((0..), 3).take(4);
|
||||
let mut it = (0..).iter_step_by(3).take(4);
|
||||
assert_eq!(it.next(), Some(0));
|
||||
assert_eq!(it.next(), Some(3));
|
||||
assert_eq!(it.next(), Some(6));
|
||||
|
@ -166,8 +173,7 @@ fn test_iterator_step_by() {
|
|||
#[test]
|
||||
#[should_panic]
|
||||
fn test_iterator_step_by_zero() {
|
||||
// Replace with (0..).step_by(0) after Range::step_by gets removed
|
||||
let mut it = Iterator::step_by((0..), 0);
|
||||
let mut it = (0..).iter_step_by(0);
|
||||
it.next();
|
||||
}
|
||||
|
||||
|
@ -246,7 +252,7 @@ fn test_iterator_step_by_size_hint() {
|
|||
|
||||
#[test]
|
||||
fn test_filter_map() {
|
||||
let it = (0..).step_by(1).take(10)
|
||||
let it = (0..).iter_step_by(1).take(10)
|
||||
.filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
|
||||
assert_eq!(it.collect::<Vec<usize>>(), [0*0, 2*2, 4*4, 6*6, 8*8]);
|
||||
}
|
||||
|
@ -648,7 +654,7 @@ fn test_iterator_scan() {
|
|||
fn test_iterator_flat_map() {
|
||||
let xs = [0, 3, 6];
|
||||
let ys = [0, 1, 2, 3, 4, 5, 6, 7, 8];
|
||||
let it = xs.iter().flat_map(|&x| (x..).step_by(1).take(3));
|
||||
let it = xs.iter().flat_map(|&x| (x..).iter_step_by(1).take(3));
|
||||
let mut i = 0;
|
||||
for x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
|
@ -674,13 +680,13 @@ fn test_inspect() {
|
|||
#[test]
|
||||
fn test_cycle() {
|
||||
let cycle_len = 3;
|
||||
let it = (0..).step_by(1).take(cycle_len).cycle();
|
||||
let it = (0..).iter_step_by(1).take(cycle_len).cycle();
|
||||
assert_eq!(it.size_hint(), (usize::MAX, None));
|
||||
for (i, x) in it.take(100).enumerate() {
|
||||
assert_eq!(i % cycle_len, x);
|
||||
}
|
||||
|
||||
let mut it = (0..).step_by(1).take(0).cycle();
|
||||
let mut it = (0..).iter_step_by(1).take(0).cycle();
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
@ -759,7 +765,7 @@ fn test_iterator_min() {
|
|||
|
||||
#[test]
|
||||
fn test_iterator_size_hint() {
|
||||
let c = (0..).step_by(1);
|
||||
let c = (0..).iter_step_by(1);
|
||||
let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
let v2 = &[10, 11, 12];
|
||||
let vi = v.iter();
|
||||
|
@ -1081,6 +1087,8 @@ fn test_range() {
|
|||
|
||||
#[test]
|
||||
fn test_range_step() {
|
||||
#![allow(deprecated)]
|
||||
|
||||
assert_eq!((0..20).step_by(5).collect::<Vec<isize>>(), [0, 5, 10, 15]);
|
||||
assert_eq!((20..0).step_by(-5).collect::<Vec<isize>>(), [20, 15, 10, 5]);
|
||||
assert_eq!((20..0).step_by(-6).collect::<Vec<isize>>(), [20, 14, 8, 2]);
|
||||
|
|
|
@ -11,4 +11,4 @@ crate-type = ["dylib"]
|
|||
|
||||
[build-dependencies]
|
||||
build_helper = { path = "../build_helper" }
|
||||
gcc = "0.3.27"
|
||||
gcc = "0.3.50"
|
||||
|
|
|
@ -254,7 +254,7 @@ and `...` are whatever edges the `/* compute value */` closure creates.
|
|||
In particular, using the memoize helper is much better than writing
|
||||
the obvious code yourself:
|
||||
|
||||
```
|
||||
```rust
|
||||
if let Some(result) = map.get(key) {
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -8,12 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||
use rustc_data_structures::stable_hasher;
|
||||
use std::mem;
|
||||
use std::slice;
|
||||
|
||||
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
|
||||
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
|
||||
pub struct Fingerprint(u64, u64);
|
||||
|
||||
impl Fingerprint {
|
||||
|
@ -37,23 +36,6 @@ impl Fingerprint {
|
|||
}
|
||||
}
|
||||
|
||||
impl Encodable for Fingerprint {
|
||||
#[inline]
|
||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
s.emit_u64(self.0.to_le())?;
|
||||
s.emit_u64(self.1.to_le())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for Fingerprint {
|
||||
#[inline]
|
||||
fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> {
|
||||
let _0 = u64::from_le(d.read_u64()?);
|
||||
let _1 = u64::from_le(d.read_u64()?);
|
||||
Ok(Fingerprint(_0, _1))
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for Fingerprint {
|
||||
fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
|
||||
write!(formatter, "{:x}-{:x}", self.0, self.1)
|
||||
|
|
|
@ -17,4 +17,4 @@ rustc_bitflags = { path = "../librustc_bitflags" }
|
|||
|
||||
[build-dependencies]
|
||||
build_helper = { path = "../build_helper" }
|
||||
gcc = "0.3.27"
|
||||
gcc = "0.3.50"
|
||||
|
|
|
@ -25,3 +25,6 @@ rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
|
|||
serialize = { path = "../libserialize" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
gcc = "0.3.50"
|
||||
|
|
|
@ -12,7 +12,6 @@ use super::archive::{ArchiveBuilder, ArchiveConfig};
|
|||
use super::linker::Linker;
|
||||
use super::rpath::RPathConfig;
|
||||
use super::rpath;
|
||||
use super::msvc;
|
||||
use metadata::METADATA_FILENAME;
|
||||
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, Input, OutputType};
|
||||
use rustc::session::filesearch;
|
||||
|
@ -142,20 +141,41 @@ pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMet
|
|||
return r;
|
||||
}
|
||||
|
||||
// The third parameter is for an extra path to add to PATH for MSVC
|
||||
// cross linkers for host toolchain DLL dependencies
|
||||
pub fn get_linker(sess: &Session) -> (String, Command, Option<PathBuf>) {
|
||||
// The third parameter is for an env vars, used to set up the path for MSVC
|
||||
// to find its DLLs
|
||||
pub fn get_linker(sess: &Session) -> (String, Command, Vec<(OsString, OsString)>) {
|
||||
if let Some(ref linker) = sess.opts.cg.linker {
|
||||
(linker.clone(), Command::new(linker), None)
|
||||
(linker.clone(), Command::new(linker), vec![])
|
||||
} else if sess.target.target.options.is_like_msvc {
|
||||
let (cmd, host) = msvc::link_exe_cmd(sess);
|
||||
("link.exe".to_string(), cmd, host)
|
||||
let (cmd, envs) = msvc_link_exe_cmd(sess);
|
||||
("link.exe".to_string(), cmd, envs)
|
||||
} else {
|
||||
(sess.target.target.options.linker.clone(),
|
||||
Command::new(&sess.target.target.options.linker), None)
|
||||
Command::new(&sess.target.target.options.linker), vec![])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn msvc_link_exe_cmd(sess: &Session) -> (Command, Vec<(OsString, OsString)>) {
|
||||
use gcc::windows_registry;
|
||||
|
||||
let target = &sess.opts.target_triple;
|
||||
let tool = windows_registry::find_tool(target, "link.exe");
|
||||
|
||||
if let Some(tool) = tool {
|
||||
let envs = tool.env().to_vec();
|
||||
(tool.to_command(), envs)
|
||||
} else {
|
||||
debug!("Failed to locate linker.");
|
||||
(Command::new("link.exe"), vec![])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn msvc_link_exe_cmd(_sess: &Session) -> (Command, Vec<(OsString, OsString)>) {
|
||||
(Command::new("link.exe"), vec![])
|
||||
}
|
||||
|
||||
pub fn get_ar_prog(sess: &Session) -> String {
|
||||
sess.opts.cg.ar.clone().unwrap_or_else(|| {
|
||||
sess.target.target.options.ar.clone()
|
||||
|
@ -706,8 +726,9 @@ fn link_natively(sess: &Session,
|
|||
let flavor = sess.linker_flavor();
|
||||
|
||||
// The invocations of cc share some flags across platforms
|
||||
let (pname, mut cmd, extra) = get_linker(sess);
|
||||
cmd.env("PATH", command_path(sess, extra));
|
||||
let (pname, mut cmd, envs) = get_linker(sess);
|
||||
// This will set PATH on MSVC
|
||||
cmd.envs(envs);
|
||||
|
||||
let root = sess.target_filesearch(PathKind::Native).get_lib_path();
|
||||
if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) {
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(non_camel_case_types, non_snake_case)]
|
||||
|
||||
use libc::c_void;
|
||||
use std::mem;
|
||||
|
||||
type DWORD = u32;
|
||||
type WORD = u16;
|
||||
type LPVOID = *mut c_void;
|
||||
type DWORD_PTR = usize;
|
||||
|
||||
const PROCESSOR_ARCHITECTURE_INTEL: WORD = 0;
|
||||
const PROCESSOR_ARCHITECTURE_AMD64: WORD = 9;
|
||||
|
||||
#[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);
|
||||
}
|
||||
|
||||
pub enum Arch {
|
||||
X86,
|
||||
Amd64,
|
||||
}
|
||||
|
||||
pub fn host_arch() -> Option<Arch> {
|
||||
let mut info = unsafe { mem::zeroed() };
|
||||
unsafe { GetNativeSystemInfo(&mut info) };
|
||||
match info.wProcessorArchitecture {
|
||||
PROCESSOR_ARCHITECTURE_INTEL => Some(Arch::X86),
|
||||
PROCESSOR_ARCHITECTURE_AMD64 => Some(Arch::Amd64),
|
||||
_ => None,
|
||||
}
|
||||
}
|
|
@ -1,305 +0,0 @@
|
|||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! MSVC-specific logic for linkers and such.
|
||||
//!
|
||||
//! This module contains a cross-platform interface but has a blank unix
|
||||
//! implementation. The Windows implementation builds on top of Windows native
|
||||
//! libraries (reading registry keys), so it otherwise wouldn't link on unix.
|
||||
//!
|
||||
//! Note that we don't have much special logic for finding the system linker on
|
||||
//! any other platforms, so it may seem a little odd to single out MSVC to have
|
||||
//! a good deal of code just to find the linker. Unlike Unix systems, however,
|
||||
//! the MSVC linker is not in the system PATH by default. It also additionally
|
||||
//! needs a few environment variables or command line flags to be able to link
|
||||
//! against system libraries.
|
||||
//!
|
||||
//! In order to have a nice smooth experience on Windows, the logic in this file
|
||||
//! is here to find the MSVC linker and set it up in the default configuration
|
||||
//! one would need to set up anyway. This means that the Rust compiler can be
|
||||
//! run not only in the developer shells of MSVC but also the standard cmd.exe
|
||||
//! shell or MSYS shells.
|
||||
//!
|
||||
//! As a high-level note, all logic in this module for looking up various
|
||||
//! paths/files is based on Microsoft's logic in their vcvars bat files, but
|
||||
//! comments can also be found below leading through the various code paths.
|
||||
|
||||
// A simple macro to make this option mess easier to read
|
||||
#[cfg(windows)]
|
||||
macro_rules! otry {
|
||||
($expr:expr) => (match $expr {
|
||||
Some(val) => val,
|
||||
None => return None,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
mod registry;
|
||||
#[cfg(windows)]
|
||||
mod arch;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod platform {
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use rustc::session::Session;
|
||||
use super::arch::{host_arch, Arch};
|
||||
use super::registry::LOCAL_MACHINE;
|
||||
|
||||
// First we need to figure out whether the environment is already correctly
|
||||
// configured by vcvars. We do this by looking at the environment variable
|
||||
// `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set
|
||||
// otherwise. If it is defined, then we find `link.exe` in `PATH and trust
|
||||
// that everything else is configured correctly.
|
||||
//
|
||||
// If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where
|
||||
// it claimed it should be), then we resort to finding everything
|
||||
// ourselves. First we find where the latest version of MSVC is installed
|
||||
// and what version it is. Then based on the version we find the
|
||||
// appropriate SDKs.
|
||||
//
|
||||
// If despite our best efforts we are still unable to find MSVC then we
|
||||
// just blindly call `link.exe` and hope for the best.
|
||||
//
|
||||
// This code only supports VC 11 through 15. For versions older than that
|
||||
// the user will need to manually execute the appropriate vcvars bat file
|
||||
// and it should hopefully work.
|
||||
//
|
||||
// The second member of the tuple we return is the directory for the host
|
||||
// linker toolchain, which is necessary when using the cross linkers.
|
||||
pub fn link_exe_cmd(sess: &Session) -> (Command, Option<PathBuf>) {
|
||||
let arch = &sess.target.target.arch;
|
||||
env::var_os("VCINSTALLDIR").and_then(|_| {
|
||||
debug!("Detected that vcvars was already run.");
|
||||
let path = otry!(env::var_os("PATH"));
|
||||
// Mingw has its own link which is not the link we want so we
|
||||
// look for `cl.exe` too as a precaution.
|
||||
env::split_paths(&path).find(|path| {
|
||||
path.join("cl.exe").is_file()
|
||||
&& path.join("link.exe").is_file()
|
||||
}).map(|path| {
|
||||
(Command::new(path.join("link.exe")), None)
|
||||
})
|
||||
}).or_else(|| {
|
||||
None.or_else(|| {
|
||||
find_msvc_latest(arch, "15.0")
|
||||
}).or_else(|| {
|
||||
find_msvc_latest(arch, "14.0")
|
||||
}).or_else(|| {
|
||||
find_msvc_12(arch)
|
||||
}).or_else(|| {
|
||||
find_msvc_11(arch)
|
||||
}).map(|(cmd, path)| (cmd, Some(path)))
|
||||
}).unwrap_or_else(|| {
|
||||
debug!("Failed to locate linker.");
|
||||
(Command::new("link.exe"), None)
|
||||
})
|
||||
}
|
||||
|
||||
// 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(arch: &str, ver: &str) -> Option<(Command, PathBuf)> {
|
||||
let vcdir = otry!(get_vc_dir(ver));
|
||||
let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
|
||||
let sub = otry!(lib_subdir(arch));
|
||||
let ucrt = otry!(get_ucrt_dir());
|
||||
debug!("Found Universal CRT {:?}", ucrt);
|
||||
add_lib(&mut cmd, &ucrt.join("ucrt").join(sub));
|
||||
if let Some(dir) = get_sdk10_dir() {
|
||||
debug!("Found Win10 SDK {:?}", dir);
|
||||
add_lib(&mut cmd, &dir.join("um").join(sub));
|
||||
} else if let Some(dir) = get_sdk81_dir() {
|
||||
debug!("Found Win8.1 SDK {:?}", dir);
|
||||
add_lib(&mut cmd, &dir.join("um").join(sub));
|
||||
} else {
|
||||
return None
|
||||
}
|
||||
Some((cmd, host))
|
||||
}
|
||||
|
||||
// For MSVC 12 we need to find the Windows 8.1 SDK.
|
||||
fn find_msvc_12(arch: &str) -> Option<(Command, PathBuf)> {
|
||||
let vcdir = otry!(get_vc_dir("12.0"));
|
||||
let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
|
||||
let sub = otry!(lib_subdir(arch));
|
||||
let sdk81 = otry!(get_sdk81_dir());
|
||||
debug!("Found Win8.1 SDK {:?}", sdk81);
|
||||
add_lib(&mut cmd, &sdk81.join("um").join(sub));
|
||||
Some((cmd, host))
|
||||
}
|
||||
|
||||
// For MSVC 11 we need to find the Windows 8 SDK.
|
||||
fn find_msvc_11(arch: &str) -> Option<(Command, PathBuf)> {
|
||||
let vcdir = otry!(get_vc_dir("11.0"));
|
||||
let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
|
||||
let sub = otry!(lib_subdir(arch));
|
||||
let sdk8 = otry!(get_sdk8_dir());
|
||||
debug!("Found Win8 SDK {:?}", sdk8);
|
||||
add_lib(&mut cmd, &sdk8.join("um").join(sub));
|
||||
Some((cmd, host))
|
||||
}
|
||||
|
||||
// A convenience function to append library paths.
|
||||
fn add_lib(cmd: &mut Command, lib: &Path) {
|
||||
let mut arg: OsString = "/LIBPATH:".into();
|
||||
arg.push(lib);
|
||||
cmd.arg(arg);
|
||||
}
|
||||
|
||||
// Given a possible MSVC installation directory, we look for the linker and
|
||||
// then add the MSVC library path.
|
||||
fn get_linker(path: &Path, arch: &str) -> Option<(Command, PathBuf)> {
|
||||
debug!("Looking for linker in {:?}", path);
|
||||
bin_subdir(arch).into_iter().map(|(sub, host)| {
|
||||
(path.join("bin").join(sub).join("link.exe"),
|
||||
path.join("bin").join(host))
|
||||
}).filter(|&(ref path, _)| {
|
||||
path.is_file()
|
||||
}).map(|(path, host)| {
|
||||
(Command::new(path), host)
|
||||
}).filter_map(|(mut cmd, host)| {
|
||||
let sub = otry!(vc_lib_subdir(arch));
|
||||
add_lib(&mut cmd, &path.join("lib").join(sub));
|
||||
Some((cmd, host))
|
||||
}).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<PathBuf> {
|
||||
let key = otry!(LOCAL_MACHINE
|
||||
.open(r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7".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.
|
||||
fn get_ucrt_dir() -> Option<PathBuf> {
|
||||
let key = otry!(LOCAL_MACHINE
|
||||
.open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots".as_ref()).ok());
|
||||
let root = otry!(key.query_str("KitsRoot10").ok());
|
||||
let readdir = otry!(fs::read_dir(Path::new(&root).join("lib")).ok());
|
||||
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()
|
||||
}
|
||||
|
||||
// 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> {
|
||||
let key = otry!(LOCAL_MACHINE
|
||||
.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0".as_ref()).ok());
|
||||
let root = otry!(key.query_str("InstallationFolder").ok());
|
||||
let readdir = otry!(fs::read_dir(Path::new(&root).join("lib")).ok());
|
||||
let mut dirs: Vec<_> = readdir.filter_map(|dir| dir.ok())
|
||||
.map(|dir| dir.path()).collect();
|
||||
dirs.sort();
|
||||
dirs.into_iter().rev().filter(|dir| {
|
||||
dir.join("um").join("x64").join("kernel32.lib").is_file()
|
||||
}).next()
|
||||
}
|
||||
|
||||
// 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<PathBuf> {
|
||||
let key = otry!(LOCAL_MACHINE
|
||||
.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1".as_ref()).ok());
|
||||
let root = otry!(key.query_str("InstallationFolder").ok());
|
||||
Some(Path::new(&root).join("lib").join("winv6.3"))
|
||||
}
|
||||
|
||||
fn get_sdk8_dir() -> Option<PathBuf> {
|
||||
let key = otry!(LOCAL_MACHINE
|
||||
.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0".as_ref()).ok());
|
||||
let root = otry!(key.query_str("InstallationFolder").ok());
|
||||
Some(Path::new(&root).join("lib").join("win8"))
|
||||
}
|
||||
|
||||
// When choosing the linker toolchain to use, we have to choose the one
|
||||
// which matches the host 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 linker which won't work.
|
||||
//
|
||||
// For the return value of this function, the first member of the tuple is
|
||||
// the folder of the linker we will be invoking, while the second member
|
||||
// is the folder of the host toolchain for that linker 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.
|
||||
//
|
||||
// FIXME - Figure out what happens when the host architecture is arm.
|
||||
fn bin_subdir(arch: &str) -> Vec<(&'static str, &'static str)> {
|
||||
match (arch, host_arch()) {
|
||||
("x86", Some(Arch::X86)) => vec![("", "")],
|
||||
("x86", Some(Arch::Amd64)) => vec![("amd64_x86", "amd64"), ("", "")],
|
||||
("x86_64", Some(Arch::X86)) => vec![("x86_amd64", "")],
|
||||
("x86_64", Some(Arch::Amd64)) => vec![("amd64", "amd64"), ("x86_amd64", "")],
|
||||
("arm", Some(Arch::X86)) => vec![("x86_arm", "")],
|
||||
("arm", Some(Arch::Amd64)) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
|
||||
_ => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn lib_subdir(arch: &str) -> Option<&'static str> {
|
||||
match arch {
|
||||
"x86" => Some("x86"),
|
||||
"x86_64" => Some("x64"),
|
||||
"arm" => Some("arm"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// MSVC's x86 libraries are not in a subfolder
|
||||
fn vc_lib_subdir(arch: &str) -> Option<&'static str> {
|
||||
match arch {
|
||||
"x86" => Some(""),
|
||||
"x86_64" => Some("amd64"),
|
||||
"arm" => Some("arm"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're not on Windows, then there's no registry to search through and MSVC
|
||||
// wouldn't be able to run, so we just call `link.exe` and hope for the best.
|
||||
#[cfg(not(windows))]
|
||||
mod platform {
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use rustc::session::Session;
|
||||
pub fn link_exe_cmd(_sess: &Session) -> (Command, Option<PathBuf>) {
|
||||
(Command::new("link.exe"), None)
|
||||
}
|
||||
}
|
||||
|
||||
pub use self::platform::*;
|
|
@ -1,136 +0,0 @@
|
|||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::io;
|
||||
use std::ffi::{OsString, OsStr};
|
||||
use std::os::windows::prelude::*;
|
||||
use std::ptr;
|
||||
use libc::c_long;
|
||||
|
||||
pub type DWORD = u32;
|
||||
type LPCWSTR = *const u16;
|
||||
type LONG = c_long;
|
||||
type LPDWORD = *mut DWORD;
|
||||
type LPBYTE = *mut u8;
|
||||
|
||||
|
||||
const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY;
|
||||
const KEY_WOW64_32KEY: REGSAM = 0x0200;
|
||||
const KEY_READ: REGSAM = (STANDARD_RIGTS_READ | KEY_QUERY_VALUE |
|
||||
KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & !SYNCHRONIZE;
|
||||
const STANDARD_RIGTS_READ: REGSAM = READ_CONTROL;
|
||||
const READ_CONTROL: REGSAM = 0x00020000;
|
||||
const KEY_QUERY_VALUE: REGSAM = 0x0001;
|
||||
const KEY_ENUMERATE_SUB_KEYS: REGSAM = 0x0008;
|
||||
const KEY_NOTIFY: REGSAM = 0x0010;
|
||||
const SYNCHRONIZE: REGSAM = 0x00100000;
|
||||
const REG_SZ: DWORD = 1;
|
||||
const ERROR_SUCCESS: i32 = 0;
|
||||
|
||||
pub enum __HKEY__ {}
|
||||
pub type HKEY = *mut __HKEY__;
|
||||
pub type PHKEY = *mut HKEY;
|
||||
pub type REGSAM = DWORD;
|
||||
|
||||
#[link(name = "advapi32")]
|
||||
extern "system" {
|
||||
fn RegOpenKeyExW(hKey: HKEY,
|
||||
lpSubKey: LPCWSTR,
|
||||
ulOptions: DWORD,
|
||||
samDesired: REGSAM,
|
||||
phkResult: PHKEY) -> LONG;
|
||||
fn RegQueryValueExW(hKey: HKEY,
|
||||
lpValueName: LPCWSTR,
|
||||
lpReserved: LPDWORD,
|
||||
lpType: LPDWORD,
|
||||
lpData: LPBYTE,
|
||||
lpcbData: LPDWORD) -> LONG;
|
||||
fn RegCloseKey(hKey: HKEY) -> LONG;
|
||||
}
|
||||
|
||||
pub struct RegistryKey(Repr);
|
||||
|
||||
struct OwnedKey(HKEY);
|
||||
|
||||
enum Repr {
|
||||
Const(HKEY),
|
||||
Owned(OwnedKey),
|
||||
}
|
||||
|
||||
unsafe impl Sync for RegistryKey {}
|
||||
unsafe impl Send for RegistryKey {}
|
||||
|
||||
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<RegistryKey> {
|
||||
let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();
|
||||
let mut ret = ptr::null_mut();
|
||||
let err = unsafe {
|
||||
RegOpenKeyExW(self.raw(), key.as_ptr(), 0,
|
||||
KEY_READ | KEY_WOW64_32KEY, &mut ret)
|
||||
};
|
||||
if err == ERROR_SUCCESS {
|
||||
Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(err as i32))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query_str(&self, name: &str) -> io::Result<OsString> {
|
||||
let name: &OsStr = name.as_ref();
|
||||
let name = name.encode_wide().chain(Some(0)).collect::<Vec<_>>();
|
||||
let mut len = 0;
|
||||
let mut kind = 0;
|
||||
unsafe {
|
||||
let err = RegQueryValueExW(self.raw(), name.as_ptr(), ptr::null_mut(),
|
||||
&mut kind, ptr::null_mut(), &mut len);
|
||||
if err != ERROR_SUCCESS {
|
||||
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(), ptr::null_mut(),
|
||||
ptr::null_mut(), v.as_mut_ptr() as *mut _,
|
||||
&mut len);
|
||||
if err != ERROR_SUCCESS {
|
||||
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); }
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@
|
|||
#![feature(slice_patterns)]
|
||||
#![feature(unicode)]
|
||||
#![feature(conservative_impl_trait)]
|
||||
#![feature(command_envs)]
|
||||
|
||||
#![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
|
||||
#![cfg_attr(stage0, feature(rustc_private))]
|
||||
|
@ -62,6 +63,8 @@ extern crate rustc_bitflags;
|
|||
extern crate syntax_pos;
|
||||
extern crate rustc_errors as errors;
|
||||
extern crate serialize;
|
||||
#[cfg(windows)]
|
||||
extern crate gcc; // Used to locate MSVC, not gcc :)
|
||||
|
||||
pub use base::trans_crate;
|
||||
pub use back::symbol_names::provide;
|
||||
|
@ -77,8 +80,7 @@ pub mod back {
|
|||
pub(crate) mod symbol_export;
|
||||
pub(crate) mod symbol_names;
|
||||
pub mod write;
|
||||
mod msvc;
|
||||
mod rpath;
|
||||
pub mod rpath;
|
||||
}
|
||||
|
||||
mod diagnostics;
|
||||
|
|
|
@ -30,4 +30,4 @@ pulldown-cmark = { version = "0.0.14", default-features = false }
|
|||
|
||||
[build-dependencies]
|
||||
build_helper = { path = "../build_helper" }
|
||||
gcc = "0.3.27"
|
||||
gcc = "0.3.50"
|
||||
|
|
|
@ -1506,8 +1506,8 @@ pub enum Type {
|
|||
/// extern "ABI" fn
|
||||
BareFunction(Box<BareFunctionDecl>),
|
||||
Tuple(Vec<Type>),
|
||||
Vector(Box<Type>),
|
||||
FixedVector(Box<Type>, String),
|
||||
Slice(Box<Type>),
|
||||
Array(Box<Type>, usize),
|
||||
Never,
|
||||
Unique(Box<Type>),
|
||||
RawPointer(Mutability, Box<Type>),
|
||||
|
@ -1573,10 +1573,8 @@ impl Type {
|
|||
pub fn primitive_type(&self) -> Option<PrimitiveType> {
|
||||
match *self {
|
||||
Primitive(p) | BorrowedRef { type_: box Primitive(p), ..} => Some(p),
|
||||
Vector(..) | BorrowedRef{ type_: box Vector(..), .. } => Some(PrimitiveType::Slice),
|
||||
FixedVector(..) | BorrowedRef { type_: box FixedVector(..), .. } => {
|
||||
Some(PrimitiveType::Array)
|
||||
}
|
||||
Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
|
||||
Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array),
|
||||
Tuple(..) => Some(PrimitiveType::Tuple),
|
||||
RawPointer(..) => Some(PrimitiveType::RawPointer),
|
||||
_ => None,
|
||||
|
@ -1717,11 +1715,11 @@ impl Clean<Type> for hir::Ty {
|
|||
BorrowedRef {lifetime: lifetime, mutability: m.mutbl.clean(cx),
|
||||
type_: box m.ty.clean(cx)}
|
||||
}
|
||||
TySlice(ref ty) => Vector(box ty.clean(cx)),
|
||||
TySlice(ref ty) => Slice(box ty.clean(cx)),
|
||||
TyArray(ref ty, length) => {
|
||||
use rustc::middle::const_val::eval_length;
|
||||
let n = eval_length(cx.tcx, length, "array length").unwrap();
|
||||
FixedVector(box ty.clean(cx), n.to_string())
|
||||
Array(box ty.clean(cx), n)
|
||||
},
|
||||
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
||||
TyPath(hir::QPath::Resolved(None, ref path)) => {
|
||||
|
@ -1832,9 +1830,8 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
|||
ty::TyUint(uint_ty) => Primitive(uint_ty.into()),
|
||||
ty::TyFloat(float_ty) => Primitive(float_ty.into()),
|
||||
ty::TyStr => Primitive(PrimitiveType::Str),
|
||||
ty::TySlice(ty) => Vector(box ty.clean(cx)),
|
||||
ty::TyArray(ty, i) => FixedVector(box ty.clean(cx),
|
||||
format!("{}", i)),
|
||||
ty::TySlice(ty) => Slice(box ty.clean(cx)),
|
||||
ty::TyArray(ty, n) => Array(box ty.clean(cx), n),
|
||||
ty::TyRawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)),
|
||||
ty::TyRef(r, mt) => BorrowedRef {
|
||||
lifetime: r.clean(cx),
|
||||
|
|
|
@ -25,7 +25,6 @@ use rustc::hir;
|
|||
use clean::{self, PrimitiveType};
|
||||
use core::DocAccessLevels;
|
||||
use html::item_type::ItemType;
|
||||
use html::escape::Escape;
|
||||
use html::render;
|
||||
use html::render::{cache, CURRENT_LOCATION_KEY};
|
||||
|
||||
|
@ -643,21 +642,15 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
|
|||
}
|
||||
}
|
||||
}
|
||||
clean::Vector(ref t) => {
|
||||
clean::Slice(ref t) => {
|
||||
primitive_link(f, PrimitiveType::Slice, "[")?;
|
||||
fmt::Display::fmt(t, f)?;
|
||||
primitive_link(f, PrimitiveType::Slice, "]")
|
||||
}
|
||||
clean::FixedVector(ref t, ref s) => {
|
||||
clean::Array(ref t, n) => {
|
||||
primitive_link(f, PrimitiveType::Array, "[")?;
|
||||
fmt::Display::fmt(t, f)?;
|
||||
if f.alternate() {
|
||||
primitive_link(f, PrimitiveType::Array,
|
||||
&format!("; {}]", s))
|
||||
} else {
|
||||
primitive_link(f, PrimitiveType::Array,
|
||||
&format!("; {}]", Escape(s)))
|
||||
}
|
||||
primitive_link(f, PrimitiveType::Array, &format!("; {}]", n))
|
||||
}
|
||||
clean::Never => f.write_str("!"),
|
||||
clean::RawPointer(m, ref t) => {
|
||||
|
@ -685,7 +678,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
|
|||
};
|
||||
let m = MutableSpace(mutability);
|
||||
match **ty {
|
||||
clean::Vector(ref bt) => { // BorrowedRef{ ... Vector(T) } is &[T]
|
||||
clean::Slice(ref bt) => { // BorrowedRef{ ... Slice(T) } is &[T]
|
||||
match **bt {
|
||||
clean::Generic(_) => {
|
||||
if f.alternate() {
|
||||
|
|
|
@ -35,7 +35,7 @@ rustc_tsan = { path = "../librustc_tsan" }
|
|||
|
||||
[build-dependencies]
|
||||
build_helper = { path = "../build_helper" }
|
||||
gcc = "0.3.27"
|
||||
gcc = "0.3.50"
|
||||
|
||||
[features]
|
||||
backtrace = []
|
||||
|
|
|
@ -1370,14 +1370,16 @@ impl<T> Receiver<T> {
|
|||
/// let (send, recv) = channel();
|
||||
///
|
||||
/// thread::spawn(move || {
|
||||
/// send.send(1u8).unwrap();
|
||||
/// send.send(2u8).unwrap();
|
||||
/// send.send(3u8).unwrap();
|
||||
/// send.send(1).unwrap();
|
||||
/// send.send(2).unwrap();
|
||||
/// send.send(3).unwrap();
|
||||
/// });
|
||||
///
|
||||
/// for x in recv.iter() {
|
||||
/// println!("Got: {}", x);
|
||||
/// }
|
||||
/// let mut iter = recv.iter();
|
||||
/// assert_eq!(iter.next(), Some(1));
|
||||
/// assert_eq!(iter.next(), Some(2));
|
||||
/// assert_eq!(iter.next(), Some(3));
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn iter(&self) -> Iter<T> {
|
||||
|
@ -1393,29 +1395,34 @@ impl<T> Receiver<T> {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// ```no_run
|
||||
/// use std::sync::mpsc::channel;
|
||||
/// use std::thread;
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let (sender, receiver) = channel();
|
||||
///
|
||||
/// // Nothing is in the buffer yet
|
||||
/// // nothing is in the buffer yet
|
||||
/// assert!(receiver.try_iter().next().is_none());
|
||||
/// println!("Nothing in the buffer...");
|
||||
///
|
||||
/// thread::spawn(move || {
|
||||
/// thread::sleep(Duration::from_secs(1));
|
||||
/// sender.send(1).unwrap();
|
||||
/// sender.send(2).unwrap();
|
||||
/// sender.send(3).unwrap();
|
||||
/// });
|
||||
///
|
||||
/// println!("Going to sleep...");
|
||||
/// thread::sleep(Duration::from_secs(2)); // block for two seconds
|
||||
/// // nothing is in the buffer yet
|
||||
/// assert!(receiver.try_iter().next().is_none());
|
||||
///
|
||||
/// for x in receiver.try_iter() {
|
||||
/// println!("Got: {}", x);
|
||||
/// }
|
||||
/// // block for two seconds
|
||||
/// thread::sleep(Duration::from_secs(2));
|
||||
///
|
||||
/// let mut iter = receiver.try_iter();
|
||||
/// assert_eq!(iter.next(), Some(1));
|
||||
/// assert_eq!(iter.next(), Some(2));
|
||||
/// assert_eq!(iter.next(), Some(3));
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
#[stable(feature = "receiver_try_iter", since = "1.15.0")]
|
||||
pub fn try_iter(&self) -> TryIter<T> {
|
||||
|
|
|
@ -1094,11 +1094,12 @@ impl<T> JoinInner<T> {
|
|||
|
||||
/// An owned permission to join on a thread (block on its termination).
|
||||
///
|
||||
/// A `JoinHandle` *detaches* the child thread when it is dropped.
|
||||
/// A `JoinHandle` *detaches* the associated thread when it is dropped, which
|
||||
/// means that there is no longer any handle to thread and no way to `join`
|
||||
/// on it.
|
||||
///
|
||||
/// Due to platform restrictions, it is not possible to [`Clone`] this
|
||||
/// handle: the ability to join a child thread is a uniquely-owned
|
||||
/// permission.
|
||||
/// handle: the ability to join a thread is a uniquely-owned permission.
|
||||
///
|
||||
/// This `struct` is created by the [`thread::spawn`] function and the
|
||||
/// [`thread::Builder::spawn`] method.
|
||||
|
@ -1127,6 +1128,30 @@ impl<T> JoinInner<T> {
|
|||
/// }).unwrap();
|
||||
/// ```
|
||||
///
|
||||
/// Child being detached and outliving its parent:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::thread;
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let original_thread = thread::spawn(|| {
|
||||
/// let _detached_thread = thread::spawn(|| {
|
||||
/// // Here we sleep to make sure that the first thread returns before.
|
||||
/// thread::sleep(Duration::from_millis(10));
|
||||
/// // This will be called, even though the JoinHandle is dropped.
|
||||
/// println!("♫ Still alive ♫");
|
||||
/// });
|
||||
/// });
|
||||
///
|
||||
/// let _ = original_thread.join();
|
||||
/// println!("Original thread is joined.");
|
||||
///
|
||||
/// // We make sure that the new thread has time to run, before the main
|
||||
/// // thread returns.
|
||||
///
|
||||
/// thread::sleep(Duration::from_millis(1000));
|
||||
/// ```
|
||||
///
|
||||
/// [`Clone`]: ../../std/clone/trait.Clone.html
|
||||
/// [`thread::spawn`]: fn.spawn.html
|
||||
/// [`thread::Builder::spawn`]: struct.Builder.html#method.spawn
|
||||
|
|
|
@ -5985,6 +5985,10 @@ impl<'a> Parser<'a> {
|
|||
return Ok(Some(self.parse_item_foreign_fn(visibility, lo, attrs)?));
|
||||
}
|
||||
|
||||
if self.check_keyword(keywords::Const) {
|
||||
return Err(self.span_fatal(self.span, "extern items cannot be `const`"));
|
||||
}
|
||||
|
||||
// FIXME #5668: this will occur for a macro invocation:
|
||||
match self.parse_macro_use_or_failure(attrs, true, false, lo, visibility)? {
|
||||
Some(item) => {
|
||||
|
|
|
@ -12,5 +12,5 @@
|
|||
|
||||
extern {
|
||||
const i: isize;
|
||||
//~^ ERROR expected one of `fn`, `pub`, `static`, or `}`, found `const`
|
||||
//~^ ERROR extern items cannot be `const`
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8707ceaf040f6d87b67a002de16a8d2bc4db7a41
|
||||
Subproject commit b4ff403041f17957f735ad750c3241a3a428b9b7
|
Loading…
Add table
Reference in a new issue