diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf3c22744f165..5f9311635f6bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,10 +152,6 @@ jobs: - name: dist-x86_64-linux os: ubuntu-latest-xl env: {} - - name: dist-x86_64-linux-alt - env: - IMAGE: dist-x86_64-linux - os: ubuntu-latest-xl timeout-minutes: 600 runs-on: "${{ matrix.os }}" steps: diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 58e4bef677efb..8f0a245a5658a 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1206,7 +1206,7 @@ impl<'a> Builder<'a> { ); } - // If Control Flow Guard is enabled, pass the `control_flow_guard=checks` flag to rustc + // If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc // when compiling the standard library, since this might be linked into the final outputs // produced by rustc. Since this mitigation is only available on Windows, only enable it // for the standard library in case the compiler is run on a non-Windows platform. @@ -1217,7 +1217,7 @@ impl<'a> Builder<'a> { && self.config.control_flow_guard && compiler.stage >= 1 { - rustflags.arg("-Zcontrol_flow_guard=checks"); + rustflags.arg("-Zcontrol-flow-guard"); } // For `cargo doc` invocations, make rustdoc print the Rust version into the docs diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index d1e53db573e4c..47673ce1e8703 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -141,6 +141,8 @@ def v(*args): "rootfs in qemu testing, you probably don't want to use this") v("qemu-aarch64-rootfs", "target.aarch64-unknown-linux-gnu.qemu-rootfs", "rootfs in qemu testing, you probably don't want to use this") +v("qemu-riscv64-rootfs", "target.riscv64gc-unknown-linux-gnu.qemu-rootfs", + "rootfs in qemu testing, you probably don't want to use this") v("experimental-targets", "llvm.experimental-targets", "experimental LLVM targets to build") v("release-channel", "rust.channel", "the name of the release channel to build") diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 252a6316e574b..0a14957384d28 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -689,48 +689,41 @@ fn supported_sanitizers( target: Interned, channel: &str, ) -> Vec { - let mut result = Vec::new(); + let darwin_libs = |os: &str, components: &[&str]| -> Vec { + components + .into_iter() + .map(move |c| SanitizerRuntime { + cmake_target: format!("clang_rt.{}_{}_dynamic", c, os), + path: out_dir + .join(&format!("build/lib/darwin/libclang_rt.{}_{}_dynamic.dylib", c, os)), + name: format!("librustc-{}_rt.{}.dylib", channel, c), + }) + .collect() + }; + + let common_libs = |os: &str, arch: &str, components: &[&str]| -> Vec { + components + .into_iter() + .map(move |c| SanitizerRuntime { + cmake_target: format!("clang_rt.{}-{}", c, arch), + path: out_dir.join(&format!("build/lib/{}/libclang_rt.{}-{}.a", os, c, arch)), + name: format!("librustc-{}_rt.{}.a", channel, c), + }) + .collect() + }; + match &*target { - "x86_64-apple-darwin" => { - for s in &["asan", "lsan", "tsan"] { - result.push(SanitizerRuntime { - cmake_target: format!("clang_rt.{}_osx_dynamic", s), - path: out_dir - .join(&format!("build/lib/darwin/libclang_rt.{}_osx_dynamic.dylib", s)), - name: format!("librustc-{}_rt.{}.dylib", channel, s), - }); - } + "aarch64-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]), + "aarch64-unknown-linux-gnu" => { + common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan"]) } + "x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), + "x86_64-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]), "x86_64-unknown-linux-gnu" => { - for s in &["asan", "lsan", "msan", "tsan"] { - result.push(SanitizerRuntime { - cmake_target: format!("clang_rt.{}-x86_64", s), - path: out_dir.join(&format!("build/lib/linux/libclang_rt.{}-x86_64.a", s)), - name: format!("librustc-{}_rt.{}.a", channel, s), - }); - } - } - "x86_64-fuchsia" => { - for s in &["asan"] { - result.push(SanitizerRuntime { - cmake_target: format!("clang_rt.{}-x86_64", s), - path: out_dir.join(&format!("build/lib/fuchsia/libclang_rt.{}-x86_64.a", s)), - name: format!("librustc-{}_rt.{}.a", channel, s), - }); - } - } - "aarch64-fuchsia" => { - for s in &["asan"] { - result.push(SanitizerRuntime { - cmake_target: format!("clang_rt.{}-aarch64", s), - path: out_dir.join(&format!("build/lib/fuchsia/libclang_rt.{}-aarch64.a", s)), - name: format!("librustc-{}_rt.{}.a", channel, s), - }); - } + common_libs("linux", "x86_64", &["asan", "lsan", "msan", "tsan"]) } - _ => {} + _ => Vec::new(), } - result } struct HashStamp { diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml index 38a0685e0f75a..818306a009229 100644 --- a/src/ci/azure-pipelines/try.yml +++ b/src/ci/azure-pipelines/try.yml @@ -26,8 +26,6 @@ jobs: strategy: matrix: dist-x86_64-linux: {} - dist-x86_64-linux-alt: - IMAGE: dist-x86_64-linux # The macOS and Windows builds here are currently disabled due to them not being # overly necessary on `try` builds. We also don't actually have anything that diff --git a/src/ci/docker/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch b/src/ci/docker/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch new file mode 100644 index 0000000000000..08d0c5b2cac1e --- /dev/null +++ b/src/ci/docker/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch @@ -0,0 +1,96 @@ +From c820da85c65c7f3aa9e9cb3ed71ada69bf9b783e Mon Sep 17 00:00:00 2001 +From: Alistair Francis +Date: Tue, 19 Nov 2019 13:06:40 +0100 +Subject: [PATCH] Remove stime() function calls + +stime() has been deprecated in glibc 2.31 and replaced with +clock_settime(). Let's replace the stime() function calls with +clock_settime() in preperation. + +function old new delta +rdate_main 197 224 +27 +clock_settime - 27 +27 +date_main 926 941 +15 +stime 37 - -37 +------------------------------------------------------------------------------ +(add/remove: 2/2 grow/shrink: 2/0 up/down: 69/-37) Total: 32 bytes + +Signed-off-by: Alistair Francis +Signed-off-by: Denys Vlasenko + +[Tom Eccles: adjust patch context to apply on top of 1.31.1-stable] +Signed-off-by: Tom Eccles +--- + coreutils/date.c | 6 +++++- + libbb/missing_syscalls.c | 8 -------- + util-linux/rdate.c | 8 ++++++-- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/coreutils/date.c b/coreutils/date.c +index 3414d38ae..4ade6abb4 100644 +--- a/coreutils/date.c ++++ b/coreutils/date.c +@@ -279,6 +279,9 @@ int date_main(int argc UNUSED_PARAM, char **argv) + time(&ts.tv_sec); + #endif + } ++#if !ENABLE_FEATURE_DATE_NANO ++ ts.tv_nsec = 0; ++#endif + localtime_r(&ts.tv_sec, &tm_time); + + /* If date string is given, update tm_time, and maybe set date */ +@@ -301,9 +304,10 @@ int date_main(int argc UNUSED_PARAM, char **argv) + if (date_str[0] != '@') + tm_time.tm_isdst = -1; + ts.tv_sec = validate_tm_time(date_str, &tm_time); ++ ts.tv_nsec = 0; + + /* if setting time, set it */ +- if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) { ++ if ((opt & OPT_SET) && clock_settime(CLOCK_REALTIME, &ts) < 0) { + bb_perror_msg("can't set date"); + } + } +diff --git a/libbb/missing_syscalls.c b/libbb/missing_syscalls.c +index 87cf59b3d..dc40d9155 100644 +--- a/libbb/missing_syscalls.c ++++ b/libbb/missing_syscalls.c +@@ -15,14 +15,6 @@ pid_t getsid(pid_t pid) + return syscall(__NR_getsid, pid); + } + +-int stime(const time_t *t) +-{ +- struct timeval tv; +- tv.tv_sec = *t; +- tv.tv_usec = 0; +- return settimeofday(&tv, NULL); +-} +- + int sethostname(const char *name, size_t len) + { + return syscall(__NR_sethostname, name, len); +diff --git a/util-linux/rdate.c b/util-linux/rdate.c +index 70f829e7f..878375d78 100644 +--- a/util-linux/rdate.c ++++ b/util-linux/rdate.c +@@ -95,9 +95,13 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) + if (!(flags & 2)) { /* no -p (-s may be present) */ + if (time(NULL) == remote_time) + bb_error_msg("current time matches remote time"); +- else +- if (stime(&remote_time) < 0) ++ else { ++ struct timespec ts; ++ ts.tv_sec = remote_time; ++ ts.tv_nsec = 0; ++ if (clock_settime(CLOCK_REALTIME, &ts) < 0) + bb_perror_msg_and_die("can't set time of day"); ++ } + } + + if (flags != 1) /* not lone -s */ +-- +2.25.1 + diff --git a/src/ci/docker/disabled/riscv64gc-linux/Dockerfile b/src/ci/docker/disabled/riscv64gc-linux/Dockerfile new file mode 100644 index 0000000000000..f21dc2ba309b8 --- /dev/null +++ b/src/ci/docker/disabled/riscv64gc-linux/Dockerfile @@ -0,0 +1,102 @@ +# based on armhf-gnu/Dockerfile +FROM ubuntu:20.04 + +RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections +RUN apt-get update -y && apt-get install -y --no-install-recommends \ + bc \ + bison \ + ca-certificates \ + cmake \ + cpio \ + curl \ + debian-ports-archive-keyring \ + debootstrap \ + flex \ + gcc \ + gcc-riscv64-linux-gnu \ + git \ + g++-riscv64-linux-gnu \ + g++ \ + libc6-dev \ + libc6-dev-riscv64-cross \ + make \ + patch \ + python3 \ + qemu-system-misc \ + xz-utils + +ENV ARCH=riscv +ENV CROSS_COMPILE=riscv64-linux-gnu- + +WORKDIR /build + +# From https://github.com/michaeljclark/busybear-linux/blob/master/conf/linux.config +COPY riscv64gc-linux/linux.config /build + +# Compile the kernel that we're going to be emulating with. This is +# basically just done to be compatible with the QEMU target that we're going +# to be using when running tests. +RUN curl https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.6.16.tar.xz | tar xJf - && \ + cp linux.config linux-5.6.16/.config && \ + cd /build/linux-5.6.16 && \ + make olddefconfig && \ + make -j$(nproc) vmlinux +RUN cp linux-5.6.16/vmlinux /tmp +RUN rm -rf linux-5.6.16 + +# Compile an instance of busybox as this provides a lightweight system and init +# binary which we will boot into. Only trick here is configuring busybox to +# build static binaries. +RUN curl https://busybox.net/downloads/busybox-1.31.1.tar.bz2 | tar xjf - +COPY riscv64gc-linux/0001-Remove-stime-function-calls.patch /build/busybox-1.31.1/ +RUN cd /build/busybox-1.31.1 && \ + patch -p1 -i 0001-Remove-stime-function-calls.patch && \ + make defconfig && \ + sed -i 's/.*CONFIG_STATIC.*/CONFIG_STATIC=y/' .config && \ + make -j$(nproc) && \ + make install && \ + mv _install /tmp/rootfs && \ + cd /build && \ + rm -rf busybox-1.31.1 + +# Download the ubuntu rootfs, which we'll use as a chroot for all our tests +# This is only needed to provide /lib/* and /usr/lib/* +WORKDIR /tmp +RUN debootstrap --variant=minbase --arch=riscv64 --foreign focal /tmp/rootfs/ubuntu +RUN cd rootfs && mkdir proc sys dev etc etc/init.d +# rootfs/ubuntu/proc is in a weird state (access fails with ELOOP) until +# rootfs/ubuntu/debootstrap/debootstrap --second-stage is run (under emulation), +# but this takes ages. Instead hack it into a good enough state. +# /proc is used by std::env::current_exe() (which is roughly +# `readlink /proc/self/exe`) +RUN cd rootfs/ubuntu && rm -rf proc && mkdir proc + +# Copy over our init script, which starts up our test server and also a few other +# misc tasks +COPY scripts/qemu-bare-bones-rcS rootfs/etc/init.d/rcS +RUN chmod +x rootfs/etc/init.d/rcS + +# Helper to quickly fill the entropy pool in the kernel +COPY scripts/qemu-bare-bones-addentropy.c /tmp/addentropy.c +RUN riscv64-linux-gnu-gcc addentropy.c -o rootfs/addentropy -static + +# download and build the riscv bootloader +RUN git clone https://github.com/riscv/riscv-pk +WORKDIR /tmp/riscv-pk +# nothing special about this revision: it is just master at the time of writing +# v1.0.0 doesn't build +RUN git checkout 5d9ed238e1cabfbca3c47f50d32894ce94bfc304 +RUN mkdir build && cd build && \ + ../configure --with-payload=/tmp/vmlinux --host=riscv64-linux-gnu && \ + make -j$(nproc) && \ + cp bbl /tmp +WORKDIR /tmp +RUN rm -rf /tmp/riscv-pk + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV RUST_CONFIGURE_ARGS --qemu-riscv64-rootfs=/tmp/rootfs +ENV SCRIPT python3 ../x.py test --target riscv64gc-unknown-linux-gnu + +ENV NO_CHANGE_USER=1 diff --git a/src/ci/docker/disabled/riscv64gc-linux/linux.config b/src/ci/docker/disabled/riscv64gc-linux/linux.config new file mode 100644 index 0000000000000..5142664742f20 --- /dev/null +++ b/src/ci/docker/disabled/riscv64gc-linux/linux.config @@ -0,0 +1,51 @@ +CONFIG_DEFAULT_HOSTNAME="busybear" +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_BPF_SYSCALL=y +CONFIG_SMP=y +CONFIG_MODULES=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_NETLINK_DIAG=y +# CONFIG_WIRELESS is not set +CONFIG_PCI=y +CONFIG_DEVTMPFS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_VIRTIO_BLK=y +CONFIG_NETDEVICES=y +CONFIG_VIRTIO_NET=y +# CONFIG_ETHERNET is not set +# CONFIG_WLAN is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_HVC_RISCV_SBI=y +# CONFIG_HW_RANDOM is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_VIRTIO_MMIO=y +CONFIG_SIFIVE_PLIC=y +CONFIG_RAS=y +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_AUTOFS4_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +# CONFIG_CRYPTO_ECHAINIV is not set +# CONFIG_CRYPTO_HW is not set +CONFIG_PRINTK_TIME=y diff --git a/src/ci/docker/dist-aarch64-linux/Dockerfile b/src/ci/docker/dist-aarch64-linux/Dockerfile index 74766dc970d9f..fd764965ef21b 100644 --- a/src/ci/docker/dist-aarch64-linux/Dockerfile +++ b/src/ci/docker/dist-aarch64-linux/Dockerfile @@ -35,5 +35,6 @@ ENV HOSTS=aarch64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ --enable-full-tools \ --enable-profiler \ + --enable-sanitizers \ --disable-docs ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index a052d0879a3db..daa2d55c04399 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -281,11 +281,6 @@ jobs: - name: dist-x86_64-linux <<: *job-linux-xl - - name: dist-x86_64-linux-alt - env: - IMAGE: dist-x86_64-linux - <<: *job-linux-xl - auto: <<: *base-ci-job name: auto diff --git a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md index 48dea213e8cee..4115825e92083 100644 --- a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md +++ b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md @@ -1,10 +1,10 @@ -# `control_flow_guard` +# `control-flow-guard` The tracking issue for this feature is: [#68793](https://github.com/rust-lang/rust/issues/68793). ------------------------ -The rustc flag `-Z control_flow_guard=checks` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature. +The rustc flag `-Z control-flow-guard` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature. CFG is an exploit mitigation designed to enforce control-flow integrity for software running on supported Windows platforms (Windows 8.1 onwards). Specifically, CFG uses runtime checks to validate the target address of every indirect call/jump before allowing the call to complete. @@ -29,7 +29,7 @@ The CFG checks and metadata can potentially increase binary size and runtime ove ## Testing Control Flow Guard -The rustc flag `-Z control_flow_guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement. +The rustc flag `-Z control-flow-guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement. ## Control Flow Guard in libraries @@ -44,14 +44,14 @@ For example: ```cmd rustup toolchain install --force nightly rustup component add rust-src -SET RUSTFLAGS=-Z control_flow_guard=checks +SET RUSTFLAGS=-Z control-flow-guard cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc ``` ```PowerShell rustup toolchain install --force nightly rustup component add rust-src -$Env:RUSTFLAGS = "-Z control_flow_guard=checks" +$Env:RUSTFLAGS = "-Z control-flow-guard" cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc ``` diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index f3da46bd0cc4e..e2dc816b01526 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -12,7 +12,6 @@ #![feature(associated_type_bounds)] #![feature(binary_heap_into_iter_sorted)] #![feature(binary_heap_drain_sorted)] -#![feature(vec_remove_item)] #![feature(split_inclusive)] #![feature(binary_heap_retain)] diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index a9813a8704f30..baa02b8997f92 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -131,21 +131,6 @@ fn test_extend_ref() { assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]); } -#[test] -fn test_remove_item() { - let mut v = vec![1, 2, 3]; - v.remove_item(&1); - - assert_eq!(v.len(), 2); - assert_eq!(v, [2, 3]); - - let mut w = vec![1, 2, 3]; - w.remove_item(&4); - - assert_eq!(w.len(), 3); - w.remove_item(&4); -} - #[test] fn test_slice_from_mut() { let mut values = vec![1, 2, 3, 4, 5]; diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 95c3b3b186161..0531084d0e4a3 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1760,17 +1760,15 @@ impl Vec { impl Vec { /// Removes the first instance of `item` from the vector if the item exists. /// - /// # Examples - /// - /// ``` - /// # #![feature(vec_remove_item)] - /// let mut vec = vec![1, 2, 3, 1]; - /// - /// vec.remove_item(&1); - /// - /// assert_eq!(vec, vec![2, 3, 1]); - /// ``` + /// This method will be removed soon. #[unstable(feature = "vec_remove_item", reason = "recently added", issue = "40062")] + #[rustc_deprecated( + reason = "Removing the first item equal to a needle is already easily possible \ + with iterators and the current Vec methods. Furthermore, having a method for \ + one particular case of removal (linear search, only the first item, no swap remove) \ + but not for others is inconsistent. This method will be removed soon.", + since = "1.46.0" + )] pub fn remove_item(&mut self, item: &V) -> Option where T: PartialEq, diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index c7a58d9f2a2f6..6c995be913c9e 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -804,7 +804,10 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { linker.args(&["-Wl,-rpath", "-Xlinker", rpath]); linker.link_dylib(Symbol::intern(&libname)); } - "x86_64-unknown-linux-gnu" | "x86_64-fuchsia" | "aarch64-fuchsia" => { + "aarch64-fuchsia" + | "aarch64-unknown-linux-gnu" + | "x86_64-fuchsia" + | "x86_64-unknown-linux-gnu" => { let filename = format!("librustc{}_rt.{}.a", channel, name); let path = default_tlib.join(&filename); linker.link_whole_rlib(&path); diff --git a/src/librustc_error_codes/error_codes/E0695.md b/src/librustc_error_codes/error_codes/E0695.md index 208f7f4c7b165..5013e83ca0362 100644 --- a/src/librustc_error_codes/error_codes/E0695.md +++ b/src/librustc_error_codes/error_codes/E0695.md @@ -1,6 +1,6 @@ A `break` statement without a label appeared inside a labeled block. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0695 # #![feature(label_break_value)] diff --git a/src/librustc_infer/infer/higher_ranked/mod.rs b/src/librustc_infer/infer/higher_ranked/mod.rs index ef18918c1772f..0499dc9ed2232 100644 --- a/src/librustc_infer/infer/higher_ranked/mod.rs +++ b/src/librustc_infer/infer/higher_ranked/mod.rs @@ -63,14 +63,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// placeholder region. This is the first step of checking subtyping /// when higher-ranked things are involved. /// - /// **Important:** you must call this function from within a snapshot. - /// Moreover, before committing the snapshot, you must eventually call - /// either `plug_leaks` or `pop_placeholders` to remove the placeholder - /// regions. If you rollback the snapshot (or are using a probe), then - /// the pop occurs as part of the rollback, so an explicit call is not - /// needed (but is also permitted). - /// - /// For more information about how placeholders and HRTBs work, see + /// **Important:** You have to be careful to not leak these placeholders, + /// for more information about how placeholders and HRTBs work, see /// the [rustc dev guide]. /// /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html diff --git a/src/librustc_infer/infer/region_constraints/leak_check.rs b/src/librustc_infer/infer/region_constraints/leak_check.rs index 473550d5433df..91c39a0e78ffb 100644 --- a/src/librustc_infer/infer/region_constraints/leak_check.rs +++ b/src/librustc_infer/infer/region_constraints/leak_check.rs @@ -128,7 +128,7 @@ impl<'tcx> TaintSet<'tcx> { verifys[i].origin.span(), "we never add verifications while doing higher-ranked things", ), - &Purged | &AddCombination(..) | &AddVar(..) => {} + &AddCombination(..) | &AddVar(..) => {} } } } diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/src/librustc_infer/infer/region_constraints/mod.rs index 90d61a78f9b99..2902c41a6bcae 100644 --- a/src/librustc_infer/infer/region_constraints/mod.rs +++ b/src/librustc_infer/infer/region_constraints/mod.rs @@ -289,14 +289,6 @@ pub(crate) enum UndoLog<'tcx> { /// We added a GLB/LUB "combination variable". AddCombination(CombineMapType, TwoRegions<'tcx>), - - /// During skolemization, we sometimes purge entries from the undo - /// log in a kind of minisnapshot (unlike other snapshots, this - /// purging actually takes place *on success*). In that case, we - /// replace the corresponding entry with `Noop` so as to avoid the - /// need to do a bunch of swapping. (We can't use `swap_remove` as - /// the order of the vector is important.) - Purged, } #[derive(Copy, Clone, PartialEq)] @@ -357,9 +349,6 @@ impl<'tcx> RegionConstraintStorage<'tcx> { fn rollback_undo_entry(&mut self, undo_entry: UndoLog<'tcx>) { match undo_entry { - Purged => { - // nothing to do here - } AddVar(vid) => { self.var_infos.pop().unwrap(); assert_eq!(self.var_infos.len(), vid.index() as usize); @@ -488,62 +477,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.var_infos[vid].origin } - /// Removes all the edges to/from the placeholder regions that are - /// in `skols`. This is used after a higher-ranked operation - /// completes to remove all trace of the placeholder regions - /// created in that time. - pub fn pop_placeholders(&mut self, placeholders: &FxHashSet>) { - debug!("pop_placeholders(placeholders={:?})", placeholders); - - assert!(UndoLogs::>::in_snapshot(&self.undo_log)); - - let constraints_to_kill: Vec = self - .undo_log - .iter() - .enumerate() - .rev() - .filter(|&(_, undo_entry)| match undo_entry { - super::UndoLog::RegionConstraintCollector(undo_entry) => { - kill_constraint(placeholders, undo_entry) - } - _ => false, - }) - .map(|(index, _)| index) - .collect(); - - for index in constraints_to_kill { - let undo_entry = match &mut self.undo_log[index] { - super::UndoLog::RegionConstraintCollector(undo_entry) => { - mem::replace(undo_entry, Purged) - } - _ => unreachable!(), - }; - self.rollback_undo_entry(undo_entry); - } - - return; - - fn kill_constraint<'tcx>( - placeholders: &FxHashSet>, - undo_entry: &UndoLog<'tcx>, - ) -> bool { - match undo_entry { - &AddConstraint(Constraint::VarSubVar(..)) => false, - &AddConstraint(Constraint::RegSubVar(a, _)) => placeholders.contains(&a), - &AddConstraint(Constraint::VarSubReg(_, b)) => placeholders.contains(&b), - &AddConstraint(Constraint::RegSubReg(a, b)) => { - placeholders.contains(&a) || placeholders.contains(&b) - } - &AddGiven(..) => false, - &AddVerify(_) => false, - &AddCombination(_, ref two_regions) => { - placeholders.contains(&two_regions.a) || placeholders.contains(&two_regions.b) - } - &AddVar(..) | &Purged => false, - } - } - } - fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) { // cannot add constraints once regions are resolved debug!("RegionConstraintCollector: add_constraint({:?})", constraint); diff --git a/src/librustc_infer/infer/undo_log.rs b/src/librustc_infer/infer/undo_log.rs index e7f1869955d20..2cfd6bb904c41 100644 --- a/src/librustc_infer/infer/undo_log.rs +++ b/src/librustc_infer/infer/undo_log.rs @@ -198,10 +198,6 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> { assert!(self.logs.len() >= snapshot.undo_len); assert!(self.num_open_snapshots > 0); } - - pub(crate) fn iter(&self) -> std::slice::Iter<'_, UndoLog<'tcx>> { - self.logs.iter() - } } impl<'tcx> std::ops::Index for InferCtxtUndoLogs<'tcx> { diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs index a15ac819be966..47555aca9f3fb 100644 --- a/src/librustc_infer/traits/mod.rs +++ b/src/librustc_infer/traits/mod.rs @@ -29,10 +29,10 @@ crate use self::util::elaborate_predicates; pub use rustc_middle::traits::*; -/// An `Obligation` represents some trait reference (e.g., `int: Eq`) for +/// An `Obligation` represents some trait reference (e.g., `i32: Eq`) for /// which the "impl_source" must be found. The process of finding a "impl_source" is /// called "resolving" the `Obligation`. This process consists of -/// either identifying an `impl` (e.g., `impl Eq for int`) that +/// either identifying an `impl` (e.g., `impl Eq for i32`) that /// satisfies the obligation, or else finding a bound that is in /// scope. The eventual result is usually a `Selection` (defined below). #[derive(Clone, PartialEq, Eq, Hash)] diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs index ee9846c64b67c..4ae7e417a8f67 100644 --- a/src/librustc_infer/traits/util.rs +++ b/src/librustc_infer/traits/util.rs @@ -63,11 +63,11 @@ impl PredicateSet<'tcx> { fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool { // We have to be careful here because we want // - // for<'a> Foo<&'a int> + // for<'a> Foo<&'a i32> // // and // - // for<'b> Foo<&'b int> + // for<'b> Foo<&'b i32> // // to be considered equivalent. So normalize all late-bound // regions before we throw things into the underlying set. diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs index a832c2decaaf6..d861b444c8816 100644 --- a/src/librustc_interface/tests.rs +++ b/src/librustc_interface/tests.rs @@ -465,7 +465,6 @@ fn test_debugging_options_tracking_hash() { untracked!(ast_json_noexpand, true); untracked!(borrowck, String::from("other")); untracked!(borrowck_stats, true); - untracked!(control_flow_guard, CFGuard::Checks); untracked!(deduplicate_diagnostics, true); untracked!(dep_tasks, true); untracked!(dont_buffer_diagnostics, true); @@ -539,6 +538,7 @@ fn test_debugging_options_tracking_hash() { tracked!(binary_dep_depinfo, true); tracked!(chalk, true); tracked!(codegen_backend, Some("abc".to_string())); + tracked!(control_flow_guard, CFGuard::Checks); tracked!(crate_attr, vec!["abc".to_string()]); tracked!(debug_macros, true); tracked!(dep_info_omit_d_target, true); diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 0335aa8358c3c..800f794121ab3 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -565,6 +565,7 @@ impl MetadataBlob { impl EntryKind { fn def_kind(&self) -> DefKind { match *self { + EntryKind::AnonConst(..) => DefKind::AnonConst, EntryKind::Const(..) => DefKind::Const, EntryKind::AssocConst(..) => DefKind::AssocConst, EntryKind::ImmStatic @@ -1121,7 +1122,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn mir_const_qualif(&self, id: DefIndex) -> mir::ConstQualifs { match self.kind(id) { - EntryKind::Const(qualif, _) + EntryKind::AnonConst(qualif, _) + | EntryKind::Const(qualif, _) | EntryKind::AssocConst( AssocContainer::ImplDefault | AssocContainer::ImplFinal @@ -1340,7 +1342,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn get_rendered_const(&self, id: DefIndex) -> String { match self.kind(id) { - EntryKind::Const(_, data) | EntryKind::AssocConst(_, _, data) => data.decode(self).0, + EntryKind::AnonConst(_, data) + | EntryKind::Const(_, data) + | EntryKind::AssocConst(_, _, data) => data.decode(self).0, _ => bug!(), } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index d797e6d4a34af..31821ea459f1b 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1358,7 +1358,7 @@ impl EncodeContext<'tcx> { let const_data = self.encode_rendered_const_for_body(body_id); let qualifs = self.tcx.mir_const_qualif(def_id); - record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Const(qualifs, const_data)); + record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst(qualifs, const_data)); record!(self.tables.visibility[def_id.to_def_id()] <- ty::Visibility::Public); record!(self.tables.span[def_id.to_def_id()] <- self.tcx.def_span(def_id)); self.encode_item_type(def_id.to_def_id()); diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index ec80a2b6171ed..381e7ee115e17 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -281,6 +281,7 @@ define_tables! { #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] enum EntryKind { + AnonConst(mir::ConstQualifs, Lazy), Const(mir::ConstQualifs, Lazy), ImmStatic, MutStatic, diff --git a/src/librustc_middle/lib.rs b/src/librustc_middle/lib.rs index 62c92e988ba60..8025246f3d6f6 100644 --- a/src/librustc_middle/lib.rs +++ b/src/librustc_middle/lib.rs @@ -45,7 +45,6 @@ #![feature(min_specialization)] #![feature(track_caller)] #![feature(trusted_len)] -#![feature(vec_remove_item)] #![feature(stmt_expr_attributes)] #![feature(test)] #![feature(in_band_lifetimes)] diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs index 17ea84836bf0a..f650240a41c63 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/src/librustc_middle/traits/mod.rs @@ -393,23 +393,25 @@ pub type SelectionResult<'tcx, T> = Result, SelectionError<'tcx>>; /// ``` /// impl Clone for Option { ... } // Impl_1 /// impl Clone for Box { ... } // Impl_2 -/// impl Clone for int { ... } // Impl_3 +/// impl Clone for i32 { ... } // Impl_3 /// -/// fn foo(concrete: Option>, -/// param: T, -/// mixed: Option) { +/// fn foo(concrete: Option>, param: T, mixed: Option) { +/// // Case A: Vtable points at a specific impl. Only possible when +/// // type is concretely known. If the impl itself has bounded +/// // type parameters, Vtable will carry resolutions for those as well: +/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])]) /// -/// // Case A: ImplSource points at a specific impl. Only possible when -/// // type is concretely known. If the impl itself has bounded -/// // type parameters, ImplSource will carry resolutions for those as well: -/// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])]) +/// // Case A: ImplSource points at a specific impl. Only possible when +/// // type is concretely known. If the impl itself has bounded +/// // type parameters, ImplSource will carry resolutions for those as well: +/// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])]) /// -/// // Case B: ImplSource must be provided by caller. This applies when -/// // type is a type parameter. -/// param.clone(); // ImplSourceParam +/// // Case B: ImplSource must be provided by caller. This applies when +/// // type is a type parameter. +/// param.clone(); // ImplSourceParam /// -/// // Case C: A mix of cases A and B. -/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam]) +/// // Case C: A mix of cases A and B. +/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam]) /// } /// ``` /// diff --git a/src/librustc_middle/ty/subst.rs b/src/librustc_middle/ty/subst.rs index 1529f1173b391..3b4254a18ea61 100644 --- a/src/librustc_middle/ty/subst.rs +++ b/src/librustc_middle/ty/subst.rs @@ -599,12 +599,12 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// /// ``` /// type Func = fn(A); - /// type MetaFunc = for<'a> fn(Func<&'a int>) + /// type MetaFunc = for<'a> fn(Func<&'a i32>) /// ``` /// /// The type `MetaFunc`, when fully expanded, will be /// - /// for<'a> fn(fn(&'a int)) + /// for<'a> fn(fn(&'a i32)) /// ^~ ^~ ^~~ /// | | | /// | | DebruijnIndex of 2 @@ -613,7 +613,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the /// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip /// over the inner binder (remember that we count De Bruijn indices from 1). However, in the - /// definition of `MetaFunc`, the binder is not visible, so the type `&'a int` will have a + /// definition of `MetaFunc`, the binder is not visible, so the type `&'a i32` will have a /// De Bruijn index of 1. It's only during the substitution that we can see we must increase the /// depth by 1 to account for the binder that we passed through. /// @@ -621,18 +621,18 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// /// ``` /// type FuncTuple = (A,fn(A)); - /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a int>) + /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>) /// ``` /// /// Here the final type will be: /// - /// for<'a> fn((&'a int, fn(&'a int))) + /// for<'a> fn((&'a i32, fn(&'a i32))) /// ^~~ ^~~ /// | | /// DebruijnIndex of 1 | /// DebruijnIndex of 2 /// - /// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the + /// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the /// first case we do not increase the De Bruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. fn shift_vars_through_binders>(&self, val: T) -> T { diff --git a/src/librustc_middle/ty/walk.rs b/src/librustc_middle/ty/walk.rs index d6f504fdb338b..633d4fda8a46d 100644 --- a/src/librustc_middle/ty/walk.rs +++ b/src/librustc_middle/ty/walk.rs @@ -22,13 +22,13 @@ impl<'tcx> TypeWalker<'tcx> { /// Skips the subtree corresponding to the last type /// returned by `next()`. /// - /// Example: Imagine you are walking `Foo, usize>`. + /// Example: Imagine you are walking `Foo, usize>`. /// /// ``` /// let mut iter: TypeWalker = ...; /// iter.next(); // yields Foo - /// iter.next(); // yields Bar - /// iter.skip_current_subtree(); // skips int + /// iter.next(); // yields Bar + /// iter.skip_current_subtree(); // skips i32 /// iter.next(); // yields usize /// ``` pub fn skip_current_subtree(&mut self) { diff --git a/src/librustc_query_system/lib.rs b/src/librustc_query_system/lib.rs index 12450a4ccd3eb..3afc4565933e5 100644 --- a/src/librustc_query_system/lib.rs +++ b/src/librustc_query_system/lib.rs @@ -6,7 +6,6 @@ #![feature(hash_raw_entry)] #![feature(min_specialization)] #![feature(stmt_expr_attributes)] -#![feature(vec_remove_item)] #[macro_use] extern crate log; diff --git a/src/librustc_query_system/query/job.rs b/src/librustc_query_system/query/job.rs index 5150b278a7722..190312bb33001 100644 --- a/src/librustc_query_system/query/job.rs +++ b/src/librustc_query_system/query/job.rs @@ -452,7 +452,9 @@ fn remove_cycle( // Remove the queries in our cycle from the list of jobs to look at for r in &stack { - jobs.remove_item(&r.1); + if let Some(pos) = jobs.iter().position(|j| j == &r.1) { + jobs.remove(pos); + } } // Find the queries in the cycle which are diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 53cec04083696..f77bf5ddefd3f 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -103,7 +103,7 @@ pub enum Strip { Symbols, } -/// The different settings that the `-Z control_flow_guard` flag can have. +/// The different settings that the `-Z control-flow-guard` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum CFGuard { /// Do not emit Control Flow Guard metadata or checks. diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 8032909bbcd7a..6c6f27502b614 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -250,7 +250,8 @@ macro_rules! options { pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `leak`, `memory` or `thread`"; pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; - pub const parse_cfguard: &str = "either `disabled`, `nochecks`, or `checks`"; + pub const parse_cfguard: &str = + "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of(); pub const parse_optimization_fuel: &str = "crate=integer"; @@ -495,12 +496,24 @@ macro_rules! options { } fn parse_cfguard(slot: &mut CFGuard, v: Option<&str>) -> bool { - match v { - Some("disabled") => *slot = CFGuard::Disabled, - Some("nochecks") => *slot = CFGuard::NoChecks, - Some("checks") => *slot = CFGuard::Checks, - _ => return false, + if v.is_some() { + let mut bool_arg = None; + if parse_opt_bool(&mut bool_arg, v) { + *slot = if bool_arg.unwrap() { + CFGuard::Checks + } else { + CFGuard::Disabled + }; + return true + } } + + *slot = match v { + None => CFGuard::Checks, + Some("checks") => CFGuard::Checks, + Some("nochecks") => CFGuard::NoChecks, + Some(_) => return false, + }; true } @@ -796,8 +809,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "enable the experimental Chalk-based trait solving engine"), codegen_backend: Option = (None, parse_opt_string, [TRACKED], "the backend to use"), - control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [UNTRACKED], - "use Windows Control Flow Guard (`disabled`, `nochecks` or `checks`)"), + control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED], + "use Windows Control Flow Guard (default: no)"), crate_attr: Vec = (Vec::new(), parse_string_push, [TRACKED], "inject the given attribute in the crate"), debug_macros: bool = (false, parse_bool, [TRACKED], diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 90cd6ae5bf99f..2ea312c42dc64 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -1349,11 +1349,19 @@ fn validate_commandline_args_with_session_available(sess: &Session) { ); } - const ASAN_SUPPORTED_TARGETS: &[&str] = - &["aarch64-fuchsia", "x86_64-apple-darwin", "x86_64-fuchsia", "x86_64-unknown-linux-gnu"]; - const LSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]; - const MSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; - const TSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]; + const ASAN_SUPPORTED_TARGETS: &[&str] = &[ + "aarch64-fuchsia", + "aarch64-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-fuchsia", + "x86_64-unknown-linux-gnu", + ]; + const LSAN_SUPPORTED_TARGETS: &[&str] = + &["aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]; + const MSAN_SUPPORTED_TARGETS: &[&str] = + &["aarch64-unknown-linux-gnu", "x86_64-unknown-linux-gnu"]; + const TSAN_SUPPORTED_TARGETS: &[&str] = + &["aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]; // Sanitizers can only be used on some tested platforms. for s in sess.opts.debugging_opts.sanitizer { diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 706e68698eb55..1964054254734 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -361,7 +361,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { // handle normalization within binders because // otherwise we wind up a need to normalize when doing // trait matching (since you can have a trait - // obligation like `for<'a> T::B : Fn(&'a int)`), but + // obligation like `for<'a> T::B: Fn(&'a i32)`), but // we can't normalize with bound regions in scope. So // far now we just ignore binders but only normalize // if all bound regions are gone (and then we still diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/src/librustc_trait_selection/traits/query/normalize.rs index 3e7749356d212..ca49ff5884f98 100644 --- a/src/librustc_trait_selection/traits/query/normalize.rs +++ b/src/librustc_trait_selection/traits/query/normalize.rs @@ -145,7 +145,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // handle normalization within binders because // otherwise we wind up a need to normalize when doing // trait matching (since you can have a trait - // obligation like `for<'a> T::B : Fn(&'a int)`), but + // obligation like `for<'a> T::B: Fn(&'a i32)`), but // we can't normalize with bound regions in scope. So // far now we just ignore binders but only normalize // if all bound regions are gone (and then we still diff --git a/src/librustc_trait_selection/traits/select/confirmation.rs b/src/librustc_trait_selection/traits/select/confirmation.rs index f8d26c06a219d..50c04e8fc3452 100644 --- a/src/librustc_trait_selection/traits/select/confirmation.rs +++ b/src/librustc_trait_selection/traits/select/confirmation.rs @@ -553,14 +553,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// /// Here is an example. Imagine we have a closure expression /// and we desugared it so that the type of the expression is - /// `Closure`, and `Closure` expects an int as argument. Then it + /// `Closure`, and `Closure` expects `i32` as argument. Then it /// is "as if" the compiler generated this impl: /// - /// impl Fn(int) for Closure { ... } + /// impl Fn(i32) for Closure { ... } /// - /// Now imagine our obligation is `Fn(usize) for Closure`. So far + /// Now imagine our obligation is `Closure: Fn(usize)`. So far /// we have matched the self type `Closure`. At this point we'll - /// compare the `int` to `usize` and generate an error. + /// compare the `i32` to `usize` and generate an error. /// /// Note that this checking occurs *after* the impl has selected, /// because these output type parameters should not affect the diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index 3fd566eab437e..7dc8c2cf4cdc2 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -1754,27 +1754,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Vec> { // Because the types were potentially derived from // higher-ranked obligations they may reference late-bound - // regions. For example, `for<'a> Foo<&'a int> : Copy` would - // yield a type like `for<'a> &'a int`. In general, we + // regions. For example, `for<'a> Foo<&'a i32> : Copy` would + // yield a type like `for<'a> &'a i32`. In general, we // maintain the invariant that we never manipulate bound // regions, so we have to process these bound regions somehow. // // The strategy is to: // // 1. Instantiate those regions to placeholder regions (e.g., - // `for<'a> &'a int` becomes `&0 int`. - // 2. Produce something like `&'0 int : Copy` - // 3. Re-bind the regions back to `for<'a> &'a int : Copy` + // `for<'a> &'a i32` becomes `&0 i32`. + // 2. Produce something like `&'0 i32 : Copy` + // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy` types - .skip_binder() + .skip_binder() // binder moved -\ .iter() .flat_map(|ty| { - // binder moved -\ let ty: ty::Binder> = ty::Binder::bind(ty); // <----/ self.infcx.commit_unconditionally(|_| { - let (skol_ty, _) = self.infcx.replace_bound_vars_with_placeholders(&ty); + let (placeholder_ty, _) = self.infcx.replace_bound_vars_with_placeholders(&ty); let Normalized { value: normalized_ty, mut obligations } = ensure_sufficient_stack(|| { project::normalize_with_depth( @@ -1782,10 +1781,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env, cause.clone(), recursion_depth, - &skol_ty, + &placeholder_ty, ) }); - let skol_obligation = predicate_for_trait_def( + let placeholder_obligation = predicate_for_trait_def( self.tcx(), param_env, cause.clone(), @@ -1794,7 +1793,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { normalized_ty, &[], ); - obligations.push(skol_obligation); + obligations.push(placeholder_obligation); obligations }) }) @@ -1844,9 +1843,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Err(()); } - let (skol_obligation, placeholder_map) = + let (placeholder_obligation, placeholder_map) = self.infcx().replace_bound_vars_with_placeholders(&obligation.predicate); - let skol_obligation_trait_ref = skol_obligation.trait_ref; + let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref; let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); @@ -1865,14 +1864,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!( "match_impl(impl_def_id={:?}, obligation={:?}, \ - impl_trait_ref={:?}, skol_obligation_trait_ref={:?})", - impl_def_id, obligation, impl_trait_ref, skol_obligation_trait_ref + impl_trait_ref={:?}, placeholder_obligation_trait_ref={:?})", + impl_def_id, obligation, impl_trait_ref, placeholder_obligation_trait_ref ); let InferOk { obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(skol_obligation_trait_ref, impl_trait_ref) + .eq(placeholder_obligation_trait_ref, impl_trait_ref) .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?; nested_obligations.extend(obligations); diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs index 2b596be954267..42901102c1076 100644 --- a/src/librustc_trait_selection/traits/specialize/mod.rs +++ b/src/librustc_trait_selection/traits/specialize/mod.rs @@ -130,7 +130,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, // We determine whether there's a subset relationship by: // - // - skolemizing impl1, + // - replacing bound vars with placeholders in impl1, // - assuming the where clauses for impl1, // - instantiating impl2 with fresh inference variables, // - unifying, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b592d30c37d3c..33d57e2571173 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1394,13 +1394,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // That is, consider this case: // // ``` - // trait SubTrait: SuperTrait { } + // trait SubTrait: SuperTrait { } // trait SuperTrait { type T; } // // ... B: SubTrait ... // ``` // - // We want to produce `>::T == foo`. + // We want to produce `>::T == foo`. // Find any late-bound regions declared in `ty` that are not // declared in the trait-ref. These are not well-formed. diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index b39cfcb377595..1d47e64630c18 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -91,14 +91,14 @@ fn compare_predicate_entailment<'tcx>( // This code is best explained by example. Consider a trait: // - // trait Trait<'t,T> { - // fn method<'a,M>(t: &'t T, m: &'a M) -> Self; + // trait Trait<'t, T> { + // fn method<'a, M>(t: &'t T, m: &'a M) -> Self; // } // // And an impl: // // impl<'i, 'j, U> Trait<'j, &'i U> for Foo { - // fn method<'b,N>(t: &'j &'i U, m: &'b N) -> Foo; + // fn method<'b, N>(t: &'j &'i U, m: &'b N) -> Foo; // } // // We wish to decide if those two method types are compatible. @@ -116,9 +116,9 @@ fn compare_predicate_entailment<'tcx>( // regions (Note: but only early-bound regions, i.e., those // declared on the impl or used in type parameter bounds). // - // impl_to_skol_substs = {'i => 'i0, U => U0, N => N0 } + // impl_to_placeholder_substs = {'i => 'i0, U => U0, N => N0 } // - // Now we can apply skol_substs to the type of the impl method + // Now we can apply placeholder_substs to the type of the impl method // to yield a new function type in terms of our fresh, placeholder // types: // @@ -127,11 +127,11 @@ fn compare_predicate_entailment<'tcx>( // We now want to extract and substitute the type of the *trait* // method and compare it. To do so, we must create a compound // substitution by combining trait_to_impl_substs and - // impl_to_skol_substs, and also adding a mapping for the method + // impl_to_placeholder_substs, and also adding a mapping for the method // type parameters. We extend the mapping to also include // the method parameters. // - // trait_to_skol_substs = { T => &'i0 U0, Self => Foo, M => N0 } + // trait_to_placeholder_substs = { T => &'i0 U0, Self => Foo, M => N0 } // // Applying this to the trait method type yields: // @@ -145,20 +145,20 @@ fn compare_predicate_entailment<'tcx>( // satisfied by the implementation's method. // // We do this by creating a parameter environment which contains a - // substitution corresponding to impl_to_skol_substs. We then build - // trait_to_skol_substs and use it to convert the predicates contained + // substitution corresponding to impl_to_placeholder_substs. We then build + // trait_to_placeholder_substs and use it to convert the predicates contained // in the trait_m.generics to the placeholder form. // // Finally we register each of these predicates as an obligation in // a fresh FulfillmentCtxt, and invoke select_all_or_error. // Create mapping from impl to placeholder. - let impl_to_skol_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id); + let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id); // Create mapping from trait to placeholder. - let trait_to_skol_substs = - impl_to_skol_substs.rebase_onto(tcx, impl_m.container.id(), trait_to_impl_substs); - debug!("compare_impl_method: trait_to_skol_substs={:?}", trait_to_skol_substs); + let trait_to_placeholder_substs = + impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container.id(), trait_to_impl_substs); + debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs); let impl_m_generics = tcx.generics_of(impl_m.def_id); let trait_m_generics = tcx.generics_of(trait_m.def_id); @@ -194,7 +194,7 @@ fn compare_predicate_entailment<'tcx>( // if all constraints hold. hybrid_preds .predicates - .extend(trait_m_predicates.instantiate_own(tcx, trait_to_skol_substs).predicates); + .extend(trait_m_predicates.instantiate_own(tcx, trait_to_placeholder_substs).predicates); // Construct trait parameter environment and then shift it into the placeholder viewpoint. // The key step here is to update the caller_bounds's predicates to be @@ -220,7 +220,7 @@ fn compare_predicate_entailment<'tcx>( let mut selcx = traits::SelectionContext::new(&infcx); - let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_skol_substs); + let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs); let (impl_m_own_bounds, _) = infcx.replace_bound_vars_with_fresh_vars( impl_m_span, infer::HigherRankedType, @@ -261,7 +261,7 @@ fn compare_predicate_entailment<'tcx>( debug!("compare_impl_method: impl_fty={:?}", impl_fty); let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, &tcx.fn_sig(trait_m.def_id)); - let trait_sig = trait_sig.subst(tcx, trait_to_skol_substs); + let trait_sig = trait_sig.subst(tcx, trait_to_placeholder_substs); let trait_sig = inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, &trait_sig); let trait_fty = tcx.mk_fn_ptr(ty::Binder::bind(trait_sig)); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index eb8f76687174e..efd23894d02d1 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1468,7 +1468,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// /// ``` /// trait Foo { ... } - /// impl Foo for Vec { ... } + /// impl Foo for Vec { ... } /// impl Foo for Vec { ... } /// ``` /// diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 7965c9c9ce12a..ea47ae68ce7d3 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -212,7 +212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // errors in some cases, such as this one: // // ``` - // fn foo<'x>(x: &'x int) { + // fn foo<'x>(x: &'x i32) { // let a = 1; // let mut z = x; // z = &a; @@ -220,7 +220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` // // The reason we might get an error is that `z` might be - // assigned a type like `&'x int`, and then we would have + // assigned a type like `&'x i32`, and then we would have // a problem when we try to assign `&a` to `z`, because // the lifetime of `&a` (i.e., the enclosing block) is // shorter than `'x`. @@ -229,11 +229,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // expected type here is whatever type the user wrote, not // the initializer's type. In this case the user wrote // nothing, so we are going to create a type variable `Z`. - // Then we will assign the type of the initializer (`&'x - // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we - // will instantiate `Z` as a type `&'0 int` where `'0` is - // a fresh region variable, with the constraint that `'x : - // '0`. So basically we're all set. + // Then we will assign the type of the initializer (`&'x i32`) + // as a subtype of `Z`: `&'x i32 <: Z`. And hence we + // will instantiate `Z` as a type `&'0 i32` where `'0` is + // a fresh region variable, with the constraint that `'x : '0`. + // So basically we're all set. // // Note that there are two tests to check that this remains true // (`regions-reassign-{match,let}-bound-pointer.rs`). diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 95d113166e001..de6fa3dbd4a89 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -9,7 +9,6 @@ #![feature(nll)] #![feature(or_patterns)] #![feature(test)] -#![feature(vec_remove_item)] #![feature(ptr_offset_from)] #![feature(crate_visibility_modifier)] #![feature(never_type)] diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index 2badfc973c972..fc6ce5770338e 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -26,18 +26,10 @@ IMAGE_BASE: .Lxsave_clear: .org .+24 .Lxsave_mxcsr: - .int 0 + .short 0x1f80 /* We can store a bunch of data in the gap between MXCSR and the XSAVE header */ -/* MXCSR initialization value for ABI */ -.Lmxcsr_init: - .int 0x1f80 - -/* x87 FPU control word initialization value for ABI */ -.Lfpucw_init: - .int 0x037f - /* The following symbols point at read-only data that will be filled in by the */ /* post-linker. */ @@ -177,13 +169,17 @@ sgx_entry: jz .Lskip_debug_init mov %r10,%gs:tcsls_debug_panic_buf_ptr .Lskip_debug_init: +/* reset cpu state */ + mov %rdx, %r10 + mov $-1, %rax + mov $-1, %rdx + xrstor .Lxsave_clear(%rip) + mov %r10, %rdx + /* check if returning from usercall */ mov %gs:tcsls_last_rsp,%r11 test %r11,%r11 jnz .Lusercall_ret -/* reset user state */ - ldmxcsr .Lmxcsr_init(%rip) - fldcw .Lfpucw_init(%rip) /* setup stack */ mov %gs:tcsls_tos,%rsp /* initially, RSP is not set to the correct value */ /* here. This is fixed below under "adjust stack". */ diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 2d7267263dedf..6e33cdd3c4826 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -428,6 +428,7 @@ mod tests { // ignored there. #[cfg_attr(target_arch = "arm", ignore)] #[cfg_attr(target_arch = "aarch64", ignore)] + #[cfg_attr(target_arch = "riscv64", ignore)] fn test_process_mask() { unsafe { // Test to make sure that a signal mask does not get inherited. diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 295ebcbb72939..84fa35e01bb09 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -811,11 +811,11 @@ mod tests { // Right now for CI this test is run in an emulator, and apparently the // aarch64 emulator's sense of time is that we're still living in the - // 70s. + // 70s. This is also true for riscv (also qemu) // // Otherwise let's assume that we're all running computers later than // 2000. - if !cfg!(target_arch = "aarch64") { + if !cfg!(target_arch = "aarch64") && !cfg!(target_arch = "riscv64") { assert!(a > thirty_years); } diff --git a/src/test/codegen/cfguard_checks.rs b/src/test/codegen/cfguard_checks.rs index 40a7353eac045..96f9158f9d394 100644 --- a/src/test/codegen/cfguard_checks.rs +++ b/src/test/codegen/cfguard_checks.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z control_flow_guard=checks +// compile-flags: -Z control-flow-guard=checks #![crate_type = "lib"] diff --git a/src/test/codegen/cfguard_disabled.rs b/src/test/codegen/cfguard_disabled.rs index d1747931e15c8..1325ffc0f2595 100644 --- a/src/test/codegen/cfguard_disabled.rs +++ b/src/test/codegen/cfguard_disabled.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z control_flow_guard=disabled +// compile-flags: -Z control-flow-guard=no #![crate_type = "lib"] diff --git a/src/test/codegen/cfguard_nochecks.rs b/src/test/codegen/cfguard_nochecks.rs index c5d7afbae257b..ae1de4c4d26d5 100644 --- a/src/test/codegen/cfguard_nochecks.rs +++ b/src/test/codegen/cfguard_nochecks.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z control_flow_guard=nochecks +// compile-flags: -Z control-flow-guard=nochecks #![crate_type = "lib"] diff --git a/src/test/ui/const-generics/auxiliary/impl-const.rs b/src/test/ui/const-generics/auxiliary/impl-const.rs new file mode 100644 index 0000000000000..fc993d63927c3 --- /dev/null +++ b/src/test/ui/const-generics/auxiliary/impl-const.rs @@ -0,0 +1,9 @@ +#![feature(const_generics)] + +pub struct Num; + +// Braces around const expression causes crash +impl Num<{5}> { + pub fn five(&self) { + } +} diff --git a/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs b/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs new file mode 100644 index 0000000000000..bda9ce8767d08 --- /dev/null +++ b/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs @@ -0,0 +1,14 @@ +// aux-build:impl-const.rs +// run-pass + +#![feature(const_generics)] +#![allow(incomplete_features)] + +extern crate impl_const; + +use impl_const::*; + +pub fn main() { + let n = Num::<5>; + n.five(); +} diff --git a/src/test/ui/sanitize/unsupported-target.stderr b/src/test/ui/sanitize/unsupported-target.stderr index f9434bc9512d0..f5961a11b1f1c 100644 --- a/src/test/ui/sanitize/unsupported-target.stderr +++ b/src/test/ui/sanitize/unsupported-target.stderr @@ -1,4 +1,4 @@ -error: `-Zsanitizer=leak` only works with targets: x86_64-apple-darwin, x86_64-unknown-linux-gnu +error: `-Zsanitizer=leak` only works with targets: aarch64-unknown-linux-gnu, x86_64-apple-darwin, x86_64-unknown-linux-gnu error: aborting due to previous error diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 93c53e779d50e..c00b0f02c3a90 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -1,5 +1,4 @@ #![crate_name = "compiletest"] -#![feature(vec_remove_item)] #![deny(warnings)] // The `test` crate is the only unstable feature // allowed here, just to share similar code. diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 0d56bf2d20fcb..0437ff8c9440a 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -82,16 +82,22 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("xcore", "xcore"), ]; -pub const ASAN_SUPPORTED_TARGETS: &'static [&'static str] = - &["aarch64-fuchsia", "x86_64-apple-darwin", "x86_64-fuchsia", "x86_64-unknown-linux-gnu"]; +pub const ASAN_SUPPORTED_TARGETS: &'static [&'static str] = &[ + "aarch64-fuchsia", + "aarch64-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-fuchsia", + "x86_64-unknown-linux-gnu", +]; pub const LSAN_SUPPORTED_TARGETS: &'static [&'static str] = - &["x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]; + &["aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]; -pub const MSAN_SUPPORTED_TARGETS: &'static [&'static str] = &["x86_64-unknown-linux-gnu"]; +pub const MSAN_SUPPORTED_TARGETS: &'static [&'static str] = + &["aarch64-unknown-linux-gnu", "x86_64-unknown-linux-gnu"]; pub const TSAN_SUPPORTED_TARGETS: &'static [&'static str] = - &["x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]; + &["aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]; pub fn matches_os(triple: &str, name: &str) -> bool { // For the wasm32 bare target we ignore anything also ignored on emscripten diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs index efc29163455be..1fafe109d34e1 100644 --- a/src/tools/remote-test-client/src/main.rs +++ b/src/tools/remote-test-client/src/main.rs @@ -107,13 +107,23 @@ fn start_android_emulator(server: &Path) { Command::new("adb").arg("shell").arg("/data/tmp/testd").spawn().unwrap(); } -fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path) { +fn prepare_rootfs(target: &str, rootfs: &Path, server: &Path, rootfs_img: &Path) { + t!(fs::copy(server, rootfs.join("testd"))); + + match target { + "arm-unknown-linux-gnueabihf" | "aarch64-unknown-linux-gnu" => { + prepare_rootfs_cpio(rootfs, rootfs_img) + } + "riscv64gc-unknown-linux-gnu" => prepare_rootfs_ext4(rootfs, rootfs_img), + _ => panic!("{} is not supported", target), + } +} + +fn prepare_rootfs_cpio(rootfs: &Path, rootfs_img: &Path) { // Generate a new rootfs image now that we've updated the test server // executable. This is the equivalent of: // // find $rootfs -print 0 | cpio --null -o --format=newc > rootfs.img - t!(fs::copy(server, rootfs.join("testd"))); - let rootfs_img = tmpdir.join("rootfs.img"); let mut cmd = Command::new("cpio"); cmd.arg("--null") .arg("-o") @@ -128,6 +138,38 @@ fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path t!(io::copy(&mut child.stdout.take().unwrap(), &mut t!(File::create(&rootfs_img)))); assert!(t!(child.wait()).success()); + fn add_files(w: &mut dyn Write, root: &Path, cur: &Path) { + for entry in t!(cur.read_dir()) { + let entry = t!(entry); + let path = entry.path(); + let to_print = path.strip_prefix(root).unwrap(); + t!(write!(w, "{}\u{0}", to_print.to_str().unwrap())); + if t!(entry.file_type()).is_dir() { + add_files(w, root, &path); + } + } + } +} + +fn prepare_rootfs_ext4(rootfs: &Path, rootfs_img: &Path) { + let mut dd = Command::new("dd"); + dd.arg("if=/dev/zero") + .arg(&format!("of={}", rootfs_img.to_string_lossy())) + .arg("bs=1M") + .arg("count=1024"); + let mut dd_child = t!(dd.spawn()); + assert!(t!(dd_child.wait()).success()); + + let mut mkfs = Command::new("mkfs.ext4"); + mkfs.arg("-d").arg(rootfs).arg(rootfs_img); + let mut mkfs_child = t!(mkfs.spawn()); + assert!(t!(mkfs_child.wait()).success()); +} + +fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path) { + let rootfs_img = &tmpdir.join("rootfs.img"); + prepare_rootfs(target, rootfs, server, rootfs_img); + // Start up the emulator, in the background match target { "arm-unknown-linux-gnueabihf" => { @@ -170,19 +212,30 @@ fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path .arg("virtio-net-device,netdev=net0,mac=00:00:00:00:00:00"); t!(cmd.spawn()); } - _ => panic!("cannot start emulator for: {}" < target), - } - - fn add_files(w: &mut dyn Write, root: &Path, cur: &Path) { - for entry in t!(cur.read_dir()) { - let entry = t!(entry); - let path = entry.path(); - let to_print = path.strip_prefix(root).unwrap(); - t!(write!(w, "{}\u{0}", to_print.to_str().unwrap())); - if t!(entry.file_type()).is_dir() { - add_files(w, root, &path); - } + "riscv64gc-unknown-linux-gnu" => { + let mut cmd = Command::new("qemu-system-riscv64"); + cmd.arg("-nographic") + .arg("-machine") + .arg("virt") + .arg("-m") + .arg("1024") + .arg("-bios") + .arg("none") + .arg("-kernel") + .arg("/tmp/bbl") + .arg("-append") + .arg("quiet console=ttyS0 root=/dev/vda rw") + .arg("-netdev") + .arg("user,id=net0,hostfwd=tcp::12345-:12345") + .arg("-device") + .arg("virtio-net-device,netdev=net0,mac=00:00:00:00:00:00") + .arg("-device") + .arg("virtio-blk-device,drive=hd0") + .arg("-drive") + .arg(&format!("file={},format=raw,id=hd0", &rootfs_img.to_string_lossy())); + t!(cmd.spawn()); } + _ => panic!("cannot start emulator for: {}", target), } }