mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-11 07:21:51 +00:00
Auto merge of #47392 - kennytm:rollup, r=kennytm
Rollup of 24 pull requests - Successful merges: #46985, #47069, #47081, #47185, #47282, #47283, #47288, #47289, #47298, #47305, #47306, #47307, #47310, #47324, #47328, #47331, #47340, #47343, #47344, #47352, #47357, #47365, #47375, #47382 - Failed merges: #47334
This commit is contained in:
commit
51b0b3734c
@ -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
|
||||
|
10
src/Cargo.lock
generated
10
src/Cargo.lock
generated
@ -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"
|
||||
|
@ -108,6 +108,8 @@ v("musl-root", "target.x86_64-unknown-linux-musl.musl-root",
|
||||
"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",
|
||||
|
@ -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",
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -69,7 +69,9 @@ struct TypedArenaChunk<T> {
|
||||
impl<T> TypedArenaChunk<T> {
|
||||
#[inline]
|
||||
unsafe fn new(capacity: usize) -> TypedArenaChunk<T> {
|
||||
TypedArenaChunk { storage: RawVec::with_capacity(capacity) }
|
||||
TypedArenaChunk {
|
||||
storage: RawVec::with_capacity(capacity),
|
||||
}
|
||||
}
|
||||
|
||||
/// Destroys this arena chunk.
|
||||
@ -132,7 +134,9 @@ impl<T> TypedArena<T> {
|
||||
|
||||
unsafe {
|
||||
if mem::size_of::<T>() == 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::<T>() as *mut T;
|
||||
// Don't drop the object. This `write` is equivalent to `forget`.
|
||||
ptr::write(ptr, object);
|
||||
@ -157,7 +161,9 @@ impl<T> TypedArena<T> {
|
||||
/// - Zero-length slices
|
||||
#[inline]
|
||||
pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
|
||||
where T: Copy {
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
assert!(mem::size_of::<T>() != 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::<T>() as isize
|
||||
) as *mut u8);
|
||||
self.ptr.set(
|
||||
intrinsics::arith_offset(self.ptr.get(), mem::size_of::<T>() 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<T>(&self, slice: &[T]) -> &mut [T]
|
||||
where T: Copy {
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
assert!(!mem::needs_drop::<T>());
|
||||
assert!(mem::size_of::<T>() != 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::<T>()) as isize
|
||||
self.ptr.get(),
|
||||
(slice.len() * mem::size_of::<T>()) 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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)]
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -218,13 +218,10 @@ pub fn record_time<T, F>(accu: &Cell<Duration>, f: F) -> T where
|
||||
// Memory reporting
|
||||
#[cfg(unix)]
|
||||
fn get_resident() -> Option<usize> {
|
||||
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::<usize>().ok()?;
|
||||
Some(npages * 4096)
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#![feature(box_syntax)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(fs_read_write)]
|
||||
|
||||
extern crate syntax;
|
||||
extern crate rand;
|
||||
|
18
src/librustc_back/target/i586_unknown_linux_musl.rs
Normal file
18
src/librustc_back/target/i586_unknown_linux_musl.rs
Normal file
@ -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 <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 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)
|
||||
}
|
@ -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<Target, String> {
|
||||
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<Target, String> {
|
||||
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)
|
||||
|
@ -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
|
||||
|
@ -889,10 +889,11 @@ pub fn phase_2_configure_and_expand<F>(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)
|
||||
}
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#![deny(warnings)]
|
||||
|
||||
#![feature(conservative_impl_trait)]
|
||||
#![feature(fs_read_write)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(inclusive_range_syntax)]
|
||||
#![feature(specialization)]
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<F>(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");
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#![feature(box_patterns)]
|
||||
#![feature(conservative_impl_trait)]
|
||||
#![feature(fs_read_write)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(libc)]
|
||||
#![feature(proc_macro_internals)]
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)]
|
||||
|
@ -122,7 +122,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
return_qualif: Option<Qualif>,
|
||||
qualif: Qualif,
|
||||
const_fn_arg_vars: BitVector,
|
||||
local_needs_drop: IndexVec<Local, Option<Span>>,
|
||||
temp_promotion_state: IndexVec<Local, TempState>,
|
||||
promotion_candidates: Vec<Candidate>
|
||||
}
|
||||
@ -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::<String>`.
|
||||
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 {
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -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)]
|
||||
|
@ -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<P: AsRef<Path>>(file_path: P) -> Result<String, LoadStringError> {
|
||||
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(_) => {
|
||||
|
@ -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
|
||||
|
@ -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)]
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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<P: AsRef<Path>>(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<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
|
||||
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<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
|
||||
/// ```
|
||||
#[unstable(feature = "fs_read_write", issue = "46588")]
|
||||
pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
|
||||
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)
|
||||
}
|
||||
|
@ -576,6 +576,13 @@ impl<'a> AsRef<OsStr> for Component<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "path_component_asref", since = "1.24.0")]
|
||||
impl<'a> AsRef<Path> 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`].
|
||||
|
@ -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
|
||||
///
|
||||
|
@ -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]
|
||||
|
@ -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,
|
||||
|
@ -286,12 +286,12 @@ impl TokenStream {
|
||||
TokenStream::concat(result)
|
||||
}
|
||||
|
||||
fn first_tree(&self) -> Option<TokenTree> {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
|
16
src/test/compile-fail/issue-39687.rs
Normal file
16
src/test/compile-fail/issue-39687.rs
Normal file
@ -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 <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.
|
||||
|
||||
#![feature(fn_traits)]
|
||||
|
||||
fn main() {
|
||||
<fn() as Fn()>::call;
|
||||
//~^ ERROR associated type bindings are not allowed here [E0229]
|
||||
}
|
21
src/test/compile-fail/issue-43105.rs
Normal file
21
src/test/compile-fail/issue-43105.rs
Normal file
@ -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 <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.
|
||||
|
||||
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!(),
|
||||
}
|
||||
}
|
@ -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>(_: T) {}
|
||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
|
||||
const fn const_drop2<T>(x: T) {
|
||||
(x, ()).1
|
||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
}
|
||||
|
||||
fn main () {}
|
||||
|
@ -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
|
||||
|
@ -15,7 +15,9 @@
|
||||
universal_impl_trait,
|
||||
fn_traits,
|
||||
step_trait,
|
||||
unboxed_closures
|
||||
unboxed_closures,
|
||||
copy_closures,
|
||||
clone_closures
|
||||
)]
|
||||
|
||||
//! Derived from: <https://raw.githubusercontent.com/quickfur/dcal/master/dcal.d>.
|
||||
@ -234,42 +236,6 @@ impl Weekday {
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper for zero-sized closures.
|
||||
// HACK(eddyb) Only needed because closures can't implement Copy.
|
||||
struct Fn0<F>(std::marker::PhantomData<F>);
|
||||
|
||||
impl<F> Copy for Fn0<F> {}
|
||||
impl<F> Clone for Fn0<F> {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
|
||||
impl<F: FnOnce<A>, A> FnOnce<A> for Fn0<F> {
|
||||
type Output = F::Output;
|
||||
|
||||
extern "rust-call" fn call_once(self, args: A) -> Self::Output {
|
||||
let f = unsafe { std::mem::uninitialized::<F>() };
|
||||
f.call_once(args)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: FnMut<A>, A> FnMut<A> for Fn0<F> {
|
||||
extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output {
|
||||
let mut f = unsafe { std::mem::uninitialized::<F>() };
|
||||
f.call_mut(args)
|
||||
}
|
||||
}
|
||||
|
||||
trait AsFn0<A>: Sized {
|
||||
fn copyable(self) -> Fn0<Self>;
|
||||
}
|
||||
|
||||
impl<F: FnMut<A>, A> AsFn0<A> for F {
|
||||
fn copyable(self) -> Fn0<Self> {
|
||||
assert_eq!(std::mem::size_of::<F>(), 0);
|
||||
Fn0(std::marker::PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
/// GroupBy implementation.
|
||||
struct GroupBy<It: Iterator, F> {
|
||||
it: std::iter::Peekable<It>,
|
||||
@ -277,11 +243,15 @@ struct GroupBy<It: Iterator, F> {
|
||||
}
|
||||
|
||||
impl<It, F> Clone for GroupBy<It, F>
|
||||
where It: Iterator + Clone, It::Item: Clone, F: Clone {
|
||||
fn clone(&self) -> GroupBy<It, F> {
|
||||
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<It: Iterator, F: FnMut(&It::Item) -> G, G: Eq> Iterator for InGroup<It, F,
|
||||
}
|
||||
|
||||
trait IteratorExt: Iterator + Sized {
|
||||
fn group_by<G, F>(self, f: F) -> GroupBy<Self, Fn0<F>>
|
||||
where F: FnMut(&Self::Item) -> G,
|
||||
fn group_by<G, F>(self, f: F) -> GroupBy<Self, F>
|
||||
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<Item=NaiveDate>+Clone {
|
||||
InGroup {
|
||||
it: NaiveDate::from_ymd(year, 1, 1)..,
|
||||
f: (|d: &NaiveDate| d.year()).copyable(),
|
||||
f: |d: &NaiveDate| d.year(),
|
||||
g: year
|
||||
}
|
||||
}
|
||||
|
17
src/test/run-pass/issue-36792.rs
Normal file
17
src/test/run-pass/issue-36792.rs
Normal file
@ -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 <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.
|
||||
|
||||
#![feature(conservative_impl_trait)]
|
||||
fn foo() -> impl Copy {
|
||||
foo
|
||||
}
|
||||
fn main() {
|
||||
foo();
|
||||
}
|
29
src/test/run-pass/issue-38091.rs
Normal file
29
src/test/run-pass/issue-38091.rs
Normal file
@ -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 <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.
|
||||
|
||||
#![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 <T as Iterate<'a>>::Ty: Valid {}
|
||||
|
||||
trait Valid {}
|
||||
|
||||
fn main() {
|
||||
Iterate::iterate(0);
|
||||
}
|
@ -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) }
|
||||
}
|
33
src/test/run-pass/issue-42956.rs
Normal file
33
src/test/run-pass/issue-42956.rs
Normal file
@ -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 <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.
|
||||
|
||||
#![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<T: A>() {
|
||||
// This panics if the universal function call syntax is used as well
|
||||
println!("{}", T::Foo::BAR);
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -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
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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<DiffLine>,
|
||||
}
|
||||
|
||||
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<Mismatch> {
|
||||
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!("");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user