diff --git a/src/Cargo.lock b/src/Cargo.lock index 77e33855f2344..fe67a1655f18d 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -199,7 +199,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.6 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.7 (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.31 (registry+https://github.com/rust-lang/crates.io-index)", "libgit2-sys 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -759,7 +759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jobserver" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1429,7 +1429,7 @@ dependencies = [ "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", - "jobserver 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_back 0.0.0", @@ -1757,7 +1757,7 @@ dependencies = [ "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2530,7 +2530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fcaf2365eb14b28ec7603c98c06cc531f19de9eb283d89a3dff8417c8c99f5" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" -"checksum jobserver 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "443ae8bc0af6c106e6e8b77e04684faecc1a5ce94e058f4c2b0a037b0ea1b133" +"checksum jobserver 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "094f87ed101b6832def8632f43db43dc204d27897eb95aca69b26ce2e4011e84" "checksum jsonrpc-core 7.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1acd0f9934da94466d2370f36832b9b19271b4abdfdb5e69f0bcd991ebcd515" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kuchiki 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ef2ea4f2f7883cd7c6772b06c14abca01a2cc1f75c426cebffcf6b3b925ef9fc" diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 2576886743949..64f76aa2ef43f 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -302,6 +302,7 @@ def default_build_triple(): return "{}-{}".format(cputype, ostype) + class RustBuild(object): """Provide all the methods required to build Rust""" def __init__(self): diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 0ea4af386c7cb..73ce82287e7ab 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -19,6 +19,7 @@ sys.path.append(os.path.join(rust_dir, "src", "bootstrap")) import bootstrap + class Option: def __init__(self, name, rustbuild, desc, value): self.name = name @@ -26,14 +27,18 @@ def __init__(self, name, rustbuild, desc, value): self.desc = desc self.value = value + options = [] + def o(*args): options.append(Option(*args, value=False)) + def v(*args): options.append(Option(*args, value=True)) + o("debug", "rust.debug", "debug mode; disables optimization unless `--enable-optimize` given") o("docs", "build.docs", "build standard library documentation") o("compiler-docs", "build.compiler-docs", "build compiler documentation") @@ -136,13 +141,16 @@ def v(*args): v("set", None, "set arbitrary key/value pairs in TOML configuration") + def p(msg): print("configure: " + msg) + def err(msg): print("configure: error: " + msg) sys.exit(1) + if '--help' in sys.argv or '-h' in sys.argv: print('Usage: ./configure [options]') print('') @@ -208,7 +216,7 @@ def err(msg): continue found = True - if not option.name in known_args: + if option.name not in known_args: known_args[option.name] = [] known_args[option.name].append((option, value)) break @@ -227,27 +235,30 @@ def err(msg): # TOML we're going to write out config = {} + def build(): if 'build' in known_args: return known_args['build'][0][1] return bootstrap.default_build_triple() + def set(key, value): - s = "{:20} := {}".format(key, value) - if len(s) < 70: - p(s) - else: - p(s[:70] + " ...") - - arr = config - parts = key.split('.') - for i, part in enumerate(parts): - if i == len(parts) - 1: - arr[part] = value - else: - if not part in arr: - arr[part] = {} - arr = arr[part] + s = "{:20} := {}".format(key, value) + if len(s) < 70: + p(s) + else: + p(s[:70] + " ...") + + arr = config + parts = key.split('.') + for i, part in enumerate(parts): + if i == len(parts) - 1: + arr[part] = value + else: + if part not in arr: + arr[part] = {} + arr = arr[part] + for key in known_args: # The `set` option is special and can be passed a bunch of times @@ -345,6 +356,7 @@ def set(key, value): targets[target] = sections['target'][:] targets[target][0] = targets[target][0].replace("x86_64-unknown-linux-gnu", target) + # Here we walk through the constructed configuration we have from the parsed # command line arguments. We then apply each piece of configuration by # basically just doing a `sed` to change the various configuration line to what @@ -362,6 +374,7 @@ def to_toml(value): else: raise RuntimeError('no toml') + def configure_section(lines, config): for key in config: value = config[key] @@ -375,9 +388,10 @@ def configure_section(lines, config): if not found: raise RuntimeError("failed to find config line for {}".format(key)) + for section_key in config: section_config = config[section_key] - if not section_key in sections: + if section_key not in sections: raise RuntimeError("config key {} not in sections".format(section_key)) if section_key == 'target': diff --git a/src/ci/docker/dist-i686-freebsd/Dockerfile b/src/ci/docker/dist-i686-freebsd/Dockerfile index b82d227b3ef2e..686afc97289b1 100644 --- a/src/ci/docker/dist-i686-freebsd/Dockerfile +++ b/src/ci/docker/dist-i686-freebsd/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:16.04 RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ + clang \ make \ file \ curl \ @@ -16,16 +16,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libssl-dev \ pkg-config -COPY dist-i686-freebsd/build-toolchain.sh /tmp/ -RUN /tmp/build-toolchain.sh i686 +COPY scripts/freebsd-toolchain.sh /tmp/ +RUN /tmp/freebsd-toolchain.sh i686 COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV \ AR_i686_unknown_freebsd=i686-unknown-freebsd10-ar \ - CC_i686_unknown_freebsd=i686-unknown-freebsd10-gcc \ - CXX_i686_unknown_freebsd=i686-unknown-freebsd10-g++ + CC_i686_unknown_freebsd=i686-unknown-freebsd10-clang \ + CXX_i686_unknown_freebsd=i686-unknown-freebsd10-clang++ ENV HOSTS=i686-unknown-freebsd diff --git a/src/ci/docker/dist-i686-freebsd/build-toolchain.sh b/src/ci/docker/dist-i686-freebsd/build-toolchain.sh deleted file mode 100755 index 8343327c33bf2..0000000000000 --- a/src/ci/docker/dist-i686-freebsd/build-toolchain.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/bash -# Copyright 2016 The Rust Project Developers. See the COPYRIGHT -# file at the top-level directory of this distribution and at -# http://rust-lang.org/COPYRIGHT. -# -# Licensed under the Apache License, Version 2.0 or the MIT license -# , at your -# option. This file may not be copied, modified, or distributed -# except according to those terms. - -set -ex - -ARCH=$1 -BINUTILS=2.25.1 -GCC=6.4.0 - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - $@ &> /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir binutils -cd binutils - -# First up, build binutils -curl https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS.tar.bz2 | tar xjf - -mkdir binutils-build -cd binutils-build -hide_output ../binutils-$BINUTILS/configure \ - --target=$ARCH-unknown-freebsd10 -hide_output make -j10 -hide_output make install -cd ../.. -rm -rf binutils - -# Next, download the FreeBSD libc and relevant header files - -mkdir freebsd -case "$ARCH" in - x86_64) - URL=ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/10.2-RELEASE/base.txz - ;; - i686) - URL=ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/10.2-RELEASE/base.txz - ;; -esac -curl $URL | tar xJf - -C freebsd ./usr/include ./usr/lib ./lib - -dst=/usr/local/$ARCH-unknown-freebsd10 - -cp -r freebsd/usr/include $dst/ -cp freebsd/usr/lib/crt1.o $dst/lib -cp freebsd/usr/lib/Scrt1.o $dst/lib -cp freebsd/usr/lib/crti.o $dst/lib -cp freebsd/usr/lib/crtn.o $dst/lib -cp freebsd/usr/lib/libc.a $dst/lib -cp freebsd/usr/lib/libutil.a $dst/lib -cp freebsd/usr/lib/libutil_p.a $dst/lib -cp freebsd/usr/lib/libm.a $dst/lib -cp freebsd/usr/lib/librt.so.1 $dst/lib -cp freebsd/usr/lib/libexecinfo.so.1 $dst/lib -cp freebsd/lib/libc.so.7 $dst/lib -cp freebsd/lib/libm.so.5 $dst/lib -cp freebsd/lib/libutil.so.9 $dst/lib -cp freebsd/lib/libthr.so.3 $dst/lib/libpthread.so - -ln -s libc.so.7 $dst/lib/libc.so -ln -s libm.so.5 $dst/lib/libm.so -ln -s librt.so.1 $dst/lib/librt.so -ln -s libutil.so.9 $dst/lib/libutil.so -ln -s libexecinfo.so.1 $dst/lib/libexecinfo.so -rm -rf freebsd - -# Finally, download and build gcc to target FreeBSD -mkdir gcc -cd gcc -curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.gz | tar xzf - -cd gcc-$GCC -./contrib/download_prerequisites - -mkdir ../gcc-build -cd ../gcc-build -hide_output ../gcc-$GCC/configure \ - --enable-languages=c,c++ \ - --target=$ARCH-unknown-freebsd10 \ - --disable-multilib \ - --disable-nls \ - --disable-libgomp \ - --disable-libquadmath \ - --disable-libssp \ - --disable-libvtv \ - --disable-libcilkrts \ - --disable-libada \ - --disable-libsanitizer \ - --disable-libquadmath-support \ - --disable-lto -hide_output make -j10 -hide_output make install -cd ../.. -rm -rf gcc diff --git a/src/ci/docker/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/dist-x86_64-freebsd/Dockerfile index b7c00df4db242..7483d395622c8 100644 --- a/src/ci/docker/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/dist-x86_64-freebsd/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:16.04 RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ + clang \ make \ file \ curl \ @@ -16,16 +16,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libssl-dev \ pkg-config -COPY dist-x86_64-freebsd/build-toolchain.sh /tmp/ -RUN /tmp/build-toolchain.sh x86_64 +COPY scripts/freebsd-toolchain.sh /tmp/ +RUN /tmp/freebsd-toolchain.sh x86_64 COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV \ AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd10-ar \ - CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd10-gcc \ - CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd10-g++ + CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd10-clang \ + CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd10-clang++ ENV HOSTS=x86_64-unknown-freebsd diff --git a/src/ci/docker/dist-x86_64-freebsd/build-toolchain.sh b/src/ci/docker/dist-x86_64-freebsd/build-toolchain.sh deleted file mode 100755 index 8343327c33bf2..0000000000000 --- a/src/ci/docker/dist-x86_64-freebsd/build-toolchain.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/bash -# Copyright 2016 The Rust Project Developers. See the COPYRIGHT -# file at the top-level directory of this distribution and at -# http://rust-lang.org/COPYRIGHT. -# -# Licensed under the Apache License, Version 2.0 or the MIT license -# , at your -# option. This file may not be copied, modified, or distributed -# except according to those terms. - -set -ex - -ARCH=$1 -BINUTILS=2.25.1 -GCC=6.4.0 - -hide_output() { - set +x - on_err=" -echo ERROR: An error was encountered with the build. -cat /tmp/build.log -exit 1 -" - trap "$on_err" ERR - bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & - PING_LOOP_PID=$! - $@ &> /tmp/build.log - trap - ERR - kill $PING_LOOP_PID - set -x -} - -mkdir binutils -cd binutils - -# First up, build binutils -curl https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS.tar.bz2 | tar xjf - -mkdir binutils-build -cd binutils-build -hide_output ../binutils-$BINUTILS/configure \ - --target=$ARCH-unknown-freebsd10 -hide_output make -j10 -hide_output make install -cd ../.. -rm -rf binutils - -# Next, download the FreeBSD libc and relevant header files - -mkdir freebsd -case "$ARCH" in - x86_64) - URL=ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/10.2-RELEASE/base.txz - ;; - i686) - URL=ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/10.2-RELEASE/base.txz - ;; -esac -curl $URL | tar xJf - -C freebsd ./usr/include ./usr/lib ./lib - -dst=/usr/local/$ARCH-unknown-freebsd10 - -cp -r freebsd/usr/include $dst/ -cp freebsd/usr/lib/crt1.o $dst/lib -cp freebsd/usr/lib/Scrt1.o $dst/lib -cp freebsd/usr/lib/crti.o $dst/lib -cp freebsd/usr/lib/crtn.o $dst/lib -cp freebsd/usr/lib/libc.a $dst/lib -cp freebsd/usr/lib/libutil.a $dst/lib -cp freebsd/usr/lib/libutil_p.a $dst/lib -cp freebsd/usr/lib/libm.a $dst/lib -cp freebsd/usr/lib/librt.so.1 $dst/lib -cp freebsd/usr/lib/libexecinfo.so.1 $dst/lib -cp freebsd/lib/libc.so.7 $dst/lib -cp freebsd/lib/libm.so.5 $dst/lib -cp freebsd/lib/libutil.so.9 $dst/lib -cp freebsd/lib/libthr.so.3 $dst/lib/libpthread.so - -ln -s libc.so.7 $dst/lib/libc.so -ln -s libm.so.5 $dst/lib/libm.so -ln -s librt.so.1 $dst/lib/librt.so -ln -s libutil.so.9 $dst/lib/libutil.so -ln -s libexecinfo.so.1 $dst/lib/libexecinfo.so -rm -rf freebsd - -# Finally, download and build gcc to target FreeBSD -mkdir gcc -cd gcc -curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.gz | tar xzf - -cd gcc-$GCC -./contrib/download_prerequisites - -mkdir ../gcc-build -cd ../gcc-build -hide_output ../gcc-$GCC/configure \ - --enable-languages=c,c++ \ - --target=$ARCH-unknown-freebsd10 \ - --disable-multilib \ - --disable-nls \ - --disable-libgomp \ - --disable-libquadmath \ - --disable-libssp \ - --disable-libvtv \ - --disable-libcilkrts \ - --disable-libada \ - --disable-libsanitizer \ - --disable-libquadmath-support \ - --disable-lto -hide_output make -j10 -hide_output make install -cd ../.. -rm -rf gcc diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh new file mode 100755 index 0000000000000..15ed318f8ce85 --- /dev/null +++ b/src/ci/docker/scripts/freebsd-toolchain.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# Copyright 2016-2017 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +set -eux + +arch=$1 +binutils_version=2.25.1 +freebsd_version=10.3 +triple=$arch-unknown-freebsd10 +sysroot=/usr/local/$triple + +hide_output() { + set +x + local on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + local ping_loop_pid=$! + $@ &> /tmp/build.log + trap - ERR + kill $ping_loop_pid + set -x +} + +# First up, build binutils +mkdir binutils +cd binutils +curl https://ftp.gnu.org/gnu/binutils/binutils-${binutils_version}.tar.bz2 | tar xjf - +mkdir binutils-build +cd binutils-build +hide_output ../binutils-${binutils_version}/configure \ + --target="$triple" --with-sysroot="$sysroot" +hide_output make -j"$(getconf _NPROCESSORS_ONLN)" +hide_output make install +cd ../.. +rm -rf binutils + +# Next, download the FreeBSD libraries and header files +mkdir -p "$sysroot" +case $arch in + (x86_64) freebsd_arch=amd64 ;; + (i686) freebsd_arch=i386 ;; +esac + +files_to_extract=( +"./usr/include" +"./usr/lib/*crt*.o" +) +# Try to unpack only the libraries the build needs, to save space. +for lib in c cxxrt gcc_s m thr util; do + files_to_extract=("${files_to_extract[@]}" "./lib/lib${lib}.*" "./usr/lib/lib${lib}.*") +done +for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared; do + files_to_extract=("${files_to_extract[@]}" "./usr/lib/lib${lib}.*") +done + +URL=https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz +curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}" + +# Fix up absolute symlinks from the system image. This can be removed +# for FreeBSD 11. (If there's an easy way to make them relative +# symlinks instead, feel free to change this.) +set +x +find "$sysroot" -type l | while read symlink_path; do + symlink_target=$(readlink "$symlink_path") + case $symlink_target in + (/*) + echo "Fixing symlink ${symlink_path} -> ${sysroot}${symlink_target}" >&2 + ln -nfs "${sysroot}${symlink_target}" "${symlink_path}" ;; + esac +done +set -x + +# Clang can do cross-builds out of the box, if we give it the right +# flags. (The local binutils seem to work, but they set the ELF +# header "OS/ABI" (EI_OSABI) field to SysV rather than FreeBSD, so +# there might be other problems.) +# +# The --target option is last because the cross-build of LLVM uses +# --target without an OS version ("-freebsd" vs. "-freebsd10"). This +# makes Clang default to libstdc++ (which no longer exists), and also +# controls other features, like GNU-style symbol table hashing and +# anything predicated on the version number in the __FreeBSD__ +# preprocessor macro. +for tool in clang clang++; do + tool_path=/usr/local/bin/${triple}-${tool} + cat > "$tool_path" <(T); + +fn must_be_valid(_t: T) { } + +fn main() { + // works + must_be_valid( MaybeValid(True) ); + + // compiler error - trait bound not satisfied + // must_be_valid( MaybeValid(False) ); +} +``` diff --git a/src/doc/unstable-book/src/language-features/unboxed-closures.md b/src/doc/unstable-book/src/language-features/unboxed-closures.md new file mode 100644 index 0000000000000..0eaed7a1989c5 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/unboxed-closures.md @@ -0,0 +1,25 @@ +# `unboxed_closures` + +The tracking issue for this feature is [#29625] + +See Also: [`fn_traits`](library-features/fn-traits.html) + +[#29625]: https://github.com/rust-lang/rust/issues/29625 + +---- + +The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI, +required for implmenting the [`Fn*`] family of traits. `"rust-call"` functions must have +exactly one (non self) argument, a tuple representing the argument list. + +[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html + +```rust +#![feature(unboxed_closures)] + +extern "rust-call" fn add_args(args: (u32, u32)) -> u32 { + args.0 + args.1 +} + +fn main() {} +``` diff --git a/src/doc/unstable-book/src/library-features/fn-traits.md b/src/doc/unstable-book/src/library-features/fn-traits.md new file mode 100644 index 0000000000000..72a3f36c10b69 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/fn-traits.md @@ -0,0 +1,35 @@ +# `fn_traits` + +The tracking issue for this feature is [#29625] + +See Also: [`unboxed_closures`](language-features/unboxed-closures.html) + +[#29625]: https://github.com/rust-lang/rust/issues/29625 + +---- + +The `fn_traits` feature allows for implementation of the [`Fn*`] traits +for creating custom closure-like types. + +[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html + +```rust +#![feature(unboxed_closures)] +#![feature(fn_traits)] + +struct Adder { + a: u32 +} + +impl FnOnce<(u32, )> for Adder { + type Output = u32; + extern "rust-call" fn call_once(self, b: (u32, )) -> Self::Output { + self.a + b.0 + } +} + +fn main() { + let adder = Adder { a: 3 }; + assert_eq!(adder(2), 5); +} +``` diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 1e45af5b105c9..c2ebb419e9e3d 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -261,6 +261,14 @@ pub struct Formatter<'a> { struct Void { _priv: (), + /// Erases all oibits, because `Void` erases the type of the object that + /// will be used to produce formatted output. Since we do not know what + /// oibits the real types have (and they can have any or none), we need to + /// take the most conservative approach and forbid all oibits. + /// + /// It was added after #45197 showed that one could share a `!Sync` + /// object across threads by passing it into `format_args!`. + _oibit_remover: PhantomData<*mut Fn()>, } /// This struct represents the generic "argument" which is taken by the Xprintf diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 0af9fcf0a3d3b..670c2afa66f85 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1405,16 +1405,6 @@ impl<'a> DoubleEndedIterator for LinesAny<'a> { #[allow(deprecated)] impl<'a> FusedIterator for LinesAny<'a> {} -/* -Section: Comparing strings -*/ - -/// Bytewise slice equality -#[inline] -fn eq_slice(a: &str, b: &str) -> bool { - a.as_bytes() == b.as_bytes() -} - /* Section: UTF-8 validation */ @@ -1590,7 +1580,6 @@ mod traits { use cmp::Ordering; use ops; use slice::{self, SliceIndex}; - use str::eq_slice; /// Implements ordering of strings. /// @@ -1611,7 +1600,7 @@ mod traits { impl PartialEq for str { #[inline] fn eq(&self, other: &str) -> bool { - eq_slice(self, other) + self.as_bytes() == other.as_bytes() } #[inline] fn ne(&self, other: &str) -> bool { !(*self).eq(other) } diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs index ce1a34faf5ee8..2221ecf07b434 100644 --- a/src/librustc/hir/itemlikevisit.rs +++ b/src/librustc/hir/itemlikevisit.rs @@ -41,7 +41,7 @@ use super::intravisit::Visitor; /// - Example: Lifetime resolution, which wants to bring lifetimes declared on the /// impl into scope while visiting the impl-items, and then back out again. /// - How: Implement `intravisit::Visitor` and override the -/// `visit_nested_map()` methods to return +/// `nested_visit_map()` methods to return /// `NestedVisitorMap::All`. Walk your crate with /// `intravisit::walk_crate()` invoked on `tcx.hir.krate()`. /// - Pro: Visitor methods for any kind of HIR node, not just item-like things. diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 75efe135f65e7..1b43970736468 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -254,6 +254,8 @@ fn main() { let stdcppname = if target.contains("openbsd") { // OpenBSD has a particular C++ runtime library name "estdc++" + } else if target.contains("freebsd") { + "c++" } else if target.contains("netbsd") && llvm_static_stdcpp.is_some() { // NetBSD uses a separate library when relocation is required "stdc++_pic" diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ff020445715d4..6dbda11e02122 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2960,6 +2960,7 @@ impl<'a> Parser<'a> { { // Foo>> err.help( "use `::<...>` instead of `<...>` if you meant to specify type arguments"); + err.help("or use `(...)` if you meant to specify fn arguments"); } err.emit(); } diff --git a/src/test/parse-fail/require-parens-for-chained-comparison.rs b/src/test/parse-fail/require-parens-for-chained-comparison.rs index 7e76dbd31f0a3..1ee6996ce9c84 100644 --- a/src/test/parse-fail/require-parens-for-chained-comparison.rs +++ b/src/test/parse-fail/require-parens-for-chained-comparison.rs @@ -21,5 +21,6 @@ fn main() { f(); //~^ ERROR: chained comparison operators require parentheses - //~^^ HELP: use `::<...>` instead of `<...>` + //~| HELP: use `::<...>` instead of `<...>` + //~| HELP: or use `(...)` } diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-allowed-cross-crate.rs b/src/test/run-pass/specialization/defaultimpl/allowed-cross-crate.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-allowed-cross-crate.rs rename to src/test/run-pass/specialization/defaultimpl/allowed-cross-crate.rs diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-assoc-fns.rs b/src/test/run-pass/specialization/defaultimpl/assoc-fns.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-assoc-fns.rs rename to src/test/run-pass/specialization/defaultimpl/assoc-fns.rs diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate.rs rename to src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate.rs diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate_defaults.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate_defaults.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate_defaults.rs rename to src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate_defaults.rs diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-basics-unsafe.rs b/src/test/run-pass/specialization/defaultimpl/basics-unsafe.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-basics-unsafe.rs rename to src/test/run-pass/specialization/defaultimpl/basics-unsafe.rs diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-basics.rs b/src/test/run-pass/specialization/defaultimpl/basics.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-basics.rs rename to src/test/run-pass/specialization/defaultimpl/basics.rs diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-defaults.rs b/src/test/run-pass/specialization/defaultimpl/cross-crate-defaults.rs similarity index 87% rename from src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-defaults.rs rename to src/test/run-pass/specialization/defaultimpl/cross-crate-defaults.rs index 62c7e3e2e4431..19e1af15bdd56 100644 --- a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-defaults.rs +++ b/src/test/run-pass/specialization/defaultimpl/cross-crate-defaults.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// aux-build:specialization_cross_crate_defaults.rs +// aux-build:cross_crate_defaults.rs #![feature(specialization)] -extern crate specialization_cross_crate_defaults; +extern crate cross_crate_defaults; -use specialization_cross_crate_defaults::*; +use cross_crate_defaults::*; struct LocalDefault; struct LocalOverride; diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-no-gate.rs b/src/test/run-pass/specialization/defaultimpl/cross-crate-no-gate.rs similarity index 89% rename from src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-no-gate.rs rename to src/test/run-pass/specialization/defaultimpl/cross-crate-no-gate.rs index b9548539e1649..67cc694ae12c7 100644 --- a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-no-gate.rs +++ b/src/test/run-pass/specialization/defaultimpl/cross-crate-no-gate.rs @@ -10,11 +10,11 @@ // Test that specialization works even if only the upstream crate enables it -// aux-build:specialization_cross_crate.rs +// aux-build:cross_crate.rs -extern crate specialization_cross_crate; +extern crate cross_crate; -use specialization_cross_crate::*; +use cross_crate::*; fn main() { assert!(0u8.foo() == "generic Clone"); diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate.rs b/src/test/run-pass/specialization/defaultimpl/cross-crate.rs similarity index 93% rename from src/test/run-pass/specialization/defaultimpl/specialization-cross-crate.rs rename to src/test/run-pass/specialization/defaultimpl/cross-crate.rs index 7517824b62bba..f1ad105db8f7c 100644 --- a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate.rs +++ b/src/test/run-pass/specialization/defaultimpl/cross-crate.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// aux-build:specialization_cross_crate.rs +// aux-build:cross_crate.rs #![feature(specialization)] -extern crate specialization_cross_crate; +extern crate cross_crate; -use specialization_cross_crate::*; +use cross_crate::*; struct NotClone; diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-default-methods.rs b/src/test/run-pass/specialization/defaultimpl/default-methods.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-default-methods.rs rename to src/test/run-pass/specialization/defaultimpl/default-methods.rs diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-out-of-order.rs b/src/test/run-pass/specialization/defaultimpl/out-of-order.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-out-of-order.rs rename to src/test/run-pass/specialization/defaultimpl/out-of-order.rs diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-overlap-projection.rs b/src/test/run-pass/specialization/defaultimpl/overlap-projection.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-overlap-projection.rs rename to src/test/run-pass/specialization/defaultimpl/overlap-projection.rs diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-projection-alias.rs b/src/test/run-pass/specialization/defaultimpl/projection-alias.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-projection-alias.rs rename to src/test/run-pass/specialization/defaultimpl/projection-alias.rs diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-projection.rs b/src/test/run-pass/specialization/defaultimpl/projection.rs similarity index 100% rename from src/test/run-pass/specialization/defaultimpl/specialization-projection.rs rename to src/test/run-pass/specialization/defaultimpl/projection.rs diff --git a/src/test/ui/did_you_mean/issue-40396.stderr b/src/test/ui/did_you_mean/issue-40396.stderr index 1a0c74dc01a09..11279f5c6129f 100644 --- a/src/test/ui/did_you_mean/issue-40396.stderr +++ b/src/test/ui/did_you_mean/issue-40396.stderr @@ -5,6 +5,7 @@ error: chained comparison operators require parentheses | ^^^^^^^^ | = help: use `::<...>` instead of `<...>` if you meant to specify type arguments + = help: or use `(...)` if you meant to specify fn arguments error: chained comparison operators require parentheses --> $DIR/issue-40396.rs:16:25 @@ -13,6 +14,7 @@ error: chained comparison operators require parentheses | ^^^^^^^ | = help: use `::<...>` instead of `<...>` if you meant to specify type arguments + = help: or use `(...)` if you meant to specify fn arguments error: chained comparison operators require parentheses --> $DIR/issue-40396.rs:20:37 @@ -21,6 +23,7 @@ error: chained comparison operators require parentheses | ^^^^^^^^ | = help: use `::<...>` instead of `<...>` if you meant to specify type arguments + = help: or use `(...)` if you meant to specify fn arguments error: chained comparison operators require parentheses --> $DIR/issue-40396.rs:20:41 @@ -29,6 +32,7 @@ error: chained comparison operators require parentheses | ^^^^^^ | = help: use `::<...>` instead of `<...>` if you meant to specify type arguments + = help: or use `(...)` if you meant to specify fn arguments error: aborting due to 4 previous errors diff --git a/src/test/ui/fmt/send-sync.rs b/src/test/ui/fmt/send-sync.rs new file mode 100644 index 0000000000000..bb4f9dfffc754 --- /dev/null +++ b/src/test/ui/fmt/send-sync.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn send(_: T) {} +fn sync(_: T) {} + +fn main() { + // `Cell` is not `Sync`, so `&Cell` is neither `Sync` nor `Send`, + // `std::fmt::Arguments` used to forget this... + let c = std::cell::Cell::new(42); + send(format_args!("{:?}", c)); + sync(format_args!("{:?}", c)); +} diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr new file mode 100644 index 0000000000000..1ec53d220e963 --- /dev/null +++ b/src/test/ui/fmt/send-sync.stderr @@ -0,0 +1,34 @@ +error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `[std::fmt::ArgumentV1<'_>]` + --> $DIR/send-sync.rs:18:5 + | +18 | send(format_args!("{:?}", c)); + | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely + | + = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static` + = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>` + = note: required because it appears within the type `core::fmt::Void` + = note: required because it appears within the type `&core::fmt::Void` + = note: required because it appears within the type `std::fmt::ArgumentV1<'_>` + = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` + = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]` + = note: required because it appears within the type `std::fmt::Arguments<'_>` + = note: required by `send` + +error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>` + --> $DIR/send-sync.rs:19:5 + | +19 | sync(format_args!("{:?}", c)); + | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely + | + = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static` + = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>` + = note: required because it appears within the type `core::fmt::Void` + = note: required because it appears within the type `&core::fmt::Void` + = note: required because it appears within the type `std::fmt::ArgumentV1<'_>` + = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` + = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]` + = note: required because it appears within the type `std::fmt::Arguments<'_>` + = note: required by `sync` + +error: aborting due to 2 previous errors +