diff options
| author | bors <bors@rust-lang.org> | 2019-08-05 11:48:01 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-08-05 11:48:01 +0000 |
| commit | 3f55461efb25b3c8b5c5c3d829065cb032ec953b (patch) | |
| tree | 68f418e03e74fe674a8f2c9393ab4017f0e07c3d /src | |
| parent | 61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e (diff) | |
| parent | 775ffd9df1b90e83c3145e3fefff30072c0683f8 (diff) | |
| download | rust-3f55461efb25b3c8b5c5c3d829065cb032ec953b.tar.gz rust-3f55461efb25b3c8b5c5c3d829065cb032ec953b.zip | |
Auto merge of #63262 - pietroalbini:beta-rollup, r=pietroalbini
[beta] Rollup backports Cherry picked: * Updated RELEASES.md for 1.37.0 #63147 * Require a value for configure --debuginfo-level #62906 * Make the parser TokenStream more resilient after mismatched delimiter recovery #62887 * ci: move .azure-pipelines to src/ci/azure-pipelines #63242 Rolled up: * [BETA] Update cargo #62911 * [beta] Backport #61207 #63254 r? @ghost
Diffstat (limited to 'src')
53 files changed, 2516 insertions, 40 deletions
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 53d3dbf60d1..907983d43ad 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -76,11 +76,11 @@ o("optimize-llvm", "llvm.optimize", "build optimized LLVM") o("llvm-assertions", "llvm.assertions", "build LLVM with assertions") o("debug-assertions", "rust.debug-assertions", "build with debugging assertions") o("llvm-release-debuginfo", "llvm.release-debuginfo", "build LLVM with debugger metadata") -o("debuginfo-level", "rust.debuginfo-level", "debuginfo level for Rust code") -o("debuginfo-level-rustc", "rust.debuginfo-level-rustc", "debuginfo level for the compiler") -o("debuginfo-level-std", "rust.debuginfo-level-std", "debuginfo level for the standard library") -o("debuginfo-level-tools", "rust.debuginfo-level-tools", "debuginfo level for the tools") -o("debuginfo-level-tests", "rust.debuginfo-level-tests", "debuginfo level for the test suites run with compiletest") +v("debuginfo-level", "rust.debuginfo-level", "debuginfo level for Rust code") +v("debuginfo-level-rustc", "rust.debuginfo-level-rustc", "debuginfo level for the compiler") +v("debuginfo-level-std", "rust.debuginfo-level-std", "debuginfo level for the standard library") +v("debuginfo-level-tools", "rust.debuginfo-level-tools", "debuginfo level for the tools") +v("debuginfo-level-tests", "rust.debuginfo-level-tests", "debuginfo level for the test suites run with compiletest") v("save-toolstates", "rust.save-toolstates", "save build and test status of external tools into this file") v("prefix", "install.prefix", "set installation prefix") diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml new file mode 100644 index 00000000000..2e6c3b7a992 --- /dev/null +++ b/src/ci/azure-pipelines/auto.yml @@ -0,0 +1,350 @@ +# +# Azure Pipelines "auto" branch build for Rust on Linux, macOS, and Windows. +# + +pr: none +trigger: + - auto + +variables: +- group: real-prod-credentials + +jobs: +- job: Linux + timeoutInMinutes: 600 + pool: + vmImage: ubuntu-16.04 + steps: + - template: steps/run.yml + strategy: + matrix: + x86_64-gnu-llvm-6.0: + IMAGE: x86_64-gnu-llvm-6.0 + RUST_BACKTRACE: 1 + + dist-x86_64-linux: + IMAGE: dist-x86_64-linux + DEPLOY: 1 + + # "alternate" deployments, these are "nightlies" but have LLVM assertions + # turned on, they're deployed to a different location primarily for + # additional testing. + dist-x86_64-linux-alt: + IMAGE: dist-x86_64-linux + DEPLOY_ALT: 1 + + # Linux builders, remaining docker images + arm-android: + IMAGE: arm-android + + armhf-gnu: + IMAGE: armhf-gnu + + dist-various-1: + IMAGE: dist-various-1 + DEPLOY: 1 + + dist-various-2: + IMAGE: dist-various-2 + DEPLOY: 1 + + dist-aarch64-linux: + IMAGE: dist-aarch64-linux + DEPLOY: 1 + + dist-android: + IMAGE: dist-android + DEPLOY: 1 + + dist-arm-linux: + IMAGE: dist-arm-linux + DEPLOY: 1 + + dist-armhf-linux: + IMAGE: dist-armhf-linux + DEPLOY: 1 + + dist-armv7-linux: + IMAGE: dist-armv7-linux + DEPLOY: 1 + + dist-i586-gnu-i586-i686-musl: + IMAGE: dist-i586-gnu-i586-i686-musl + DEPLOY: 1 + + dist-i686-freebsd: + IMAGE: dist-i686-freebsd + DEPLOY: 1 + + dist-i686-linux: + IMAGE: dist-i686-linux + DEPLOY: 1 + + dist-mips-linux: + IMAGE: dist-mips-linux + DEPLOY: 1 + + dist-mips64-linux: + IMAGE: dist-mips64-linux + DEPLOY: 1 + + dist-mips64el-linux: + IMAGE: dist-mips64el-linux + DEPLOY: 1 + + dist-mipsel-linux: + IMAGE: dist-mipsel-linux + DEPLOY: 1 + + dist-powerpc-linux: + IMAGE: dist-powerpc-linux + DEPLOY: 1 + + dist-powerpc64-linux: + IMAGE: dist-powerpc64-linux + DEPLOY: 1 + + dist-powerpc64le-linux: + IMAGE: dist-powerpc64le-linux + DEPLOY: 1 + + dist-s390x-linux: + IMAGE: dist-s390x-linux + DEPLOY: 1 + + dist-x86_64-freebsd: + IMAGE: dist-x86_64-freebsd + DEPLOY: 1 + + dist-x86_64-musl: + IMAGE: dist-x86_64-musl + DEPLOY: 1 + + dist-x86_64-netbsd: + IMAGE: dist-x86_64-netbsd + DEPLOY: 1 + + asmjs: + IMAGE: asmjs + i686-gnu: + IMAGE: i686-gnu + i686-gnu-nopt: + IMAGE: i686-gnu-nopt + test-various: + IMAGE: test-various + x86_64-gnu: + IMAGE: x86_64-gnu + x86_64-gnu-full-bootstrap: + IMAGE: x86_64-gnu-full-bootstrap + x86_64-gnu-aux: + IMAGE: x86_64-gnu-aux + x86_64-gnu-tools: + IMAGE: x86_64-gnu-tools + x86_64-gnu-debug: + IMAGE: x86_64-gnu-debug + x86_64-gnu-nopt: + IMAGE: x86_64-gnu-nopt + x86_64-gnu-distcheck: + IMAGE: x86_64-gnu-distcheck + mingw-check: + IMAGE: mingw-check + +- job: macOS + timeoutInMinutes: 600 + pool: + vmImage: macos-10.13 + steps: + - template: steps/run.yml + strategy: + matrix: + # OSX builders running tests, these run the full test suite. + # NO_DEBUG_ASSERTIONS=1 to make them go faster, but also do have some + # runners that run `//ignore-debug` tests. + # + # Note that the compiler is compiled to target 10.8 here because the Xcode + # version that we're using, 8.2, cannot compile LLVM for OSX 10.7. + x86_64-apple: + SCRIPT: ./x.py test + RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.8 + MACOSX_STD_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + + 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 --enable-lldb --set rust.jemalloc + DEPLOY: 1 + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + DIST_REQUIRE_ALL_TOOLS: 1 + + dist-x86_64-apple-alt: + SCRIPT: ./x.py dist + 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 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + + i686-apple: + SCRIPT: ./x.py test + RUST_CONFIGURE_ARGS: --build=i686-apple-darwin --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.8 + MACOSX_STD_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + + dist-i686-apple: + SCRIPT: ./x.py dist + 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 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + DIST_REQUIRE_ALL_TOOLS: 1 + + + +- job: Windows + timeoutInMinutes: 600 + pool: + vmImage: 'vs2017-win2016' + steps: + - template: steps/run.yml + strategy: + matrix: + # 32/64 bit MSVC tests + x86_64-msvc-1: + MSYS_BITS: 64 + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler + SCRIPT: make ci-subset-1 + # FIXME(#59637) + NO_DEBUG_ASSERTIONS: 1 + NO_LLVM_ASSERTIONS: 1 + x86_64-msvc-2: + MSYS_BITS: 64 + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler + SCRIPT: make ci-subset-2 + i686-msvc-1: + MSYS_BITS: 32 + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc + SCRIPT: make ci-subset-1 + i686-msvc-2: + MSYS_BITS: 32 + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc + SCRIPT: make ci-subset-2 + # MSVC aux tests + x86_64-msvc-aux: + MSYS_BITS: 64 + RUST_CHECK_TARGET: check-aux EXCLUDE_CARGO=1 + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc + x86_64-msvc-cargo: + MSYS_BITS: 64 + SCRIPT: python x.py test src/tools/cargotest src/tools/cargo + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc + VCVARS_BAT: vcvars64.bat + # MSVC tools tests + 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 --enable-test-miri + + # 32/64-bit MinGW builds. + # + # We are using MinGW with posix threads since LLVM does not compile with + # the win32 threads version due to missing support for C++'s std::thread. + # + # Instead of relying on the MinGW version installed on appveryor we download + # and install one ourselves so we won't be surprised by changes to appveyor's + # build image. + # + # Finally, note that the downloads below are all in the `rust-lang-ci` S3 + # bucket, but they cleraly didn't originate there! The downloads originally + # came from the mingw-w64 SourceForge download site. Unfortunately + # SourceForge is notoriously flaky, so we mirror it on our own infrastructure. + i686-mingw-1: + MSYS_BITS: 32 + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu + SCRIPT: make ci-subset-1 + MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z + MINGW_DIR: mingw32 + # FIXME(#59637) + NO_DEBUG_ASSERTIONS: 1 + NO_LLVM_ASSERTIONS: 1 + i686-mingw-2: + MSYS_BITS: 32 + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu + SCRIPT: make ci-subset-2 + MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z + MINGW_DIR: mingw32 + x86_64-mingw-1: + MSYS_BITS: 64 + SCRIPT: make ci-subset-1 + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu + MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z + MINGW_DIR: mingw64 + # FIXME(#59637) + NO_DEBUG_ASSERTIONS: 1 + NO_LLVM_ASSERTIONS: 1 + x86_64-mingw-2: + MSYS_BITS: 64 + SCRIPT: make ci-subset-2 + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu + MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z + MINGW_DIR: mingw64 + + # 32/64 bit MSVC and GNU deployment + dist-x86_64-msvc: + RUST_CONFIGURE_ARGS: > + --build=x86_64-pc-windows-msvc + --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc + --enable-full-tools + --enable-profiler + SCRIPT: python x.py dist + DIST_REQUIRE_ALL_TOOLS: 1 + DEPLOY: 1 + dist-i686-msvc: + RUST_CONFIGURE_ARGS: > + --build=i686-pc-windows-msvc + --target=i586-pc-windows-msvc + --enable-full-tools + --enable-profiler + SCRIPT: python x.py dist + DIST_REQUIRE_ALL_TOOLS: 1 + DEPLOY: 1 + dist-i686-mingw: + MSYS_BITS: 32 + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler + SCRIPT: python x.py dist + MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z + MINGW_DIR: mingw32 + DIST_REQUIRE_ALL_TOOLS: 1 + DEPLOY: 1 + dist-x86_64-mingw: + MSYS_BITS: 64 + SCRIPT: python x.py dist + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler + MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror + MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z + MINGW_DIR: mingw64 + DIST_REQUIRE_ALL_TOOLS: 1 + DEPLOY: 1 + + # "alternate" deployment, see .travis.yml for more info + dist-x86_64-msvc-alt: + MSYS_BITS: 64 + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler + SCRIPT: python x.py dist + DEPLOY_ALT: 1 diff --git a/src/ci/azure-pipelines/master.yml b/src/ci/azure-pipelines/master.yml new file mode 100644 index 00000000000..9742c719658 --- /dev/null +++ b/src/ci/azure-pipelines/master.yml @@ -0,0 +1,25 @@ +# +# Azure Pipelines job to publish toolstate. Only triggers on pushes to master. +# + +pr: none +trigger: + - master + +variables: +- group: real-prod-credentials + +pool: + vmImage: ubuntu-16.04 + +steps: +- checkout: self + fetchDepth: 2 + +- script: | + export MESSAGE_FILE=$(mktemp -t msg.XXXXXX) + . src/ci/docker/x86_64-gnu-tools/repo.sh + commit_toolstate_change "$MESSAGE_FILE" "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "$MESSAGE_FILE" "$TOOLSTATE_REPO_ACCESS_TOKEN" + displayName: Publish toolstate + env: + TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN) diff --git a/src/ci/azure-pipelines/pr.yml b/src/ci/azure-pipelines/pr.yml new file mode 100644 index 00000000000..88b5067b4a3 --- /dev/null +++ b/src/ci/azure-pipelines/pr.yml @@ -0,0 +1,33 @@ +# +# Azure Pipelines pull request build for Rust +# + +trigger: none +pr: +- master + +jobs: +- job: Linux + timeoutInMinutes: 600 + pool: + vmImage: ubuntu-16.04 + steps: + - template: steps/run.yml + strategy: + matrix: + x86_64-gnu-llvm-6.0: + IMAGE: x86_64-gnu-llvm-6.0 + mingw-check: + IMAGE: mingw-check + +# 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 new file mode 100644 index 00000000000..0cd6f24e32c --- /dev/null +++ b/src/ci/azure-pipelines/steps/install-clang.yml @@ -0,0 +1,40 @@ +steps: + +- bash: | + set -e + curl -f http://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz | tar xJf - + + export CC=`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang + echo "##vso[task.setvariable variable=CC]$CC" + + export CXX=`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang++ + echo "##vso[task.setvariable variable=CXX]$CXX" + + # Configure `AR` specifically so rustbuild doesn't try to infer it as + # `clang-ar` by accident. + echo "##vso[task.setvariable variable=AR]ar" + displayName: Install clang (OSX) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin')) + +# If we're compiling for MSVC then we, like most other distribution builders, +# switch to clang as the compiler. This'll allow us eventually to enable LTO +# amongst LLVM and rustc. Note that we only do this on MSVC as I don't think +# clang has an output mode compatible with MinGW that we need. If it does we +# should switch to clang for MinGW as well! +# +# Note that the LLVM installer is an NSIS installer +# +# Original downloaded here came from +# http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.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) + +# Note that we don't install clang on Linux since its compiler story is just so +# different. Each container has its own toolchain configured appropriately +# already. diff --git a/src/ci/azure-pipelines/steps/install-sccache.yml b/src/ci/azure-pipelines/steps/install-sccache.yml new file mode 100644 index 00000000000..427e50f571f --- /dev/null +++ b/src/ci/azure-pipelines/steps/install-sccache.yml @@ -0,0 +1,21 @@ +steps: + +- bash: | + set -e + curl -fo /usr/local/bin/sccache https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-02-sccache-x86_64-apple-darwin + chmod +x /usr/local/bin/sccache + displayName: Install sccache (OSX) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin')) + +- script: | + md sccache + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf sccache\sccache.exe https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-26-sccache-x86_64-pc-windows-msvc" + echo ##vso[task.prependpath]%CD%\sccache + displayName: Install sccache (Windows) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + +# Note that we don't install sccache on Linux since it's installed elsewhere +# through all the containers. +# +# FIXME: we should probably install sccache outside the containers and then +# mount it inside the containers so we can centralize all installation here. diff --git a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml new file mode 100644 index 00000000000..ed06679464c --- /dev/null +++ b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml @@ -0,0 +1,94 @@ +steps: +# 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 +# point, but this seems to fix our "disk space full" problems. +- script: | + mkdir c:\MORE_SPACE + mklink /J build c:\MORE_SPACE + displayName: "Ensure build happens on C:/ instead of D:/" + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + +- bash: git config --replace-all --global core.autocrlf false + displayName: "Disable git automatic line ending conversion (on C:/)" + +# Download and install MSYS2, needed primarily for the test suite (run-make) but +# also used by the MinGW toolchain for assembling things. +# +# FIXME: we should probe the default azure image and see if we can use the MSYS2 +# toolchain there. (if there's even one there). For now though this gets the job +# done. +- script: | + set MSYS_PATH=%CD%\citools\msys64 + choco install msys2 --params="/InstallDir:%MSYS_PATH% /NoPath" -y + set PATH=%MSYS_PATH%\usr\bin;%PATH% + pacman -S --noconfirm --needed base-devel ca-certificates make diffutils tar + IF "%MINGW_URL%"=="" ( + IF "%MSYS_BITS%"=="32" pacman -S --noconfirm --needed mingw-w64-i686-toolchain mingw-w64-i686-cmake mingw-w64-i686-gcc mingw-w64-i686-python2 + IF "%MSYS_BITS%"=="64" pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-x86_64-python2 + ) + where rev + rev --help + where make + + echo ##vso[task.setvariable variable=MSYS_PATH]%MSYS_PATH% + echo ##vso[task.prependpath]%MSYS_PATH%\usr\bin + displayName: Install msys2 + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + +# If we need to download a custom MinGW, do so here and set the path +# appropriately. +# +# Here we also do a pretty heinous thing which is to mangle the MinGW +# installation we just downloaded. Currently, as of this writing, we're using +# MinGW-w64 builds of gcc, and that's currently at 6.3.0. We use 6.3.0 as it +# appears to be the first version which contains a fix for #40546, builds +# randomly failing during LLVM due to ar.exe/ranlib.exe failures. +# +# Unfortunately, though, 6.3.0 *also* is the first version of MinGW-w64 builds +# to contain a regression in gdb (#40184). As a result if we were to use the +# gdb provided (7.11.1) then we would fail all debuginfo tests. +# +# In order to fix spurious failures (pretty high priority) we use 6.3.0. To +# avoid disabling gdb tests we download an *old* version of gdb, specifically +# that found inside the 6.2.0 distribution. We then overwrite the 6.3.0 gdb +# with the 6.2.0 gdb to get tests passing. +# +# Note that we don't literally overwrite the gdb.exe binary because it appears +# to just use gdborig.exe, so that's the binary we deal with instead. +- script: | + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf %MINGW_ARCHIVE% %MINGW_URL%/%MINGW_ARCHIVE%" + 7z x -y %MINGW_ARCHIVE% > nul + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-04-20-%MSYS_BITS%bit-gdborig.exe %MINGW_URL%/2017-04-20-%MSYS_BITS%bit-gdborig.exe" + mv 2017-04-20-%MSYS_BITS%bit-gdborig.exe %MINGW_DIR%\bin\gdborig.exe + echo ##vso[task.prependpath]%CD%\%MINGW_DIR%\bin + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],'')) + displayName: Download custom MinGW + +# Otherwise pull in the MinGW installed on appveyor +- script: | + echo ##vso[task.prependpath]%MSYS_PATH%\mingw%MSYS_BITS%\bin + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],'')) + displayName: Add MinGW to path + +# Make sure we use the native python interpreter instead of some msys equivalent +# one way or another. The msys interpreters seem to have weird path conversions +# baked in which break LLVM's build system one way or another, so let's use the +# native version which keeps everything as native as possible. +- script: | + copy C:\Python27amd64\python.exe C:\Python27amd64\python2.7.exe + echo ##vso[task.prependpath]C:\Python27amd64 + displayName: Prefer the "native" Python as LLVM has trouble building with MSYS sometimes + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + +# Note that this is originally from the github releases patch of Ninja +- script: | + md ninja + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-03-15-ninja-win.zip https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-03-15-ninja-win.zip" + 7z x -oninja 2017-03-15-ninja-win.zip + del 2017-03-15-ninja-win.zip + set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --enable-ninja + echo ##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]%RUST_CONFIGURE_ARGS% + echo ##vso[task.prependpath]%CD%\ninja + displayName: Download and install ninja + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml new file mode 100644 index 00000000000..18385f078bf --- /dev/null +++ b/src/ci/azure-pipelines/steps/run.yml @@ -0,0 +1,200 @@ +# FIXME(linux): need to configure core dumps, enable them, and then dump +# backtraces on failure from all core dumps: +# +# - bash: sudo apt install gdb +# - bash: sudo sh -c 'echo "/checkout/obj/cores/core.%p.%E" > /proc/sys/kernel/core_pattern' +# +# Check travis config for `gdb --batch` command to print all crash logs + +steps: + +# Disable automatic line ending conversion, which is enabled by default on +# Azure's Windows image. Having the conversion enabled caused regressions both +# in our test suite (it broke miri tests) and in the ecosystem, since we +# started shipping install scripts with CRLF endings instead of the old LF. +# +# Note that we do this a couple times during the build as the PATH and current +# user/directory change, e.g. when mingw is enabled. +- bash: git config --global core.autocrlf false + displayName: "Disable git automatic line ending conversion" + +- checkout: self + fetchDepth: 2 + +# 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. +- bash: python src/ci/cpu-usage-over-time.py &> cpu-usage.csv & + displayName: "Collect CPU-usage statistics in the background" + +- bash: printenv | sort + displayName: Show environment variables + +- bash: | + set -e + df -h + du . | sort -nr | head -n100 + displayName: Show disk usage + # FIXME: this hasn't been tested, but maybe it works on Windows? Should test! + condition: and(succeeded(), ne(variables['Agent.OS'], 'Windows_NT')) + +- 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. +- bash: | + set -e + sudo xcode-select --switch /Applications/Xcode_9.3.app + displayName: Switch to Xcode 9.3 (OSX) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin')) + +- template: install-windows-build-deps.yml + +# Looks like docker containers have IPv6 disabled by default, so let's turn it +# on since libstd tests require it +- bash: | + set -e + sudo mkdir -p /etc/docker + 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(), 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 +# re-enables autocrlf. We've not tracked down the exact cause -- and there may +# be multiple -- but this should ensure submodules are checked out with the +# appropriate line endings. +- bash: git config --replace-all --global core.autocrlf false + displayName: "Disable git automatic line ending conversion" + +# Check out all our submodules, but more quickly than using git by using one of +# our custom scripts +- bash: | + set -e + mkdir -p $HOME/rustsrc + $BUILD_SOURCESDIRECTORY/src/ci/init_repo.sh . $HOME/rustsrc + condition: and(succeeded(), ne(variables['Agent.OS'], 'Windows_NT')) + displayName: Check out submodules (Unix) +- script: | + 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 +# +# We check both in rust-lang/rust and in a submodule to make sure both are +# accurate. Submodules are checked out significantly later than the main +# repository in this script, so settings can (and do!) change between then. +# +# Linux (and maybe macOS) builders don't currently have dos2unix so just only +# run this step on Windows. +- bash: | + set -x + # print out the git configuration so we can better investigate failures in + # the following + git config --list --show-origin + dos2unix -ih Cargo.lock src/tools/rust-installer/install-template.sh + endings=$(dos2unix -ic Cargo.lock src/tools/rust-installer/install-template.sh) + # if endings has non-zero length, error out + if [ -n "$endings" ]; then exit 1 ; fi + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + displayName: Verify line endings are LF + +# Ensure the `aws` CLI is installed so we can deploy later on, cache docker +# images, etc. +- 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: 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 +# check our own internal scripts. +- bash: | + set -e + git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git + cd rust-toolstate + 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(), eq(variables['IMAGE'], 'mingw-check')) + displayName: Verify the publish_toolstate script works + +- bash: | + set -e + # Remove any preexisting rustup installation since it can interfere + # with the cargotest step and its auto-detection of things like Clippy in + # the environment + rustup self uninstall -y || true + if [ "$IMAGE" = "" ]; then + src/ci/run.sh + else + src/ci/docker/run.sh $IMAGE + fi + #timeoutInMinutes: 180 + timeoutInMinutes: 600 + env: + CI: true + SRC: . + AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) + TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN) + displayName: Run build + +# If we're a deploy builder, use the `aws` command to publish everything to our +# bucket. +- bash: | + set -e + source src/ci/shared.sh + if [ "$AGENT_OS" = "Linux" ]; then + rm -rf obj/build/dist/doc + upload_dir=obj/build/dist + else + rm -rf build/dist/doc + upload_dir=build/dist + fi + ls -la $upload_dir + deploy_dir=rustc-builds + if [ "$DEPLOY_ALT" == "1" ]; then + deploy_dir=rustc-builds-alt + fi + 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(), 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 +# execute this step in case we want to inspect failed builds, but don't let +# errors here ever fail the build since this is just informational. +- bash: aws s3 cp --acl public-read cpu-usage.csv s3://$DEPLOY_BUCKET/rustc-builds/$BUILD_SOURCEVERSION/cpu-$SYSTEM_JOBNAME.csv + env: + AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) + condition: variables['AWS_SECRET_ACCESS_KEY'] + continueOnError: true + displayName: Upload CPU usage statistics diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml new file mode 100644 index 00000000000..6a22e57c124 --- /dev/null +++ b/src/ci/azure-pipelines/try.yml @@ -0,0 +1,78 @@ +pr: none +trigger: +- try + +variables: +- group: real-prod-credentials + +jobs: +- job: Linux + timeoutInMinutes: 600 + pool: + vmImage: ubuntu-16.04 + steps: + - template: steps/run.yml + strategy: + matrix: + dist-x86_64-linux: + IMAGE: dist-x86_64-linux + DEPLOY: 1 + + dist-x86_64-linux-alt: + IMAGE: dist-x86_64-linux + DEPLOY_ALT: 1 + +# The macOS and Windows builds here are currently disabled due to them not being +# overly necessary on `try` builds. We also don't actually have anything that +# consumes the artifacts currently. Perhaps one day we can reenable, but for now +# it helps free up capacity on Azure. +# - job: macOS +# timeoutInMinutes: 600 +# pool: +# vmImage: macos-10.13 +# steps: +# - template: steps/run.yml +# strategy: +# 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 --enable-lldb --set rust.jemalloc +# DEPLOY: 1 +# RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 +# MACOSX_DEPLOYMENT_TARGET: 10.7 +# NO_LLVM_ASSERTIONS: 1 +# NO_DEBUG_ASSERTIONS: 1 +# DIST_REQUIRE_ALL_TOOLS: 1 +# +# dist-x86_64-apple-alt: +# SCRIPT: ./x.py dist +# 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 +# NO_LLVM_ASSERTIONS: 1 +# NO_DEBUG_ASSERTIONS: 1 +# +# - job: Windows +# timeoutInMinutes: 600 +# pool: +# vmImage: 'vs2017-win2016' +# steps: +# - template: steps/run.yml +# strategy: +# matrix: +# dist-x86_64-msvc: +# RUST_CONFIGURE_ARGS: > +# --build=x86_64-pc-windows-msvc +# --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc +# --enable-full-tools +# --enable-profiler +# SCRIPT: python x.py dist +# DIST_REQUIRE_ALL_TOOLS: 1 +# DEPLOY: 1 +# +# dist-x86_64-msvc-alt: +# MSYS_BITS: 64 +# RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler +# SCRIPT: python x.py dist +# DEPLOY_ALT: 1 diff --git a/src/ci/run.sh b/src/ci/run.sh index b91859bfceb..e5e0e6cf603 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -50,7 +50,7 @@ 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" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.remap-debuginfo" - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.debuginfo-level-std=1" + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level-std=1" if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions" diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 412346bab25..3d80fb28c73 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2117,48 +2117,77 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // First (determined here), if `self` is by-reference, then the // implied output region is the region of the self parameter. if has_self { - // Look for `self: &'a Self` - also desugared from `&'a self`, - // and if that matches, use it for elision and return early. - let is_self_ty = |res: Res| { - if let Res::SelfTy(..) = res { - return true; - } - - // Can't always rely on literal (or implied) `Self` due - // to the way elision rules were originally specified. - let impl_self = impl_self.map(|ty| &ty.node); - if let Some(&hir::TyKind::Path(hir::QPath::Resolved(None, ref path))) = impl_self { - match path.res { - // Whitelist the types that unambiguously always - // result in the same type constructor being used - // (it can't differ between `Self` and `self`). - Res::Def(DefKind::Struct, _) - | Res::Def(DefKind::Union, _) - | Res::Def(DefKind::Enum, _) - | Res::PrimTy(_) => { - return res == path.res + struct SelfVisitor<'a> { + map: &'a NamedRegionMap, + impl_self: Option<&'a hir::TyKind>, + lifetime: Set1<Region>, + } + + impl SelfVisitor<'_> { + // Look for `self: &'a Self` - also desugared from `&'a self`, + // and if that matches, use it for elision and return early. + fn is_self_ty(&self, res: Res) -> bool { + if let Res::SelfTy(..) = res { + return true; + } + + // Can't always rely on literal (or implied) `Self` due + // to the way elision rules were originally specified. + if let Some(&hir::TyKind::Path(hir::QPath::Resolved(None, ref path))) = + self.impl_self + { + match path.res { + // Whitelist the types that unambiguously always + // result in the same type constructor being used + // (it can't differ between `Self` and `self`). + Res::Def(DefKind::Struct, _) + | Res::Def(DefKind::Union, _) + | Res::Def(DefKind::Enum, _) + | Res::PrimTy(_) => { + return res == path.res + } + _ => {} } - _ => {} } + + false } + } - false - }; + impl<'a> Visitor<'a> for SelfVisitor<'a> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'a> { + NestedVisitorMap::None + } - if let hir::TyKind::Rptr(lifetime_ref, ref mt) = inputs[0].node { - if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node { - if is_self_ty(path.res) { - if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) { - let scope = Scope::Elision { - elide: Elide::Exact(lifetime), - s: self.scope, - }; - self.with(scope, |_, this| this.visit_ty(output)); - return; + fn visit_ty(&mut self, ty: &'a hir::Ty) { + if let hir::TyKind::Rptr(lifetime_ref, ref mt) = ty.node { + if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node + { + if self.is_self_ty(path.res) { + if let Some(lifetime) = self.map.defs.get(&lifetime_ref.hir_id) { + self.lifetime.insert(*lifetime); + } + } } } + intravisit::walk_ty(self, ty) } } + + let mut visitor = SelfVisitor { + map: self.map, + impl_self: impl_self.map(|ty| &ty.node), + lifetime: Set1::Empty, + }; + visitor.visit_ty(&inputs[0]); + if let Set1::One(lifetime) = visitor.lifetime { + let scope = Scope::Elision { + elide: Elide::Exact(lifetime), + s: self.scope, + }; + self.with(scope, |_, this| this.visit_ty(output)); + return; + } } // Second, if there was exactly one lifetime (either a substitution or a diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 26c76ae5606..b2e319a478e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7716,6 +7716,11 @@ impl<'a> Parser<'a> { let ret = f(self); let last_token = if self.token_cursor.stack.len() == prev { &mut self.token_cursor.frame.last_token + } else if self.token_cursor.stack.get(prev).is_none() { + // This can happen due to a bad interaction of two unrelated recovery mechanisms with + // mismatched delimiters *and* recovery lookahead on the likely typo `pub ident(` + // (#62881). + return Ok((ret?, TokenStream::new(vec![]))); } else { &mut self.token_cursor.stack[prev].last_token }; @@ -7723,7 +7728,15 @@ impl<'a> Parser<'a> { // Pull out the tokens that we've collected from the call to `f` above. let mut collected_tokens = match *last_token { LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()), - LastToken::Was(_) => panic!("our vector went away?"), + LastToken::Was(ref was) => { + let msg = format!("our vector went away? - found Was({:?})", was); + debug!("collect_tokens: {}", msg); + self.sess.span_diagnostic.delay_span_bug(self.token.span, &msg); + // This can happen due to a bad interaction of two unrelated recovery mechanisms + // with mismatched delimiters *and* recovery lookahead on the likely typo + // `pub ident(` (#62895, different but similar to the case above). + return Ok((ret?, TokenStream::new(vec![]))); + } }; // If we're not at EOF our current token wasn't actually consumed by diff --git a/src/test/ui/parser/issue-62881.rs b/src/test/ui/parser/issue-62881.rs new file mode 100644 index 00000000000..1782c2e375d --- /dev/null +++ b/src/test/ui/parser/issue-62881.rs @@ -0,0 +1,6 @@ +fn main() {} + +fn f() -> isize { fn f() -> isize {} pub f< +//~^ ERROR missing `fn` or `struct` for function or struct definition +//~| ERROR mismatched types +//~ ERROR this file contains an un-closed delimiter diff --git a/src/test/ui/parser/issue-62881.stderr b/src/test/ui/parser/issue-62881.stderr new file mode 100644 index 00000000000..85c3575fd92 --- /dev/null +++ b/src/test/ui/parser/issue-62881.stderr @@ -0,0 +1,29 @@ +error: this file contains an un-closed delimiter + --> $DIR/issue-62881.rs:6:53 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | - un-closed delimiter +... +LL | + | ^ + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/issue-62881.rs:3:41 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | ^ + +error[E0308]: mismatched types + --> $DIR/issue-62881.rs:3:29 + | +LL | fn f() -> isize { fn f() -> isize {} pub f< + | - ^^^^^ expected isize, found () + | | + | this function's body doesn't return + | + = note: expected type `isize` + found type `()` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issue-62895.rs b/src/test/ui/parser/issue-62895.rs new file mode 100644 index 00000000000..53f17405d79 --- /dev/null +++ b/src/test/ui/parser/issue-62895.rs @@ -0,0 +1,11 @@ +fn main() {} + +fn v() -> isize { //~ ERROR mismatched types +mod _ { //~ ERROR expected identifier +pub fn g() -> isizee { //~ ERROR cannot find type `isizee` in this scope +mod _ { //~ ERROR expected identifier +pub g() -> is //~ ERROR missing `fn` for function definition +(), w20); +} +(), w20); //~ ERROR expected item, found `;` +} diff --git a/src/test/ui/parser/issue-62895.stderr b/src/test/ui/parser/issue-62895.stderr new file mode 100644 index 00000000000..882764cb946 --- /dev/null +++ b/src/test/ui/parser/issue-62895.stderr @@ -0,0 +1,49 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-62895.rs:4:5 + | +LL | mod _ { + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-62895.rs:6:5 + | +LL | mod _ { + | ^ expected identifier, found reserved identifier + +error: missing `fn` for function definition + --> $DIR/issue-62895.rs:7:4 + | +LL | pub g() -> is + | ^^^^ +help: add `fn` here to parse `g` as a public function + | +LL | pub fn g() -> is + | ^^ + +error: expected item, found `;` + --> $DIR/issue-62895.rs:10:9 + | +LL | (), w20); + | ^ help: remove this semicolon + +error[E0412]: cannot find type `isizee` in this scope + --> $DIR/issue-62895.rs:5:15 + | +LL | pub fn g() -> isizee { + | ^^^^^^ help: a primitive type with a similar name exists: `isize` + +error[E0308]: mismatched types + --> $DIR/issue-62895.rs:3:11 + | +LL | fn v() -> isize { + | - ^^^^^ expected isize, found () + | | + | this function's body doesn't return + | + = note: expected type `isize` + found type `()` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0412. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs new file mode 100644 index 00000000000..30020138812 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs @@ -0,0 +1,60 @@ +// check-pass + +use std::pin::Pin; +use std::task::{Context, Poll}; + +struct Foo; + +impl Foo { + fn pin_ref(self: Pin<&Self>) -> Pin<&Self> { self } + + fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut Self> { self } + + fn pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> Pin<Pin<Pin<&Self>>> { self } + + fn pin_ref_impl_trait(self: Pin<&Self>) -> impl Clone + '_ { self } + + fn b(self: Pin<&Foo>, f: &Foo) -> Pin<&Foo> { self } +} + +type Alias<T> = Pin<T>; +impl Foo { + fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self } +} + +struct Bar<T: Unpin, U: Unpin> { + field1: T, + field2: U, +} + +impl<T: Unpin, U: Unpin> Bar<T, U> { + fn fields(self: Pin<&mut Self>) -> (Pin<&mut T>, Pin<&mut U>) { + let this = self.get_mut(); + (Pin::new(&mut this.field1), Pin::new(&mut this.field2)) + } +} + +trait AsyncBufRead { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll<std::io::Result<&[u8]>>; +} + +struct Baz(Vec<u8>); + +impl AsyncBufRead for Baz { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll<std::io::Result<&[u8]>> + { + Poll::Ready(Ok(&self.get_mut().0)) + } +} + +fn main() { + let mut foo = Foo; + { Pin::new(&foo).pin_ref() }; + { Pin::new(&mut foo).pin_mut() }; + { Pin::new(Pin::new(Pin::new(&foo))).pin_pin_pin_ref() }; + { Pin::new(&foo).pin_ref_impl_trait() }; + let mut bar = Bar { field1: 0u8, field2: 1u8 }; + { Pin::new(&mut bar).fields() }; +} diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr new file mode 100644 index 00000000000..dcfc9ba511d --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr @@ -0,0 +1,14 @@ +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:31 + | +LL | fn f(self: Pin<&Self>) -> impl Clone { self } + | - ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` + | | + | let's call the lifetime of this reference `'1` +help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint + | +LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs new file mode 100644 index 00000000000..ad8959727cb --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs @@ -0,0 +1,13 @@ +// compile-fail + +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn f(self: Pin<&Self>) -> impl Clone { self } //~ ERROR cannot infer an appropriate lifetime +} + +fn main() { + { Pin::new(&Foo).f() }; +} diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr new file mode 100644 index 00000000000..5118280e7ec --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -0,0 +1,20 @@ +error: cannot infer an appropriate lifetime + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:44 + | +LL | fn f(self: Pin<&Self>) -> impl Clone { self } + | ---------- ^^^^ ...but this borrow... + | | + | this return type evaluates to the `'static` lifetime... + | +note: ...can't outlive the anonymous lifetime #1 defined on the method body at 8:5 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:5 + | +LL | fn f(self: Pin<&Self>) -> impl Clone { self } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 8:5 + | +LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr new file mode 100644 index 00000000000..8a0f1a804ad --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr @@ -0,0 +1,28 @@ +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46 + | +LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } + | - - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | | + | | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` + +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:69 + | +LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | - - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | | + | | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` + +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58 + | +LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } + | -- ---- has type `std::pin::Pin<&'1 Foo>` ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | | + | lifetime `'a` defined here + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs new file mode 100644 index 00000000000..fc5f94201b8 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs @@ -0,0 +1,18 @@ +// compile-fail + +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } //~ ERROR E0623 + + fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } //~ ERROR E0623 +} + +type Alias<T> = Pin<T>; +impl Foo { + fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } //~ ERROR E0623 +} + +fn main() {} diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr new file mode 100644 index 00000000000..3296e14f806 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr @@ -0,0 +1,26 @@ +error[E0623]: lifetime mismatch + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46 + | +LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } + | ---- ---- ^ ...but data from `f` is returned here + | | + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:76 + | +LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | ---- ----------------- ^ ...but data from `f` is returned here + | | + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58 + | +LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } + | ------ --- ^^^ ...but data from `arg` is returned here + | | + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md new file mode 100644 index 00000000000..7ace2e0c890 --- /dev/null +++ b/src/test/ui/self/elision/README.md @@ -0,0 +1,44 @@ +Test cases intended to document behavior and try to exhaustively +explore the combinations. + +## Confidence + +These tests are not yet considered 100% normative, in that some +aspects of the current behavior are not desirable. This is expressed +in the "confidence" field in the following table. Values: + +| Confidence | Interpretation | +| --- | --- | +| 100% | this will remain recommended behavior | +| 75% | unclear whether we will continue to accept this | +| 50% | this will likely be deprecated but remain valid | +| 25% | this could change in the future | +| 0% | this is definitely bogus and will likely change in the future in *some* way | + +## Tests + +| Test file | `Self` type | Pattern | Current elision behavior | Confidence | +| --- | --- | --- | --- | --- | +| `self.rs` | `Struct` | `Self` | ignore `self` parameter | 100% | +| `struct.rs` | `Struct` | `Struct` | ignore `self` parameter | 100% | +| `alias.rs` | `Struct` | `Alias` | ignore `self` parameter | 100% | +| `ref-self.rs` | `Struct` | `&Self` | take lifetime from `&Self` | 100% | +| `ref-mut-self.rs` | `Struct` | `&mut Self` | take lifetime from `&mut Self` | 100% | +| `ref-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% | +| `ref-mut-struct.rs` | `Struct` | `&mut Struct` | take lifetime from `&mut Self` | 50% | +| `ref-alias.rs` | `Struct` | `&Alias` | ignore `Alias` | 0% | +| `ref-mut-alias.rs` | `Struct` | `&mut Alias` | ignore `Alias` | 0% | +| `lt-self.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 25% | +| `lt-struct.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% | +| `lt-alias.rs` | `Alias<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% | +| `lt-ref-self.rs` | `Struct<'a>` | `&Self` | take lifetime from `&Self` | 75% | + +In each case, we test the following patterns: + +- `self: XXX` +- `self: Box<XXX>` +- `self: Pin<XXX>` +- `self: Box<Box<XXX>>` +- `self: Box<Pin<XXX>>` + +In the non-reference cases, `Pin` causes errors so we substitute `Rc`. diff --git a/src/test/ui/self/elision/alias.rs b/src/test/ui/self/elision/alias.rs new file mode 100644 index 00000000000..b5aacfaeec4 --- /dev/null +++ b/src/test/ui/self/elision/alias.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + + fn alias(self: Alias, f: &u32) -> &u32 { + f + } + + fn box_Alias(self: Box<Alias>, f: &u32) -> &u32 { + f + } + + fn rc_Alias(self: Rc<Alias>, f: &u32) -> &u32 { + f + } + + fn box_box_Alias(self: Box<Box<Alias>>, f: &u32) -> &u32 { + f + } + + fn box_rc_Alias(self: Box<Rc<Alias>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/assoc.rs b/src/test/ui/self/elision/assoc.rs new file mode 100644 index 00000000000..163eb49383a --- /dev/null +++ b/src/test/ui/self/elision/assoc.rs @@ -0,0 +1,40 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +trait Trait { + type AssocType; +} + +struct Struct { } + +impl Trait for Struct { + type AssocType = Self; +} + +impl Struct { + fn assoc(self: <Struct as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + fn box_AssocType(self: Box<<Struct as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn rc_AssocType(self: Rc<<Struct as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn box_box_AssocType(self: Box<Box<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } + + fn box_rc_AssocType(self: Box<Rc<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-alias.rs b/src/test/ui/self/elision/lt-alias.rs new file mode 100644 index 00000000000..df2300deda2 --- /dev/null +++ b/src/test/ui/self/elision/lt-alias.rs @@ -0,0 +1,38 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +type Alias<'a> = Struct<'a>; + +impl<'a> Alias<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 { + f + } + + fn take_Box_Alias(self: Box<Alias<'a>>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Alias(self: Box<Box<Alias<'a>>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Alias(self: Rc<Alias<'a>>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Alias(self: Box<Rc<Alias<'a>>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-assoc.rs b/src/test/ui/self/elision/lt-assoc.rs new file mode 100644 index 00000000000..70573598fcb --- /dev/null +++ b/src/test/ui/self/elision/lt-assoc.rs @@ -0,0 +1,44 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +trait Trait { + type AssocType; +} + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Trait for Struct<'a> { + type AssocType = Self; +} + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_AssocType(self: <Struct<'a> as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + fn take_Box_AssocType(self: Box<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_AssocType(self: Box<Box<<Struct<'a> as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_AssocType(self: Rc<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_AssocType(self: Box<Rc<<Struct<'a> as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-ref-self.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr new file mode 100644 index 00000000000..e97a01e746d --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self.nll.stderr @@ -0,0 +1,62 @@ +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:12:9 + | +LL | fn ref_self(&self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:18:9 + | +LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:22:9 + | +LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:26:9 + | +LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:30:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:34:9 + | +LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/lt-ref-self.rs b/src/test/ui/self/elision/lt-ref-self.rs new file mode 100644 index 00000000000..8abf2876a5c --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self.rs @@ -0,0 +1,38 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct<'a> { data: &'a u32 } + +impl<'a> Struct<'a> { + // Test using `&self` sugar: + + fn ref_self(&self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + // Test using `&Self` explicitly: + + fn ref_Self(self: &Self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.stderr new file mode 100644 index 00000000000..f73b3eddd38 --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self.stderr @@ -0,0 +1,62 @@ +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:12:9 + | +LL | fn ref_self(&self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:18:9 + | +LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:22:9 + | +LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:26:9 + | +LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:30:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:34:9 + | +LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/lt-self.rs b/src/test/ui/self/elision/lt-self.rs new file mode 100644 index 00000000000..9b0ee5e42a5 --- /dev/null +++ b/src/test/ui/self/elision/lt-self.rs @@ -0,0 +1,49 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; +use std::rc::Rc; + +struct Struct<'a> { + x: &'a u32 +} + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 { + f + } + + // N/A + //fn take_Pin_Self(self: Pin<Self>, f: &u32) -> &u32 { + // f + //} + + // N/A + //fn take_Box_Pin_Self(self: Box<Pin<Self>>, f: &u32) -> &u32 { + // f + //} +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-struct.rs b/src/test/ui/self/elision/lt-struct.rs new file mode 100644 index 00000000000..e41dfbbe0bf --- /dev/null +++ b/src/test/ui/self/elision/lt-struct.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Struct(self: Struct<'a>, f: &u32) -> &u32 { + f + } + + fn take_Box_Struct(self: Box<Struct<'a>>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Struct(self: Box<Box<Struct<'a>>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Struct(self: Rc<Struct<'a>>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Struct(self: Box<Rc<Struct<'a>>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/multiple-ref-self.rs b/src/test/ui/self/elision/multiple-ref-self.rs new file mode 100644 index 00000000000..f39613d0c90 --- /dev/null +++ b/src/test/ui/self/elision/multiple-ref-self.rs @@ -0,0 +1,43 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::pin::Pin; + +struct Struct { } + +struct Wrap<T, P>(T, PhantomData<P>); + +impl<T, P> Deref for Wrap<T, P> { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using multiple `&Self`: + + fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 { + f + } + + fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 { + f + } + + fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 { + f + } + + fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 { + f + } + + fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-alias.rs b/src/test/ui/self/elision/ref-alias.rs new file mode 100644 index 00000000000..d83ac612235 --- /dev/null +++ b/src/test/ui/self/elision/ref-alias.rs @@ -0,0 +1,39 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + // + // FIXME. We currently fail to recognize this as the self type, which + // feels like a bug. + + fn ref_Alias(self: &Alias, f: &u32) -> &u32 { + f + } + + fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 { + f + } + + fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-assoc.rs b/src/test/ui/self/elision/ref-assoc.rs new file mode 100644 index 00000000000..f9354bc8847 --- /dev/null +++ b/src/test/ui/self/elision/ref-assoc.rs @@ -0,0 +1,40 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +trait Trait { + type AssocType; +} + +struct Struct { } + +impl Trait for Struct { + type AssocType = Self; +} + +impl Struct { + fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-alias.rs b/src/test/ui/self/elision/ref-mut-alias.rs new file mode 100644 index 00000000000..395816f8f5d --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-alias.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + + fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 { + f + } + + fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 { + f + } + + fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-self.nll.stderr b/src/test/ui/self/elision/ref-mut-self.nll.stderr new file mode 100644 index 00000000000..3a8ae3fdcba --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self.nll.stderr @@ -0,0 +1,62 @@ +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:12:9 + | +LL | fn ref_self(&mut self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:18:9 + | +LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:22:9 + | +LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:26:9 + | +LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:30:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:34:9 + | +LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/ref-mut-self.rs b/src/test/ui/self/elision/ref-mut-self.rs new file mode 100644 index 00000000000..a7ea47bb7f6 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self.rs @@ -0,0 +1,38 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut self` sugar: + + fn ref_self(&mut self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + // Test using `&mut Self` explicitly: + + fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr new file mode 100644 index 00000000000..37984cd72fb --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self.stderr @@ -0,0 +1,62 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:12:9 + | +LL | fn ref_self(&mut self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:18:9 + | +LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:22:9 + | +LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:26:9 + | +LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:30:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:34:9 + | +LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/ref-mut-struct.nll.stderr b/src/test/ui/self/elision/ref-mut-struct.nll.stderr new file mode 100644 index 00000000000..66152ba40a5 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct.nll.stderr @@ -0,0 +1,52 @@ +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:12:9 + | +LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:16:9 + | +LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:20:9 + | +LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:24:9 + | +LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:28:9 + | +LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/ref-mut-struct.rs b/src/test/ui/self/elision/ref-mut-struct.rs new file mode 100644 index 00000000000..795ddf8ac13 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct.rs @@ -0,0 +1,32 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut Struct` explicitly: + + fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr new file mode 100644 index 00000000000..2a4826905b9 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct.stderr @@ -0,0 +1,52 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:12:9 + | +LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:16:9 + | +LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:20:9 + | +LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:24:9 + | +LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:28:9 + | +LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/ref-self.nll.stderr b/src/test/ui/self/elision/ref-self.nll.stderr new file mode 100644 index 00000000000..20045be0527 --- /dev/null +++ b/src/test/ui/self/elision/ref-self.nll.stderr @@ -0,0 +1,72 @@ +error: lifetime may not live long enough + --> $DIR/ref-self.rs:21:9 + | +LL | fn ref_self(&self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:27:9 + | +LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:31:9 + | +LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:35:9 + | +LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:39:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:43:9 + | +LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:47:9 + | +LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/self/elision/ref-self.rs b/src/test/ui/self/elision/ref-self.rs new file mode 100644 index 00000000000..e389d8518ad --- /dev/null +++ b/src/test/ui/self/elision/ref-self.rs @@ -0,0 +1,51 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::pin::Pin; + +struct Struct { } + +struct Wrap<T, P>(T, PhantomData<P>); + +impl<T, P> Deref for Wrap<T, P> { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using `&self` sugar: + + fn ref_self(&self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + // Test using `&Self` explicitly: + + fn ref_Self(self: &Self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-self.stderr b/src/test/ui/self/elision/ref-self.stderr new file mode 100644 index 00000000000..611498f18da --- /dev/null +++ b/src/test/ui/self/elision/ref-self.stderr @@ -0,0 +1,72 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:21:9 + | +LL | fn ref_self(&self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:27:9 + | +LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:31:9 + | +LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:35:9 + | +LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:39:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:43:9 + | +LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:47:9 + | +LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + | --- --- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/self/elision/ref-struct.nll.stderr b/src/test/ui/self/elision/ref-struct.nll.stderr new file mode 100644 index 00000000000..a258bc9f743 --- /dev/null +++ b/src/test/ui/self/elision/ref-struct.nll.stderr @@ -0,0 +1,52 @@ +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:12:9 + | +LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:16:9 + | +LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:20:9 + | +LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:24:9 + | +LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:28:9 + | +LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/ref-struct.rs b/src/test/ui/self/elision/ref-struct.rs new file mode 100644 index 00000000000..342d6d2b363 --- /dev/null +++ b/src/test/ui/self/elision/ref-struct.rs @@ -0,0 +1,32 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&Struct` explicitly: + + fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr new file mode 100644 index 00000000000..186e651c143 --- /dev/null +++ b/src/test/ui/self/elision/ref-struct.stderr @@ -0,0 +1,52 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:12:9 + | +LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:16:9 + | +LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:20:9 + | +LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:24:9 + | +LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:28:9 + | +LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/self.rs b/src/test/ui/self/elision/self.rs new file mode 100644 index 00000000000..dbcef71ba14 --- /dev/null +++ b/src/test/ui/self/elision/self.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/struct.rs b/src/test/ui/self/elision/struct.rs new file mode 100644 index 00000000000..227e993bd3c --- /dev/null +++ b/src/test/ui/self/elision/struct.rs @@ -0,0 +1,32 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + fn ref_Struct(self: Struct, f: &u32) -> &u32 { + f + } + + fn box_Struct(self: Box<Struct>, f: &u32) -> &u32 { + f + } + + fn rc_Struct(self: Rc<Struct>, f: &u32) -> &u32 { + f + } + + fn box_box_Struct(self: Box<Box<Struct>>, f: &u32) -> &u32 { + f + } + + fn box_rc_Struct(self: Box<Rc<Struct>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/self_lifetime.rs b/src/test/ui/self/self_lifetime.rs new file mode 100644 index 00000000000..f04bd83ab6e --- /dev/null +++ b/src/test/ui/self/self_lifetime.rs @@ -0,0 +1,15 @@ +// check-pass + +// https://github.com/rust-lang/rust/pull/60944#issuecomment-495346120 + +struct Foo<'a>(&'a ()); +impl<'a> Foo<'a> { + fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } +} + +type Alias = Foo<'static>; +impl Alias { + fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } +} + +fn main() {} diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 4c1fa54d10f58d69ac9ff55be68e1b1c25ecb81 +Subproject 9edd089168f8795b3890bc3daf5b99f03e9f876 |
