diff options
Diffstat (limited to 'src/test')
40 files changed, 1515 insertions, 9 deletions
diff --git a/src/test/ui/issues/issue-45296.stderr b/src/test/ui/issues/issue-45296.stderr index bc14d20b623..c0d4ce1243e 100644 --- a/src/test/ui/issues/issue-45296.stderr +++ b/src/test/ui/issues/issue-45296.stderr @@ -1,8 +1,8 @@ error: an inner attribute is not permitted in this context - --> $DIR/issue-45296.rs:4:7 + --> $DIR/issue-45296.rs:4:5 | LL | #![allow(unused_variables)] - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/ui/parser/attr.stderr b/src/test/ui/parser/attr.stderr index 5111b40603c..400a0276b3b 100644 --- a/src/test/ui/parser/attr.stderr +++ b/src/test/ui/parser/attr.stderr @@ -1,8 +1,8 @@ error: an inner attribute is not permitted in this context - --> $DIR/attr.rs:5:3 + --> $DIR/attr.rs:5:1 | LL | #![lang = "foo"] - | ^ + | ^^^^^^^^^^^^^^^^ | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/ui/parser/inner-attr-after-doc-comment.stderr b/src/test/ui/parser/inner-attr-after-doc-comment.stderr index 0dde49a2913..b012abc25e7 100644 --- a/src/test/ui/parser/inner-attr-after-doc-comment.stderr +++ b/src/test/ui/parser/inner-attr-after-doc-comment.stderr @@ -1,8 +1,13 @@ error: an inner attribute is not permitted following an outer doc comment - --> $DIR/inner-attr-after-doc-comment.rs:6:3 + --> $DIR/inner-attr-after-doc-comment.rs:6:1 | -LL | #![recursion_limit="100"] - | ^ +LL | / /** +LL | | * My module +LL | | */ + | |___- previous doc comment +LL | +LL | #![recursion_limit="100"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attibute | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/ui/parser/inner-attr.stderr b/src/test/ui/parser/inner-attr.stderr index 11a37bc139b..070d9f47d96 100644 --- a/src/test/ui/parser/inner-attr.stderr +++ b/src/test/ui/parser/inner-attr.stderr @@ -1,8 +1,11 @@ error: an inner attribute is not permitted following an outer attribute - --> $DIR/inner-attr.rs:3:3 + --> $DIR/inner-attr.rs:3:1 | +LL | #[feature(lang_items)] + | ---------------------- previous outer attribute +LL | LL | #![recursion_limit="100"] - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attibute | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs new file mode 100644 index 00000000000..30020138812 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs @@ -0,0 +1,60 @@ +// check-pass + +use std::pin::Pin; +use std::task::{Context, Poll}; + +struct Foo; + +impl Foo { + fn pin_ref(self: Pin<&Self>) -> Pin<&Self> { self } + + fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut Self> { self } + + fn pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> Pin<Pin<Pin<&Self>>> { self } + + fn pin_ref_impl_trait(self: Pin<&Self>) -> impl Clone + '_ { self } + + fn b(self: Pin<&Foo>, f: &Foo) -> Pin<&Foo> { self } +} + +type Alias<T> = Pin<T>; +impl Foo { + fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self } +} + +struct Bar<T: Unpin, U: Unpin> { + field1: T, + field2: U, +} + +impl<T: Unpin, U: Unpin> Bar<T, U> { + fn fields(self: Pin<&mut Self>) -> (Pin<&mut T>, Pin<&mut U>) { + let this = self.get_mut(); + (Pin::new(&mut this.field1), Pin::new(&mut this.field2)) + } +} + +trait AsyncBufRead { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll<std::io::Result<&[u8]>>; +} + +struct Baz(Vec<u8>); + +impl AsyncBufRead for Baz { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll<std::io::Result<&[u8]>> + { + Poll::Ready(Ok(&self.get_mut().0)) + } +} + +fn main() { + let mut foo = Foo; + { Pin::new(&foo).pin_ref() }; + { Pin::new(&mut foo).pin_mut() }; + { Pin::new(Pin::new(Pin::new(&foo))).pin_pin_pin_ref() }; + { Pin::new(&foo).pin_ref_impl_trait() }; + let mut bar = Bar { field1: 0u8, field2: 1u8 }; + { Pin::new(&mut bar).fields() }; +} diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr new file mode 100644 index 00000000000..dcfc9ba511d --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr @@ -0,0 +1,14 @@ +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:31 + | +LL | fn f(self: Pin<&Self>) -> impl Clone { self } + | - ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` + | | + | let's call the lifetime of this reference `'1` +help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint + | +LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs new file mode 100644 index 00000000000..ad8959727cb --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs @@ -0,0 +1,13 @@ +// compile-fail + +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn f(self: Pin<&Self>) -> impl Clone { self } //~ ERROR cannot infer an appropriate lifetime +} + +fn main() { + { Pin::new(&Foo).f() }; +} diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr new file mode 100644 index 00000000000..5118280e7ec --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -0,0 +1,20 @@ +error: cannot infer an appropriate lifetime + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:44 + | +LL | fn f(self: Pin<&Self>) -> impl Clone { self } + | ---------- ^^^^ ...but this borrow... + | | + | this return type evaluates to the `'static` lifetime... + | +note: ...can't outlive the anonymous lifetime #1 defined on the method body at 8:5 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:5 + | +LL | fn f(self: Pin<&Self>) -> impl Clone { self } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 8:5 + | +LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr new file mode 100644 index 00000000000..8a0f1a804ad --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr @@ -0,0 +1,28 @@ +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46 + | +LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } + | - - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | | + | | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` + +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:69 + | +LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | - - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | | + | | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` + +error: lifetime may not live long enough + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58 + | +LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } + | -- ---- has type `std::pin::Pin<&'1 Foo>` ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | | + | lifetime `'a` defined here + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs new file mode 100644 index 00000000000..fc5f94201b8 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs @@ -0,0 +1,18 @@ +// compile-fail + +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } //~ ERROR E0623 + + fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } //~ ERROR E0623 +} + +type Alias<T> = Pin<T>; +impl Foo { + fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } //~ ERROR E0623 +} + +fn main() {} diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr new file mode 100644 index 00000000000..3296e14f806 --- /dev/null +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr @@ -0,0 +1,26 @@ +error[E0623]: lifetime mismatch + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46 + | +LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } + | ---- ---- ^ ...but data from `f` is returned here + | | + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:76 + | +LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | ---- ----------------- ^ ...but data from `f` is returned here + | | + | this parameter and the return type are declared with different lifetimes... + +error[E0623]: lifetime mismatch + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58 + | +LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } + | ------ --- ^^^ ...but data from `arg` is returned here + | | + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md new file mode 100644 index 00000000000..7ace2e0c890 --- /dev/null +++ b/src/test/ui/self/elision/README.md @@ -0,0 +1,44 @@ +Test cases intended to document behavior and try to exhaustively +explore the combinations. + +## Confidence + +These tests are not yet considered 100% normative, in that some +aspects of the current behavior are not desirable. This is expressed +in the "confidence" field in the following table. Values: + +| Confidence | Interpretation | +| --- | --- | +| 100% | this will remain recommended behavior | +| 75% | unclear whether we will continue to accept this | +| 50% | this will likely be deprecated but remain valid | +| 25% | this could change in the future | +| 0% | this is definitely bogus and will likely change in the future in *some* way | + +## Tests + +| Test file | `Self` type | Pattern | Current elision behavior | Confidence | +| --- | --- | --- | --- | --- | +| `self.rs` | `Struct` | `Self` | ignore `self` parameter | 100% | +| `struct.rs` | `Struct` | `Struct` | ignore `self` parameter | 100% | +| `alias.rs` | `Struct` | `Alias` | ignore `self` parameter | 100% | +| `ref-self.rs` | `Struct` | `&Self` | take lifetime from `&Self` | 100% | +| `ref-mut-self.rs` | `Struct` | `&mut Self` | take lifetime from `&mut Self` | 100% | +| `ref-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% | +| `ref-mut-struct.rs` | `Struct` | `&mut Struct` | take lifetime from `&mut Self` | 50% | +| `ref-alias.rs` | `Struct` | `&Alias` | ignore `Alias` | 0% | +| `ref-mut-alias.rs` | `Struct` | `&mut Alias` | ignore `Alias` | 0% | +| `lt-self.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 25% | +| `lt-struct.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% | +| `lt-alias.rs` | `Alias<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% | +| `lt-ref-self.rs` | `Struct<'a>` | `&Self` | take lifetime from `&Self` | 75% | + +In each case, we test the following patterns: + +- `self: XXX` +- `self: Box<XXX>` +- `self: Pin<XXX>` +- `self: Box<Box<XXX>>` +- `self: Box<Pin<XXX>>` + +In the non-reference cases, `Pin` causes errors so we substitute `Rc`. diff --git a/src/test/ui/self/elision/alias.rs b/src/test/ui/self/elision/alias.rs new file mode 100644 index 00000000000..b5aacfaeec4 --- /dev/null +++ b/src/test/ui/self/elision/alias.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + + fn alias(self: Alias, f: &u32) -> &u32 { + f + } + + fn box_Alias(self: Box<Alias>, f: &u32) -> &u32 { + f + } + + fn rc_Alias(self: Rc<Alias>, f: &u32) -> &u32 { + f + } + + fn box_box_Alias(self: Box<Box<Alias>>, f: &u32) -> &u32 { + f + } + + fn box_rc_Alias(self: Box<Rc<Alias>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/assoc.rs b/src/test/ui/self/elision/assoc.rs new file mode 100644 index 00000000000..163eb49383a --- /dev/null +++ b/src/test/ui/self/elision/assoc.rs @@ -0,0 +1,40 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +trait Trait { + type AssocType; +} + +struct Struct { } + +impl Trait for Struct { + type AssocType = Self; +} + +impl Struct { + fn assoc(self: <Struct as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + fn box_AssocType(self: Box<<Struct as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn rc_AssocType(self: Rc<<Struct as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn box_box_AssocType(self: Box<Box<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } + + fn box_rc_AssocType(self: Box<Rc<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-alias.rs b/src/test/ui/self/elision/lt-alias.rs new file mode 100644 index 00000000000..df2300deda2 --- /dev/null +++ b/src/test/ui/self/elision/lt-alias.rs @@ -0,0 +1,38 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +type Alias<'a> = Struct<'a>; + +impl<'a> Alias<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 { + f + } + + fn take_Box_Alias(self: Box<Alias<'a>>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Alias(self: Box<Box<Alias<'a>>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Alias(self: Rc<Alias<'a>>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Alias(self: Box<Rc<Alias<'a>>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-assoc.rs b/src/test/ui/self/elision/lt-assoc.rs new file mode 100644 index 00000000000..70573598fcb --- /dev/null +++ b/src/test/ui/self/elision/lt-assoc.rs @@ -0,0 +1,44 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +trait Trait { + type AssocType; +} + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Trait for Struct<'a> { + type AssocType = Self; +} + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_AssocType(self: <Struct<'a> as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + fn take_Box_AssocType(self: Box<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_AssocType(self: Box<Box<<Struct<'a> as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_AssocType(self: Rc<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_AssocType(self: Box<Rc<<Struct<'a> as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-ref-self.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr new file mode 100644 index 00000000000..e97a01e746d --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self.nll.stderr @@ -0,0 +1,62 @@ +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:12:9 + | +LL | fn ref_self(&self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:18:9 + | +LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:22:9 + | +LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:26:9 + | +LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:30:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/lt-ref-self.rs:34:9 + | +LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/lt-ref-self.rs b/src/test/ui/self/elision/lt-ref-self.rs new file mode 100644 index 00000000000..8abf2876a5c --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self.rs @@ -0,0 +1,38 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct<'a> { data: &'a u32 } + +impl<'a> Struct<'a> { + // Test using `&self` sugar: + + fn ref_self(&self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + // Test using `&Self` explicitly: + + fn ref_Self(self: &Self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.stderr new file mode 100644 index 00000000000..f73b3eddd38 --- /dev/null +++ b/src/test/ui/self/elision/lt-ref-self.stderr @@ -0,0 +1,62 @@ +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:12:9 + | +LL | fn ref_self(&self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:18:9 + | +LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:22:9 + | +LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:26:9 + | +LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:30:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/lt-ref-self.rs:34:9 + | +LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/lt-self.rs b/src/test/ui/self/elision/lt-self.rs new file mode 100644 index 00000000000..9b0ee5e42a5 --- /dev/null +++ b/src/test/ui/self/elision/lt-self.rs @@ -0,0 +1,49 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; +use std::rc::Rc; + +struct Struct<'a> { + x: &'a u32 +} + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 { + f + } + + // N/A + //fn take_Pin_Self(self: Pin<Self>, f: &u32) -> &u32 { + // f + //} + + // N/A + //fn take_Box_Pin_Self(self: Box<Pin<Self>>, f: &u32) -> &u32 { + // f + //} +} + +fn main() { } diff --git a/src/test/ui/self/elision/lt-struct.rs b/src/test/ui/self/elision/lt-struct.rs new file mode 100644 index 00000000000..e41dfbbe0bf --- /dev/null +++ b/src/test/ui/self/elision/lt-struct.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Struct(self: Struct<'a>, f: &u32) -> &u32 { + f + } + + fn take_Box_Struct(self: Box<Struct<'a>>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Struct(self: Box<Box<Struct<'a>>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Struct(self: Rc<Struct<'a>>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Struct(self: Box<Rc<Struct<'a>>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/multiple-ref-self.rs b/src/test/ui/self/elision/multiple-ref-self.rs new file mode 100644 index 00000000000..f39613d0c90 --- /dev/null +++ b/src/test/ui/self/elision/multiple-ref-self.rs @@ -0,0 +1,43 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::pin::Pin; + +struct Struct { } + +struct Wrap<T, P>(T, PhantomData<P>); + +impl<T, P> Deref for Wrap<T, P> { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using multiple `&Self`: + + fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 { + f + } + + fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 { + f + } + + fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 { + f + } + + fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 { + f + } + + fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-alias.rs b/src/test/ui/self/elision/ref-alias.rs new file mode 100644 index 00000000000..d83ac612235 --- /dev/null +++ b/src/test/ui/self/elision/ref-alias.rs @@ -0,0 +1,39 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + // + // FIXME. We currently fail to recognize this as the self type, which + // feels like a bug. + + fn ref_Alias(self: &Alias, f: &u32) -> &u32 { + f + } + + fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 { + f + } + + fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-assoc.rs b/src/test/ui/self/elision/ref-assoc.rs new file mode 100644 index 00000000000..f9354bc8847 --- /dev/null +++ b/src/test/ui/self/elision/ref-assoc.rs @@ -0,0 +1,40 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +trait Trait { + type AssocType; +} + +struct Struct { } + +impl Trait for Struct { + type AssocType = Self; +} + +impl Struct { + fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-alias.rs b/src/test/ui/self/elision/ref-mut-alias.rs new file mode 100644 index 00000000000..395816f8f5d --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-alias.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + + fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 { + f + } + + fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 { + f + } + + fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-self.nll.stderr b/src/test/ui/self/elision/ref-mut-self.nll.stderr new file mode 100644 index 00000000000..3a8ae3fdcba --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self.nll.stderr @@ -0,0 +1,62 @@ +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:12:9 + | +LL | fn ref_self(&mut self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:18:9 + | +LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:22:9 + | +LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:26:9 + | +LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:30:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-self.rs:34:9 + | +LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/ref-mut-self.rs b/src/test/ui/self/elision/ref-mut-self.rs new file mode 100644 index 00000000000..a7ea47bb7f6 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self.rs @@ -0,0 +1,38 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut self` sugar: + + fn ref_self(&mut self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + // Test using `&mut Self` explicitly: + + fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr new file mode 100644 index 00000000000..37984cd72fb --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-self.stderr @@ -0,0 +1,62 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:12:9 + | +LL | fn ref_self(&mut self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:18:9 + | +LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:22:9 + | +LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:26:9 + | +LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:30:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-self.rs:34:9 + | +LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/self/elision/ref-mut-struct.nll.stderr b/src/test/ui/self/elision/ref-mut-struct.nll.stderr new file mode 100644 index 00000000000..66152ba40a5 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct.nll.stderr @@ -0,0 +1,52 @@ +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:12:9 + | +LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:16:9 + | +LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:20:9 + | +LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:24:9 + | +LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-mut-struct.rs:28:9 + | +LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/ref-mut-struct.rs b/src/test/ui/self/elision/ref-mut-struct.rs new file mode 100644 index 00000000000..795ddf8ac13 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct.rs @@ -0,0 +1,32 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut Struct` explicitly: + + fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr new file mode 100644 index 00000000000..2a4826905b9 --- /dev/null +++ b/src/test/ui/self/elision/ref-mut-struct.stderr @@ -0,0 +1,52 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:12:9 + | +LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:16:9 + | +LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:20:9 + | +LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:24:9 + | +LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-mut-struct.rs:28:9 + | +LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/ref-self.nll.stderr b/src/test/ui/self/elision/ref-self.nll.stderr new file mode 100644 index 00000000000..20045be0527 --- /dev/null +++ b/src/test/ui/self/elision/ref-self.nll.stderr @@ -0,0 +1,72 @@ +error: lifetime may not live long enough + --> $DIR/ref-self.rs:21:9 + | +LL | fn ref_self(&self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:27:9 + | +LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:31:9 + | +LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:35:9 + | +LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:39:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:43:9 + | +LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-self.rs:47:9 + | +LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/self/elision/ref-self.rs b/src/test/ui/self/elision/ref-self.rs new file mode 100644 index 00000000000..e389d8518ad --- /dev/null +++ b/src/test/ui/self/elision/ref-self.rs @@ -0,0 +1,51 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::pin::Pin; + +struct Struct { } + +struct Wrap<T, P>(T, PhantomData<P>); + +impl<T, P> Deref for Wrap<T, P> { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using `&self` sugar: + + fn ref_self(&self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + // Test using `&Self` explicitly: + + fn ref_Self(self: &Self, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-self.stderr b/src/test/ui/self/elision/ref-self.stderr new file mode 100644 index 00000000000..611498f18da --- /dev/null +++ b/src/test/ui/self/elision/ref-self.stderr @@ -0,0 +1,72 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:21:9 + | +LL | fn ref_self(&self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:27:9 + | +LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:31:9 + | +LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:35:9 + | +LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:39:9 + | +LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:43:9 + | +LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-self.rs:47:9 + | +LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + | --- --- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/self/elision/ref-struct.nll.stderr b/src/test/ui/self/elision/ref-struct.nll.stderr new file mode 100644 index 00000000000..a258bc9f743 --- /dev/null +++ b/src/test/ui/self/elision/ref-struct.nll.stderr @@ -0,0 +1,52 @@ +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:12:9 + | +LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:16:9 + | +LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:20:9 + | +LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:24:9 + | +LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/ref-struct.rs:28:9 + | +LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { + | - - let's call the lifetime of this reference `'1` + | | + | let's call the lifetime of this reference `'2` +LL | f + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/ref-struct.rs b/src/test/ui/self/elision/ref-struct.rs new file mode 100644 index 00000000000..342d6d2b363 --- /dev/null +++ b/src/test/ui/self/elision/ref-struct.rs @@ -0,0 +1,32 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&Struct` explicitly: + + fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } + + fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { + f //~ ERROR lifetime mismatch + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr new file mode 100644 index 00000000000..186e651c143 --- /dev/null +++ b/src/test/ui/self/elision/ref-struct.stderr @@ -0,0 +1,52 @@ +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:12:9 + | +LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:16:9 + | +LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:20:9 + | +LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:24:9 + | +LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error[E0623]: lifetime mismatch + --> $DIR/ref-struct.rs:28:9 + | +LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { + | ---- ---- + | | + | this parameter and the return type are declared with different lifetimes... +LL | f + | ^ ...but data from `f` is returned here + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/self/elision/self.rs b/src/test/ui/self/elision/self.rs new file mode 100644 index 00000000000..dbcef71ba14 --- /dev/null +++ b/src/test/ui/self/elision/self.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/elision/struct.rs b/src/test/ui/self/elision/struct.rs new file mode 100644 index 00000000000..227e993bd3c --- /dev/null +++ b/src/test/ui/self/elision/struct.rs @@ -0,0 +1,32 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + fn ref_Struct(self: Struct, f: &u32) -> &u32 { + f + } + + fn box_Struct(self: Box<Struct>, f: &u32) -> &u32 { + f + } + + fn rc_Struct(self: Rc<Struct>, f: &u32) -> &u32 { + f + } + + fn box_box_Struct(self: Box<Box<Struct>>, f: &u32) -> &u32 { + f + } + + fn box_rc_Struct(self: Box<Rc<Struct>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } diff --git a/src/test/ui/self/self_lifetime.rs b/src/test/ui/self/self_lifetime.rs new file mode 100644 index 00000000000..f04bd83ab6e --- /dev/null +++ b/src/test/ui/self/self_lifetime.rs @@ -0,0 +1,15 @@ +// check-pass + +// https://github.com/rust-lang/rust/pull/60944#issuecomment-495346120 + +struct Foo<'a>(&'a ()); +impl<'a> Foo<'a> { + fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } +} + +type Alias = Foo<'static>; +impl Alias { + fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } +} + +fn main() {} |
