diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml index 687856cca6b62..06fa3bd9f4347 100644 --- a/src/ci/azure-pipelines/auto.yml +++ b/src/ci/azure-pipelines/auto.yml @@ -273,7 +273,7 @@ jobs: 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_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 # FIXME(#59637) @@ -283,14 +283,14 @@ jobs: 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_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc 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_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 # FIXME(#59637) @@ -300,7 +300,7 @@ jobs: 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_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 @@ -327,7 +327,7 @@ jobs: 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_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 DIST_REQUIRE_ALL_TOOLS: 1 @@ -336,7 +336,7 @@ jobs: 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_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 DIST_REQUIRE_ALL_TOOLS: 1 diff --git a/src/ci/azure-pipelines/steps/install-clang.yml b/src/ci/azure-pipelines/steps/install-clang.yml index 45ec767e0b875..14daf81b43075 100644 --- a/src/ci/azure-pipelines/steps/install-clang.yml +++ b/src/ci/azure-pipelines/steps/install-clang.yml @@ -36,7 +36,7 @@ steps: 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 - + curl -f https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/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" 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-sccache.yml b/src/ci/azure-pipelines/steps/install-sccache.yml index 427e50f571f76..d4679c1c6733e 100644 --- a/src/ci/azure-pipelines/steps/install-sccache.yml +++ b/src/ci/azure-pipelines/steps/install-sccache.yml @@ -2,14 +2,14 @@ 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 + curl -fo /usr/local/bin/sccache https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/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" + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf sccache\sccache.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/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')) 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..9aaeb4b79d634 100644 --- a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml +++ b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml @@ -4,7 +4,7 @@ steps: # 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 + curl -O https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/wix311-binaries.zip echo "##vso[task.setvariable variable=WIX]`pwd`/wix" mkdir -p wix/bin cd wix/bin @@ -18,7 +18,7 @@ steps: # 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" + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/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 @@ -109,7 +109,7 @@ steps: # 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" + powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-03-15-ninja-win.zip https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/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 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-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/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 9f531f5b83c75..3d04f30e7bde5 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -1163,6 +1163,9 @@ impl FusedIterator for Drain<'_, T> {} #[stable(feature = "binary_heap_extras_15", since = "1.5.0")] impl From> for BinaryHeap { + /// Converts a `Vec` into a `BinaryHeap`. + /// + /// This conversion happens in-place, and has `O(n)` time complexity. fn from(vec: Vec) -> BinaryHeap { let mut heap = BinaryHeap { data: vec }; heap.rebuild(); diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index e6a6fdde54042..4087333e2cf6d 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -14,6 +14,7 @@ use crate::fmt; use crate::ops::Range; use crate::iter::FusedIterator; +use crate::str::from_utf8_unchecked; /// An iterator over the escaped version of a byte. /// @@ -22,6 +23,7 @@ use crate::iter::FusedIterator; /// /// [`escape_default`]: fn.escape_default.html #[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] pub struct EscapeDefault { range: Range, data: [u8; 4], @@ -130,6 +132,13 @@ impl ExactSizeIterator for EscapeDefault {} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for EscapeDefault {} +#[stable(feature = "ascii_escape_display", since = "1.39.0")] +impl fmt::Display for EscapeDefault { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(unsafe { from_utf8_unchecked(&self.data[self.range.clone()]) }) + } +} + #[stable(feature = "std_debug", since = "1.16.0")] impl fmt::Debug for EscapeDefault { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index c4cbf40a93a15..685540ba6fc26 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -553,8 +553,6 @@ impl PartialEq for BuildHasherDefault { #[stable(since = "1.29.0", feature = "build_hasher_eq")] impl Eq for BuildHasherDefault {} -////////////////////////////////////////////////////////////////////////////// - mod impls { use crate::mem; use crate::slice; diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index fe69c9e634635..803a2ebbb012d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -337,49 +337,6 @@ enum AnonymousLifetimeMode { /// Pass responsibility to `resolve_lifetime` code for all cases. PassThrough, - - /// Used in the return types of `async fn` where there exists - /// exactly one argument-position elided lifetime. - /// - /// In `async fn`, we lower the arguments types using the `CreateParameter` - /// mode, meaning that non-`dyn` elided lifetimes are assigned a fresh name. - /// If any corresponding elided lifetimes appear in the output, we need to - /// replace them with references to the fresh name assigned to the corresponding - /// elided lifetime in the arguments. - /// - /// For **Modern cases**, replace the anonymous parameter with a - /// reference to a specific freshly-named lifetime that was - /// introduced in argument - /// - /// For **Dyn Bound** cases, pass responsibility to - /// `resole_lifetime` code. - Replace(LtReplacement), -} - -/// The type of elided lifetime replacement to perform on `async fn` return types. -#[derive(Copy, Clone)] -enum LtReplacement { - /// Fresh name introduced by the single non-dyn elided lifetime - /// in the arguments of the async fn. - Some(ParamName), - - /// There is no single non-dyn elided lifetime because no lifetimes - /// appeared in the arguments. - NoLifetimes, - - /// There is no single non-dyn elided lifetime because multiple - /// lifetimes appeared in the arguments. - MultipleLifetimes, -} - -/// Calculates the `LtReplacement` to use for elided lifetimes in the return -/// type based on the fresh elided lifetimes introduced in argument position. -fn get_elided_lt_replacement(arg_position_lifetimes: &[(Span, ParamName)]) -> LtReplacement { - match arg_position_lifetimes { - [] => LtReplacement::NoLifetimes, - [(_span, param)] => LtReplacement::Some(*param), - _ => LtReplacement::MultipleLifetimes, - } } struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[NodeId; 1]> } @@ -1953,8 +1910,7 @@ impl<'a> LoweringContext<'a> { err.emit(); } AnonymousLifetimeMode::PassThrough | - AnonymousLifetimeMode::ReportError | - AnonymousLifetimeMode::Replace(_) => { + AnonymousLifetimeMode::ReportError => { self.sess.buffer_lint_with_diagnostic( ELIDED_LIFETIMES_IN_PATHS, CRATE_NODE_ID, @@ -2141,7 +2097,6 @@ impl<'a> LoweringContext<'a> { // Remember how many lifetimes were already around so that we can // only look at the lifetime parameters introduced by the arguments. - let lifetime_count_before_args = self.lifetimes_to_define.len(); let inputs = self.with_anonymous_lifetime_mode(lt_mode, |this| { decl.inputs .iter() @@ -2156,16 +2111,10 @@ impl<'a> LoweringContext<'a> { }); let output = if let Some(ret_id) = make_ret_async { - // Calculate the `LtReplacement` to use for any return-position elided - // lifetimes based on the elided lifetime parameters introduced in the args. - let lt_replacement = get_elided_lt_replacement( - &self.lifetimes_to_define[lifetime_count_before_args..] - ); self.lower_async_fn_ret_ty( &decl.output, in_band_ty_params.expect("`make_ret_async` but no `fn_def_id`").0, ret_id, - lt_replacement, ) } else { match decl.output { @@ -2230,7 +2179,6 @@ impl<'a> LoweringContext<'a> { output: &FunctionRetTy, fn_def_id: DefId, opaque_ty_node_id: NodeId, - elided_lt_replacement: LtReplacement, ) -> hir::FunctionRetTy { let span = output.span(); @@ -2248,9 +2196,65 @@ impl<'a> LoweringContext<'a> { self.allocate_hir_id_counter(opaque_ty_node_id); + // When we create the opaque type for this async fn, it is going to have + // to capture all the lifetimes involved in the signature (including in the + // return type). This is done by introducing lifetime parameters for: + // + // - all the explicitly declared lifetimes from the impl and function itself; + // - all the elided lifetimes in the fn arguments; + // - all the elided lifetimes in the return type. + // + // So for example in this snippet: + // + // ```rust + // impl<'a> Foo<'a> { + // async fn bar<'b>(&self, x: &'b Vec, y: &str) -> &u32 { + // // ^ '0 ^ '1 ^ '2 + // // elided lifetimes used below + // } + // } + // ``` + // + // we would create an opaque type like: + // + // ``` + // type Bar<'a, 'b, '0, '1, '2> = impl Future; + // ``` + // + // and we would then desugar `bar` to the equivalent of: + // + // ```rust + // impl<'a> Foo<'a> { + // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_> + // } + // ``` + // + // Note that the final parameter to `Bar` is `'_`, not `'2` -- + // this is because the elided lifetimes from the return type + // should be figured out using the ordinary elision rules, and + // this desugaring achieves that. + // + // The variable `input_lifetimes_count` tracks the number of + // lifetime parameters to the opaque type *not counting* those + // lifetimes elided in the return type. This includes those + // that are explicitly declared (`in_scope_lifetimes`) and + // those elided lifetimes we found in the arguments (current + // content of `lifetimes_to_define`). Next, we will process + // the return type, which will cause `lifetimes_to_define` to + // grow. + let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len(); + let (opaque_ty_id, lifetime_params) = self.with_hir_id_owner(opaque_ty_node_id, |this| { + // We have to be careful to get elision right here. The + // idea is that we create a lifetime parameter for each + // lifetime in the return type. So, given a return type + // like `async fn foo(..) -> &[&u32]`, we lower to `impl + // Future`. + // + // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and + // hence the elision takes place at the fn site. let future_bound = this.with_anonymous_lifetime_mode( - AnonymousLifetimeMode::Replace(elided_lt_replacement), + AnonymousLifetimeMode::CreateParameter, |this| this.lower_async_fn_output_type_to_future_bound( output, fn_def_id, @@ -2304,19 +2308,52 @@ impl<'a> LoweringContext<'a> { (opaque_ty_id, lifetime_params) }); - let generic_args = - lifetime_params - .iter().cloned() - .map(|(span, hir_name)| { - GenericArg::Lifetime(hir::Lifetime { - hir_id: self.next_id(), - span, - name: hir::LifetimeName::Param(hir_name), - }) + // As documented above on the variable + // `input_lifetimes_count`, we need to create the lifetime + // arguments to our opaque type. Continuing with our example, + // we're creating the type arguments for the return type: + // + // ``` + // Bar<'a, 'b, '0, '1, '_> + // ``` + // + // For the "input" lifetime parameters, we wish to create + // references to the parameters themselves, including the + // "implicit" ones created from parameter types (`'a`, `'b`, + // '`0`, `'1`). + // + // For the "output" lifetime parameters, we just want to + // generate `'_`. + let mut generic_args: Vec<_> = + lifetime_params[..input_lifetimes_count] + .iter() + .map(|&(span, hir_name)| { + // Input lifetime like `'a` or `'1`: + GenericArg::Lifetime(hir::Lifetime { + hir_id: self.next_id(), + span, + name: hir::LifetimeName::Param(hir_name), }) - .collect(); + }) + .collect(); + generic_args.extend( + lifetime_params[input_lifetimes_count..] + .iter() + .map(|&(span, _)| { + // Output lifetime like `'_`. + GenericArg::Lifetime(hir::Lifetime { + hir_id: self.next_id(), + span, + name: hir::LifetimeName::Implicit, + }) + }) + ); - let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args); + // Create the `Foo<...>` refernece itself. Note that the `type + // Foo = impl Trait` is, internally, created as a child of the + // async fn, so the *type parameters* are inherited. It's + // only the lifetime parameters that we must supply. + let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args.into()); hir::FunctionRetTy::Return(P(hir::Ty { node: opaque_ty_ref, @@ -2412,11 +2449,6 @@ impl<'a> LoweringContext<'a> { } AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span), - - AnonymousLifetimeMode::Replace(replacement) => { - let hir_id = self.lower_node_id(l.id); - self.replace_elided_lifetime(hir_id, span, replacement) - } }, ident => { self.maybe_collect_in_band_lifetime(ident); @@ -2439,39 +2471,6 @@ impl<'a> LoweringContext<'a> { } } - /// Replace a return-position elided lifetime with the elided lifetime - /// from the arguments. - fn replace_elided_lifetime( - &mut self, - hir_id: hir::HirId, - span: Span, - replacement: LtReplacement, - ) -> hir::Lifetime { - let multiple_or_none = match replacement { - LtReplacement::Some(name) => { - return hir::Lifetime { - hir_id, - span, - name: hir::LifetimeName::Param(name), - }; - } - LtReplacement::MultipleLifetimes => "multiple", - LtReplacement::NoLifetimes => "none", - }; - - let mut err = crate::middle::resolve_lifetime::report_missing_lifetime_specifiers( - self.sess, - span, - 1, - ); - err.note(&format!( - "return-position elided lifetimes require exactly one \ - input-position elided lifetime, found {}.", multiple_or_none)); - err.emit(); - - hir::Lifetime { hir_id, span, name: hir::LifetimeName::Error } - } - fn lower_generic_params( &mut self, params: &[GenericParam], @@ -3174,10 +3173,6 @@ impl<'a> LoweringContext<'a> { AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span), AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span), - - AnonymousLifetimeMode::Replace(replacement) => { - self.new_replacement_lifetime(replacement, span) - } } } @@ -3231,10 +3226,6 @@ impl<'a> LoweringContext<'a> { // This is the normal case. AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span), - AnonymousLifetimeMode::Replace(replacement) => { - self.new_replacement_lifetime(replacement, span) - } - AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span), } } @@ -3266,25 +3257,11 @@ impl<'a> LoweringContext<'a> { // This is the normal case. AnonymousLifetimeMode::PassThrough => {} - - // We don't need to do any replacement here as this lifetime - // doesn't refer to an elided lifetime elsewhere in the function - // signature. - AnonymousLifetimeMode::Replace(_) => {} } self.new_implicit_lifetime(span) } - fn new_replacement_lifetime( - &mut self, - replacement: LtReplacement, - span: Span, - ) -> hir::Lifetime { - let hir_id = self.next_id(); - self.replace_elided_lifetime(hir_id, span, replacement) - } - fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime { hir::Lifetime { hir_id: self.next_id(), diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 424d7c0038389..e11ba75da9866 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -120,6 +120,9 @@ impl Diagnostic { } /// Adds a span/label to be included in the resulting snippet. + /// This label will be shown together with the original span/label used when creating the + /// diagnostic, *not* a span added by one of the `span_*` methods. + /// /// This is pushed onto the `MultiSpan` that was created when the /// diagnostic was first built. If you don't call this function at /// all, and you just supplied a `Span` to create the diagnostic, @@ -196,6 +199,7 @@ impl Diagnostic { self } + /// Prints the span with a note above it. pub fn span_note>(&mut self, sp: S, msg: &str) @@ -209,6 +213,7 @@ impl Diagnostic { self } + /// Prints the span with a warn above it. pub fn span_warn>(&mut self, sp: S, msg: &str) @@ -222,6 +227,7 @@ impl Diagnostic { self } + /// Prints the span with some help above it. pub fn span_help>(&mut self, sp: S, msg: &str) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 36d80d0cb5767..52225ea8f024f 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -540,6 +540,12 @@ pub fn error_to_const_error<'mir, 'tcx>( ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span } } +pub fn note_on_undefined_behavior_error() -> &'static str { + "The rules on what exactly is undefined behavior aren't clear, \ + so this check might be overzealous. Please open an issue on the rust compiler \ + repository if you believe it should not be considered undefined behavior" +} + fn validate_and_turn_into_const<'tcx>( tcx: TyCtxt<'tcx>, constant: RawConst<'tcx>, @@ -579,10 +585,7 @@ fn validate_and_turn_into_const<'tcx>( let err = error_to_const_error(&ecx, error); match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") { Ok(mut diag) => { - diag.note("The rules on what exactly is undefined behavior aren't clear, \ - so this check might be overzealous. Please open an issue on the rust compiler \ - repository if you believe it should not be considered undefined behavior", - ); + diag.note(note_on_undefined_behavior_error()); diag.emit(); ErrorHandled::Reported } diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 1074ab941a761..32ba70a81c997 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -296,11 +296,7 @@ pub fn intern_const_alloc_recursive( let err = crate::const_eval::error_to_const_error(&ecx, error); match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") { Ok(mut diag) => { - diag.note("The rules on what exactly is undefined behavior aren't clear, \ - so this check might be overzealous. Please open an issue on the rust \ - compiler repository if you believe it should not be considered \ - undefined behavior", - ); + diag.note(crate::const_eval::note_on_undefined_behavior_error()); diag.emit(); } Err(ErrorHandled::TooGeneric) | diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4fb28db6e94fa..14fc0d6347e4b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1325,12 +1325,94 @@ fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) { check_packed(tcx, span, def_id); } +/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo` +/// projections that would result in "inheriting lifetimes". fn check_opaque<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, span: Span, - origin: &hir::OpaqueTyOrigin + origin: &hir::OpaqueTyOrigin, +) { + check_opaque_for_inheriting_lifetimes(tcx, def_id, span); + check_opaque_for_cycles(tcx, def_id, substs, span, origin); +} + +/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result +/// in "inheriting lifetimes". +fn check_opaque_for_inheriting_lifetimes( + tcx: TyCtxt<'tcx>, + def_id: DefId, + span: Span, +) { + let item = tcx.hir().expect_item( + tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local")); + debug!("check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}", + def_id, span, item); + + #[derive(Debug)] + struct ProhibitOpaqueVisitor<'tcx> { + opaque_identity_ty: Ty<'tcx>, + generics: &'tcx ty::Generics, + }; + + impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> { + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t); + if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) } + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { + debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r); + if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r { + return *index < self.generics.parent_count as u32; + } + + r.super_visit_with(self) + } + } + + let prohibit_opaque = match item.node { + ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. }) | + ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => { + let mut visitor = ProhibitOpaqueVisitor { + opaque_identity_ty: tcx.mk_opaque( + def_id, InternalSubsts::identity_for_item(tcx, def_id)), + generics: tcx.generics_of(def_id), + }; + debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor); + + tcx.predicates_of(def_id).predicates.iter().any( + |(predicate, _)| predicate.visit_with(&mut visitor)) + }, + _ => false, + }; + + debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque); + if prohibit_opaque { + let is_async = match item.node { + ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin { + hir::OpaqueTyOrigin::AsyncFn => true, + _ => false, + }, + _ => unreachable!(), + }; + + tcx.sess.span_err(span, &format!( + "`{}` return type cannot contain a projection or `Self` that references lifetimes from \ + a parent scope", + if is_async { "async fn" } else { "impl Trait" }, + )); + } +} + +/// Checks that an opaque type does not contain cycles. +fn check_opaque_for_cycles<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + substs: SubstsRef<'tcx>, + span: Span, + origin: &hir::OpaqueTyOrigin, ) { if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) { if let hir::OpaqueTyOrigin::AsyncFn = origin { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1c1428c5713f7..2286e74e63304 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1236,7 +1236,7 @@ impl<'a> Parser<'a> { let args: Vec<_> = args.into_iter().filter_map(|x| x).collect(); - if c_variadic && args.is_empty() { + if c_variadic && args.len() <= 1 { self.span_err(sp, "C-variadic function must be declared with at least one named argument"); } diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index 4432c1329cbfe..4fdb000ed9029 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -224,6 +224,10 @@ impl<'a> Parser<'a> { self.err_dotdotdot_syntax(self.token.span); } + if self.token == token::LArrow { + self.err_larrow_operator(self.token.span); + } + self.bump(); if op.is_comparison() { self.check_no_chained_comparison(&lhs, &op); @@ -1702,6 +1706,19 @@ impl<'a> Parser<'a> { .emit(); } + fn err_larrow_operator(&self, span: Span) { + self.struct_span_err( + span, + "unexpected token: `<-`" + ).span_suggestion( + span, + "if you meant to write a comparison against a negative value, add a \ + space in between `<` and `-`", + "< -".to_string(), + Applicability::MaybeIncorrect + ).emit(); + } + fn mk_assign_op(&self, binop: BinOp, lhs: P, rhs: P) -> ExprKind { ExprKind::AssignOp(binop, lhs, rhs) } diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index d71358f45c470..a501541c95909 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -97,6 +97,8 @@ impl AssocOp { // DotDotDot is no longer supported, but we need some way to display the error token::DotDotDot => Some(DotDotEq), token::Colon => Some(Colon), + // `<-` should probably be `< -` + token::LArrow => Some(Less), _ if t.is_keyword(kw::As) => Some(As), _ => None } diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs new file mode 100644 index 0000000000000..c5a66d5d4a312 --- /dev/null +++ b/src/test/ui/async-await/issue-61949-self-return-type.rs @@ -0,0 +1,28 @@ +// ignore-tidy-linelength +// edition:2018 +#![feature(async_await)] + +// This test checks that `Self` is prohibited as a return type. See #61949 for context. + +pub struct Foo<'a> { + pub bar: &'a i32, +} + +impl<'a> Foo<'a> { + pub async fn new(_bar: &'a i32) -> Self { + //~^ ERROR `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope + Foo { + bar: &22 + } + } +} + +async fn foo() { + let x = { + let bar = 22; + Foo::new(&bar).await + }; + drop(x); +} + +fn main() { } diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr new file mode 100644 index 0000000000000..a9ae544502d08 --- /dev/null +++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr @@ -0,0 +1,8 @@ +error: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope + --> $DIR/issue-61949-self-return-type.rs:12:40 + | +LL | pub async fn new(_bar: &'a i32) -> Self { + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/issues/issue-63388-1.rs b/src/test/ui/async-await/issues/issue-63388-1.rs new file mode 100644 index 0000000000000..80003b0d701f5 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-63388-1.rs @@ -0,0 +1,20 @@ +// edition:2018 + +#![feature(async_await)] + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth<'a>( + &'a self, foo: &dyn Foo + ) -> &dyn Foo //~ ERROR lifetime mismatch + { + foo + } +} + +fn main() {} diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr new file mode 100644 index 0000000000000..5302adce5a01e --- /dev/null +++ b/src/test/ui/async-await/issues/issue-63388-1.stderr @@ -0,0 +1,12 @@ +error[E0623]: lifetime mismatch + --> $DIR/issue-63388-1.rs:14:10 + | +LL | &'a self, foo: &dyn Foo + | -------- this parameter and the return type are declared with different lifetimes... +LL | ) -> &dyn Foo + | ^^^^^^^^ + | | + | ...but data from `foo` is returned here + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/issues/issue-63388-2.rs b/src/test/ui/async-await/issues/issue-63388-2.rs new file mode 100644 index 0000000000000..ca9bbef0d503d --- /dev/null +++ b/src/test/ui/async-await/issues/issue-63388-2.rs @@ -0,0 +1,20 @@ +// edition:2018 + +#![feature(async_await)] + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth<'a>( + foo: &dyn Foo, bar: &'a dyn Foo //~ ERROR cannot infer + ) -> &dyn Foo //~ ERROR missing lifetime specifier + { + foo + } +} + +fn main() {} diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr new file mode 100644 index 0000000000000..1810138dc80e0 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-63388-2.stderr @@ -0,0 +1,29 @@ +error[E0106]: missing lifetime specifier + --> $DIR/issue-63388-2.rs:14:10 + | +LL | ) -> &dyn Foo + | ^ help: consider using the named lifetime: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` + +error: cannot infer an appropriate lifetime + --> $DIR/issue-63388-2.rs:13:9 + | +LL | foo: &dyn Foo, bar: &'a dyn Foo + | ^^^ ...but this borrow... +LL | ) -> &dyn Foo + | -------- this return type evaluates to the `'static` lifetime... + | +note: ...can't outlive the lifetime '_ as defined on the method body at 13:14 + --> $DIR/issue-63388-2.rs:13:14 + | +LL | foo: &dyn Foo, bar: &'a dyn Foo + | ^ +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 13:14 + | +LL | ) -> &dyn Foo + '_ + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/async-await/issues/issue-63388-3.rs b/src/test/ui/async-await/issues/issue-63388-3.rs new file mode 100644 index 0000000000000..05f23f95965b9 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-63388-3.rs @@ -0,0 +1,19 @@ +// edition:2018 +// check-pass + +#![feature(async_await)] + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth( + &self, foo: &dyn Foo + ) { + } +} + +fn main() {} diff --git a/src/test/ui/async-await/issues/issue-63388-4.rs b/src/test/ui/async-await/issues/issue-63388-4.rs new file mode 100644 index 0000000000000..0939242d7fc7a --- /dev/null +++ b/src/test/ui/async-await/issues/issue-63388-4.rs @@ -0,0 +1,12 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +struct A; + +impl A { + async fn foo(&self, f: &u32) -> &A { self } +} + +fn main() { } diff --git a/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.rs b/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.rs new file mode 100644 index 0000000000000..e3b642a9d418d --- /dev/null +++ b/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.rs @@ -0,0 +1,6 @@ +extern { + fn foo(...); + //~^ ERROR C-variadic function must be declared with at least one named argument +} + +fn main() {} diff --git a/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.stderr b/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.stderr new file mode 100644 index 0000000000000..cb6060525fc0d --- /dev/null +++ b/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.stderr @@ -0,0 +1,8 @@ +error: C-variadic function must be declared with at least one named argument + --> $DIR/variadic-ffi-no-fixed-args.rs:2:11 + | +LL | fn foo(...); + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs index c33261bfd0909..9ba7c91fc7201 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.rs +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -1,4 +1,5 @@ // compile-fail +// ignore-tidy-linelength // edition:2018 #![feature(async_await)] @@ -44,7 +45,8 @@ mod lifetimes { /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further. fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { - //~^ ERROR: type mismatch + //~^ ERROR: type mismatch + //~^^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope Foo(()) } } diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index aa306a7e08a4c..b5c8e078f0f13 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/bound-normalization-fail.rs:5:12 + --> $DIR/bound-normalization-fail.rs:6:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: `#[warn(incomplete_features)]` on by default error[E0271]: type mismatch resolving ` as FooLike>::Output == ::Assoc` - --> $DIR/bound-normalization-fail.rs:29:32 + --> $DIR/bound-normalization-fail.rs:30:32 | LL | fn foo_fail() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type @@ -16,8 +16,14 @@ LL | fn foo_fail() -> impl FooLike { found type `::Assoc` = note: the return type of a function must have a statically known size +error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope + --> $DIR/bound-normalization-fail.rs:47:41 + | +LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0271]: type mismatch resolving ` as FooLike>::Output == >::Assoc` - --> $DIR/bound-normalization-fail.rs:46:41 + --> $DIR/bound-normalization-fail.rs:47:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type @@ -26,6 +32,6 @@ LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { found type `>::Assoc` = note: the return type of a function must have a statically known size -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/obsolete-in-place/bad.rs b/src/test/ui/obsolete-in-place/bad.rs index 3530862f76787..a491bb21a57a0 100644 --- a/src/test/ui/obsolete-in-place/bad.rs +++ b/src/test/ui/obsolete-in-place/bad.rs @@ -2,7 +2,7 @@ fn foo() { let (x, y) = (0, 0); - x <- y; //~ ERROR expected one of + x <- y; //~ ERROR unexpected token: `<-` } fn main() { diff --git a/src/test/ui/obsolete-in-place/bad.stderr b/src/test/ui/obsolete-in-place/bad.stderr index 373b7ea42183d..8a731b6240b2f 100644 --- a/src/test/ui/obsolete-in-place/bad.stderr +++ b/src/test/ui/obsolete-in-place/bad.stderr @@ -1,8 +1,12 @@ -error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `<-` +error: unexpected token: `<-` --> $DIR/bad.rs:5:7 | LL | x <- y; - | ^^ expected one of 8 possible tokens here + | ^^ +help: if you meant to write a comparison against a negative value, add a space in between `<` and `-` + | +LL | x < - y; + | ^^^ error: expected expression, found keyword `in` --> $DIR/bad.rs:10:5 diff --git a/src/test/ui/placement-syntax.rs b/src/test/ui/placement-syntax.rs index 2edd78ec8ab3d..4df96dedbd45b 100644 --- a/src/test/ui/placement-syntax.rs +++ b/src/test/ui/placement-syntax.rs @@ -1,6 +1,6 @@ fn main() { let x = -5; - if x<-1 { //~ ERROR expected `{`, found `<-` + if x<-1 { //~ ERROR unexpected token: `<-` println!("ok"); } } diff --git a/src/test/ui/placement-syntax.stderr b/src/test/ui/placement-syntax.stderr index e90acce168e47..e26931e60d88f 100644 --- a/src/test/ui/placement-syntax.stderr +++ b/src/test/ui/placement-syntax.stderr @@ -1,10 +1,12 @@ -error: expected `{`, found `<-` +error: unexpected token: `<-` --> $DIR/placement-syntax.rs:3:9 | LL | if x<-1 { - | -- ^^ expected `{` - | | - | this `if` statement has a condition, but no block + | ^^ +help: if you meant to write a comparison against a negative value, add a space in between `<` and `-` + | +LL | if x< -1 { + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs new file mode 100644 index 0000000000000..b853f88a96dde --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs @@ -0,0 +1,37 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +use std::pin::Pin; +use std::task::{Context, Poll}; + +struct Foo; + +impl Foo { + async fn pin_ref(self: Pin<&Self>) -> Pin<&Self> { self } + + async fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut Self> { self } + + async fn pin_pin_pin_ref(self: Pin>>) -> Pin>> { self } + + async fn pin_ref_impl_trait(self: Pin<&Self>) -> impl Clone + '_ { self } + + fn b(self: Pin<&Foo>, f: &Foo) -> Pin<&Foo> { self } +} + +type Alias = Pin; +impl Foo { + async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self } +} + +// FIXME(Centril): extend with the rest of the non-`async fn` test +// when we allow `async fn`s inside traits and trait implementations. + +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() }; +} diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr new file mode 100644 index 0000000000000..2421632c664c1 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr @@ -0,0 +1,14 @@ +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:48 + | +LL | async fn f(self: Pin<&Self>) -> impl Clone { self } + | - ^^^^^^^^ returning this value requires that `'_` must outlive `'static` + | | + | lifetime `'_` defined here +help: to allow this `impl Trait` to capture borrowed data with lifetime `'_`, add `'_` as a constraint + | +LL | async 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-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs new file mode 100644 index 0000000000000..aecb82325c1f2 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs @@ -0,0 +1,16 @@ +// edition:2018 + +#![feature(async_await)] + +use std::pin::Pin; + +struct Foo; + +impl Foo { + async 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-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr new file mode 100644 index 0000000000000..f0032449db14e --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -0,0 +1,20 @@ +error: cannot infer an appropriate lifetime + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:16 + | +LL | async fn f(self: Pin<&Self>) -> impl Clone { self } + | ^^^^ ---------- this return type evaluates to the `'static` lifetime... + | | + | ...but this borrow... + | +note: ...can't outlive the lifetime '_ as defined on the method body at 10:26 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:26 + | +LL | async 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 lifetime '_ as defined on the method body at 10:26 + | +LL | async 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-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr new file mode 100644 index 0000000000000..6585609555675 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr @@ -0,0 +1,27 @@ +error[E0106]: missing lifetime specifier + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45 + | +LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:60 + | +LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:67 + | +LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs new file mode 100644 index 0000000000000..53ab75ee16bd0 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs @@ -0,0 +1,22 @@ +// edition:2018 + +#![feature(async_await)] + +use std::pin::Pin; + +struct Foo; + +impl Foo { + async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } + //~^ ERROR lifetime mismatch + + async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + //~^ ERROR lifetime mismatch +} + +type Alias = Pin; +impl Foo { + async 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-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr new file mode 100644 index 0000000000000..74fc474134949 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr @@ -0,0 +1,29 @@ +error[E0623]: lifetime mismatch + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45 + | +LL | async 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-async.rs:13:55 + | +LL | async 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-async.rs:19:58 + | +LL | async 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 index 7ace2e0c89039..3bd7a6c00b2ad 100644 --- a/src/test/ui/self/elision/README.md +++ b/src/test/ui/self/elision/README.md @@ -42,3 +42,34 @@ In each case, we test the following patterns: - `self: Box>` In the non-reference cases, `Pin` causes errors so we substitute `Rc`. + +### `async fn` + +For each of the tests above we also check that `async fn` behaves as an `fn` would. +These tests are in files named `*-async.rs`. + +Legends: +- ✓ ⟹ Yes / Pass +- X ⟹ No +- α ⟹ lifetime mismatch +- β ⟹ cannot infer an appropriate lifetime +- γ ⟹ missing lifetime specifier + +| `async` file | Pass? | Conforms to `fn`? | How does it diverge?
`fn` ⟶ `async fn` | +| --- | --- | --- | --- | +| `self-async.rs` | ✓ | ✓ | N/A | +| `struct-async.rs`| ✓ | ✓ | N/A | +| `alias-async.rs`| ✓ | ✓ | N/A | +| `assoc-async.rs`| ✓ | ✓ | N/A | +| `ref-self-async.rs` | X | ✓ | N/A | +| `ref-mut-self-async.rs` | X | ✓ | N/A | +| `ref-struct-async.rs` | X | ✓ | N/A | +| `ref-mut-struct-async.rs` | X | ✓ | N/A | +| `ref-alias-async.rs` | ✓ | ✓ | N/A | +| `ref-assoc-async.rs` | ✓ | ✓ | N/A | +| `ref-mut-alias-async.rs` | ✓ | ✓ | N/A | +| `lt-self-async.rs` | ✓ | ✓ | N/A +| `lt-struct-async.rs` | ✓ | ✓ | N/A +| `lt-alias-async.rs` | ✓ | ✓ | N/A +| `lt-assoc-async.rs` | ✓ | ✓ | N/A +| `lt-ref-self-async.rs` | X | ✓ | N/A | diff --git a/src/test/ui/self/elision/alias-async.rs b/src/test/ui/self/elision/alias-async.rs new file mode 100644 index 0000000000000..3d5b24a8946aa --- /dev/null +++ b/src/test/ui/self/elision/alias-async.rs @@ -0,0 +1,39 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![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`: + + async fn alias(self: Alias, f: &u32) -> &u32 { + f + } + + async fn box_Alias(self: Box, f: &u32) -> &u32 { + f + } + + async fn rc_Alias(self: Rc, f: &u32) -> &u32 { + f + } + + async fn box_box_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + async fn box_rc_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/assoc-async.rs b/src/test/ui/self/elision/assoc-async.rs new file mode 100644 index 0000000000000..0f33f2887726c --- /dev/null +++ b/src/test/ui/self/elision/assoc-async.rs @@ -0,0 +1,43 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![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 { + async fn assoc(self: ::AssocType, f: &u32) -> &u32 { + f + } + + async fn box_AssocType(self: Box<::AssocType>, f: &u32) -> &u32 { + f + } + + async fn rc_AssocType(self: Rc<::AssocType>, f: &u32) -> &u32 { + f + } + + async fn box_box_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } + + async fn box_rc_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-alias-async.rs b/src/test/ui/self/elision/lt-alias-async.rs new file mode 100644 index 0000000000000..5a8989f078ef3 --- /dev/null +++ b/src/test/ui/self/elision/lt-alias-async.rs @@ -0,0 +1,41 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![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> { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_Alias(self: Box>>, f: &u32) -> &u32 { + f + } + + async fn take_Rc_Alias(self: Rc>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_Alias(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-assoc-async.rs b/src/test/ui/self/elision/lt-assoc-async.rs new file mode 100644 index 0000000000000..98c9aa3b6c26a --- /dev/null +++ b/src/test/ui/self/elision/lt-assoc-async.rs @@ -0,0 +1,53 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![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> { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_AssocType(self: as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + async fn take_Box_AssocType(self: Box< as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_AssocType( + self: Box as Trait>::AssocType>>, + f: &u32 + ) -> &u32 { + f + } + + async fn take_Rc_AssocType(self: Rc< as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_AssocType( + self: Box as Trait>::AssocType>>, + f: &u32 + ) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr new file mode 100644 index 0000000000000..d3aeb73b9b7c2 --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr @@ -0,0 +1,51 @@ +error[E0106]: missing lifetime specifier + --> $DIR/lt-ref-self-async.rs:15:42 + | +LL | async fn ref_self(&self, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/lt-ref-self-async.rs:23:48 + | +LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/lt-ref-self-async.rs:29:57 + | +LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/lt-ref-self-async.rs:35:57 + | +LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/lt-ref-self-async.rs:41:66 + | +LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/lt-ref-self-async.rs:47:62 + | +LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/self/elision/lt-ref-self-async.rs b/src/test/ui/self/elision/lt-ref-self-async.rs new file mode 100644 index 0000000000000..79a4771978a8e --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self-async.rs @@ -0,0 +1,42 @@ +// edition:2018 + +#![feature(async_await)] + +#![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: + + async fn ref_self(&self, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + // Test using `&Self` explicitly: + + async fn ref_Self(self: &Self, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr new file mode 100644 index 0000000000000..0a459257fa708 --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self-async.stderr @@ -0,0 +1,56 @@ +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self-async.rs:15:42 + | +LL | async fn ref_self(&self, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self-async.rs:21:48 + | +LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self-async.rs:25:57 + | +LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self-async.rs:29:57 + | +LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self-async.rs:33:66 + | +LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self-async.rs:37:62 + | +LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/lt-self-async.rs b/src/test/ui/self/elision/lt-self-async.rs new file mode 100644 index 0000000000000..0202db8a63526 --- /dev/null +++ b/src/test/ui/self/elision/lt-self-async.rs @@ -0,0 +1,52 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![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> { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + async fn take_Box_Self(self: Box, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_Self(self: Box>, f: &u32) -> &u32 { + f + } + + async fn take_Rc_Self(self: Rc, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_Self(self: Box>, f: &u32) -> &u32 { + f + } + + // N/A + //fn take_Pin_Self(self: Pin, f: &u32) -> &u32 { + // f + //} + + // N/A + //fn take_Box_Pin_Self(self: Box>, f: &u32) -> &u32 { + // f + //} +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-struct-async.rs b/src/test/ui/self/elision/lt-struct-async.rs new file mode 100644 index 0000000000000..c0fc63d423257 --- /dev/null +++ b/src/test/ui/self/elision/lt-struct-async.rs @@ -0,0 +1,39 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Struct<'a> { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_Struct(self: Struct<'a>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Struct(self: Box>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_Struct(self: Box>>, f: &u32) -> &u32 { + f + } + + async fn take_Rc_Struct(self: Rc>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_Struct(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/multiple-ref-self-async.rs b/src/test/ui/self/elision/multiple-ref-self-async.rs new file mode 100644 index 0000000000000..eb8c25277e145 --- /dev/null +++ b/src/test/ui/self/elision/multiple-ref-self-async.rs @@ -0,0 +1,46 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![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, PhantomData

); + +impl Deref for Wrap { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using multiple `&Self`: + + async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 { + f + } + + async fn box_wrap_ref_Self_ref_Self(self: Box>, f: &u32) -> &u32 { + f + } + + async fn pin_wrap_ref_Self_ref_Self(self: Pin>, f: &u32) -> &u32 { + f + } + + async fn box_box_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { + f + } + + async fn box_pin_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-alias-async.rs b/src/test/ui/self/elision/ref-alias-async.rs new file mode 100644 index 0000000000000..acc4b2153ef66 --- /dev/null +++ b/src/test/ui/self/elision/ref-alias-async.rs @@ -0,0 +1,42 @@ +// edition:2018 +// check-pass + +#![feature(async_await)] + +#![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. + + async fn ref_Alias(self: &Alias, f: &u32) -> &u32 { + f + } + + async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 { + f + } + + async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 { + f + } + + async fn box_box_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + async fn box_pin_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-assoc-async.rs b/src/test/ui/self/elision/ref-assoc-async.rs new file mode 100644 index 0000000000000..a6b6cbd6da391 --- /dev/null +++ b/src/test/ui/self/elision/ref-assoc-async.rs @@ -0,0 +1,43 @@ +// edition:2018 +// check-pass + +#![feature(async_await)] + +#![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 { + async fn ref_AssocType(self: &::AssocType, f: &u32) -> &u32 { + f + } + + async fn box_ref_AssocType(self: Box<&::AssocType>, f: &u32) -> &u32 { + f + } + + async fn pin_ref_AssocType(self: Pin<&::AssocType>, f: &u32) -> &u32 { + f + } + + async fn box_box_ref_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } + + async fn box_pin_ref_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-alias-async.rs b/src/test/ui/self/elision/ref-mut-alias-async.rs new file mode 100644 index 0000000000000..873e92bc6d33e --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-alias-async.rs @@ -0,0 +1,38 @@ +// edition:2018 +// check-pass + +#![feature(async_await)] +#![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`: + + async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 { + f + } + + async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 { + f + } + + async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 { + f + } + + async fn box_box_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + async fn box_pin_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr new file mode 100644 index 0000000000000..35969659b19d1 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr @@ -0,0 +1,51 @@ +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-self-async.rs:15:46 + | +LL | async fn ref_self(&mut self, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-self-async.rs:23:52 + | +LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-self-async.rs:29:61 + | +LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-self-async.rs:35:61 + | +LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-self-async.rs:41:70 + | +LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-self-async.rs:47:70 + | +LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/self/elision/ref-mut-self-async.rs b/src/test/ui/self/elision/ref-mut-self-async.rs new file mode 100644 index 0000000000000..a6bd9d693163e --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self-async.rs @@ -0,0 +1,42 @@ +// edition:2018 + +#![feature(async_await)] + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut self` sugar: + + async fn ref_self(&mut self, f: &u32) -> &u32 { //~ ERROR lifetime mismatch + f + } + + // Test using `&mut Self` explicitly: + + async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr new file mode 100644 index 0000000000000..805833f94720d --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self-async.stderr @@ -0,0 +1,56 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self-async.rs:15:46 + | +LL | async fn ref_self(&mut self, f: &u32) -> &u32 { + | --------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self-async.rs:21:52 + | +LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + | --------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self-async.rs:25:61 + | +LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + | --------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self-async.rs:29:61 + | +LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + | --------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self-async.rs:33:70 + | +LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + | --------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self-async.rs:37:70 + | +LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + | --------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr new file mode 100644 index 0000000000000..a70dcf5b0ad19 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr @@ -0,0 +1,43 @@ +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-struct-async.rs:15:56 + | +LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-struct-async.rs:21:65 + | +LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-struct-async.rs:27:65 + | +LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-struct-async.rs:33:74 + | +LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-mut-struct-async.rs:39:74 + | +LL | async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/self/elision/ref-mut-struct-async.rs b/src/test/ui/self/elision/ref-mut-struct-async.rs new file mode 100644 index 0000000000000..7a89ef9596a37 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct-async.rs @@ -0,0 +1,36 @@ +// edition:2018 + +#![feature(async_await)] + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut Struct` explicitly: + + async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr new file mode 100644 index 0000000000000..4c983872942c1 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr @@ -0,0 +1,47 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct-async.rs:15:56 + | +LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + | ----------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct-async.rs:19:65 + | +LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + | ----------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct-async.rs:23:65 + | +LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + | ----------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct-async.rs:27:74 + | +LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + | ----------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct-async.rs:31:74 + | +LL | async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { + | ----------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr new file mode 100644 index 0000000000000..ae17ba9839d22 --- /dev/null +++ b/src/test/ui/self/elision/ref-self-async.nll.stderr @@ -0,0 +1,59 @@ +error[E0106]: missing lifetime specifier + --> $DIR/ref-self-async.rs:24:42 + | +LL | async fn ref_self(&self, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-self-async.rs:32:48 + | +LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-self-async.rs:38:57 + | +LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-self-async.rs:44:57 + | +LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-self-async.rs:50:66 + | +LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-self-async.rs:56:66 + | +LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-self-async.rs:62:69 + | +LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/self/elision/ref-self-async.rs b/src/test/ui/self/elision/ref-self-async.rs new file mode 100644 index 0000000000000..5a5705d7e099b --- /dev/null +++ b/src/test/ui/self/elision/ref-self-async.rs @@ -0,0 +1,55 @@ +// edition:2018 + +#![feature(async_await)] + +#![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, PhantomData

); + +impl Deref for Wrap { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using `&self` sugar: + + async fn ref_self(&self, f: &u32) -> &u32 { //~ ERROR lifetime mismatch + f + } + + // Test using `&Self` explicitly: + + async fn ref_Self(self: &Self, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async 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-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr new file mode 100644 index 0000000000000..eb796a07a86d5 --- /dev/null +++ b/src/test/ui/self/elision/ref-self-async.stderr @@ -0,0 +1,65 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-self-async.rs:24:42 + | +LL | async fn ref_self(&self, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-self-async.rs:30:48 + | +LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-self-async.rs:34:57 + | +LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-self-async.rs:38:57 + | +LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-self-async.rs:42:66 + | +LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-self-async.rs:46:66 + | +LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + | ----- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-self-async.rs:50:69 + | +LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + | ----- ^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr new file mode 100644 index 0000000000000..b4f12d7057db4 --- /dev/null +++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr @@ -0,0 +1,43 @@ +error[E0106]: missing lifetime specifier + --> $DIR/ref-struct-async.rs:15:52 + | +LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-struct-async.rs:21:61 + | +LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-struct-async.rs:27:61 + | +LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-struct-async.rs:33:70 + | +LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error[E0106]: missing lifetime specifier + --> $DIR/ref-struct-async.rs:39:66 + | +LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { + | ^ + | + = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple. + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/self/elision/ref-struct-async.rs b/src/test/ui/self/elision/ref-struct-async.rs new file mode 100644 index 0000000000000..f0410bbee906d --- /dev/null +++ b/src/test/ui/self/elision/ref-struct-async.rs @@ -0,0 +1,36 @@ +// edition:2018 + +#![feature(async_await)] + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&Struct` explicitly: + + async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } + + async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { + f //~^ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr new file mode 100644 index 0000000000000..574b0fddc1eb2 --- /dev/null +++ b/src/test/ui/self/elision/ref-struct-async.stderr @@ -0,0 +1,47 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-struct-async.rs:15:52 + | +LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | ------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct-async.rs:19:61 + | +LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + | ------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct-async.rs:23:61 + | +LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + | ------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct-async.rs:27:70 + | +LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + | ------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct-async.rs:31:66 + | +LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { + | ------- ^^^^ + | | | + | | ...but data from `f` is returned here + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/self-async.rs b/src/test/ui/self/elision/self-async.rs new file mode 100644 index 0000000000000..d1dc050be0d1e --- /dev/null +++ b/src/test/ui/self/elision/self-async.rs @@ -0,0 +1,39 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + async fn take_Box_Self(self: Box, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_Self(self: Box>, f: &u32) -> &u32 { + f + } + + async fn take_Rc_Self(self: Rc, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_Self(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/struct-async.rs b/src/test/ui/self/elision/struct-async.rs new file mode 100644 index 0000000000000..f7c8591ebd31d --- /dev/null +++ b/src/test/ui/self/elision/struct-async.rs @@ -0,0 +1,35 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + async fn ref_Struct(self: Struct, f: &u32) -> &u32 { + f + } + + async fn box_Struct(self: Box, f: &u32) -> &u32 { + f + } + + async fn rc_Struct(self: Rc, f: &u32) -> &u32 { + f + } + + async fn box_box_Struct(self: Box>, f: &u32) -> &u32 { + f + } + + async fn box_rc_Struct(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/self_lifetime-async.rs b/src/test/ui/self/self_lifetime-async.rs new file mode 100644 index 0000000000000..ec4c3d1522423 --- /dev/null +++ b/src/test/ui/self/self_lifetime-async.rs @@ -0,0 +1,16 @@ +// check-pass +// edition:2018 + +#![feature(async_await)] + +struct Foo<'a>(&'a ()); +impl<'a> Foo<'a> { + async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } +} + +type Alias = Foo<'static>; +impl Alias { + async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } +} + +fn main() {}