diff --git a/README.md b/README.md index 40df6a4737871..f8d7692c7b2e4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ -# The Rust Programming Language +# The Rust Programming Language For Xtensa processors + +This fork enables projects to be built for the ESP32 and ESP8266 using [espressif's llvm fork](https://github.com/espressif/llvm-xtensa). The [esp-rs](https://github.com/esp-rs) organization has been formed to develop runtime, pac and hal crates for the esp32 and eventually esp8266. + +## Using this fork + +The [quickstart repo](https://github.com/MabezDev/xtensa-rust-quickstart) has more information on how to build this fork and use it to build xtensa compatible code. This is the main source code repository for [Rust]. It contains the compiler, standard library, and documentation. diff --git a/RELEASES.md b/RELEASES.md index 7ad739d06d54f..ecf49278f4b52 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,117 @@ +Version 1.38.0 (2019-09-26) +========================== + +Language +-------- +- [The `#[global_allocator]` attribute can now be used in submodules.][62735] +- [The `#[deprecated]` attribute can now be used on macros.][62042] + +Compiler +-------- +- [Added pipelined compilation support to `rustc`.][62766] This will + improve compilation times in some cases. For further information please refer + to the [_"Evaluating pipelined rustc compilation"_][pipeline-internals] thread. +- [Added tier 3\* support for the `aarch64-uwp-windows-msvc`, `i686-uwp-windows-gnu`, + `i686-uwp-windows-msvc`, `x86_64-uwp-windows-gnu`, and + `x86_64-uwp-windows-msvc` targets.][60260] +- [Added tier 3 support for the `armv7-unknown-linux-gnueabi` and + `armv7-unknown-linux-musleabi` targets.][63107] +- [Added tier 3 support for the `hexagon-unknown-linux-musl` target.][62814] +- [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784] + +\* Refer to Rust's [platform support page][forge-platform-support] for more +information on Rust's tiered platform support. + +Libraries +--------- +- [`ascii::EscapeDefault` now implements `Clone` and `Display`.][63421] +- [Derive macros for prelude traits (e.g. `Clone`, `Debug`, `Hash`) are now + available at the same path as the trait.][63056] (e.g. The `Clone` derive macro + is available at `std::clone::Clone`). This also makes all built-in macros + available in `std`/`core` root. e.g. `std::include_bytes!`. +- [`str::Chars` now implements `Debug`.][63000] +- [`slice::{concat, connect, join}` now accepts `&[T]` in addition to `&T`.][62528] +- [`*const T` and `*mut T` now implement `marker::Unpin`.][62583] +- [`Arc<[T]>` and `Rc<[T]>` now implement `FromIterator`.][61953] +- [Added euclidean remainder and division operations (`div_euclid`, + `rem_euclid`) to all numeric primitives.][61884] Additionally `checked`, + `overflowing`, and `wrapping` versions are available for all + integer primitives. +- [`thread::AccessError` now implements `Clone`, `Copy`, `Eq`, `Error`, and + `PartialEq`.][61491] +- [`iter::{StepBy, Peekable, Take}` now implement `DoubleEndedIterator`.][61457] + +Stabilized APIs +--------------- +- [`<*const T>::cast`] +- [`<*mut T>::cast`] +- [`Duration::as_secs_f32`] +- [`Duration::as_secs_f64`] +- [`Duration::div_duration_f32`] +- [`Duration::div_duration_f64`] +- [`Duration::div_f32`] +- [`Duration::div_f64`] +- [`Duration::from_secs_f32`] +- [`Duration::from_secs_f64`] +- [`Duration::mul_f32`] +- [`Duration::mul_f64`] +- [`any::type_name`] + +Cargo +----- +- [Added pipelined compilation support to `cargo`.][cargo/7143] +- [You can now pass the `--features` option multiple times to enable + multiple features.][cargo/7084] + +Misc +---- +- [`rustc` will now warn about some incorrect uses of + `mem::{uninitialized, zeroed}` that are known to cause undefined behaviour.][63346] + +Compatibility Notes +------------------- +- Unfortunately the [`x86_64-unknown-uefi` platform can not be built][62785] + with rustc 1.39.0. +- The [`armv7-unknown-linux-gnueabihf` platform is also known to have + issues][62896] for certain crates such as libc. + +[60260]: https://github.com/rust-lang/rust/pull/60260/ +[61457]: https://github.com/rust-lang/rust/pull/61457/ +[61491]: https://github.com/rust-lang/rust/pull/61491/ +[61884]: https://github.com/rust-lang/rust/pull/61884/ +[61953]: https://github.com/rust-lang/rust/pull/61953/ +[62042]: https://github.com/rust-lang/rust/pull/62042/ +[62528]: https://github.com/rust-lang/rust/pull/62528/ +[62583]: https://github.com/rust-lang/rust/pull/62583/ +[62735]: https://github.com/rust-lang/rust/pull/62735/ +[62766]: https://github.com/rust-lang/rust/pull/62766/ +[62784]: https://github.com/rust-lang/rust/pull/62784/ +[62785]: https://github.com/rust-lang/rust/issues/62785/ +[62814]: https://github.com/rust-lang/rust/pull/62814/ +[62896]: https://github.com/rust-lang/rust/issues/62896/ +[63000]: https://github.com/rust-lang/rust/pull/63000/ +[63056]: https://github.com/rust-lang/rust/pull/63056/ +[63107]: https://github.com/rust-lang/rust/pull/63107/ +[63346]: https://github.com/rust-lang/rust/pull/63346/ +[63421]: https://github.com/rust-lang/rust/pull/63421/ +[cargo/7084]: https://github.com/rust-lang/cargo/pull/7084/ +[cargo/7143]: https://github.com/rust-lang/cargo/pull/7143/ +[`<*const T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast +[`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast +[`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32 +[`Duration::as_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f64 +[`Duration::div_duration_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f32 +[`Duration::div_duration_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f64 +[`Duration::div_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f32 +[`Duration::div_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f64 +[`Duration::from_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f32 +[`Duration::from_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f64 +[`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32 +[`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64 +[`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html +[forge-platform-support]: https://forge.rust-lang.org/platform-support.html +[pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199 + Version 1.37.0 (2019-08-15) ========================== @@ -22,7 +136,7 @@ Language - [You can now use `_` as an identifier for consts.][61347] e.g. You can write `const _: u32 = 5;`. - [You can now use `#[repr(align(X)]` on enums.][61229] -- [The `?`/_"Kleene"_ macro operator is now available in the +- [The `?` Kleene macro operator is now available in the 2015 edition.][60932] Compiler diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index bd012a887c26e..552965863d10a 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -808,6 +808,7 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str] "llvm-project/lld", "llvm-project\\lld", "llvm-project/lldb", "llvm-project\\lldb", "llvm-project/llvm", "llvm-project\\llvm", + "llvm-project/compiler-rt", "llvm-project\\compiler-rt", ]; if spath.contains("llvm-project") && !spath.ends_with("llvm-project") && !LLVM_PROJECTS.iter().any(|path| spath.contains(path)) diff --git a/src/ci/awscli-requirements.txt b/src/ci/awscli-requirements.txt new file mode 100644 index 0000000000000..c1ffa525a1b41 --- /dev/null +++ b/src/ci/awscli-requirements.txt @@ -0,0 +1,13 @@ +awscli==1.16.201 +botocore==1.12.191 +colorama==0.3.9 +docutils==0.14 +jmespath==0.9.4 +pyasn1==0.4.5 +python-dateutil==2.8.0 +PyYAML==5.1 +rsa==3.4.2 +s3transfer==0.2.1 +six==1.12.0 +urllib3==1.25.3 +futures==3.3.0; python_version < '3.0' diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml index 687856cca6b62..2e6c3b7a992af 100644 --- a/src/ci/azure-pipelines/auto.yml +++ b/src/ci/azure-pipelines/auto.yml @@ -174,7 +174,7 @@ jobs: dist-x86_64-apple: SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc + RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --enable-lldb --set rust.jemalloc DEPLOY: 1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 @@ -184,7 +184,7 @@ jobs: dist-x86_64-apple-alt: SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc + RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --enable-lldb --set rust.jemalloc DEPLOY_ALT: 1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 @@ -202,7 +202,7 @@ jobs: dist-i686-apple: SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --build=i686-apple-darwin --enable-full-tools --enable-profiler --set rust.jemalloc + RUST_CONFIGURE_ARGS: --build=i686-apple-darwin --enable-full-tools --enable-profiler --enable-lldb --set rust.jemalloc DEPLOY: 1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 @@ -254,7 +254,7 @@ jobs: x86_64-msvc-tools: MSYS_BITS: 64 SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri # 32/64-bit MinGW builds. # diff --git a/src/ci/azure-pipelines/pr.yml b/src/ci/azure-pipelines/pr.yml index 62e23efe1ef16..88b5067b4a330 100644 --- a/src/ci/azure-pipelines/pr.yml +++ b/src/ci/azure-pipelines/pr.yml @@ -6,9 +6,6 @@ trigger: none pr: - master -variables: -- group: public-credentials - jobs: - job: Linux timeoutInMinutes: 600 @@ -23,13 +20,14 @@ jobs: mingw-check: IMAGE: mingw-check -- job: LinuxTools - timeoutInMinutes: 600 - pool: - vmImage: ubuntu-16.04 - steps: - - template: steps/run.yml - parameters: - only_on_updated_submodules: 'yes' - variables: - IMAGE: x86_64-gnu-tools +# TODO: enable this job if the commit message matches this regex, need tools +# figure out how to get the current commit message on azure and stick it in a +# condition somewhere +# if: commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri|cargo)\b)/ +# - job: Linux-x86_64-gnu-tools +# pool: +# vmImage: ubuntu-16.04 +# steps: +# - template: steps/run.yml +# variables: +# IMAGE: x86_64-gnu-tools diff --git a/src/ci/azure-pipelines/steps/install-clang.yml b/src/ci/azure-pipelines/steps/install-clang.yml index 45ec767e0b875..0cd6f24e32c7c 100644 --- a/src/ci/azure-pipelines/steps/install-clang.yml +++ b/src/ci/azure-pipelines/steps/install-clang.yml @@ -26,18 +26,12 @@ steps: # # Original downloaded here came from # http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.exe -# That installer was run through `wine` on Linux and then the resulting -# installation directory (found in `$HOME/.wine/drive_c/Program Files/LLVM`) was -# packaged up into a tarball. We've had issues otherwise that the installer will -# randomly hang, provide not a lot of useful information, pollute global state, -# etc. In general the tarball is just more confined and easier to deal with when -# working with various CI environments. -- bash: | - set -e - mkdir -p citools - cd citools - curl -f https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/LLVM-7.0.0-win64.tar.gz | tar xzf - - echo "##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]$RUST_CONFIGURE_ARGS --set llvm.clang-cl=`pwd`/clang-rust/bin/clang-cl.exe" +- script: | + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf %TEMP%\LLVM-7.0.0-win64.exe https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/LLVM-7.0.0-win64.exe" + set CLANG_DIR=%CD%\citools\clang-rust + %TEMP%\LLVM-7.0.0-win64.exe /S /NCRC /D=%CLANG_DIR% + set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --set llvm.clang-cl=%CLANG_DIR%\bin\clang-cl.exe + echo ##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]%RUST_CONFIGURE_ARGS% condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],'')) displayName: Install clang (Windows) diff --git a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml index c42c2311b493f..ed06679464c06 100644 --- a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml +++ b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml @@ -1,29 +1,4 @@ steps: -# We use the WIX toolset to create combined installers for Windows, and these -# binaries are downloaded from -# https://github.com/wixtoolset/wix3 originally -- bash: | - set -e - curl -O https://rust-lang-ci2.s3-us-west-1.amazonaws.com/rust-ci-mirror/wix311-binaries.zip - echo "##vso[task.setvariable variable=WIX]`pwd`/wix" - mkdir -p wix/bin - cd wix/bin - 7z x ../../wix311-binaries.zip - displayName: Install wix - condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) - -# We use InnoSetup and its `iscc` program to also create combined installers. -# Honestly at this point WIX above and `iscc` are just holdovers from -# oh-so-long-ago and are required for creating installers on Windows. I think -# one is MSI installers and one is EXE, but they're not used so frequently at -# this point anyway so perhaps it's a wash! -- script: | - powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf is-install.exe https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-08-22-is.exe" - is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- - echo ##vso[task.prependpath]C:\Program Files (x86)\Inno Setup 5 - displayName: Install InnoSetup - condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) - # We've had issues with the default drive in use running out of space during a # build, and it looks like the `C:` drive has more space than the default `D:` # drive. We should probably confirm this with the azure pipelines team at some diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml index ca32888b74c34..ab990575f93b3 100644 --- a/src/ci/azure-pipelines/steps/run.yml +++ b/src/ci/azure-pipelines/steps/run.yml @@ -6,11 +6,6 @@ # # Check travis config for `gdb --batch` command to print all crash logs -parameters: - # When this parameter is set to anything other than an empty string the tests - # will only be executed when the commit updates submodules - only_on_updated_submodules: '' - steps: # Disable automatic line ending conversion, which is enabled by default on @@ -26,22 +21,6 @@ steps: - checkout: self fetchDepth: 2 -# Set the SKIP_JOB environment variable if this job is supposed to only run -# when submodules are updated and they were not. The following time consuming -# tasks will be skipped when the environment variable is present. -- ${{ if parameters.only_on_updated_submodules }}: - - bash: | - set -e - # Submodules pseudo-files inside git have the 160000 permissions, so when - # those files are present in the diff a submodule was updated. - if git diff HEAD^ | grep "^index .* 160000" >/dev/null 2>&1; then - echo "Executing the job since submodules are updated" - else - echo "Not executing this job since no submodules were updated" - echo "##vso[task.setvariable variable=SKIP_JOB;]1" - fi - displayName: Decide whether to run this job - # Spawn a background process to collect CPU usage statistics which we'll upload # at the end of the build. See the comments in the script here for more # information. @@ -51,6 +30,10 @@ steps: - bash: printenv | sort displayName: Show environment variables +# Log the date, even on failure. Attempting to debug SSL certificate errors. +- bash: date + displayName: Print out date (before build) + - bash: | set -e df -h @@ -62,6 +45,17 @@ steps: - template: install-sccache.yml - template: install-clang.yml +# Install some dependencies needed to build LLDB/Clang, currently only needed +# during the `dist` target +- bash: | + set -e + brew update + brew install xz + brew install swig@3 + brew link --force swig@3 + displayName: Install build dependencies (OSX) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'), eq(variables['SCRIPT'],'./x.py dist')) + # Switch to XCode 9.3 on OSX since it seems to be the last version that supports # i686-apple-darwin. We'll eventually want to upgrade this and it will probably # force us to drop i686-apple-darwin, but let's keep the wheels turning for now. @@ -81,7 +75,7 @@ steps: echo '{"ipv6":true,"fixed-cidr-v6":"fd9a:8454:6789:13f7::/64"}' | sudo tee /etc/docker/daemon.json sudo service docker restart displayName: Enable IPv6 - condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['Agent.OS'], 'Linux')) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # Disable automatic line ending conversion (again). On Windows, when we're # installing dependencies, something switches the git configuration directory or @@ -97,12 +91,12 @@ steps: set -e mkdir -p $HOME/rustsrc $BUILD_SOURCESDIRECTORY/src/ci/init_repo.sh . $HOME/rustsrc - condition: and(succeeded(), not(variables.SKIP_JOB), ne(variables['Agent.OS'], 'Windows_NT')) + condition: and(succeeded(), ne(variables['Agent.OS'], 'Windows_NT')) displayName: Check out submodules (Unix) - script: | - if not exist C:\cache\rustsrc\NUL mkdir C:\cache\rustsrc - sh src/ci/init_repo.sh . /c/cache/rustsrc - condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['Agent.OS'], 'Windows_NT')) + if not exist D:\cache\rustsrc\NUL mkdir D:\cache\rustsrc + sh src/ci/init_repo.sh . /d/cache/rustsrc + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) displayName: Check out submodules (Windows) # See also the disable for autocrlf above, this just checks that it worked @@ -127,17 +121,21 @@ steps: # Ensure the `aws` CLI is installed so we can deploy later on, cache docker # images, etc. -- bash: src/ci/install-awscli.sh - env: - AGENT_OS: $(Agent.OS) - condition: and(succeeded(), not(variables.SKIP_JOB)) - displayName: Install awscli +- bash: | + set -e + source src/ci/shared.sh + sudo apt-get install -y python3-setuptools + retry pip3 install -r src/ci/awscli-requirements.txt --upgrade --user + echo "##vso[task.prependpath]$HOME/.local/bin" + displayName: Install awscli (Linux) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) +- script: pip install -r src/ci/awscli-requirements.txt + displayName: Install awscli (non-Linux) + condition: and(succeeded(), ne(variables['Agent.OS'], 'Linux')) # Configure our CI_JOB_NAME variable which log analyzers can use for the main # step to see what's going on. -- bash: | - builder=$(echo $AGENT_JOBNAME | cut -d ' ' -f 2) - echo "##vso[task.setvariable variable=CI_JOB_NAME]$builder" +- bash: echo "##vso[task.setvariable variable=CI_JOB_NAME]$SYSTEM_JOBNAME" displayName: Configure Job Name # As a quick smoke check on the otherwise very fast mingw-check linux builder @@ -149,7 +147,7 @@ steps: python2.7 "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" "" cd .. rm -rf rust-toolstate - condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['IMAGE'], 'mingw-check')) + condition: and(succeeded(), eq(variables['IMAGE'], 'mingw-check')) displayName: Verify the publish_toolstate script works - bash: | @@ -170,7 +168,6 @@ steps: SRC: . AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN) - condition: and(succeeded(), not(variables.SKIP_JOB)) displayName: Run build # If we're a deploy builder, use the `aws` command to publish everything to our @@ -193,7 +190,7 @@ steps: retry aws s3 cp --no-progress --recursive --acl public-read ./$upload_dir s3://$DEPLOY_BUCKET/$deploy_dir/$BUILD_SOURCEVERSION env: AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) - condition: and(succeeded(), not(variables.SKIP_JOB), or(eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1'))) + condition: and(succeeded(), or(eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1'))) displayName: Upload artifacts # Upload CPU usage statistics that we've been gathering this whole time. Always @@ -205,3 +202,8 @@ steps: condition: variables['AWS_SECRET_ACCESS_KEY'] continueOnError: true displayName: Upload CPU usage statistics + +# Log the date, even on failure. Attempting to debug SSL certificate errors. +- bash: date + continueOnError: true + displayName: Print out date (after build) diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml index 0df6c6c951f24..6a22e57c12406 100644 --- a/src/ci/azure-pipelines/try.yml +++ b/src/ci/azure-pipelines/try.yml @@ -36,7 +36,7 @@ jobs: # matrix: # dist-x86_64-apple: # SCRIPT: ./x.py dist -# RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc +# RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --enable-lldb --set rust.jemalloc # DEPLOY: 1 # RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 # MACOSX_DEPLOYMENT_TARGET: 10.7 @@ -46,7 +46,7 @@ jobs: # # dist-x86_64-apple-alt: # SCRIPT: ./x.py dist -# RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc +# RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --enable-lldb --set rust.jemalloc # DEPLOY_ALT: 1 # RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 # MACOSX_DEPLOYMENT_TARGET: 10.7 diff --git a/src/ci/docker/armhf-gnu/Dockerfile b/src/ci/docker/armhf-gnu/Dockerfile index 235920833f839..9493b33698708 100644 --- a/src/ci/docker/armhf-gnu/Dockerfile +++ b/src/ci/docker/armhf-gnu/Dockerfile @@ -72,7 +72,7 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static # TODO: What is this?! # Source of the file: https://github.com/vfdev-5/qemu-rpi2-vexpress/raw/master/vexpress-v2p-ca15-tc1.dtb -RUN curl -O https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/vexpress-v2p-ca15-tc1.dtb +RUN curl -O https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/vexpress-v2p-ca15-tc1.dtb COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/dist-various-1/install-mips-musl.sh b/src/ci/docker/dist-various-1/install-mips-musl.sh index 60a96e3b8e952..29cfb5d96083e 100755 --- a/src/ci/docker/dist-various-1/install-mips-musl.sh +++ b/src/ci/docker/dist-various-1/install-mips-musl.sh @@ -5,7 +5,7 @@ mkdir /usr/local/mips-linux-musl # originally from # https://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/ # OpenWrt-Toolchain-ar71xx-generic_gcc-5.3.0_musl-1.1.16.Linux-x86_64.tar.bz2 -URL="https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror" +URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc" FILE="OpenWrt-Toolchain-ar71xx-generic_gcc-5.3.0_musl-1.1.16.Linux-x86_64.tar.bz2" curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mips-linux-musl --strip-components=2 diff --git a/src/ci/docker/dist-various-1/install-mipsel-musl.sh b/src/ci/docker/dist-various-1/install-mipsel-musl.sh index 9ae41218ee4fb..de8c359d16757 100755 --- a/src/ci/docker/dist-various-1/install-mipsel-musl.sh +++ b/src/ci/docker/dist-various-1/install-mipsel-musl.sh @@ -5,7 +5,7 @@ mkdir /usr/local/mipsel-linux-musl # Note that this originally came from: # https://downloads.openwrt.org/snapshots/trunk/malta/generic/ # OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 -URL="https://rust-lang-ci2.s3.amazonaws.com/libc" +URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc" FILE="OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2" curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mipsel-linux-musl --strip-components=2 diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh index 7bf8946c4f136..f04ee78157167 100755 --- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh @@ -5,7 +5,7 @@ set -ex # Originally from https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz -curl https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/clang%2Bllvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \ +curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/clang%2Bllvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \ tar xJf - export PATH=`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH diff --git a/src/ci/docker/dist-x86_64-linux/build-openssl.sh b/src/ci/docker/dist-x86_64-linux/build-openssl.sh index 13dae6169053a..be8a6c93945e9 100755 --- a/src/ci/docker/dist-x86_64-linux/build-openssl.sh +++ b/src/ci/docker/dist-x86_64-linux/build-openssl.sh @@ -4,7 +4,7 @@ set -ex source shared.sh VERSION=1.0.2k -URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/openssl-$VERSION.tar.gz +URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/openssl-$VERSION.tar.gz curl $URL | tar xzf - diff --git a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh index 2e9b9dcc2344e..797f674b954f2 100755 --- a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh +++ b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh @@ -25,7 +25,7 @@ cd netbsd mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot -URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror +URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc # Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/source/sets/*.tgz curl $URL/2018-03-01-netbsd-src.tgz | tar xzf - diff --git a/src/ci/docker/scripts/android-sdk-manager.py b/src/ci/docker/scripts/android-sdk-manager.py index 7c9a8b82e9282..c9e2961f6eb15 100755 --- a/src/ci/docker/scripts/android-sdk-manager.py +++ b/src/ci/docker/scripts/android-sdk-manager.py @@ -23,8 +23,9 @@ HOST_OS = "linux" # Mirroring options -MIRROR_BUCKET = "rust-lang-ci2" -MIRROR_BASE_DIR = "rust-ci-mirror/android/" +MIRROR_BUCKET = "rust-lang-ci-mirrors" +MIRROR_BUCKET_REGION = "us-west-1" +MIRROR_BASE_DIR = "rustc/android/" import argparse import hashlib @@ -144,7 +145,8 @@ def cli_install(args): lockfile = Lockfile(args.lockfile) for package in lockfile.packages.values(): # Download the file from the mirror into a temp file - url = "https://" + MIRROR_BUCKET + ".s3.amazonaws.com/" + MIRROR_BASE_DIR + url = "https://" + MIRROR_BUCKET + ".s3-" + MIRROR_BUCKET_REGION + \ + ".amazonaws.com/" + MIRROR_BASE_DIR downloaded = package.download(url) # Extract the file in a temporary directory extract_dir = tempfile.mkdtemp() diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh index 8cef69d9c26bb..70155e770a960 100755 --- a/src/ci/docker/scripts/freebsd-toolchain.sh +++ b/src/ci/docker/scripts/freebsd-toolchain.sh @@ -59,7 +59,7 @@ done # Originally downloaded from: # https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz -URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2019-04-04-freebsd-${freebsd_arch}-${freebsd_version}-RELEASE-base.txz +URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2019-04-04-freebsd-${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 diff --git a/src/ci/docker/scripts/sccache.sh b/src/ci/docker/scripts/sccache.sh index 194de3c339f8c..efeb0ed0d72d0 100644 --- a/src/ci/docker/scripts/sccache.sh +++ b/src/ci/docker/scripts/sccache.sh @@ -1,6 +1,6 @@ set -ex curl -fo /usr/local/bin/sccache \ - https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-02-sccache-x86_64-unknown-linux-musl + https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-02-sccache-x86_64-unknown-linux-musl chmod +x /usr/local/bin/sccache diff --git a/src/ci/install-awscli.sh b/src/ci/install-awscli.sh index d491b9fbcdcf8..69c8d2e3099ab 100755 --- a/src/ci/install-awscli.sh +++ b/src/ci/install-awscli.sh @@ -16,7 +16,7 @@ set -euo pipefail IFS=$'\n\t' -MIRROR="https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2019-07-27-awscli.tar" +MIRROR="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2019-07-27-awscli.tar" DEPS_DIR="/tmp/awscli-deps" pip="pip" diff --git a/src/ci/run.sh b/src/ci/run.sh index f1eb417cdf982..a61e90b0af76a 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -45,7 +45,7 @@ fi # # FIXME: need a scheme for changing this `nightly` value to `beta` and `stable` # either automatically or manually. -export RUST_RELEASE_CHANNEL=nightly +export RUST_RELEASE_CHANNEL=stable if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp" diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md index 2ae726c4ba61d..6f1bbe60569fd 100644 --- a/src/doc/rustc/src/linker-plugin-lto.md +++ b/src/doc/rustc/src/linker-plugin-lto.md @@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions. | Rust 1.34 | ✗ | ✓ | | Rust 1.35 | ✗ | ✓ | | Rust 1.36 | ✗ | ✓ | +| Rust 1.37 | ✗ | ✓ | Note that the compatibility policy for this feature might change in the future. diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index f9dc53874acb1..680fcd12c4f2b 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -1281,8 +1281,10 @@ pub(crate) mod builtin { pub macro test($item:item) { /* compiler built-in */ } /// Attribute macro applied to a function to turn it into a benchmark test. - #[unstable(feature = "test", issue = "50297", - reason = "`bench` is a part of custom test frameworks which are unstable")] + #[cfg_attr(not(boostrap_stdarch_ignore_this), unstable(soft, feature = "test", issue = "50297", + reason = "`bench` is a part of custom test frameworks which are unstable"))] + #[cfg_attr(boostrap_stdarch_ignore_this, unstable(feature = "test", issue = "50297", + reason = "`bench` is a part of custom test frameworks which are unstable"))] #[allow_internal_unstable(test, rustc_attrs)] #[rustc_builtin_macro] #[rustc_macro_transparency = "semitransparent"] diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 5cc8324b31606..daa69efe2849d 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -136,9 +136,10 @@ for ::syntax::attr::StabilityLevel { hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => { + ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue, ref is_soft } => { reason.hash_stable(hcx, hasher); issue.hash_stable(hcx, hasher); + is_soft.hash_stable(hcx, hasher); } ::syntax::attr::StabilityLevel::Stable { ref since } => { since.hash_stable(hcx, hasher); diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 6d9a6bb77dd55..dd290572d7bb7 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -395,6 +395,12 @@ declare_lint! { "reservation of a two-phased borrow conflicts with other shared borrows" } +declare_lint! { + pub SOFT_UNSTABLE, + Deny, + "a feature gate that doesn't break dependent crates" +} + declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. @@ -460,6 +466,7 @@ declare_lint_pass! { NESTED_IMPL_TRAIT, MUTABLE_BORROW_RESERVATION_CONFLICT, INDIRECT_STRUCTURAL_MATCH, + SOFT_UNSTABLE, ] } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 5ab762ab225f9..0d22c37cd6d71 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -438,6 +438,7 @@ impl<'tcx> Index<'tcx> { level: attr::StabilityLevel::Unstable { reason: Some(Symbol::intern(reason)), issue: 27812, + is_soft: false, }, feature: sym::rustc_private, rustc_depr: None, @@ -480,7 +481,7 @@ pub fn provide(providers: &mut Providers<'_>) { } pub fn report_unstable( - sess: &Session, feature: Symbol, reason: Option, issue: u32, span: Span + sess: &Session, feature: Symbol, reason: Option, issue: u32, is_soft: bool, span: Span ) { let msg = match reason { Some(r) => format!("use of unstable library feature '{}': {}", feature, r), @@ -505,7 +506,13 @@ pub fn report_unstable( let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id); if fresh { - emit_feature_err(&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg); + if is_soft { + sess.buffer_lint(lint::builtin::SOFT_UNSTABLE, CRATE_NODE_ID, span, &msg); + } else { + emit_feature_err( + &sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg + ); + } } } @@ -621,6 +628,7 @@ pub enum EvalResult { feature: Symbol, reason: Option, issue: u32, + is_soft: bool, }, /// The item does not have the `#[stable]` or `#[unstable]` marker assigned. Unmarked, @@ -720,7 +728,9 @@ impl<'tcx> TyCtxt<'tcx> { } match stability { - Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => { + Some(&Stability { + level: attr::Unstable { reason, issue, is_soft }, feature, .. + }) => { if span.allows_unstable(feature) { debug!("stability: skipping span={:?} since it is internal", span); return EvalResult::Allow; @@ -744,7 +754,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - EvalResult::Deny { feature, reason, issue } + EvalResult::Deny { feature, reason, issue, is_soft } } Some(_) => { // Stable APIs are always ok to call and deprecated APIs are @@ -767,8 +777,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn check_stability(self, def_id: DefId, id: Option, span: Span) { match self.eval_stability(def_id, id, span) { EvalResult::Allow => {} - EvalResult::Deny { feature, reason, issue } => - report_unstable(self.sess, feature, reason, issue, span), + EvalResult::Deny { feature, reason, issue, is_soft } => + report_unstable(self.sess, feature, reason, issue, is_soft, span), EvalResult::Unmarked => { // The API could be uncallable for other reasons, for example when a private module // was referenced. diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 51e789b17880a..928532a1f4760 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -683,11 +683,13 @@ pub fn type_metadata( } ty::Closure(def_id, substs) => { let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect(); + let containing_scope = get_namespace_for_item(cx, def_id); prepare_tuple_metadata(cx, t, &upvar_tys, unique_type_id, - usage_site_span).finalize(cx) + usage_site_span, + Some(containing_scope)).finalize(cx) } ty::Generator(def_id, substs, _) => { let upvar_tys : Vec<_> = substs.prefix_tys(def_id, cx.tcx).map(|t| { @@ -728,7 +730,8 @@ pub fn type_metadata( t, &tys, unique_type_id, - usage_site_span).finalize(cx) + usage_site_span, + NO_SCOPE_METADATA).finalize(cx) } _ => { bug!("debuginfo: unexpected type in type_metadata: {:?}", t) @@ -1205,6 +1208,7 @@ fn prepare_tuple_metadata( component_types: &[Ty<'tcx>], unique_type_id: UniqueTypeId, span: Span, + containing_scope: Option<&'ll DIScope>, ) -> RecursiveTypeDescription<'ll, 'tcx> { let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false); @@ -1212,7 +1216,7 @@ fn prepare_tuple_metadata( tuple_type, &tuple_name[..], unique_type_id, - NO_SCOPE_METADATA); + containing_scope); create_and_register_recursive_type_forward_declaration( cx, diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs index ea39913d4b91b..9b5ad94ecd7cb 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs @@ -190,11 +190,17 @@ pub fn push_debuginfo_type_name<'tcx>( // processing visited.remove(t); }, - ty::Closure(..) => { - output.push_str("closure"); + ty::Closure(def_id, ..) => { + output.push_str(&format!( + "closure-{}", + tcx.def_key(def_id).disambiguated_data.disambiguator + )); } - ty::Generator(..) => { - output.push_str("generator"); + ty::Generator(def_id, ..) => { + output.push_str(&format!( + "generator-{}", + tcx.def_key(def_id).disambiguated_data.disambiguator + )); } ty::Error | ty::Infer(_) | diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 3a540fdf4b91f..5648f9d0fdb3c 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -433,7 +433,12 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(INDIRECT_STRUCTURAL_MATCH), reference: "issue #62411 ", edition: None, - } + }, + FutureIncompatibleInfo { + id: LintId::of(SOFT_UNSTABLE), + reference: "issue #64266 ", + edition: None, + }, ]); // Register renamed and removed lints. diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 16cdbb7dd4d39..ede714f1c2d39 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -72,7 +72,7 @@ fn main() { let mut optional_components = vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc", "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx", - "hexagon"]; + "hexagon", "xtensa"]; let mut version_cmd = Command::new(&llvm_config); version_cmd.arg("--version"); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 647d473f01572..75e020ee45f07 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -105,4 +105,11 @@ pub fn initialize_available_targets() { LLVMInitializeWebAssemblyTarget, LLVMInitializeWebAssemblyTargetMC, LLVMInitializeWebAssemblyAsmPrinter); + init_target!(llvm_component = "xtensa", + LLVMInitializeXtensaTargetInfo, + LLVMInitializeXtensaTarget, + LLVMInitializeXtensaTargetMC, + LLVMInitializeXtensaAsmPrinter, + LLVMInitializeXtensaAsmParser); + } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 4e970aee42cf4..6a3bb8b8b86a2 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -502,7 +502,7 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool { // This is a special case: some functions have a C abi but are meant to // unwind anyway. Don't stop them. match unwind_attr { - None => true, + None => false, // FIXME(#58794) Some(UnwindAttr::Allowed) => false, Some(UnwindAttr::Aborts) => true, } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 5ecfb84b63236..c82bb5d2ed710 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -1203,7 +1203,13 @@ fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>, ty::RawPtr(..) => { // `#[structural_match]` ignores substructure of // `*const _`/`*mut _`, so skip super_visit_with - + // + // (But still tell caller to continue search.) + return false; + } + ty::FnDef(..) | ty::FnPtr(..) => { + // types of formals and return in `fn(_) -> _` are also irrelevant + // // (But still tell caller to continue search.) return false; } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 8e9e1380002cf..50ab0749d7f32 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -182,6 +182,10 @@ impl<'a> base::Resolver for Resolver<'a> { fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool) -> Result>, Indeterminate> { + if !self.invocations.contains_key(&invoc.expansion_data.id) { + self.invocations.insert(invoc.expansion_data.id, self.invocations[&invoc_id]); + } + let invoc_id = invoc.expansion_data.id; let (path, kind, derives_in_scope, after_derive) = match invoc.kind { InvocationKind::Attr { ref attr, ref derives, after_derive, .. } => (&attr.path, MacroKind::Attr, derives.clone(), after_derive), @@ -201,7 +205,7 @@ impl<'a> base::Resolver for Resolver<'a> { match self.resolve_macro_path(path, Some(MacroKind::Derive), parent_scope, true, force) { Ok((Some(ref ext), _)) if ext.is_derive_copy => { - self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY); + self.add_derives(invoc_id, SpecialDerives::COPY); return Ok(None); } Err(Determinacy::Undetermined) => result = Err(Indeterminate), @@ -217,17 +221,15 @@ impl<'a> base::Resolver for Resolver<'a> { let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); - invoc.expansion_data.id.set_expn_info(ext.expn_info(span, fast_print_path(path))); + invoc_id.set_expn_info(ext.expn_info(span, fast_print_path(path))); if let Res::Def(_, def_id) = res { if after_derive { self.session.span_err(span, "macro attributes must be placed before `#[derive]`"); } - self.macro_defs.insert(invoc.expansion_data.id, def_id); - let normal_module_def_id = - self.macro_def_scope(invoc.expansion_data.id).normal_ancestor_id; - self.definitions.add_parent_module_of_macro_def(invoc.expansion_data.id, - normal_module_def_id); + self.macro_defs.insert(invoc_id, def_id); + let normal_module_def_id = self.macro_def_scope(invoc_id).normal_ancestor_id; + self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id); } Ok(Some(ext)) @@ -795,10 +797,10 @@ impl<'a> Resolver<'a> { fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &ast::Path) { let span = path.span; if let Some(stability) = &ext.stability { - if let StabilityLevel::Unstable { reason, issue } = stability.level { + if let StabilityLevel::Unstable { reason, issue, is_soft } = stability.level { let feature = stability.feature; if !self.active_features.contains(&feature) && !span.allows_unstable(feature) { - stability::report_unstable(self.session, feature, reason, issue, span); + stability::report_unstable(self.session, feature, reason, issue, is_soft, span); } } if let Some(depr) = &stability.rustc_depr { diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index fbbd120f934be..9746d76a6b7f4 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -22,6 +22,7 @@ mod x86; mod x86_64; mod x86_win64; mod wasm32; +mod xtensa; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum IgnoreMode { @@ -581,6 +582,7 @@ impl<'a, Ty> FnType<'a, Ty> { "hexagon" => hexagon::compute_abi_info(self), "riscv32" => riscv::compute_abi_info(self, 32), "riscv64" => riscv::compute_abi_info(self, 64), + "xtensa" => xtensa::compute_abi_info(self, 32), a => return Err(format!("unrecognized arch \"{}\" in target specification", a)) } diff --git a/src/librustc_target/abi/call/xtensa.rs b/src/librustc_target/abi/call/xtensa.rs new file mode 100644 index 0000000000000..6a46b8a547141 --- /dev/null +++ b/src/librustc_target/abi/call/xtensa.rs @@ -0,0 +1,113 @@ +// reference: https://github.com/espressif/clang-xtensa/commit/6fb488d2553f06029e6611cf81c6efbd45b56e47#diff-aa74ae1e1ab6b7149789237edb78e688R8450 + + +use crate::abi::call::{ArgType, FnType, Reg, Uniform}; + +const NUM_ARG_GPR: u64 = 6; +const MAX_ARG_IN_REGS_SIZE: u64 = 4 * 32; +// const MAX_ARG_DIRECT_SIZE: u64 = MAX_ARG_IN_REGS_SIZE; +const MAX_RET_IN_REGS_SIZE: u64 = 2 * 32; + +fn classify_ret_ty(arg: &mut ArgType<'_, Ty>, xlen: u64) { + // The rules for return and argument types are the same, so defer to + // classifyArgumentType. + classify_arg_ty(arg, xlen, &mut 2); // two as max return size +} + + +fn classify_arg_ty(arg: &mut ArgType<'_, Ty>, xlen: u64, remaining_gpr: &mut u64) { + // Determine the number of GPRs needed to pass the current argument + // according to the ABI. 2*XLen-aligned varargs are passed in "aligned" + // register pairs, so may consume 3 registers. + + let arg_size = arg.layout.size; + if arg_size.bits() > MAX_ARG_IN_REGS_SIZE { + arg.make_indirect(); + return; + } + + let alignment = arg.layout.details.align.abi; + let mut required_gpr = 1u64; // at least one per arg + + if alignment.bits() == 2 * xlen { + required_gpr = 2 + (*remaining_gpr % 2); + } else if arg_size.bits() > xlen && arg_size.bits() <= MAX_ARG_IN_REGS_SIZE { + required_gpr = (arg_size.bits() + (xlen - 1)) / xlen; + } + + let mut stack_required = false; + if required_gpr > *remaining_gpr { + stack_required = true; + required_gpr = *remaining_gpr; + } + *remaining_gpr -= required_gpr; + + // if a value can fit in a reg and the + // stack is not required, extend + if !arg.layout.is_aggregate() { // non-aggregate types + if arg_size.bits() < xlen && !stack_required { + arg.extend_integer_width_to(xlen); + } + } else if arg_size.bits() as u64 <= MAX_ARG_IN_REGS_SIZE { // aggregate types + // Aggregates which are <= 4*32 will be passed in registers if possible, + // so coerce to integers. + + // Use a single XLen int if possible, 2*XLen if 2*XLen alignment is + // required, and a 2-element XLen array if only XLen alignment is + // required. + // if alignment == 2 * xlen { + // arg.extend_integer_width_to(xlen * 2); + // } else { + // arg.extend_integer_width_to(arg_size + (xlen - 1) / xlen); + // } + if alignment.bits() == 2 * xlen { + arg.cast_to(Uniform { + unit: Reg::i64(), + total: arg_size + }); + } else { + //TODO array type - this should be a homogenous array type + // arg.extend_integer_width_to(arg_size + (xlen - 1) / xlen); + } + + } else { + // if we get here the stack is required + assert!(stack_required); + arg.make_indirect(); + } + + + // if arg_size as u64 <= MAX_ARG_IN_REGS_SIZE { + // let align = arg.layout.align.abi.bytes(); + // let total = arg.layout.size; + // arg.cast_to(Uniform { + // unit: if align <= 4 { Reg::i32() } else { Reg::i64() }, + // total + // }); + // return; + // } + + +} + +pub fn compute_abi_info(fty: &mut FnType<'_, Ty>, xlen: u64) { + if !fty.ret.is_ignore() { + classify_ret_ty(&mut fty.ret, xlen); + } + + let return_indirect = fty.ret.layout.size.bits() > MAX_RET_IN_REGS_SIZE || + fty.ret.is_indirect(); + + let mut remaining_gpr = if return_indirect { + NUM_ARG_GPR - 1 + } else { + NUM_ARG_GPR + }; + + for arg in &mut fty.args { + if arg.is_ignore() { + continue; + } + classify_arg_ty(arg, xlen, &mut remaining_gpr); + } +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index ec72c00c28f61..84e647284105e 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -462,6 +462,8 @@ supported_targets! { ("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf), ("msp430-none-elf", msp430_none_elf), + ("xtensa-esp32-none-elf", xtensa_esp32_none_elf), + ("xtensa-esp8266-none-elf", xtensa_esp8266_none_elf), ("aarch64-unknown-cloudabi", aarch64_unknown_cloudabi), ("armv7-unknown-cloudabi-eabihf", armv7_unknown_cloudabi_eabihf), diff --git a/src/librustc_target/spec/xtensa_esp32_none_elf.rs b/src/librustc_target/spec/xtensa_esp32_none_elf.rs new file mode 100644 index 0000000000000..8402f1a3663fa --- /dev/null +++ b/src/librustc_target/spec/xtensa_esp32_none_elf.rs @@ -0,0 +1,66 @@ +use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult, abi::Abi}; +// use crate::spec::abi::Abi; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "xtensa-none-elf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32".to_string(), + arch: "xtensa".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Gcc, + + options: TargetOptions { + executables: true, + cpu: "esp32".to_string(), + // The LLVM backend currently can't generate object files. To + // workaround this LLVM generates assembly files which then we feed + // to gcc to get object files. For this reason we have a hard + // dependency on this specific gcc. + // asm_args: vec!["-mcpu=esp32".to_string()], + linker: Some("xtensa-esp32-elf-gcc".to_string()), + no_integrated_as: true, + + max_atomic_width: Some(32), + atomic_cas: true, + + // Because these devices have very little resources having an + // unwinder is too onerous so we default to "abort" because the + // "unwind" strategy is very rare. + panic_strategy: PanicStrategy::Abort, + + // Similarly, one almost always never wants to use relocatable + // code because of the extra costs it involves. + relocation_model: "static".to_string(), + + // Right now we invoke an external assembler and this isn't + // compatible with multiple codegen units, and plus we probably + // don't want to invoke that many gcc instances. + default_codegen_units: Some(1), + + // Since MSP430 doesn't meaningfully support faulting on illegal + // instructions, LLVM generates a call to abort() function instead + // of a trap instruction. Such calls are 4 bytes long, and that is + // too much overhead for such small target. + trap_unreachable: false, + + // See the thumb_base.rs file for an explanation of this value + emit_debug_gdb_scripts: false, + + abi_blacklist: vec![ + Abi::Stdcall, + Abi::Fastcall, + Abi::Vectorcall, + Abi::Thiscall, + Abi::Win64, + Abi::SysV64, + ], + + .. Default::default( ) + } + }) +} diff --git a/src/librustc_target/spec/xtensa_esp8266_none_elf.rs b/src/librustc_target/spec/xtensa_esp8266_none_elf.rs new file mode 100644 index 0000000000000..9b8b2fe63cffe --- /dev/null +++ b/src/librustc_target/spec/xtensa_esp8266_none_elf.rs @@ -0,0 +1,66 @@ +use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult, abi::Abi}; +// use crate::spec::abi::Abi; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "xtensa-none-elf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32".to_string(), + arch: "xtensa".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Gcc, + + options: TargetOptions { + executables: true, + cpu: "esp8266".to_string(), + // The LLVM backend currently can't generate object files. To + // workaround this LLVM generates assembly files which then we feed + // to gcc to get object files. For this reason we have a hard + // dependency on this specific gcc. + // asm_args: vec!["-mcpu=esp8266".to_string()], + linker: Some("xtensa-esp32-elf-gcc".to_string()), + no_integrated_as: true, + + max_atomic_width: Some(32), + atomic_cas: true, + + // Because these devices have very little resources having an + // unwinder is too onerous so we default to "abort" because the + // "unwind" strategy is very rare. + panic_strategy: PanicStrategy::Abort, + + // Similarly, one almost always never wants to use relocatable + // code because of the extra costs it involves. + relocation_model: "static".to_string(), + + // Right now we invoke an external assembler and this isn't + // compatible with multiple codegen units, and plus we probably + // don't want to invoke that many gcc instances. + default_codegen_units: Some(1), + + // Since MSP430 doesn't meaningfully support faulting on illegal + // instructions, LLVM generates a call to abort() function instead + // of a trap instruction. Such calls are 4 bytes long, and that is + // too much overhead for such small target. + trap_unreachable: false, + + // See the thumb_base.rs file for an explanation of this value + emit_debug_gdb_scripts: false, + + abi_blacklist: vec![ + Abi::Stdcall, + Abi::Fastcall, + Abi::Vectorcall, + Abi::Thiscall, + Abi::Win64, + Abi::SysV64, + ], + + .. Default::default( ) + } + }) +} diff --git a/src/librustc_target/spec/xtensa_none_elf.rs b/src/librustc_target/spec/xtensa_none_elf.rs new file mode 100644 index 0000000000000..afd043cf9047e --- /dev/null +++ b/src/librustc_target/spec/xtensa_none_elf.rs @@ -0,0 +1,66 @@ +use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult, abi::Abi}; +// use crate::spec::abi::Abi; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "xtensa-none-elf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32".to_string(), + arch: "xtensa".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Gcc, + + options: TargetOptions { + executables: true, + + // The LLVM backend currently can't generate object files. To + // workaround this LLVM generates assembly files which then we feed + // to gcc to get object files. For this reason we have a hard + // dependency on this specific gcc. + // asm_args: vec!["-mcpu=generic".to_string()], + linker: Some("xtensa-esp32-elf-gcc".to_string()), + no_integrated_as: true, + + max_atomic_width: Some(32), + atomic_cas: true, + + // Because these devices have very little resources having an + // unwinder is too onerous so we default to "abort" because the + // "unwind" strategy is very rare. + panic_strategy: PanicStrategy::Abort, + + // Similarly, one almost always never wants to use relocatable + // code because of the extra costs it involves. + relocation_model: "static".to_string(), + + // Right now we invoke an external assembler and this isn't + // compatible with multiple codegen units, and plus we probably + // don't want to invoke that many gcc instances. + default_codegen_units: Some(1), + + // Since MSP430 doesn't meaningfully support faulting on illegal + // instructions, LLVM generates a call to abort() function instead + // of a trap instruction. Such calls are 4 bytes long, and that is + // too much overhead for such small target. + trap_unreachable: false, + + // See the thumb_base.rs file for an explanation of this value + emit_debug_gdb_scripts: false, + + abi_blacklist: vec![ + Abi::Stdcall, + Abi::Fastcall, + Abi::Vectorcall, + Abi::Thiscall, + Abi::Win64, + Abi::SysV64, + ], + + .. Default::default( ) + } + }) +} diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 357e17d2d1bc4..67aa014a788f2 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { // We couldn't calculate the span of the markdown block that had the error, so our // diagnostics are going to be a bit lacking. let mut diag = self.cx.sess().struct_span_warn( - super::span_of_attrs(&item.attrs), + super::span_of_attrs(&item.attrs).unwrap_or(item.source.span()), "doc comment contains an invalid Rust code block", ); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 5c9fac7eab421..7f4a17225e644 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -464,7 +464,7 @@ fn resolution_failure( } }; let attrs = &item.attrs; - let sp = span_of_attrs(attrs); + let sp = span_of_attrs(attrs).unwrap_or(item.source.span()); let mut diag = cx.tcx.struct_span_lint_hir( lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, @@ -516,7 +516,7 @@ fn ambiguity_error( } }; let attrs = &item.attrs; - let sp = span_of_attrs(attrs); + let sp = span_of_attrs(attrs).unwrap_or(item.source.span()); let mut msg = format!("`{}` is ", path_str); diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 641a6df221446..49a34c7e46281 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -339,7 +339,7 @@ pub fn look_for_tests<'tcx>( find_testable_code(&dox, &mut tests, ErrorCodes::No); if check_missing_code == true && tests.found_tests == 0 { - let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span()); + let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span()); let mut diag = cx.tcx.struct_span_lint_hir( lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id, @@ -352,20 +352,23 @@ pub fn look_for_tests<'tcx>( let mut diag = cx.tcx.struct_span_lint_hir( lint::builtin::PRIVATE_DOC_TESTS, hir_id, - span_of_attrs(&item.attrs), + span_of_attrs(&item.attrs).unwrap_or(item.source.span()), "Documentation test in private item"); diag.emit(); } } /// Returns a span encompassing all the given attributes. -crate fn span_of_attrs(attrs: &clean::Attributes) -> Span { +crate fn span_of_attrs(attrs: &clean::Attributes) -> Option { if attrs.doc_strings.is_empty() { - return DUMMY_SP; + return None; } let start = attrs.doc_strings[0].span(); + if start == DUMMY_SP { + return None; + } let end = attrs.doc_strings.last().expect("No doc strings provided").span(); - start.to(end) + Some(start.to(end)) } /// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code. @@ -391,7 +394,7 @@ crate fn source_span_for_markdown_range( let snippet = cx .sess() .source_map() - .span_to_snippet(span_of_attrs(attrs)) + .span_to_snippet(span_of_attrs(attrs)?) .ok()?; let starting_line = markdown[..md_range.start].matches('\n').count(); @@ -441,10 +444,8 @@ crate fn source_span_for_markdown_range( } } - let sp = span_of_attrs(attrs).from_inner(InnerSpan::new( + Some(span_of_attrs(attrs)?.from_inner(InnerSpan::new( md_range.start + start_bytes, md_range.end + start_bytes + end_bytes, - )); - - Some(sp) + ))) } diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 5fb513783fbaa..b5037b75f79e7 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -154,23 +154,10 @@ pub struct Stability { #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)] pub enum StabilityLevel { // Reason for the current stability level and the relevant rust-lang issue - Unstable { reason: Option, issue: u32 }, + Unstable { reason: Option, issue: u32, is_soft: bool }, Stable { since: Symbol }, } -impl Stability { - pub fn unstable(feature: Symbol, reason: Option, issue: u32) -> Stability { - Stability { - level: StabilityLevel::Unstable { reason, issue }, - feature, - rustc_depr: None, - const_stability: None, - promotable: false, - allow_const_fn_ptr: false, - } - } -} - impl StabilityLevel { pub fn is_unstable(&self) -> bool { if let StabilityLevel::Unstable {..} = *self { @@ -356,19 +343,27 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let mut feature = None; let mut reason = None; let mut issue = None; + let mut is_soft = false; for meta in metas { if let Some(mi) = meta.meta_item() { match mi.name_or_empty() { sym::feature => if !get(mi, &mut feature) { continue 'outer }, sym::reason => if !get(mi, &mut reason) { continue 'outer }, sym::issue => if !get(mi, &mut issue) { continue 'outer }, + sym::soft => { + if !mi.is_word() { + let msg = "`soft` should not have any arguments"; + sess.span_diagnostic.span_err(mi.span, msg); + } + is_soft = true; + } _ => { handle_errors( sess, meta.span(), AttrError::UnknownMetaItem( mi.path.to_string(), - &["feature", "reason", "issue"] + &["feature", "reason", "issue", "soft"] ), ); continue 'outer @@ -400,7 +395,8 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, "incorrect 'issue'"); continue } - } + }, + is_soft, }, feature, rustc_depr: None, diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7f4feff6be670..50ae052b4b7e6 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -944,9 +944,6 @@ pub fn expr_to_spanned_string<'a>( mut expr: P, err_msg: &str, ) -> Result, Option>> { - // Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation. - expr.span = expr.span.apply_mark(cx.current_expansion.id); - // we want to be able to handle e.g., `concat!("foo", "bar")` cx.expander().visit_expr(&mut expr); Err(match expr.node { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9a3195b1165b1..cf1ae3e316463 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -331,7 +331,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { progress = true; let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data; self.cx.current_expansion = invoc.expansion_data.clone(); - self.cx.current_expansion.id = scope; // FIXME(jseyfried): Refactor out the following logic let (expanded_fragment, new_invocations) = if let Some(ext) = ext { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bda761244d5ca..536687bdbed45 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -152,6 +152,18 @@ pub fn to_string(f: F) -> String where printer.s.eof() } +// This makes comma-separated lists look slightly nicer, +// and also addresses a specific regression described in issue #63896. +fn tt_prepend_space(tt: &TokenTree) -> bool { + match tt { + TokenTree::Token(token) => match token.kind { + token::Comma => false, + _ => true, + } + _ => true, + } +} + fn binop_to_string(op: BinOpToken) -> &'static str { match op { token::Plus => "+", @@ -684,7 +696,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::DerefM fn print_tts(&mut self, tts: tokenstream::TokenStream, convert_dollar_crate: bool) { for (i, tt) in tts.into_trees().enumerate() { - if i != 0 { + if i != 0 && tt_prepend_space(&tt) { self.space(); } self.print_tt(tt, convert_dollar_crate); diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 4e29c77c89e42..74cab00d3c1eb 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -519,7 +519,7 @@ impl SourceMap { /// extract function takes three arguments: a string slice containing the source, an index in /// the slice for the beginning of the span and an index in the slice for the end of the span. fn span_to_source(&self, sp: Span, extract_source: F) -> Result - where F: Fn(&str, usize, usize) -> String + where F: Fn(&str, usize, usize) -> Result { if sp.lo() > sp.hi() { return Err(SpanSnippetError::IllFormedSpan(sp)); @@ -554,9 +554,9 @@ impl SourceMap { } if let Some(ref src) = local_begin.sf.src { - return Ok(extract_source(src, start_index, end_index)); + return extract_source(src, start_index, end_index); } else if let Some(src) = local_begin.sf.external_src.borrow().get_source() { - return Ok(extract_source(src, start_index, end_index)); + return extract_source(src, start_index, end_index); } else { return Err(SpanSnippetError::SourceNotAvailable { filename: local_begin.sf.name.clone() @@ -567,8 +567,9 @@ impl SourceMap { /// Returns the source snippet as `String` corresponding to the given `Span` pub fn span_to_snippet(&self, sp: Span) -> Result { - self.span_to_source(sp, |src, start_index, end_index| src[start_index..end_index] - .to_string()) + self.span_to_source(sp, |src, start_index, end_index| src.get(start_index..end_index) + .map(|s| s.to_string()) + .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp))) } pub fn span_to_margin(&self, sp: Span) -> Option { @@ -582,7 +583,9 @@ impl SourceMap { /// Returns the source snippet as `String` before the given `Span` pub fn span_to_prev_source(&self, sp: Span) -> Result { - self.span_to_source(sp, |src, start_index, _| src[..start_index].to_string()) + self.span_to_source(sp, |src, start_index, _| src.get(..start_index) + .map(|s| s.to_string()) + .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp))) } /// Extend the given `Span` to just after the previous occurrence of `c`. Return the same span diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 2d9556233d15f..e301a06997003 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -623,6 +623,7 @@ symbols! { size, slice_patterns, slicing_syntax, + soft, Some, specialization, speed, diff --git a/src/llvm-project b/src/llvm-project index 48818e9f5d0f2..71fe7ec06b85f 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 48818e9f5d0f2d5978a9b43ad1a2e8d0b83f6aa0 +Subproject commit 71fe7ec06b85f612fc0e4eb4134c7a7d0f23fac5 diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 0cda3465dc093..6dba95ed35584 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -174,6 +174,14 @@ void LLVMRustAddLastExtensionPasses( #define SUBTARGET_HEXAGON #endif +#ifdef LLVM_COMPONENT_XTENSA +#define SUBTARGET_XTENSA SUBTARGET(XTENSA) +#else +#define SUBTARGET_XTENSA +#endif + + + #define GEN_SUBTARGETS \ SUBTARGET_X86 \ SUBTARGET_ARM \ @@ -185,6 +193,7 @@ void LLVMRustAddLastExtensionPasses( SUBTARGET_SPARC \ SUBTARGET_HEXAGON \ SUBTARGET_RISCV \ + SUBTARGET_XTENSA \ #define SUBTARGET(x) \ namespace llvm { \ diff --git a/src/stage0.txt b/src/stage0.txt index 14d65bef8f6dd..017ff4b277d6c 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,9 +12,9 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2019-07-04 -rustc: beta -cargo: beta +date: 2019-08-15 +rustc: 1.37.0 +cargo: 0.38.0 # When making a stable release the process currently looks like: # @@ -25,7 +25,7 @@ cargo: beta # # This means that there's a small window of time (a few days) where artifacts # are downloaded from dev-static.rust-lang.org instead of static.rust-lang.org. -# In order to ease this transition we have an extra key which is in the +# In order to ease this transition we have an extra key which is in the # configuration file below. When uncommented this will instruct the bootstrap.py # script to download from dev-static.rust-lang.org. # diff --git a/src/test/codegen/c-variadic.rs b/src/test/codegen/c-variadic.rs index 13be5ced27fa9..bb90a9653f573 100644 --- a/src/test/codegen/c-variadic.rs +++ b/src/test/codegen/c-variadic.rs @@ -2,6 +2,7 @@ #![crate_type = "lib"] #![feature(c_variadic)] +#![feature(unwind_attributes)] #![no_std] use core::ffi::VaList; @@ -10,6 +11,7 @@ extern "C" { fn foreign_c_variadic_1(_: VaList, ...); } +#[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_0() { // Ensure that we correctly call foreign C-variadic functions. // CHECK: invoke void (i32, ...) @foreign_c_variadic_0(i32 0) @@ -24,20 +26,24 @@ pub unsafe extern "C" fn use_foreign_c_variadic_0() { // Ensure that we do not remove the `va_list` passed to the foreign function when // removing the "spoofed" `VaListImpl` that is used by Rust defined C-variadics. +#[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) { // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap) foreign_c_variadic_1(ap); } +#[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) { // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 42) foreign_c_variadic_1(ap, 42i32); } +#[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) { // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 2, i32 42) foreign_c_variadic_1(ap, 2i32, 42i32); } +#[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) { // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 2, i32 42, i32 0) foreign_c_variadic_1(ap, 2i32, 42i32, 0i32); diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs index c6f98e5782b1f..bfa7a05cad057 100644 --- a/src/test/debuginfo/generator-objects.rs +++ b/src/test/debuginfo/generator-objects.rs @@ -10,31 +10,31 @@ // gdb-command:run // gdb-command:print b -// gdb-check:$1 = generator_objects::main::generator {__0: 0x[...], <>: {__state: 0, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {[...]}}} +// gdb-check:$1 = generator_objects::main::generator-0 {__0: 0x[...], <>: {__state: 0, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}} // gdb-command:continue // gdb-command:print b -// gdb-check:$2 = generator_objects::main::generator {__0: 0x[...], <>: {__state: 3, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {c: 6, d: 7}, 4: generator_objects::main::generator::Suspend1 {[...]}}} +// gdb-check:$2 = generator_objects::main::generator-0 {__0: 0x[...], <>: {__state: 3, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {c: 6, d: 7}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}} // gdb-command:continue // gdb-command:print b -// gdb-check:$3 = generator_objects::main::generator {__0: 0x[...], <>: {__state: 4, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {c: 7, d: 8}}} +// gdb-check:$3 = generator_objects::main::generator-0 {__0: 0x[...], <>: {__state: 4, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {c: 7, d: 8}}} // gdb-command:continue // gdb-command:print b -// gdb-check:$4 = generator_objects::main::generator {__0: 0x[...], <>: {__state: 1, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {[...]}}} +// gdb-check:$4 = generator_objects::main::generator-0 {__0: 0x[...], <>: {__state: 1, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}} // === LLDB TESTS ================================================================================== // lldb-command:run // lldb-command:print b -// lldbg-check:(generator_objects::main::generator) $0 = generator(&0x[...]) +// lldbg-check:(generator_objects::main::generator-0) $0 = generator-0(&0x[...]) // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::generator) $1 = generator(&0x[...]) +// lldbg-check:(generator_objects::main::generator-0) $1 = generator-0(&0x[...]) // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::generator) $2 = generator(&0x[...]) +// lldbg-check:(generator_objects::main::generator-0) $2 = generator-0(&0x[...]) // lldb-command:continue // lldb-command:print b -// lldbg-check:(generator_objects::main::generator) $3 = generator(&0x[...]) +// lldbg-check:(generator_objects::main::generator-0) $3 = generator-0(&0x[...]) #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)] #![omit_gdb_pretty_printer_section] diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs new file mode 100644 index 0000000000000..f18e41db0e6ba --- /dev/null +++ b/src/test/debuginfo/issue-57822.rs @@ -0,0 +1,55 @@ +// This test makes sure that the LLDB pretty printer does not throw an exception +// for nested closures and generators. + +// Require LLVM with DW_TAG_variant_part and a gdb that can read it. +// min-system-llvm-version: 8.0 +// min-gdb-version: 8.2 +// ignore-tidy-linelength + +// compile-flags:-g + +// === GDB TESTS =================================================================================== + +// gdb-command:run + +// gdb-command:print g +// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1)) + +// gdb-command:print b +// gdb-check:$2 = issue_57822::main::generator-3 {__0: issue_57822::main::generator-2 {__0: 2, <>: {[...]}}, <>: {[...]}} + +// === LLDB TESTS ================================================================================== + +// lldb-command:run + +// lldb-command:print g +// lldbg-check:(issue_57822::main::closure-1) $0 = closure-1(closure-0(1)) + +// lldb-command:print b +// lldbg-check:(issue_57822::main::generator-3) $1 = generator-3(generator-2(2)) + +#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)] +#![omit_gdb_pretty_printer_section] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let mut x = 1; + let f = move || x; + let g = move || f(); + + let mut y = 2; + let mut a = move || { + y += 1; + yield; + }; + let mut b = move || { + Pin::new(&mut a).resume(); + yield; + }; + + zzz(); // #break +} + +fn zzz() { () } diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index 84680a52ff3ce..4515e36166eb8 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -94,7 +94,7 @@ pub unsafe fn make_unsafe() {} pub fn make_extern() {} #[cfg(not(cfail1))] -#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, mir_built, typeck_tables_of, fn_sig")] +#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, typeck_tables_of, fn_sig")] #[rustc_clean(cfg = "cfail3")] pub extern "C" fn make_extern() {} diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index 882383e841957..538fd2c29203b 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -263,7 +263,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="Hir,HirBody,mir_built,fn_sig,typeck_tables_of")] + #[rustc_clean(cfg="cfail2", except="Hir,HirBody,fn_sig,typeck_tables_of")] #[rustc_clean(cfg="cfail3")] pub extern fn make_method_extern(&self) { } } diff --git a/src/test/pretty/attr-literals.rs b/src/test/pretty/attr-literals.rs index bcd6ffaaf815b..9db7e27b16103 100644 --- a/src/test/pretty/attr-literals.rs +++ b/src/test/pretty/attr-literals.rs @@ -5,10 +5,10 @@ #![feature(rustc_attrs)] fn main() { - #![rustc_dummy("hi" , 1 , 2 , 1.012 , pi = 3.14 , bye , name ("John"))] + #![rustc_dummy("hi", 1, 2, 1.012, pi = 3.14, bye, name ("John"))] #[rustc_dummy = 8] fn f() { } - #[rustc_dummy(1 , 2 , 3)] + #[rustc_dummy(1, 2, 3)] fn g() { } } diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp index f15d7cdc44ccd..9317b36ba497b 100644 --- a/src/test/pretty/block-comment-wchar.pp +++ b/src/test/pretty/block-comment-wchar.pp @@ -99,8 +99,5 @@ '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}', '\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}', '\u{205F}', '\u{3000}']; - for c in &chars { - let ws = c.is_whitespace(); - println!("{} {}" , c , ws); - } + for c in &chars { let ws = c.is_whitespace(); println!("{} {}", c, ws); } } diff --git a/src/test/pretty/delimited-token-groups.rs b/src/test/pretty/delimited-token-groups.rs index 768f27ad23a8e..7bbb7dc911f93 100644 --- a/src/test/pretty/delimited-token-groups.rs +++ b/src/test/pretty/delimited-token-groups.rs @@ -5,7 +5,7 @@ macro_rules! mac { ($ ($ tt : tt) *) => () } mac! { - struct S { field1 : u8 , field2 : u16 , } impl Clone for S + struct S { field1 : u8, field2 : u16, } impl Clone for S { fn clone () -> S { diff --git a/src/test/pretty/do1.rs b/src/test/pretty/do1.rs index 7be835cb22f2d..233ccdb0098b3 100644 --- a/src/test/pretty/do1.rs +++ b/src/test/pretty/do1.rs @@ -2,4 +2,4 @@ fn f(f: F) where F: Fn(isize) { f(10) } -fn main() { f(|i| { assert_eq!(i , 10) }) } +fn main() { f(|i| { assert_eq!(i, 10) }) } diff --git a/src/test/pretty/match-block-expr.rs b/src/test/pretty/match-block-expr.rs index 0db6574b0737f..10903e928cda8 100644 --- a/src/test/pretty/match-block-expr.rs +++ b/src/test/pretty/match-block-expr.rs @@ -2,5 +2,5 @@ fn main() { let x = match { 5 } { 1 => 5, 2 => 6, _ => 7, }; - assert_eq!(x , 7); + assert_eq!(x, 7); } diff --git a/src/test/run-pass/abi-sysv64-arg-passing.rs b/src/test/run-pass/abi-sysv64-arg-passing.rs new file mode 100644 index 0000000000000..fdf0573b5e3ec --- /dev/null +++ b/src/test/run-pass/abi-sysv64-arg-passing.rs @@ -0,0 +1,366 @@ +// Checks if the "sysv64" calling convention behaves the same as the +// "C" calling convention on platforms where both should be the same + +// This file contains versions of the following run-pass tests with +// the calling convention changed to "sysv64" + +// cabi-int-widening +// extern-pass-char +// extern-pass-u32 +// extern-pass-u64 +// extern-pass-double +// extern-pass-empty +// extern-pass-TwoU8s +// extern-pass-TwoU16s +// extern-pass-TwoU32s +// extern-pass-TwoU64s +// extern-return-TwoU8s +// extern-return-TwoU16s +// extern-return-TwoU32s +// extern-return-TwoU64s +// foreign-fn-with-byval +// issue-28676 +// issue-62350-sysv-neg-reg-counts +// struct-return + +// ignore-android +// ignore-arm +// ignore-aarch64 +// ignore-windows + +// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows + +#[allow(dead_code)] +#[allow(improper_ctypes)] + +#[cfg(target_arch = "x86_64")] +mod tests { + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU8s { + one: u8, two: u8 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU16s { + one: u16, two: u16 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU32s { + one: u32, two: u32 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU64s { + one: u64, two: u64 + } + + #[repr(C)] + pub struct ManyInts { + arg1: i8, + arg2: i16, + arg3: i32, + arg4: i16, + arg5: i8, + arg6: TwoU8s, + } + + #[repr(C)] + pub struct Empty; + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct S { + x: u64, + y: u64, + z: u64, + } + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + + #[derive(Copy, Clone)] + pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct Floats { a: f64, b: u8, c: f64 } + + #[link(name = "rust_test_helpers", kind = "static")] + extern "sysv64" { + pub fn rust_int8_to_int32(_: i8) -> i32; + pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; + pub fn rust_dbg_extern_identity_u32(v: u32) -> u32; + pub fn rust_dbg_extern_identity_u64(v: u64) -> u64; + pub fn rust_dbg_extern_identity_double(v: f64) -> f64; + pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); + pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; + pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; + pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; + pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; + pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s; + pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s; + pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s; + pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s; + pub fn get_x(x: S) -> u64; + pub fn get_y(x: S) -> u64; + pub fn get_z(x: S) -> u64; + pub fn get_c_many_params(_: *const (), _: *const (), + _: *const (), _: *const (), f: Quad) -> u64; + pub fn get_c_exhaust_sysv64_ints( + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + h: QuadFloats, + ) -> f32; + pub fn rust_dbg_abi_1(q: Quad) -> Quad; + pub fn rust_dbg_abi_2(f: Floats) -> Floats; + } + + pub fn cabi_int_widening() { + let x = unsafe { + rust_int8_to_int32(-1) + }; + + assert!(x == -1); + } + + pub fn extern_pass_char() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u8(22)); + } + } + + pub fn extern_pass_u32() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u32(22)); + } + } + + pub fn extern_pass_u64() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u64(22)); + } + } + + pub fn extern_pass_double() { + unsafe { + assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64)); + } + } + + pub fn extern_pass_empty() { + unsafe { + let x = ManyInts { + arg1: 2, + arg2: 3, + arg3: 4, + arg4: 5, + arg5: 6, + arg6: TwoU8s { one: 7, two: 8, } + }; + let y = ManyInts { + arg1: 1, + arg2: 2, + arg3: 3, + arg4: 4, + arg5: 5, + arg6: TwoU8s { one: 6, two: 7, } + }; + let empty = Empty; + rust_dbg_extern_empty_struct(x, empty, y); + } + } + + pub fn extern_pass_twou8s() { + unsafe { + let x = TwoU8s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU8s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou16s() { + unsafe { + let x = TwoU16s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU16s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou32s() { + unsafe { + let x = TwoU32s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU32s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou64s() { + unsafe { + let x = TwoU64s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU64s(x); + assert_eq!(x, y); + } + } + + pub fn extern_return_twou8s() { + unsafe { + let y = rust_dbg_extern_return_TwoU8s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou16s() { + unsafe { + let y = rust_dbg_extern_return_TwoU16s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou32s() { + unsafe { + let y = rust_dbg_extern_return_TwoU32s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou64s() { + unsafe { + let y = rust_dbg_extern_return_TwoU64s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + #[inline(never)] + fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 { + unsafe { + func(s) + } + } + + pub fn foreign_fn_with_byval() { + let s = S { x: 1, y: 2, z: 3 }; + assert_eq!(s.x, indirect_call(get_x, s)); + assert_eq!(s.y, indirect_call(get_y, s)); + assert_eq!(s.z, indirect_call(get_z, s)); + } + + fn test() { + use std::ptr; + unsafe { + let null = ptr::null(); + let q = Quad { + a: 1, + b: 2, + c: 3, + d: 4 + }; + assert_eq!(get_c_many_params(null, null, null, null, q), q.c); + } + } + + pub fn issue_28676() { + test(); + } + + fn test_62350() { + use std::ptr; + unsafe { + let null = ptr::null(); + let q = QuadFloats { + a: 10.2, + b: 20.3, + c: 30.4, + d: 40.5 + }; + assert_eq!( + get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), + q.c, + ); + } + } + + pub fn issue_62350() { + test_62350(); + } + + fn test1() { + unsafe { + let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, + b: 0xbbbb_bbbb_bbbb_bbbb, + c: 0xcccc_cccc_cccc_cccc, + d: 0xdddd_dddd_dddd_dddd }; + let qq = rust_dbg_abi_1(q); + println!("a: {:x}", qq.a as usize); + println!("b: {:x}", qq.b as usize); + println!("c: {:x}", qq.c as usize); + println!("d: {:x}", qq.d as usize); + assert_eq!(qq.a, q.c + 1); + assert_eq!(qq.b, q.d - 1); + assert_eq!(qq.c, q.a + 1); + assert_eq!(qq.d, q.b - 1); + } + } + + fn test2() { + unsafe { + let f = Floats { a: 1.234567890e-15_f64, + b: 0b_1010_1010, + c: 1.0987654321e-15_f64 }; + let ff = rust_dbg_abi_2(f); + println!("a: {}", ff.a as f64); + println!("b: {}", ff.b as usize); + println!("c: {}", ff.c as f64); + assert_eq!(ff.a, f.c + 1.0f64); + assert_eq!(ff.b, 0xff); + assert_eq!(ff.c, f.a - 1.0f64); + } + } + + pub fn struct_return() { + test1(); + test2(); + } +} + +#[cfg(target_arch = "x86_64")] +fn main() { + use tests::*; + cabi_int_widening(); + extern_pass_char(); + extern_pass_u32(); + extern_pass_u64(); + extern_pass_double(); + extern_pass_empty(); + extern_pass_twou8s(); + extern_pass_twou16s(); + extern_pass_twou32s(); + extern_pass_twou64s(); + extern_return_twou8s(); + extern_return_twou16s(); + extern_return_twou32s(); + extern_return_twou64s(); + foreign_fn_with_byval(); + issue_28676(); + issue_62350(); + struct_return(); +} + +#[cfg(not(target_arch = "x86_64"))] +fn main() { + +} diff --git a/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs b/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs new file mode 100644 index 0000000000000..df819306e4aa2 --- /dev/null +++ b/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(dead_code)] +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Copy, Clone)] +pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } + +mod rustrt { + use super::QuadFloats; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn get_c_exhaust_sysv64_ints( + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + h: QuadFloats, + ) -> f32; + } +} + +fn test() { + unsafe { + let null = std::ptr::null(); + let q = QuadFloats { + a: 10.2, + b: 20.3, + c: 30.4, + d: 40.5 + }; + assert_eq!( + rustrt::get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), + q.c, + ); + } +} + +pub fn main() { + test(); +} diff --git a/src/test/run-pass/abort-on-c-abi.rs b/src/test/run-pass/abort-on-c-abi.rs new file mode 100644 index 0000000000000..263f093c51a0b --- /dev/null +++ b/src/test/run-pass/abort-on-c-abi.rs @@ -0,0 +1,38 @@ +#![allow(unused_must_use)] +#![feature(unwind_attributes)] +// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that +// we never unwind through them. + +// ignore-cloudabi no env and process +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::{env, panic}; +use std::io::prelude::*; +use std::io; +use std::process::{Command, Stdio}; + +#[unwind(aborts)] // FIXME(#58794) +extern "C" fn panic_in_ffi() { + panic!("Test"); +} + +fn test() { + let _ = panic::catch_unwind(|| { panic_in_ffi(); }); + // The process should have aborted by now. + io::stdout().write(b"This should never be printed.\n"); + let _ = io::stdout().flush(); +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "test" { + return test(); + } + + let mut p = Command::new(&args[0]) + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .arg("test").spawn().unwrap(); + assert!(!p.wait().unwrap().success()); +} diff --git a/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs b/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs new file mode 100644 index 0000000000000..5c4a01ee3a74a --- /dev/null +++ b/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs @@ -0,0 +1,20 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] +#![crate_name="some_macros"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn first(_attr: TokenStream, item: TokenStream) -> TokenStream { + item // This doesn't erase the spans. +} + +#[proc_macro_attribute] +pub fn second(_attr: TokenStream, item: TokenStream) -> TokenStream { + // Make a new `TokenStream` to erase the spans: + let mut out: TokenStream = TokenStream::new(); + out.extend(item); + out +} diff --git a/src/test/rustdoc/through-proc-macro.rs b/src/test/rustdoc/through-proc-macro.rs new file mode 100644 index 0000000000000..348c9eea2dcbf --- /dev/null +++ b/src/test/rustdoc/through-proc-macro.rs @@ -0,0 +1,12 @@ +// aux-build:through-proc-macro-aux.rs +// build-aux-docs +#![warn(intra_doc_link_resolution_failure)] +extern crate some_macros; + +#[some_macros::second] +pub enum Boom { + /// [Oooops] + Bam, +} + +fn main() {} diff --git a/src/test/ui/abort-on-c-abi.rs b/src/test/ui/abort-on-c-abi.rs index cd7dd1b6a452f..2f08730ec6132 100644 --- a/src/test/ui/abort-on-c-abi.rs +++ b/src/test/ui/abort-on-c-abi.rs @@ -1,6 +1,7 @@ // run-pass #![allow(unused_must_use)] +#![feature(unwind_attributes)] // Since we mark some ABIs as "nounwind" to LLVM, we must make sure that // we never unwind through them. @@ -13,6 +14,7 @@ use std::io::prelude::*; use std::io; use std::process::{Command, Stdio}; +#[unwind(aborts)] // FIXME(#58794) extern "C" fn panic_in_ffi() { panic!("Test"); } diff --git a/src/test/ui/feature-gates/bench.rs b/src/test/ui/feature-gates/bench.rs new file mode 100644 index 0000000000000..afe4dc7d54c9b --- /dev/null +++ b/src/test/ui/feature-gates/bench.rs @@ -0,0 +1,5 @@ +#[bench] //~ ERROR use of unstable library feature 'test' + //~| WARN this was previously accepted +fn bench() {} + +fn main() {} diff --git a/src/test/ui/feature-gates/bench.stderr b/src/test/ui/feature-gates/bench.stderr new file mode 100644 index 0000000000000..b9e24e931d42b --- /dev/null +++ b/src/test/ui/feature-gates/bench.stderr @@ -0,0 +1,12 @@ +error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable + --> $DIR/bench.rs:1:3 + | +LL | #[bench] + | ^^^^^ + | + = note: `#[deny(soft_unstable)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #64266 + +error: aborting due to previous error + diff --git a/src/test/ui/hygiene/eager-from-opaque-2.rs b/src/test/ui/hygiene/eager-from-opaque-2.rs new file mode 100644 index 0000000000000..220e5526745c3 --- /dev/null +++ b/src/test/ui/hygiene/eager-from-opaque-2.rs @@ -0,0 +1,22 @@ +// Regression test for the issue #63460. + +// check-pass + +#[macro_export] +macro_rules! separator { + () => { "/" }; +} + +#[macro_export] +macro_rules! concat_separator { + ( $e:literal, $($other:literal),+ ) => { + concat!($e, $crate::separator!(), $crate::concat_separator!($($other),+)) + }; + ( $e:literal ) => { + $e + } +} + +fn main() { + println!("{}", concat_separator!(2, 3, 4)) +} diff --git a/src/test/ui/hygiene/eager-from-opaque.rs b/src/test/ui/hygiene/eager-from-opaque.rs new file mode 100644 index 0000000000000..6f3215dd697f3 --- /dev/null +++ b/src/test/ui/hygiene/eager-from-opaque.rs @@ -0,0 +1,20 @@ +// Opaque macro can eagerly expand its input without breaking its resolution. +// Regression test for issue #63685. + +// check-pass + +macro_rules! foo { + () => { + "foo" + }; +} + +macro_rules! bar { + () => { + foo!() + }; +} + +fn main() { + format_args!(bar!()); +} diff --git a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr index 1ef9427666bc5..5ca4088e585db 100644 --- a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr +++ b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr @@ -8,6 +8,9 @@ LL | | LL | | "" LL | | } | |_____^ +... +LL | format_args!(hang!()); + | ------- in this macro invocation help: you might be missing a string literal to format with | LL | format_args!("{}", hang!()); diff --git a/src/test/ui/macros/macro-first-set.rs b/src/test/ui/macros/macro-first-set.rs index a21e4cd201a4f..34529cdaa64f1 100644 --- a/src/test/ui/macros/macro-first-set.rs +++ b/src/test/ui/macros/macro-first-set.rs @@ -25,7 +25,7 @@ macro_rules! foo_26444 { } fn test_26444() { - assert_eq!("a , b , c , d , e", foo_26444!(a, b; c; d, e)); + assert_eq!("a, b, c, d, e", foo_26444!(a, b; c; d, e)); assert_eq!("f", foo_26444!(; f ;)); } diff --git a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs index d81e16d9d2961..f1de3709b166b 100644 --- a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs +++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs @@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println!(\"{}\" , string);"); + assert_eq!(item.to_string(), "println!(\"{}\", string);"); item } @@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println!(\"{}\" , string)"); + assert_eq!(item.to_string(), "println!(\"{}\", string)"); item } diff --git a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs index 0a82cbedd77ce..d2180def5b760 100644 --- a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs +++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs @@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println!(\"{}\" , string);"); + assert_eq!(item.to_string(), "println!(\"{}\", string);"); item } @@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream { assert!(attr.to_string().is_empty()); - assert_eq!(item.to_string(), "println!(\"{}\" , string)"); + assert_eq!(item.to_string(), "println!(\"{}\", string)"); item } diff --git a/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs b/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs new file mode 100644 index 0000000000000..5b378fb2a5928 --- /dev/null +++ b/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs @@ -0,0 +1,135 @@ +// run-pass + +// This file checks that fn ptrs are considered structurally matchable. +// See also rust-lang/rust#63479. + +fn main() { + let mut count = 0; + + // A type which is not structurally matchable: + struct NotSM; + + // And one that is: + #[derive(PartialEq, Eq)] + struct SM; + + fn trivial() {} + + fn sm_to(_: SM) {} + fn not_sm_to(_: NotSM) {} + fn to_sm() -> SM { SM } + fn to_not_sm() -> NotSM { NotSM } + + // To recreate the scenario of interest in #63479, we need to add + // a ref-level-of-indirection so that we descend into the type. + + fn r_sm_to(_: &SM) {} + fn r_not_sm_to(_: &NotSM) {} + fn r_to_r_sm(_: &()) -> &SM { &SM } + fn r_to_r_not_sm(_: &()) -> &NotSM { &NotSM } + + #[derive(PartialEq, Eq)] + struct Wrap(T); + + // In the code below, we put the match input into a local so that + // we can assign it an explicit type that is an fn ptr instead of + // a singleton type of the fn itself that the type inference would + // otherwise assign. + + // Check that fn() is #[structural_match] + const CFN1: Wrap = Wrap(trivial); + let input: Wrap = Wrap(trivial); + match Wrap(input) { + Wrap(CFN1) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is #[structural_match] when T is too. + const CFN2: Wrap = Wrap(sm_to); + let input: Wrap = Wrap(sm_to); + match Wrap(input) { + Wrap(CFN2) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is #[structural_match] when T is too. + const CFN3: Wrap SM> = Wrap(to_sm); + let input: Wrap SM> = Wrap(to_sm); + match Wrap(input) { + Wrap(CFN3) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is #[structural_match] even if T is not. + const CFN4: Wrap = Wrap(not_sm_to); + let input: Wrap = Wrap(not_sm_to); + match Wrap(input) { + Wrap(CFN4) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is #[structural_match] even if T is not. + const CFN5: Wrap NotSM> = Wrap(to_not_sm); + let input: Wrap NotSM> = Wrap(to_not_sm); + match Wrap(input) { + Wrap(CFN5) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(&T) is #[structural_match] when T is too. + const CFN6: Wrap = Wrap(r_sm_to); + let input: Wrap = Wrap(r_sm_to); + match Wrap(input) { + Wrap(CFN6) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> &T is #[structural_match] when T is too. + const CFN7: Wrap &SM> = Wrap(r_to_r_sm); + let input: Wrap &SM> = Wrap(r_to_r_sm); + match Wrap(input) { + Wrap(CFN7) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is #[structural_match] even if T is not. + const CFN8: Wrap = Wrap(r_not_sm_to); + let input: Wrap = Wrap(r_not_sm_to); + match Wrap(input) { + Wrap(CFN8) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is #[structural_match] even if T is not. + const CFN9: Wrap &NotSM> = Wrap(r_to_r_not_sm); + let input: Wrap &NotSM> = Wrap(r_to_r_not_sm); + match Wrap(input) { + Wrap(CFN9) => count += 1, + Wrap(_) => {} + }; + + // Check that a type which has fn ptrs is `#[structural_match]`. + #[derive(PartialEq, Eq)] + struct Foo { + alpha: fn(NotSM), + beta: fn() -> NotSM, + gamma: fn(SM), + delta: fn() -> SM, + } + + const CFOO: Foo = Foo { + alpha: not_sm_to, + beta: to_not_sm, + gamma: sm_to, + delta: to_sm, + }; + + let input = Foo { alpha: not_sm_to, beta: to_not_sm, gamma: sm_to, delta: to_sm }; + match input { + CFOO => count += 1, + Foo { .. } => {} + }; + + // Final count must be 10 now if all + assert_eq!(count, 10); +} diff --git a/src/test/ui/rfc1445/issue-63479-match-fnptr.rs b/src/test/ui/rfc1445/issue-63479-match-fnptr.rs new file mode 100644 index 0000000000000..b3c91cec580bf --- /dev/null +++ b/src/test/ui/rfc1445/issue-63479-match-fnptr.rs @@ -0,0 +1,36 @@ +// run-pass + +// The actual regression test from #63479. (Including this because my +// first draft at fn-ptr-is-structurally-matchable.rs failed to actually +// cover the case this hit; I've since expanded it accordingly, but the +// experience left me wary of leaving this regression test out.) + +#[derive(Eq)] +struct A { + a: i64 +} + +impl PartialEq for A { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.a.eq(&other.a) + } +} + +type Fn = fn(&[A]); + +fn my_fn(_args: &[A]) { + println!("hello world"); +} + +const TEST: Fn = my_fn; + +struct B(Fn); + +fn main() { + let s = B(my_fn); + match s { + B(TEST) => println!("matched"), + _ => panic!("didn't match") + }; +} diff --git a/src/test/ui/suggestions/issue-61226.rs b/src/test/ui/suggestions/issue-61226.rs new file mode 100644 index 0000000000000..e83b0b4d6308d --- /dev/null +++ b/src/test/ui/suggestions/issue-61226.rs @@ -0,0 +1,5 @@ +struct X {} +fn main() { + vec![X]; //… + //~^ ERROR expected value, found struct `X` +} diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr new file mode 100644 index 0000000000000..6d7d98ac6a16b --- /dev/null +++ b/src/test/ui/suggestions/issue-61226.stderr @@ -0,0 +1,9 @@ +error[E0423]: expected value, found struct `X` + --> $DIR/issue-61226.rs:3:10 + | +LL | vec![X]; //… + | ^ did you mean `X { /* fields */ }`? + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0423`. diff --git a/src/tools/cargo b/src/tools/cargo index e853aa9765431..23ef9a4ef8a96 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit e853aa976543168fbb6bfcc983c35c3facca9840 +Subproject commit 23ef9a4ef8a96d09b1fd67b2f4e023f416bb1ff1 diff --git a/src/tools/clippy b/src/tools/clippy index 72da1015d6d91..3aea86030eeca 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 72da1015d6d918fe1b29170acbf486d30e0c2695 +Subproject commit 3aea86030eeca7dff94139b24d6b76294609dbce diff --git a/src/tools/rust-installer b/src/tools/rust-installer index 85958b001dbff..9f66c14c3f91a 160000 --- a/src/tools/rust-installer +++ b/src/tools/rust-installer @@ -1 +1 @@ -Subproject commit 85958b001dbff8523396809bfa844fc34a7869a8 +Subproject commit 9f66c14c3f91a48a118c7817f434167b311c3515