summaryrefslogtreecommitdiffstats
path: root/src/test/ui/impl-header-lifetime-elision
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/impl-header-lifetime-elision')
-rw-r--r--src/test/ui/impl-header-lifetime-elision/assoc-type.rs25
-rw-r--r--src/test/ui/impl-header-lifetime-elision/assoc-type.stderr15
-rw-r--r--src/test/ui/impl-header-lifetime-elision/constant-used-as-arraylen.rs24
-rw-r--r--src/test/ui/impl-header-lifetime-elision/dyn-trait.rs36
-rw-r--r--src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr16
-rw-r--r--src/test/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs13
-rw-r--r--src/test/ui/impl-header-lifetime-elision/inherent-impl.rs9
-rw-r--r--src/test/ui/impl-header-lifetime-elision/path-elided.rs11
-rw-r--r--src/test/ui/impl-header-lifetime-elision/path-elided.stderr15
-rw-r--r--src/test/ui/impl-header-lifetime-elision/path-underscore.rs34
-rw-r--r--src/test/ui/impl-header-lifetime-elision/ref-underscore.rs30
-rw-r--r--src/test/ui/impl-header-lifetime-elision/trait-elided.rs8
-rw-r--r--src/test/ui/impl-header-lifetime-elision/trait-elided.stderr15
-rw-r--r--src/test/ui/impl-header-lifetime-elision/trait-underscore.rs35
14 files changed, 286 insertions, 0 deletions
diff --git a/src/test/ui/impl-header-lifetime-elision/assoc-type.rs b/src/test/ui/impl-header-lifetime-elision/assoc-type.rs
new file mode 100644
index 000000000..b0089a37a
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/assoc-type.rs
@@ -0,0 +1,25 @@
+// Test that we do not yet support elision in associated types, even
+// when there is just one name we could take from the impl header.
+
+#![allow(warnings)]
+
+trait MyTrait {
+ type Output;
+}
+
+impl MyTrait for &i32 {
+ type Output = &i32;
+ //~^ ERROR `&` without an explicit lifetime name cannot be used here
+}
+
+impl MyTrait for &u32 {
+ type Output = &'_ i32;
+ //~^ ERROR `'_` cannot be used here
+}
+
+// This is what you have to do:
+impl<'a> MyTrait for &'a f32 {
+ type Output = &'a f32;
+}
+
+fn main() { }
diff --git a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr
new file mode 100644
index 000000000..c4f27e0b8
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr
@@ -0,0 +1,15 @@
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/assoc-type.rs:11:19
+ |
+LL | type Output = &i32;
+ | ^ explicit lifetime name needed here
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/assoc-type.rs:16:20
+ |
+LL | type Output = &'_ i32;
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/impl-header-lifetime-elision/constant-used-as-arraylen.rs b/src/test/ui/impl-header-lifetime-elision/constant-used-as-arraylen.rs
new file mode 100644
index 000000000..929b82bfc
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/constant-used-as-arraylen.rs
@@ -0,0 +1,24 @@
+// check-pass
+// Verify that we do not ICE when anonymous lifetimes appear inside an AnonConst.
+
+pub struct EntriesBuffer(Box<[[u8; HashesEntry::LEN]; 5]>);
+
+impl EntriesBuffer {
+ pub fn iter_child_buffers(&mut self) -> impl Iterator<Item = &mut [u8; HashesEntry::LEN]> {
+ self.0.iter_mut()
+ }
+
+ pub fn iter_child_buffers_explicit(
+ &mut self,
+ ) -> impl Iterator<Item = &mut [u8; HashesEntry::<'_>::LEN]> {
+ self.0.iter_mut()
+ }
+}
+
+pub struct HashesEntry<'a>(&'a [u8]);
+
+impl HashesEntry<'_> {
+ pub const LEN: usize = 1;
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.rs b/src/test/ui/impl-header-lifetime-elision/dyn-trait.rs
new file mode 100644
index 000000000..359c08c98
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.rs
@@ -0,0 +1,36 @@
+// Test that `impl MyTrait<'_> for &i32` is equivalent to `impl<'a,
+// 'b> MyTrait<'a> for &'b i32`.
+
+#![allow(warnings)]
+
+use std::fmt::Debug;
+
+// Equivalent to `Box<dyn Debug + 'static>`:
+trait StaticTrait { }
+impl StaticTrait for Box<dyn Debug> { }
+
+// Equivalent to `Box<dyn Debug + 'static>`:
+trait NotStaticTrait { }
+impl NotStaticTrait for Box<dyn Debug + '_> { }
+
+// Check that we don't err when the trait has a lifetime parameter.
+trait TraitWithLifetime<'a> { }
+impl NotStaticTrait for &dyn TraitWithLifetime<'_> { }
+
+fn static_val<T: StaticTrait>(_: T) {
+}
+
+fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
+ static_val(x);
+ //~^ ERROR borrowed data escapes outside of function
+}
+
+fn not_static_val<T: NotStaticTrait>(_: T) {
+}
+
+fn with_dyn_debug_not_static<'a>(x: Box<dyn Debug + 'a>) {
+ not_static_val(x); // OK
+}
+
+fn main() {
+}
diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
new file mode 100644
index 000000000..762698c4f
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
@@ -0,0 +1,16 @@
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/dyn-trait.rs:24:5
+ |
+LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
+ | -- - `x` is a reference that is only valid in the function body
+ | |
+ | lifetime `'a` defined here
+LL | static_val(x);
+ | ^^^^^^^^^^^^^
+ | |
+ | `x` escapes the function body here
+ | argument requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs b/src/test/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs
new file mode 100644
index 000000000..6301ac4a3
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+#![allow(warnings)]
+
+// This works for functions...
+fn foo<'a>(x: &str, y: &'a str) {}
+
+// ...so this should work for impls
+impl<'a> Foo<&str> for &'a str {}
+trait Foo<T> {}
+
+fn main() {
+}
diff --git a/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs b/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs
new file mode 100644
index 000000000..9d7b2f2d0
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs
@@ -0,0 +1,9 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+struct Foo<'a>(&'a u8);
+
+impl Foo<'_> {
+ fn x() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-header-lifetime-elision/path-elided.rs b/src/test/ui/impl-header-lifetime-elision/path-elided.rs
new file mode 100644
index 000000000..40a52efc7
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/path-elided.rs
@@ -0,0 +1,11 @@
+#![allow(warnings)]
+
+trait MyTrait { }
+
+struct Foo<'a> { x: &'a u32 }
+
+impl MyTrait for Foo {
+ //~^ ERROR implicit elided lifetime not allowed here
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-header-lifetime-elision/path-elided.stderr b/src/test/ui/impl-header-lifetime-elision/path-elided.stderr
new file mode 100644
index 000000000..0b7d3f1e8
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/path-elided.stderr
@@ -0,0 +1,15 @@
+error[E0726]: implicit elided lifetime not allowed here
+ --> $DIR/path-elided.rs:7:18
+ |
+LL | impl MyTrait for Foo {
+ | ^^^ expected lifetime parameter
+ |
+ = note: assuming a `'static` lifetime...
+help: indicate the anonymous lifetime
+ |
+LL | impl MyTrait for Foo<'_> {
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0726`.
diff --git a/src/test/ui/impl-header-lifetime-elision/path-underscore.rs b/src/test/ui/impl-header-lifetime-elision/path-underscore.rs
new file mode 100644
index 000000000..f39ba5733
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/path-underscore.rs
@@ -0,0 +1,34 @@
+// Test that `impl MyTrait for Foo<'_>` works.
+
+// run-pass
+
+#![allow(warnings)]
+
+trait MyTrait { }
+
+struct Foo<'a> { x: &'a u32 }
+
+impl MyTrait for Foo<'_> {
+}
+
+fn impls_my_trait<T: MyTrait>() { }
+
+fn impls_my_trait_val<T: MyTrait>(_: T) {
+ impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a> Foo<'a>: MyTrait { }
+
+fn main() {
+ let x = 22;
+ let f = Foo { x: &x };
+
+ // This type is `Foo<'x>` for a local lifetime `'x`; so the impl
+ // must apply to any lifetime to apply to this.
+ impls_my_trait_val(f);
+
+ impls_my_trait::<Foo<'static>>();
+
+ random_where_clause();
+}
diff --git a/src/test/ui/impl-header-lifetime-elision/ref-underscore.rs b/src/test/ui/impl-header-lifetime-elision/ref-underscore.rs
new file mode 100644
index 000000000..5be04d08a
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/ref-underscore.rs
@@ -0,0 +1,30 @@
+// Test that `impl MyTrait for &i32` works and is equivalent to any lifetime.
+
+// run-pass
+
+#![allow(warnings)]
+
+trait MyTrait { }
+
+impl MyTrait for &i32 {
+}
+
+fn impls_my_trait<T: MyTrait>() { }
+
+fn impls_my_trait_val<T: MyTrait>(_: T) {
+ impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a> &'a i32: MyTrait { }
+
+fn main() {
+ let x = 22;
+ let f = &x;
+
+ impls_my_trait_val(f);
+
+ impls_my_trait::<&'static i32>();
+
+ random_where_clause();
+}
diff --git a/src/test/ui/impl-header-lifetime-elision/trait-elided.rs b/src/test/ui/impl-header-lifetime-elision/trait-elided.rs
new file mode 100644
index 000000000..c3e76d9cb
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/trait-elided.rs
@@ -0,0 +1,8 @@
+#![allow(warnings)]
+
+trait MyTrait<'a> {}
+
+impl MyTrait for u32 {}
+//~^ ERROR implicit elided lifetime not allowed here
+
+fn main() {}
diff --git a/src/test/ui/impl-header-lifetime-elision/trait-elided.stderr b/src/test/ui/impl-header-lifetime-elision/trait-elided.stderr
new file mode 100644
index 000000000..412bba6be
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/trait-elided.stderr
@@ -0,0 +1,15 @@
+error[E0726]: implicit elided lifetime not allowed here
+ --> $DIR/trait-elided.rs:5:6
+ |
+LL | impl MyTrait for u32 {}
+ | ^^^^^^^ expected lifetime parameter
+ |
+ = note: assuming a `'static` lifetime...
+help: indicate the anonymous lifetime
+ |
+LL | impl MyTrait<'_> for u32 {}
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0726`.
diff --git a/src/test/ui/impl-header-lifetime-elision/trait-underscore.rs b/src/test/ui/impl-header-lifetime-elision/trait-underscore.rs
new file mode 100644
index 000000000..3e13b0426
--- /dev/null
+++ b/src/test/ui/impl-header-lifetime-elision/trait-underscore.rs
@@ -0,0 +1,35 @@
+// Test that `impl MyTrait<'_> for &i32` is equivalent to `impl<'a,
+// 'b> MyTrait<'a> for &'b i32`.
+//
+// run-pass
+
+#![allow(warnings)]
+
+trait MyTrait<'a> { }
+
+// This is equivalent to `MyTrait<'a> for &'b i32`, which is proven by
+// the code below.
+impl MyTrait<'_> for &i32 {
+}
+
+// When called, T will be `&'x i32` for some `'x`, so since we can
+// prove that `&'x i32: for<'a> MyTrait<'a>, then we know that the
+// lifetime parameter above is disconnected.
+fn impls_my_trait<T: for<'a> MyTrait<'a>>() { }
+
+fn impls_my_trait_val<T: for<'a> MyTrait<'a>>(_: T) {
+ impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a, 'b> &'a i32: MyTrait<'b> { }
+
+fn main() {
+ let x = 22;
+ let f = &x;
+ impls_my_trait_val(f);
+
+ impls_my_trait::<&'static i32>();
+
+ random_where_clause();
+}