diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/impl-header-lifetime-elision | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/impl-header-lifetime-elision')
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(); +} |