diff --git a/.travis.yml b/.travis.yml index d955c3ac3c397..6e242b74894c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -126,7 +126,7 @@ matrix: if: branch = auto - env: IMAGE=dist-armv7-linux DEPLOY=1 if: branch = auto - - env: IMAGE=dist-i586-gnu-i686-musl DEPLOY=1 + - env: IMAGE=dist-i586-gnu-i586-i686-musl DEPLOY=1 if: branch = auto - env: IMAGE=dist-i686-freebsd DEPLOY=1 if: branch = auto diff --git a/src/Cargo.lock b/src/Cargo.lock index f2fef63203513..8fbf3535264fc 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -194,7 +194,7 @@ dependencies = [ "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", "libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -928,7 +928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jobserver" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1711,7 +1711,7 @@ dependencies = [ "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", - "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_apfloat 0.0.0", "rustc_back 0.0.0", @@ -2057,7 +2057,7 @@ dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -2862,7 +2862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fcaf2365eb14b28ec7603c98c06cc531f19de9eb283d89a3dff8417c8c99f5" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" -"checksum jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "931b04e5e57d88cc909528f0d701db36a870b72a052648ded8baf80f9f445e0f" +"checksum jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "565f6106bd87b394398f813bea4e5ecad6d6b0f6aa077592d088f882a506481d" "checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483" "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 48ca2838e4feb..aa9fe459e88c9 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -108,6 +108,8 @@ def v(*args): "MUSL root installation directory (deprecated)") v("musl-root-x86_64", "target.x86_64-unknown-linux-musl.musl-root", "x86_64-unknown-linux-musl install directory") +v("musl-root-i586", "target.i586-unknown-linux-musl.musl-root", + "i586-unknown-linux-musl install directory") v("musl-root-i686", "target.i686-unknown-linux-musl.musl-root", "i686-unknown-linux-musl install directory") v("musl-root-arm", "target.arm-unknown-linux-musleabi.musl-root", diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index a5408ee381bbb..ba8cf3a8e2eb5 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -429,6 +429,8 @@ impl Step for Openssl { "arm-unknown-linux-gnueabihf" => "linux-armv4", "armv7-linux-androideabi" => "android-armv7", "armv7-unknown-linux-gnueabihf" => "linux-armv4", + "i586-unknown-linux-gnu" => "linux-elf", + "i586-unknown-linux-musl" => "linux-elf", "i686-apple-darwin" => "darwin-i386-cc", "i686-linux-android" => "android-x86", "i686-unknown-freebsd" => "BSD-x86-elf", diff --git a/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile similarity index 63% rename from src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile rename to src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile index c59476fab009c..4c9d4b3ba78ed 100644 --- a/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile +++ b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile @@ -21,6 +21,9 @@ COPY scripts/musl.sh /build/ RUN CC=gcc CFLAGS="-m32 -fPIC -Wa,-mrelax-relocations=no" \ CXX=g++ CXXFLAGS="-m32 -Wa,-mrelax-relocations=no" \ bash musl.sh i686 --target=i686 && \ + CC=gcc CFLAGS="-march=pentium -m32 -fPIC -Wa,-mrelax-relocations=no" \ + CXX=g++ CXXFLAGS="-march=pentium -m32 -Wa,-mrelax-relocations=no" \ + bash musl.sh i586 --target=i586 && \ rm -rf /build COPY scripts/sccache.sh /scripts/ @@ -28,6 +31,7 @@ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ --target=i686-unknown-linux-musl,i586-unknown-linux-gnu \ + --musl-root-i586=/musl-i586 \ --musl-root-i686=/musl-i686 \ --enable-extended @@ -38,12 +42,13 @@ ENV RUST_CONFIGURE_ARGS \ # See: https://github.com/rust-lang/rust/issues/34978 ENV CFLAGS_i686_unknown_linux_musl=-Wa,-mrelax-relocations=no ENV CFLAGS_i586_unknown_linux_gnu=-Wa,-mrelax-relocations=no +# FIXME remove -Wl,-melf_i386 after cc is updated to include +# https://github.com/alexcrichton/cc-rs/pull/281 +ENV CFLAGS_i586_unknown_linux_musl="-Wa,-mrelax-relocations=no -Wl,-melf_i386" + +ENV TARGETS=i586-unknown-linux-gnu +ENV TARGETS=$TARGETS,i686-unknown-linux-musl ENV SCRIPT \ - python2.7 ../x.py test \ - --target i686-unknown-linux-musl \ - --target i586-unknown-linux-gnu \ - && \ - python2.7 ../x.py dist \ - --target i686-unknown-linux-musl \ - --target i586-unknown-linux-gnu + python2.7 ../x.py test --target $TARGETS && \ + python2.7 ../x.py dist --target $TARGETS,i586-unknown-linux-musl diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh index b704e37d59291..7a7233216a35f 100644 --- a/src/ci/docker/scripts/musl.sh +++ b/src/ci/docker/scripts/musl.sh @@ -30,7 +30,7 @@ exit 1 TAG=$1 shift -MUSL=musl-1.1.17 +MUSL=musl-1.1.18 # may have been downloaded in a previous run if [ ! -d $MUSL ]; then @@ -39,7 +39,7 @@ fi cd $MUSL ./configure --disable-shared --prefix=/musl-$TAG $@ -if [ "$TAG" = "i686" ]; then +if [ "$TAG" = "i586" -o "$TAG" = "i686" ]; then hide_output make -j$(nproc) AR=ar RANLIB=ranlib else hide_output make -j$(nproc) diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index e635df5204007..72fa3148fe54a 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -69,7 +69,9 @@ struct TypedArenaChunk { impl TypedArenaChunk { #[inline] unsafe fn new(capacity: usize) -> TypedArenaChunk { - TypedArenaChunk { storage: RawVec::with_capacity(capacity) } + TypedArenaChunk { + storage: RawVec::with_capacity(capacity), + } } /// Destroys this arena chunk. @@ -132,7 +134,9 @@ impl TypedArena { unsafe { if mem::size_of::() == 0 { - self.ptr.set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) as *mut T); + self.ptr + .set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) + as *mut T); let ptr = mem::align_of::() as *mut T; // Don't drop the object. This `write` is equivalent to `forget`. ptr::write(ptr, object); @@ -157,7 +161,9 @@ impl TypedArena { /// - Zero-length slices #[inline] pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] - where T: Copy { + where + T: Copy, + { assert!(mem::size_of::() != 0); assert!(slice.len() != 0); @@ -321,7 +327,10 @@ impl DroplessArena { let (chunk, mut new_capacity); if let Some(last_chunk) = chunks.last_mut() { let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize; - if last_chunk.storage.reserve_in_place(used_bytes, needed_bytes) { + if last_chunk + .storage + .reserve_in_place(used_bytes, needed_bytes) + { self.end.set(last_chunk.end()); return; } else { @@ -357,9 +366,9 @@ impl DroplessArena { let ptr = self.ptr.get(); // Set the pointer past ourselves - self.ptr.set(intrinsics::arith_offset( - self.ptr.get(), mem::size_of::() as isize - ) as *mut u8); + self.ptr.set( + intrinsics::arith_offset(self.ptr.get(), mem::size_of::() as isize) as *mut u8, + ); // Write into uninitialized memory. ptr::write(ptr as *mut T, object); &mut *(ptr as *mut T) @@ -375,7 +384,9 @@ impl DroplessArena { /// - Zero-length slices #[inline] pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] - where T: Copy { + where + T: Copy, + { assert!(!mem::needs_drop::()); assert!(mem::size_of::() != 0); assert!(slice.len() != 0); @@ -391,7 +402,8 @@ impl DroplessArena { unsafe { let arena_slice = slice::from_raw_parts_mut(self.ptr.get() as *mut T, slice.len()); self.ptr.set(intrinsics::arith_offset( - self.ptr.get(), (slice.len() * mem::size_of::()) as isize + self.ptr.get(), + (slice.len() * mem::size_of::()) as isize, ) as *mut u8); arena_slice.copy_from_slice(slice); arena_slice @@ -456,8 +468,9 @@ mod tests { let arena = Wrap(TypedArena::new()); - let result = - arena.alloc_outer(|| Outer { inner: arena.alloc_inner(|| Inner { value: 10 }) }); + let result = arena.alloc_outer(|| Outer { + inner: arena.alloc_inner(|| Inner { value: 10 }), + }); assert_eq!(result.inner.value, 10); } diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs index 7eb5ff9885777..587dcbe6d6784 100644 --- a/src/libcore/tests/num/mod.rs +++ b/src/libcore/tests/num/mod.rs @@ -197,7 +197,6 @@ test_impl_from! { test_u16f64, u16, f64 } test_impl_from! { test_u32f64, u32, f64 } // Float -> Float -#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 #[test] fn test_f32f64() { use core::f32; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 44f23c11b04c3..075ee0b8c7c28 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -48,6 +48,7 @@ #![feature(drain_filter)] #![feature(dyn_trait)] #![feature(from_ref)] +#![feature(fs_read_write)] #![feature(i128)] #![feature(i128_type)] #![feature(inclusive_range)] diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 32ab458cb91de..5336c1944e8c4 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -1046,7 +1046,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) { // calculated the lint levels for all AST nodes. for (_id, lints) in cx.buffered.map { for early_lint in lints { - span_bug!(early_lint.span, "failed to process bufferd lint here"); + span_bug!(early_lint.span, "failed to process buffered lint here"); } } } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 29af9bb668e9d..2971f3e853a99 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -218,13 +218,10 @@ pub fn record_time(accu: &Cell, f: F) -> T where // Memory reporting #[cfg(unix)] fn get_resident() -> Option { - use std::fs::File; - use std::io::Read; + use std::fs; let field = 1; - let mut f = File::open("/proc/self/statm").ok()?; - let mut contents = String::new(); - f.read_to_string(&mut contents).ok()?; + let contents = fs::read_string("/proc/self/statm").ok()?; let s = contents.split_whitespace().nth(field)?; let npages = s.parse::().ok()?; Some(npages * 4096) diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index ccf1db778d296..8bf60b091a7ad 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -28,6 +28,7 @@ #![feature(box_syntax)] #![feature(const_fn)] +#![feature(fs_read_write)] extern crate syntax; extern crate rand; diff --git a/src/librustc_back/target/i586_unknown_linux_musl.rs b/src/librustc_back/target/i586_unknown_linux_musl.rs new file mode 100644 index 0000000000000..416eacf475b5c --- /dev/null +++ b/src/librustc_back/target/i586_unknown_linux_musl.rs @@ -0,0 +1,18 @@ +// 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. + +use target::TargetResult; + +pub fn target() -> TargetResult { + let mut base = super::i686_unknown_linux_musl::target()?; + base.options.cpu = "pentium".to_string(); + base.llvm_target = "i586-unknown-linux-musl".to_string(); + Ok(base) +} diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 6fcdedfb34042..b65b18d0caa8c 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -47,7 +47,6 @@ use serialize::json::{Json, ToJson}; use std::collections::BTreeMap; use std::default::Default; -use std::io::prelude::*; use syntax::abi::{Abi, lookup as lookup_abi}; use {LinkerFlavor, PanicStrategy, RelroLevel}; @@ -147,6 +146,7 @@ supported_targets! { ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu), ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), ("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu), + ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu), ("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi), ("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf), ("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi), @@ -156,16 +156,17 @@ supported_targets! { ("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf), ("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf), ("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu), + ("aarch64-unknown-linux-musl", aarch64_unknown_linux_musl), ("x86_64-unknown-linux-musl", x86_64_unknown_linux_musl), ("i686-unknown-linux-musl", i686_unknown_linux_musl), + ("i586-unknown-linux-musl", i586_unknown_linux_musl), ("mips-unknown-linux-musl", mips_unknown_linux_musl), ("mipsel-unknown-linux-musl", mipsel_unknown_linux_musl), + ("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc), ("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc), - ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu), - ("i686-linux-android", i686_linux_android), ("x86_64-linux-android", x86_64_linux_android), ("arm-linux-androideabi", arm_linux_androideabi), @@ -809,14 +810,12 @@ impl Target { pub fn search(target: &str) -> Result { use std::env; use std::ffi::OsString; - use std::fs::File; + use std::fs; use std::path::{Path, PathBuf}; use serialize::json; fn load_file(path: &Path) -> Result { - let mut f = File::open(path).map_err(|e| e.to_string())?; - let mut contents = Vec::new(); - f.read_to_end(&mut contents).map_err(|e| e.to_string())?; + let contents = fs::read(path).map_err(|e| e.to_string())?; let obj = json::from_reader(&mut &contents[..]) .map_err(|e| e.to_string())?; Target::from_json(obj) diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index cfbb9623f7dc9..3cfa1d6797d1f 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -280,7 +280,8 @@ impl<'a, 'tcx> Pattern<'tcx> { let mut pcx = PatternContext::new(tcx, param_env_and_substs, tables); let result = pcx.lower_pattern(pat); if !pcx.errors.is_empty() { - span_bug!(pat.span, "encountered errors lowering pattern: {:?}", pcx.errors) + let msg = format!("encountered errors lowering pattern: {:?}", pcx.errors); + tcx.sess.delay_span_bug(pat.span, &msg); } debug!("Pattern::from_hir({:?}) = {:?}", pat, result); result diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 8d3b2bc47ec9d..b726576220801 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -889,10 +889,11 @@ pub fn phase_2_configure_and_expand(sess: &Session, let dep_graph = match future_dep_graph { None => DepGraph::new_disabled(), Some(future) => { - let prev_graph = future - .open() - .expect("Could not join with background dep_graph thread") - .open(sess); + let prev_graph = time(time_passes, "blocked while dep-graph loading finishes", || { + future.open() + .expect("Could not join with background dep_graph thread") + .open(sess) + }); DepGraph::new(prev_graph) } }; diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 9fa29380dc646..5976b80d90f87 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -55,7 +55,7 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::ich::{ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED}; use graphviz::IntoCow; use std::env; -use std::fs::File; +use std::fs::{self, File}; use std::io::Write; use syntax::ast; use syntax_pos::Span; @@ -260,7 +260,7 @@ fn dump_graph(tcx: TyCtxt) { let dot_path = format!("{}.dot", path); let mut v = Vec::new(); dot::render(&GraphvizDepGraph(nodes, edges), &mut v).unwrap(); - File::create(&dot_path).and_then(|mut f| f.write_all(&v)).unwrap(); + fs::write(dot_path, v).unwrap(); } } diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 5eaf8553ee3d3..0b827a0ee9873 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -16,6 +16,7 @@ #![deny(warnings)] #![feature(conservative_impl_trait)] +#![feature(fs_read_write)] #![feature(i128_type)] #![feature(inclusive_range_syntax)] #![feature(specialization)] diff --git a/src/librustc_incremental/persist/file_format.rs b/src/librustc_incremental/persist/file_format.rs index 108eccf047efe..d45994adeb67b 100644 --- a/src/librustc_incremental/persist/file_format.rs +++ b/src/librustc_incremental/persist/file_format.rs @@ -21,7 +21,7 @@ use std::io::{self, Read}; use std::path::Path; -use std::fs::File; +use std::fs; use std::env; use rustc::session::config::nightly_options; @@ -66,11 +66,7 @@ pub fn read_file(report_incremental_info: bool, path: &Path) return Ok(None); } - let mut file = File::open(path)?; - let file_size = file.metadata()?.len() as usize; - - let mut data = Vec::with_capacity(file_size); - file.read_to_end(&mut data)?; + let data = fs::read(path)?; let mut file = io::Cursor::new(data); diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index e51587e1cd3b4..d44d1d6f26024 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -15,8 +15,8 @@ use rustc::util::common::time; use rustc_data_structures::fx::FxHashMap; use rustc_serialize::Encodable as RustcEncodable; use rustc_serialize::opaque::Encoder; -use std::io::{self, Cursor, Write}; -use std::fs::{self, File}; +use std::io::{self, Cursor}; +use std::fs; use std::path::PathBuf; use super::data::*; @@ -125,7 +125,7 @@ fn save_in(sess: &Session, path_buf: PathBuf, encode: F) // write the data out let data = wr.into_inner(); - match File::create(&path_buf).and_then(|mut file| file.write_all(&data)) { + match fs::write(&path_buf, data) { Ok(_) => { debug!("save: data written to disk successfully"); } diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 18117533c18f1..33075e404321c 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(conservative_impl_trait)] +#![feature(fs_read_write)] #![feature(i128_type)] #![feature(libc)] #![feature(proc_macro_internals)] diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 90c469eea843d..e0fb924f1aa3e 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -237,7 +237,7 @@ use rustc_back::target::Target; use std::cmp; use std::fmt; -use std::fs::{self, File}; +use std::fs; use std::io::{self, Read}; use std::path::{Path, PathBuf}; use std::time::Instant; @@ -870,10 +870,7 @@ fn get_metadata_section_imp(target: &Target, } } CrateFlavor::Rmeta => { - let mut file = File::open(filename).map_err(|_| - format!("could not open file: '{}'", filename.display()))?; - let mut buf = vec![]; - file.read_to_end(&mut buf).map_err(|_| + let buf = fs::read(filename).map_err(|_| format!("failed to read rmeta metadata: '{}'", filename.display()))?; OwningRef::new(buf).map_owner_box().erase_owner() } diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index b79e044b24f20..fb3cb1518cbb8 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -18,7 +18,7 @@ use rustc_data_structures::indexed_vec::Idx; use dot; use dot::IntoCow; -use std::fs::File; +use std::fs; use std::io; use std::io::prelude::*; use std::marker::PhantomData; @@ -67,7 +67,7 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>( dot::render(&g, &mut v)?; debug!("print_borrowck_graph_to path: {} node_id: {}", path.display(), mbcx.node_id); - File::create(path).and_then(|mut f| f.write_all(&v)) + fs::write(path, v) } pub type Node = BasicBlock; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index e9e7e688f1f07..5379bf3f5a7ae 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(core_intrinsics)] #![feature(decl_macro)] #![feature(dyn_trait)] +#![feature(fs_read_write)] #![feature(i128_type)] #![feature(inclusive_range_syntax)] #![feature(inclusive_range)] diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index f0871bb188d49..b896e6ca85343 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -122,7 +122,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { return_qualif: Option, qualif: Qualif, const_fn_arg_vars: BitVector, - local_needs_drop: IndexVec>, temp_promotion_state: IndexVec, promotion_candidates: Vec } @@ -136,6 +135,16 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { let mut rpo = traversal::reverse_postorder(mir); let temps = promote_consts::collect_temps(mir, &mut rpo); rpo.reset(); + + let param_env = tcx.param_env(def_id); + + let mut temp_qualif = IndexVec::from_elem(None, &mir.local_decls); + for arg in mir.args_iter() { + let mut qualif = Qualif::NEEDS_DROP; + qualif.restrict(mir.local_decls[arg].ty, tcx, param_env); + temp_qualif[arg] = Some(qualif); + } + Qualifier { mode, span: mir.span, @@ -143,12 +152,11 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { mir, rpo, tcx, - param_env: tcx.param_env(def_id), - temp_qualif: IndexVec::from_elem(None, &mir.local_decls), + param_env, + temp_qualif, return_qualif: None, qualif: Qualif::empty(), const_fn_arg_vars: BitVector::new(mir.local_decls.len()), - local_needs_drop: IndexVec::from_elem(None, &mir.local_decls), temp_promotion_state: temps, promotion_candidates: vec![] } @@ -255,15 +263,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { return; } - // When initializing a local, record whether the *value* being - // stored in it needs dropping, which it may not, even if its - // type does, e.g. `None::`. - if let Place::Local(local) = *dest { - if qualif.intersects(Qualif::NEEDS_DROP) { - self.local_needs_drop[local] = Some(self.span); - } - } - match *dest { Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp => { debug!("store to temp {:?}", index); @@ -424,17 +423,20 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { &local: &Local, _: PlaceContext<'tcx>, _: Location) { - match self.mir.local_kind(local) { + let kind = self.mir.local_kind(local); + match kind { LocalKind::ReturnPointer => { self.not_const(); } - LocalKind::Arg => { - self.add(Qualif::FN_ARGUMENT); - } LocalKind::Var => { self.add(Qualif::NOT_CONST); } + LocalKind::Arg | LocalKind::Temp => { + if let LocalKind::Arg = kind { + self.add(Qualif::FN_ARGUMENT); + } + if !self.temp_promotion_state[local].is_promotable() { self.add(Qualif::NOT_PROMOTABLE); } @@ -529,16 +531,18 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { match *operand { - Operand::Copy(ref place) | - Operand::Move(ref place) => { + Operand::Copy(_) | + Operand::Move(_) => { self.nest(|this| { this.super_operand(operand, location); this.try_consume(); }); // Mark the consumed locals to indicate later drops are noops. - if let Place::Local(local) = *place { - self.local_needs_drop[local] = None; + if let Operand::Move(Place::Local(local)) = *operand { + self.temp_qualif[local] = self.temp_qualif[local].map(|q| + q - Qualif::NEEDS_DROP + ); } } Operand::Constant(ref constant) => { @@ -847,9 +851,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { // HACK(eddyb) Emulate a bit of dataflow analysis, // conservatively, that drop elaboration will do. let needs_drop = if let Place::Local(local) = *place { - self.local_needs_drop[local] + if self.temp_qualif[local].map_or(true, |q| q.intersects(Qualif::NEEDS_DROP)) { + Some(self.mir.local_decls[local].source_info.span) + } else { + None + } } else { - None + Some(self.span) }; if let Some(span) = needs_drop { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index c39faf021df8e..30e3c9c4ca8a3 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1252,7 +1252,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { root_item: &'l ast::Item, prefix: &ast::Path) { let path = &use_tree.prefix; - let access = access_from!(self.save_ctxt, root_item); + + // The access is calculated using the current tree ID, but with the root tree's visibility + // (since nested trees don't have their own visibility). + let access = Access { + public: root_item.vis == ast::Visibility::Public, + reachable: self.save_ctxt.analysis.access_levels.is_reachable(id), + }; // The parent def id of a given use tree is always the enclosing item. let parent = self.save_ctxt.tcx.hir.opt_local_def_id(id) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 42538c5a3ad96..13a319d31bf06 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -342,9 +342,7 @@ fn archive_config<'a>(sess: &'a Session, fn emit_metadata<'a>(sess: &'a Session, trans: &CrateTranslation, tmpdir: &TempDir) -> PathBuf { let out_filename = tmpdir.path().join(METADATA_FILENAME); - let result = fs::File::create(&out_filename).and_then(|mut f| { - f.write_all(&trans.metadata.raw_data) - }); + let result = fs::write(&out_filename, &trans.metadata.raw_data); if let Err(e) = result { sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 4d1bcd9bf467d..1ee04a46243a2 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -46,9 +46,8 @@ use rustc_demangle; use std::any::Any; use std::ffi::{CString, CStr}; -use std::fs::{self, File}; -use std::io; -use std::io::{Read, Write}; +use std::fs; +use std::io::{self, Write}; use std::mem; use std::path::{Path, PathBuf}; use std::str; @@ -666,7 +665,7 @@ unsafe fn codegen(cgcx: &CodegenContext, timeline.record("make-bc"); if write_bc { - if let Err(e) = File::create(&bc_out).and_then(|mut f| f.write_all(data)) { + if let Err(e) = fs::write(&bc_out, data) { diag_handler.err(&format!("failed to write bytecode: {}", e)); } timeline.record("write-bc"); @@ -675,7 +674,7 @@ unsafe fn codegen(cgcx: &CodegenContext, if config.emit_bc_compressed { let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION); let data = bytecode::encode(&mtrans.llmod_id, data); - if let Err(e) = File::create(&dst).and_then(|mut f| f.write_all(&data)) { + if let Err(e) = fs::write(&dst, data) { diag_handler.err(&format!("failed to write bytecode: {}", e)); } timeline.record("compress-bc"); @@ -799,9 +798,7 @@ fn binaryen_assemble(cgcx: &CodegenContext, object: &Path) { use rustc_binaryen::{Module, ModuleOptions}; - let input = File::open(&assembly).and_then(|mut f| { - let mut contents = Vec::new(); - f.read_to_end(&mut contents)?; + let input = fs::read(&assembly).and_then(|contents| { Ok(CString::new(contents)?) }); let mut options = ModuleOptions::new(); @@ -818,7 +815,7 @@ fn binaryen_assemble(cgcx: &CodegenContext, .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) }); let err = assembled.and_then(|binary| { - File::create(&object).and_then(|mut f| f.write_all(binary.data())) + fs::write(&object, binary.data()) }); if let Err(e) = err { handler.err(&format!("failed to run binaryen assembler: {}", e)); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index fd6cd5c371d97..ee08a7f1ec471 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -22,6 +22,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(custom_attribute)] +#![feature(fs_read_write)] #![allow(unused_attributes)] #![feature(i128_type)] #![feature(i128)] diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 2f7bd5e39a149..f8320330ad265 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::fs::File; -use std::io::prelude::*; +use std::fs; use std::path::Path; use std::str; use html::markdown::{Markdown, RenderType}; @@ -65,13 +64,13 @@ pub enum LoadStringError { pub fn load_string>(file_path: P) -> Result { let file_path = file_path.as_ref(); - let mut contents = vec![]; - let result = File::open(file_path) - .and_then(|mut f| f.read_to_end(&mut contents)); - if let Err(e) = result { - eprintln!("error reading `{}`: {}", file_path.display(), e); - return Err(LoadStringError::ReadFail); - } + let contents = match fs::read(file_path) { + Ok(bytes) => bytes, + Err(e) => { + eprintln!("error reading `{}`: {}", file_path.display(), e); + return Err(LoadStringError::ReadFail); + } + }; match str::from_utf8(&contents) { Ok(s) => Ok(s.to_string()), Err(_) => { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 7449c08fcd290..93a3035e06ace 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -866,15 +866,8 @@ fn write_shared(cx: &Context, write(cx.dst.join("main.css"), include_bytes!("static/styles/main.css"))?; if let Some(ref css) = cx.shared.css_file_extension { - let mut content = String::new(); - let css = css.as_path(); - let mut f = try_err!(File::open(css), css); - - try_err!(f.read_to_string(&mut content), css); - let css = cx.dst.join("theme.css"); - let css = css.as_path(); - let mut f = try_err!(File::create(css), css); - try_err!(write!(f, "{}", &content), css); + let out = cx.dst.join("theme.css"); + try_err!(fs::copy(css, out), css); } write(cx.dst.join("normalize.css"), include_bytes!("static/normalize.css"))?; @@ -1027,7 +1020,7 @@ fn render_sources(dst: &Path, scx: &mut SharedContext, /// Writes the entire contents of a string to a destination, not attempting to /// catch any errors. fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> { - Ok(try_err!(try_err!(File::create(&dst), &dst).write_all(contents), &dst)) + Ok(try_err!(fs::write(&dst, contents), &dst)) } /// Takes a path to a source file and cleans the path to it. This canonicalizes @@ -1124,16 +1117,13 @@ impl<'a> SourceCollector<'a> { return Ok(()); } - let mut contents = Vec::new(); - File::open(&p).and_then(|mut f| f.read_to_end(&mut contents))?; - - let contents = str::from_utf8(&contents).unwrap(); + let contents = fs::read_string(&p)?; // Remove the utf-8 BOM if any let contents = if contents.starts_with("\u{feff}") { &contents[3..] } else { - contents + &contents[..] }; // Create the intermediate directories diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1740816ef6b16..3b43eafb849bd 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -18,6 +18,7 @@ #![feature(rustc_private)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(fs_read_write)] #![feature(libc)] #![feature(set_stdio)] #![feature(slice_patterns)] diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index a75596351e4cf..a37a5e8ae820b 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -53,7 +53,7 @@ //! terminator, so the buffer length is really `len+1` characters. //! Rust strings don't have a nul terminator; their length is always //! stored and does not need to be calculated. While in Rust -//! accessing a string's length is a O(1) operation (becasue the +//! accessing a string's length is a O(1) operation (because the //! length is stored); in C it is an O(length) operation because the //! length needs to be computed by scanning the string for the nul //! terminator. diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 109173d31c501..3959e8533be5f 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -36,7 +36,7 @@ use sys_common::{AsInner, IntoInner, FromInner}; /// and platform-native string values, and in particular allowing a Rust string /// to be converted into an "OS" string with no cost if possible. /// -/// `OsString` is to [`OsStr`] as [`String`] is to [`&str`]: the former +/// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former /// in each pair are owned strings; the latter are borrowed /// references. /// @@ -64,6 +64,7 @@ use sys_common::{AsInner, IntoInner, FromInner}; /// the traits which `OsString` implements for conversions from/to native representations. /// /// [`OsStr`]: struct.OsStr.html +/// [`&OsStr`]: struct.OsStr.html /// [`From`]: ../convert/trait.From.html /// [`String`]: ../string/struct.String.html /// [`&str`]: ../primitive.str.html @@ -84,13 +85,15 @@ pub struct OsString { /// This type represents a borrowed reference to a string in the operating system's preferred /// representation. /// -/// `OsStr` is to [`OsString`] as [`String`] is to [`&str`]: the former in each pair are borrowed +/// `&OsStr` is to [`OsString`] as [`&str`] is to [`String`]: the former in each pair are borrowed /// references; the latter are owned strings. /// /// See the [module's toplevel documentation about conversions][conversions] for a discussion on /// the traits which `OsStr` implements for conversions from/to native representations. /// /// [`OsString`]: struct.OsString.html +/// [`&str`]: ../primitive.str.html +/// [`String`]: ../string/struct.String.html /// [conversions]: index.html#conversions #[stable(feature = "rust1", since = "1.0.0")] pub struct OsStr { diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index f40aed2478a17..51cb9609120e3 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -211,6 +211,14 @@ pub struct DirBuilder { recursive: bool, } +/// How large a buffer to pre-allocate before reading the entire file at `path`. +fn initial_buffer_size>(path: P) -> usize { + // Allocate one extra byte so the buffer doesn't need to grow before the + // final `read` call at the end of the file. Don't worry about `usize` + // overflow because reading will fail regardless in that case. + metadata(path).map(|m| m.len() as usize + 1).unwrap_or(0) +} + /// Read the entire contents of a file into a bytes vector. /// /// This is a convenience function for using [`File::open`] and [`read_to_end`] @@ -246,7 +254,7 @@ pub struct DirBuilder { /// ``` #[unstable(feature = "fs_read_write", issue = "46588")] pub fn read>(path: P) -> io::Result> { - let mut bytes = Vec::new(); + let mut bytes = Vec::with_capacity(initial_buffer_size(&path)); File::open(path)?.read_to_end(&mut bytes)?; Ok(bytes) } @@ -287,7 +295,7 @@ pub fn read>(path: P) -> io::Result> { /// ``` #[unstable(feature = "fs_read_write", issue = "46588")] pub fn read_string>(path: P) -> io::Result { - let mut string = String::new(); + let mut string = String::with_capacity(initial_buffer_size(&path)); File::open(path)?.read_to_string(&mut string)?; Ok(string) } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index bed9efcb8469d..e8297c20af34e 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -576,6 +576,13 @@ impl<'a> AsRef for Component<'a> { } } +#[stable(feature = "path_component_asref", since = "1.24.0")] +impl<'a> AsRef for Component<'a> { + fn as_ref(&self) -> &Path { + self.as_os_str().as_ref() + } +} + /// An iterator over the [`Component`]s of a [`Path`]. /// /// This `struct` is created by the [`components`] method on [`Path`]. diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 0f3f4e50f7e32..2edf02efc477c 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -36,7 +36,7 @@ use sys_common::rwlock as sys; /// required that `T` satisfies [`Send`] to be shared across threads and /// [`Sync`] to allow concurrent access through readers. The RAII guards /// returned from the locking methods implement [`Deref`][] (and [`DerefMut`] -/// for the `write` methods) to allow access to the contained of the lock. +/// for the `write` methods) to allow access to the content of the lock. /// /// # Poisoning /// diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 15ddb62bab5c8..cb5bfb9176ec7 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -206,7 +206,7 @@ impl Duration { /// /// let duration = Duration::from_millis(5432); /// assert_eq!(duration.as_secs(), 5); - /// assert_eq!(duration.subsec_nanos(), 432_000_000); + /// assert_eq!(duration.subsec_millis(), 432); /// ``` #[unstable(feature = "duration_extras", issue = "46507")] #[inline] @@ -226,7 +226,7 @@ impl Duration { /// /// let duration = Duration::from_micros(1_234_567); /// assert_eq!(duration.as_secs(), 1); - /// assert_eq!(duration.subsec_nanos(), 234_567_000); + /// assert_eq!(duration.subsec_micros(), 234_567); /// ``` #[unstable(feature = "duration_extras", issue = "46507")] #[inline] diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b61c39d589bb1..49035203150db 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5894,10 +5894,14 @@ impl<'a> Parser<'a> { if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) { return Ok(ModulePathSuccess { directory_ownership: match path.file_name().and_then(|s| s.to_str()) { - Some("mod.rs") => DirectoryOwnership::Owned { relative: None }, - Some(_) => { - DirectoryOwnership::Owned { relative: Some(id) } - } + // All `#[path]` files are treated as though they are a `mod.rs` file. + // This means that `mod foo;` declarations inside `#[path]`-included + // files are siblings, + // + // Note that this will produce weirdness when a file named `foo.rs` is + // `#[path]` included and contains a `mod foo;` declaration. + // If you encounter this, it's your own darn fault :P + Some(_) => DirectoryOwnership::Owned { relative: None }, _ => DirectoryOwnership::UnownedViaMod(true), }, path, diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 870f54e4396af..ad04b6ab2b559 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -286,12 +286,12 @@ impl TokenStream { TokenStream::concat(result) } - fn first_tree(&self) -> Option { + fn first_tree_and_joint(&self) -> Option<(TokenTree, bool)> { match self.kind { TokenStreamKind::Empty => None, - TokenStreamKind::Tree(ref tree) | - TokenStreamKind::JointTree(ref tree) => Some(tree.clone()), - TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree(), + TokenStreamKind::Tree(ref tree) => Some((tree.clone(), false)), + TokenStreamKind::JointTree(ref tree) => Some((tree.clone(), true)), + TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree_and_joint(), } } @@ -315,12 +315,18 @@ impl TokenStreamBuilder { let stream = stream.into(); let last_tree_if_joint = self.0.last().and_then(TokenStream::last_tree_if_joint); if let Some(TokenTree::Token(last_span, last_tok)) = last_tree_if_joint { - if let Some(TokenTree::Token(span, tok)) = stream.first_tree() { + if let Some((TokenTree::Token(span, tok), is_joint)) = stream.first_tree_and_joint() { if let Some(glued_tok) = last_tok.glue(tok) { let last_stream = self.0.pop().unwrap(); self.push_all_but_last_tree(&last_stream); let glued_span = last_span.to(span); - self.0.push(TokenTree::Token(glued_span, glued_tok).into()); + let glued_tt = TokenTree::Token(glued_span, glued_tok); + let glued_tokenstream = if is_joint { + glued_tt.joint() + } else { + glued_tt.into() + }; + self.0.push(glued_tokenstream); self.push_all_but_first_tree(&stream); return } @@ -669,4 +675,16 @@ mod tests { assert_eq!(test1.is_empty(), false); assert_eq!(test2.is_empty(), false); } + + #[test] + fn test_dotdotdot() { + let mut builder = TokenStreamBuilder::new(); + builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint()); + builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint()); + builder.push(TokenTree::Token(sp(2, 3), Token::Dot)); + let stream = builder.build(); + assert!(stream.eq_unspanned(&string_to_ts("..."))); + assert_eq!(stream.trees().count(), 1); + } + } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 76557982a0276..f7880d3c4d854 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -36,14 +36,14 @@ #![feature(asm)] #![feature(fnbox)] -#![cfg_attr(unix, feature(libc))] +#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))] #![feature(set_stdio)] #![feature(panic_unwind)] #![feature(staged_api)] extern crate getopts; extern crate term; -#[cfg(unix)] +#[cfg(any(unix, target_os = "cloudabi"))] extern crate libc; extern crate panic_unwind; @@ -1191,13 +1191,14 @@ fn get_concurrency() -> usize { 1 } - #[cfg(any(target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "android", - target_os = "solaris", + #[cfg(any(target_os = "android", + target_os = "cloudabi", target_os = "emscripten", - target_os = "fuchsia"))] + target_os = "fuchsia", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "solaris"))] fn num_cpus() -> usize { unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } } diff --git a/src/test/compile-fail/issue-39687.rs b/src/test/compile-fail/issue-39687.rs new file mode 100644 index 0000000000000..404465e6a0fa7 --- /dev/null +++ b/src/test/compile-fail/issue-39687.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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(fn_traits)] + +fn main() { + ::call; + //~^ ERROR associated type bindings are not allowed here [E0229] +} diff --git a/src/test/compile-fail/issue-43105.rs b/src/test/compile-fail/issue-43105.rs new file mode 100644 index 0000000000000..fb419d751b4e8 --- /dev/null +++ b/src/test/compile-fail/issue-43105.rs @@ -0,0 +1,21 @@ +// Copyright 2018 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. + +fn xyz() -> u8 { 42 } + +const NUM: u8 = xyz(); +//~^ ERROR calls in constants are limited to constant functions, struct and enum constructors + +fn main() { + match 1 { + NUM => unimplemented!(), + _ => unimplemented!(), + } +} diff --git a/src/test/compile-fail/static-drop-scope.rs b/src/test/compile-fail/static-drop-scope.rs index c96cadece97a5..e22eb7e4484d6 100644 --- a/src/test/compile-fail/static-drop-scope.rs +++ b/src/test/compile-fail/static-drop-scope.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(const_fn)] + struct WithDtor; impl Drop for WithDtor { @@ -28,4 +30,12 @@ static EARLY_DROP_S: i32 = (WithDtor, 0).1; const EARLY_DROP_C: i32 = (WithDtor, 0).1; //~^ ERROR destructors cannot be evaluated at compile-time +const fn const_drop(_: T) {} +//~^ ERROR destructors cannot be evaluated at compile-time + +const fn const_drop2(x: T) { + (x, ()).1 + //~^ ERROR destructors cannot be evaluated at compile-time +} + fn main () {} diff --git a/src/test/run-make/linker-output-non-utf8/Makefile b/src/test/run-make/linker-output-non-utf8/Makefile index 76d4b133defe2..5f1577ab44dc5 100644 --- a/src/test/run-make/linker-output-non-utf8/Makefile +++ b/src/test/run-make/linker-output-non-utf8/Makefile @@ -2,15 +2,16 @@ # Make sure we don't ICE if the linker prints a non-UTF-8 error message. -ifdef IS_WINDOWS -# ignore windows +# Ignore Windows and Apple # This does not work in its current form on windows, possibly due to # gcc bugs or something about valid Windows paths. See issue #29151 # for more information. -all: +ifndef IS_WINDOWS -else +# This also does not work on Apple APFS due to the filesystem requiring +# valid UTF-8 paths. +ifneq ($(shell uname),Darwin) # The zzz it to allow humans to tab complete or glob this thing. bad_dir := $(TMPDIR)/zzz$$'\xff' @@ -20,5 +21,12 @@ all: mkdir $(bad_dir) mv $(TMPDIR)/liblibrary.a $(bad_dir) LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined +else +all: + +endif + +else +all: endif diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs index 8d035bafab78d..aca100591ddec 100644 --- a/src/test/run-pass/impl-trait/example-calendar.rs +++ b/src/test/run-pass/impl-trait/example-calendar.rs @@ -15,7 +15,9 @@ universal_impl_trait, fn_traits, step_trait, - unboxed_closures + unboxed_closures, + copy_closures, + clone_closures )] //! Derived from: . @@ -234,42 +236,6 @@ impl Weekday { } } -/// Wrapper for zero-sized closures. -// HACK(eddyb) Only needed because closures can't implement Copy. -struct Fn0(std::marker::PhantomData); - -impl Copy for Fn0 {} -impl Clone for Fn0 { - fn clone(&self) -> Self { *self } -} - -impl, A> FnOnce for Fn0 { - type Output = F::Output; - - extern "rust-call" fn call_once(self, args: A) -> Self::Output { - let f = unsafe { std::mem::uninitialized::() }; - f.call_once(args) - } -} - -impl, A> FnMut for Fn0 { - extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output { - let mut f = unsafe { std::mem::uninitialized::() }; - f.call_mut(args) - } -} - -trait AsFn0: Sized { - fn copyable(self) -> Fn0; -} - -impl, A> AsFn0 for F { - fn copyable(self) -> Fn0 { - assert_eq!(std::mem::size_of::(), 0); - Fn0(std::marker::PhantomData) - } -} - /// GroupBy implementation. struct GroupBy { it: std::iter::Peekable, @@ -277,11 +243,15 @@ struct GroupBy { } impl Clone for GroupBy -where It: Iterator + Clone, It::Item: Clone, F: Clone { - fn clone(&self) -> GroupBy { +where + It: Iterator + Clone, + It::Item: Clone, + F: Clone, +{ + fn clone(&self) -> Self { GroupBy { it: self.it.clone(), - f: self.f.clone() + f: self.f.clone(), } } } @@ -331,14 +301,11 @@ impl G, G: Eq> Iterator for InGroup(self, f: F) -> GroupBy> - where F: FnMut(&Self::Item) -> G, + fn group_by(self, f: F) -> GroupBy + where F: Clone + FnMut(&Self::Item) -> G, G: Eq { - GroupBy { - it: self.peekable(), - f: f.copyable(), - } + GroupBy { it: self.peekable(), f } } fn join(mut self, sep: &str) -> String @@ -382,7 +349,7 @@ fn test_spaces() { fn dates_in_year(year: i32) -> impl Iterator+Clone { InGroup { it: NaiveDate::from_ymd(year, 1, 1).., - f: (|d: &NaiveDate| d.year()).copyable(), + f: |d: &NaiveDate| d.year(), g: year } } diff --git a/src/test/run-pass/issue-36792.rs b/src/test/run-pass/issue-36792.rs new file mode 100644 index 0000000000000..faf983f6ecb1c --- /dev/null +++ b/src/test/run-pass/issue-36792.rs @@ -0,0 +1,17 @@ +// Copyright 2018 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(conservative_impl_trait)] +fn foo() -> impl Copy { + foo +} +fn main() { + foo(); +} diff --git a/src/test/run-pass/issue-38091.rs b/src/test/run-pass/issue-38091.rs new file mode 100644 index 0000000000000..34050242f84fa --- /dev/null +++ b/src/test/run-pass/issue-38091.rs @@ -0,0 +1,29 @@ +// Copyright 2018 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(specialization)] + +trait Iterate<'a> { + type Ty: Valid; + fn iterate(self); +} +impl<'a, T> Iterate<'a> for T where T: Check { + default type Ty = (); + default fn iterate(self) {} +} + +trait Check {} +impl<'a, T> Check for T where >::Ty: Valid {} + +trait Valid {} + +fn main() { + Iterate::iterate(0); +} diff --git a/src/test/compile-fail/directory_ownership/backcompat-warnings.rs b/src/test/run-pass/issue-42148.rs similarity index 67% rename from src/test/compile-fail/directory_ownership/backcompat-warnings.rs rename to src/test/run-pass/issue-42148.rs index 2da07a2cc7210..0196649a3f624 100644 --- a/src/test/compile-fail/directory_ownership/backcompat-warnings.rs +++ b/src/test/run-pass/issue-42148.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,9 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: mod statements in non-mod.rs files are unstable +struct Zst; -#[path="mod_file_not_owning_aux3.rs"] -mod foo; - -fn main() {} +fn main() { + unsafe { ::std::ptr::write_volatile(1 as *mut Zst, Zst) } +} diff --git a/src/test/run-pass/issue-42956.rs b/src/test/run-pass/issue-42956.rs new file mode 100644 index 0000000000000..9bda6ee4bcb56 --- /dev/null +++ b/src/test/run-pass/issue-42956.rs @@ -0,0 +1,33 @@ +// Copyright 2018 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)] + +impl A for i32 { + type Foo = u32; +} +impl B for u32 { + const BAR: i32 = 0; +} + +trait A { + type Foo: B; +} + +trait B { + const BAR: i32; +} + +fn generic() { + // This panics if the universal function call syntax is used as well + println!("{}", T::Foo::BAR); +} + +fn main() {} diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs similarity index 100% rename from src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs rename to src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs similarity index 100% rename from src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs rename to src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs diff --git a/src/test/ui/non_modrs_mods/non_modrs_mods.stderr b/src/test/ui/non_modrs_mods/non_modrs_mods.stderr index b4b524786cd7c..95a2539ed646d 100644 --- a/src/test/ui/non_modrs_mods/non_modrs_mods.stderr +++ b/src/test/ui/non_modrs_mods/non_modrs_mods.stderr @@ -34,14 +34,5 @@ error: mod statements in non-mod.rs files are unstable (see issue #44660) = help: add #![feature(non_modrs_mods)] to the crate attributes to enable = help: on stable builds, rename this file to inner_foors_mod/mod.rs -error: mod statements in non-mod.rs files are unstable (see issue #44660) - --> $DIR/some_crazy_attr_mod_dir/arbitrary_name.rs:11:9 - | -11 | pub mod inner_modrs_mod; - | ^^^^^^^^^^^^^^^ - | - = help: add #![feature(non_modrs_mods)] to the crate attributes to enable - = help: on stable builds, rename this file to attr_mod/mod.rs - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs similarity index 100% rename from src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs rename to src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs similarity index 100% rename from src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs rename to src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index fc2759df44748..4113f8fd124c7 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -67,6 +67,7 @@ static TARGETS: &'static [&'static str] = &[ "i386-apple-ios", "i586-pc-windows-msvc", "i586-unknown-linux-gnu", + "i586-unknown-linux-musl", "i686-apple-darwin", "i686-linux-android", "i686-pc-windows-gnu", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d1643c0aa4b63..efbe5e32fcd27 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -21,6 +21,7 @@ use header::TestProps; use util::logv; use regex::Regex; +use std::collections::VecDeque; use std::collections::HashMap; use std::collections::HashSet; use std::env; @@ -48,6 +49,88 @@ pub fn dylib_env_var() -> &'static str { } } +#[derive(Debug, PartialEq)] +pub enum DiffLine { + Context(String), + Expected(String), + Resulting(String), +} + +#[derive(Debug, PartialEq)] +pub struct Mismatch { + pub line_number: u32, + pub lines: Vec, +} + +impl Mismatch { + fn new(line_number: u32) -> Mismatch { + Mismatch { + line_number: line_number, + lines: Vec::new(), + } + } +} + +// Produces a diff between the expected output and actual output. +pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec { + let mut line_number = 1; + let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size); + let mut lines_since_mismatch = context_size + 1; + let mut results = Vec::new(); + let mut mismatch = Mismatch::new(0); + + for result in diff::lines(actual, expected) { + match result { + diff::Result::Left(str) => { + if lines_since_mismatch >= context_size && lines_since_mismatch > 0 { + results.push(mismatch); + mismatch = Mismatch::new(line_number - context_queue.len() as u32); + } + + while let Some(line) = context_queue.pop_front() { + mismatch.lines.push(DiffLine::Context(line.to_owned())); + } + + mismatch.lines.push(DiffLine::Resulting(str.to_owned())); + lines_since_mismatch = 0; + } + diff::Result::Right(str) => { + if lines_since_mismatch >= context_size && lines_since_mismatch > 0 { + results.push(mismatch); + mismatch = Mismatch::new(line_number - context_queue.len() as u32); + } + + while let Some(line) = context_queue.pop_front() { + mismatch.lines.push(DiffLine::Context(line.to_owned())); + } + + mismatch.lines.push(DiffLine::Expected(str.to_owned())); + line_number += 1; + lines_since_mismatch = 0; + } + diff::Result::Both(str, _) => { + if context_queue.len() >= context_size { + let _ = context_queue.pop_front(); + } + + if lines_since_mismatch < context_size { + mismatch.lines.push(DiffLine::Context(str.to_owned())); + } else if context_size > 0 { + context_queue.push_back(str); + } + + line_number += 1; + lines_since_mismatch += 1; + } + } + } + + results.push(mismatch); + results.remove(0); + + results +} + pub fn run(config: Config, testpaths: &TestPaths) { match &*config.target { "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => { @@ -2720,15 +2803,29 @@ impl<'test> TestCx<'test> { return 0; } - println!("normalized {}:\n{}\n", kind, actual); - println!("expected {}:\n{}\n", kind, expected); - println!("diff of {}:\n", kind); - - for diff in diff::lines(expected, actual) { - match diff { - diff::Result::Left(l) => println!("-{}", l), - diff::Result::Both(l, _) => println!(" {}", l), - diff::Result::Right(r) => println!("+{}", r), + if expected.is_empty() { + println!("normalized {}:\n{}\n", kind, actual); + } else { + println!("diff of {}:\n", kind); + let diff_results = make_diff(expected, actual, 3); + for result in diff_results { + let mut line_number = result.line_number; + for line in result.lines { + match line { + DiffLine::Expected(e) => { + println!("-\t{}", e); + line_number += 1; + }, + DiffLine::Context(c) => { + println!("{}\t{}", line_number, c); + line_number += 1; + }, + DiffLine::Resulting(r) => { + println!("+\t{}", r); + }, + } + } + println!(""); } }