diff --git a/RELEASES.md b/RELEASES.md index 43a5fda61297a..6049a8ef4c9ea 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,121 @@ +Version 1.37.0 (2019-08-15) +========================== + +Language +-------- +- `#[must_use]` will now warn if the type is contained in a [tuple][61100], + [`Box`][62228], or an [array][62235] and unused. +- [You can now use the `cfg` and `cfg_attr` attributes on + generic parameters.][61547] +- [You can now use enum variants through type alias.][61682] e.g. You can + write the following: + ```rust + type MyOption = Option; + + fn increment_or_zero(x: MyOption) -> u8 { + match x { + MyOption::Some(y) => y + 1, + MyOption::None => 0, + } + } + ``` +- [You can now use `_` as an identifier for consts.][61347] e.g. You can write + `const _: u32 = 5;`. +- [You can now use `#[repr(align(X)]` on enums.][61229] +- [The `?`/_"Kleene"_ macro operator is now available in the + 2015 edition.][60932] + +Compiler +-------- +- [You can now enable Profile-Guided Optimization with the `-C profile-generate` + and `-C profile-use` flags.][61268] For more information on how to use profile + guided optimization, please refer to the [rustc book][rustc-book-pgo]. +- [The `rust-lldb` wrapper script should now work again.][61827] + +Libraries +--------- +- [`mem::MaybeUninit` is now ABI-compatible with `T`.][61802] + +Stabilized APIs +--------------- +- [`BufReader::buffer`] +- [`BufWriter::buffer`] +- [`Cell::from_mut`] +- [`Cell<[T]>::as_slice_of_cells`][`Cell::as_slice_of_cells`] +- [`DoubleEndedIterator::nth_back`] +- [`Option::xor`] +- [`Wrapping::reverse_bits`] +- [`i128::reverse_bits`] +- [`i16::reverse_bits`] +- [`i32::reverse_bits`] +- [`i64::reverse_bits`] +- [`i8::reverse_bits`] +- [`isize::reverse_bits`] +- [`slice::copy_within`] +- [`u128::reverse_bits`] +- [`u16::reverse_bits`] +- [`u32::reverse_bits`] +- [`u64::reverse_bits`] +- [`u8::reverse_bits`] +- [`usize::reverse_bits`] + +Cargo +----- +- [`Cargo.lock` files are now included by default when publishing executable crates + with executables.][cargo/7026] +- [You can now specify `default-run="foo"` in `[package]` to specify the + default executable to use for `cargo run`.][cargo/7056] + +Misc +---- + +Compatibility Notes +------------------- +- [Using `...` for inclusive range patterns will now warn by default.][61342] + Please transition your code to using the `..=` syntax for inclusive + ranges instead. +- [Using a trait object without the `dyn` will now warn by default.][61203] + Please transition your code to use `dyn Trait` for trait objects instead. + +[62228]: https://github.com/rust-lang/rust/pull/62228/ +[62235]: https://github.com/rust-lang/rust/pull/62235/ +[61802]: https://github.com/rust-lang/rust/pull/61802/ +[61827]: https://github.com/rust-lang/rust/pull/61827/ +[61547]: https://github.com/rust-lang/rust/pull/61547/ +[61682]: https://github.com/rust-lang/rust/pull/61682/ +[61268]: https://github.com/rust-lang/rust/pull/61268/ +[61342]: https://github.com/rust-lang/rust/pull/61342/ +[61347]: https://github.com/rust-lang/rust/pull/61347/ +[61100]: https://github.com/rust-lang/rust/pull/61100/ +[61203]: https://github.com/rust-lang/rust/pull/61203/ +[61229]: https://github.com/rust-lang/rust/pull/61229/ +[60932]: https://github.com/rust-lang/rust/pull/60932/ +[cargo/7026]: https://github.com/rust-lang/cargo/pull/7026/ +[cargo/7056]: https://github.com/rust-lang/cargo/pull/7056/ +[`BufReader::buffer`]: https://doc.rust-lang.org/std/io/struct.BufReader.html#method.buffer +[`BufWriter::buffer`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html#method.buffer +[`Cell::from_mut`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.from_mut +[`Cell::as_slice_of_cells`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_slice_of_cells +[`DoubleEndedIterator::nth_back`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.nth_back +[`Option::xor`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.xor +[`RefCell::try_borrow_unguarded`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.try_borrow_unguarded +[`Wrapping::reverse_bits`]: https://doc.rust-lang.org/std/num/struct.Wrapping.html#method.reverse_bits +[`i128::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i128.html#method.reverse_bits +[`i16::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i16.html#method.reverse_bits +[`i32::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i32.html#method.reverse_bits +[`i64::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i64.html#method.reverse_bits +[`i8::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i8.html#method.reverse_bits +[`isize::reverse_bits`]: https://doc.rust-lang.org/std/primitive.isize.html#method.reverse_bits +[`slice::copy_within`]: https://doc.rust-lang.org/std/primitive.slice.html#method.copy_within +[`u128::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u128.html#method.reverse_bits +[`u16::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u16.html#method.reverse_bits +[`u32::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u32.html#method.reverse_bits +[`u64::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u64.html#method.reverse_bits +[`u8::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u8.html#method.reverse_bits +[`usize::reverse_bits`]: https://doc.rust-lang.org/std/primitive.usize.html#method.reverse_bits +[rustc-book-pgo]: https://doc.rust-lang.org/rustc/profile-guided-optimization.html + + Version 1.36.0 (2019-07-04) ========================== diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 53d3dbf60d1d7..907983d43ade7 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -76,11 +76,11 @@ def v(*args): 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/.azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml similarity index 100% rename from .azure-pipelines/auto.yml rename to src/ci/azure-pipelines/auto.yml diff --git a/.azure-pipelines/master.yml b/src/ci/azure-pipelines/master.yml similarity index 100% rename from .azure-pipelines/master.yml rename to src/ci/azure-pipelines/master.yml diff --git a/.azure-pipelines/pr.yml b/src/ci/azure-pipelines/pr.yml similarity index 100% rename from .azure-pipelines/pr.yml rename to src/ci/azure-pipelines/pr.yml diff --git a/.azure-pipelines/steps/install-clang.yml b/src/ci/azure-pipelines/steps/install-clang.yml similarity index 100% rename from .azure-pipelines/steps/install-clang.yml rename to src/ci/azure-pipelines/steps/install-clang.yml diff --git a/.azure-pipelines/steps/install-sccache.yml b/src/ci/azure-pipelines/steps/install-sccache.yml similarity index 100% rename from .azure-pipelines/steps/install-sccache.yml rename to src/ci/azure-pipelines/steps/install-sccache.yml diff --git a/.azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml similarity index 100% rename from .azure-pipelines/steps/install-windows-build-deps.yml rename to src/ci/azure-pipelines/steps/install-windows-build-deps.yml diff --git a/.azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml similarity index 100% rename from .azure-pipelines/steps/run.yml rename to src/ci/azure-pipelines/steps/run.yml diff --git a/.azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml similarity index 100% rename from .azure-pipelines/try.yml rename to src/ci/azure-pipelines/try.yml diff --git a/src/ci/run.sh b/src/ci/run.sh index b91859bfceb78..e5e0e6cf6033d 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 412346bab257e..3d80fb28c738d 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, + } + + 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 26c76ae560654..b2e319a478e3a 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 0000000000000..1782c2e375df5 --- /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 0000000000000..85c3575fd9288 --- /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 0000000000000..53f17405d79f4 --- /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 0000000000000..882764cb94678 --- /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 0000000000000..3002013881249 --- /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>> { self } + + 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 { + fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self } +} + +struct Bar { + field1: T, + field2: U, +} + +impl Bar { + 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>; +} + +struct Baz(Vec); + +impl AsyncBufRead for Baz { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll> + { + 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 0000000000000..dcfc9ba511d74 --- /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 0000000000000..ad8959727cbee --- /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 0000000000000..5118280e7ec0c --- /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 0000000000000..8a0f1a804ad82 --- /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 0000000000000..fc5f94201b81a --- /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 = Pin; +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 0000000000000..3296e14f806e1 --- /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 0000000000000..7ace2e0c89039 --- /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` +- `self: Pin` +- `self: Box>` +- `self: Box>` + +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 0000000000000..b5aacfaeec427 --- /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, f: &u32) -> &u32 { + f + } + + fn rc_Alias(self: Rc, f: &u32) -> &u32 { + f + } + + fn box_box_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + fn box_rc_Alias(self: Box>, 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 0000000000000..163eb49383a87 --- /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: ::AssocType, f: &u32) -> &u32 { + f + } + + fn box_AssocType(self: Box<::AssocType>, f: &u32) -> &u32 { + f + } + + fn rc_AssocType(self: Rc<::AssocType>, f: &u32) -> &u32 { + f + } + + fn box_box_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } + + fn box_rc_AssocType(self: Box::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 0000000000000..df2300deda25f --- /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>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Alias(self: Box>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Alias(self: Rc>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Alias(self: Box>>, 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 0000000000000..70573598fcb16 --- /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: as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + fn take_Box_AssocType(self: Box< as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_AssocType(self: Box as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_AssocType(self: Rc< as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + 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.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr new file mode 100644 index 0000000000000..e97a01e746d4b --- /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>, 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>, 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 0000000000000..8abf2876a5c1b --- /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>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + 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.stderr b/src/test/ui/self/elision/lt-ref-self.stderr new file mode 100644 index 0000000000000..f73b3eddd3821 --- /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>, 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>, 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 0000000000000..9b0ee5e42a51a --- /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, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Self(self: Box>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Self(self: Rc, f: &u32) -> &u32 { + f + } + + 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.rs b/src/test/ui/self/elision/lt-struct.rs new file mode 100644 index 0000000000000..e41dfbbe0bf0d --- /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>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Struct(self: Box>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Struct(self: Rc>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Struct(self: Box>>, 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 0000000000000..f39613d0c9007 --- /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, PhantomData

); + +impl Deref for Wrap { + 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>, f: &u32) -> &u32 { + f + } + + fn pin_wrap_ref_Self_ref_Self(self: Pin>, f: &u32) -> &u32 { + f + } + + fn box_box_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { + f + } + + 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.rs b/src/test/ui/self/elision/ref-alias.rs new file mode 100644 index 0000000000000..d83ac612235e3 --- /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>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_Alias(self: Box>, 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 0000000000000..f9354bc884710 --- /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: &::AssocType, f: &u32) -> &u32 { + f + } + + fn box_ref_AssocType(self: Box<&::AssocType>, f: &u32) -> &u32 { + f + } + + fn pin_ref_AssocType(self: Pin<&::AssocType>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } + + 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.rs b/src/test/ui/self/elision/ref-mut-alias.rs new file mode 100644 index 0000000000000..395816f8f5d80 --- /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>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_Alias(self: Box>, 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 0000000000000..3a8ae3fdcba8c --- /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>, 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>, 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 0000000000000..a7ea47bb7f6de --- /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>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + 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.stderr b/src/test/ui/self/elision/ref-mut-self.stderr new file mode 100644 index 0000000000000..37984cd72fbac --- /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>, 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>, 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 0000000000000..66152ba40a5f5 --- /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>, 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>, 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 0000000000000..795ddf8ac1354 --- /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>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + 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.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr new file mode 100644 index 0000000000000..2a4826905b94a --- /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>, 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>, 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 0000000000000..20045be0527a4 --- /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>, 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>, 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 0000000000000..e389d8518ada4 --- /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, PhantomData

); + +impl Deref for Wrap { + 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>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_ref_Self(self: Box>, 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 0000000000000..611498f18da42 --- /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>, 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>, 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 0000000000000..a258bc9f74390 --- /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>, 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>, 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 0000000000000..342d6d2b36357 --- /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>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + 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.stderr b/src/test/ui/self/elision/ref-struct.stderr new file mode 100644 index 0000000000000..186e651c143bf --- /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>, 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>, 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 0000000000000..dbcef71ba14fc --- /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, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Self(self: Box>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Self(self: Rc, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Self(self: Box>, 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 0000000000000..227e993bd3c61 --- /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, f: &u32) -> &u32 { + f + } + + fn rc_Struct(self: Rc, f: &u32) -> &u32 { + f + } + + fn box_box_Struct(self: Box>, f: &u32) -> &u32 { + f + } + + fn box_rc_Struct(self: Box>, 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 0000000000000..f04bd83ab6e4c --- /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 index 4c1fa54d10f58..9edd089168f87 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 4c1fa54d10f58d69ac9ff55be68e1b1c25ecb816 +Subproject commit 9edd089168f8795b3890bc3daf5b99f03e9f8765