Skip to content

Commit

Permalink
Test that opaque types can't have themselves as a hidden type with in…
Browse files Browse the repository at this point in the history
…compatible lifetimes
  • Loading branch information
oli-obk committed Jun 18, 2024
1 parent c1f62a7 commit de473a5
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 0 deletions.
14 changes: 14 additions & 0 deletions tests/ui/type-alias-impl-trait/different_args_considered_equal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![feature(type_alias_impl_trait)]

pub type Opaque<'a> = impl Sized;

fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> {
a
}

fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
//~^ ERROR: item does not constrain
None::<Opaque<'static>>
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: item does not constrain `Opaque::{opaque#0}`, but has it in its signature
--> $DIR/different_args_considered_equal.rs:9:4
|
LL | fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
| ^^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/different_args_considered_equal.rs:3:23
|
LL | pub type Opaque<'a> = impl Sized;
| ^^^^^^^^^^

error: aborting due to 1 previous error

14 changes: 14 additions & 0 deletions tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![feature(type_alias_impl_trait)]

pub type Opaque<'a> = impl Sized;

fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator<Item = Opaque<'a>> {
if a.is_null() {
Some(a)
} else {
None::<Opaque<'static>>
//~^ ERROR hidden type for `Opaque<'static>` captures lifetime that does not appear in bounds
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error[E0700]: hidden type for `Opaque<'static>` captures lifetime that does not appear in bounds
--> $DIR/different_args_considered_equal2.rs:9:9
|
LL | pub type Opaque<'a> = impl Sized;
| ---------- opaque type defined here
LL |
LL | fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator<Item = Opaque<'a>> {
| -- hidden type `*mut &'a str` captures the lifetime `'a` as defined here
...
LL | None::<Opaque<'static>>
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: to declare that `impl IntoIterator<Item = Opaque<'a>>` captures `'a`, you can add an explicit `'a` lifetime bound
|
LL | fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator<Item = Opaque<'a>> + 'a {
| ++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0700`.
22 changes: 22 additions & 0 deletions tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//! Test that we don't allow coercing an opaque type with a non-static
//! lifetime to one with a static lifetime. While `get_iter` looks like
//! it would be doing the opposite, the way we're handling projections
//! makes `Opaque<'a>` the hidden type of `Opaque<'static>`.

#![feature(type_alias_impl_trait)]

mod defining_scope {
pub type Opaque<'a> = impl Sized;

fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> {
a
}
}
use defining_scope::Opaque;

fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
None::<Opaque<'static>>
//~^ ERROR lifetime may not live long enough
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: lifetime may not live long enough
--> $DIR/different_args_considered_equal3.rs:18:5
|
LL | fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
| -- lifetime `'a` defined here
LL | None::<Opaque<'static>>
| ^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`

error: aborting due to 1 previous error

0 comments on commit de473a5

Please sign in to comment.