Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Mar 14, 2024
1 parent 323069f commit c8f0f17
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 0 deletions.
@@ -0,0 +1,22 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ok.rs:17:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
found existential trait ref `for<'a> Supertrait<'a, 'a>`

error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ok.rs:17:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
found existential trait ref `for<'a> Supertrait<'a, 'a>`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
@@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ok.rs:17:5
|
LL | fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
| ------------------------------- expected `&dyn for<'a> Supertrait<'a, 'a>` because of return type
LL | x
| ^ expected trait `Supertrait`, found trait `Subtrait`
|
= note: expected reference `&dyn for<'a> Supertrait<'a, 'a>`
found reference `&dyn for<'a, 'b> Subtrait<'a, 'b>`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.
19 changes: 19 additions & 0 deletions tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
@@ -0,0 +1,19 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

// We should be able to instantiate a binder during trait upcasting.
// This test could be `check-pass`, but we should make sure that we
// do so in both trait solvers.
#![feature(trait_upcasting)]
#![crate_type = "rlib"]
trait Supertrait<'a, 'b> {}

trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}

impl<'a> Supertrait<'a, 'a> for () {}
impl<'a> Subtrait<'a, 'a> for () {}
fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
x //~ ERROR mismatched types
//[current]~^ ERROR mismatched types
}
@@ -0,0 +1,22 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`

error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
@@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
|
LL | fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> {
| ----------------------------------- expected `&dyn for<'a, 'b> Supertrait<'a, 'b>` because of return type
LL | x
| ^ expected trait `Supertrait`, found trait `Subtrait`
|
= note: expected reference `&dyn for<'a, 'b> Supertrait<'a, 'b>`
found reference `&dyn for<'a> Subtrait<'a, 'a>`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.
37 changes: 37 additions & 0 deletions tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs
@@ -0,0 +1,37 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

// We previously wrongly instantiated binders during trait upcasting,
// allowing the super trait to be more generic than the sub trait.
// This was unsound.
#![feature(trait_upcasting)]
trait Supertrait<'a, 'b> {
fn cast(&self, x: &'a str) -> &'b str;
}

trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}

impl<'a> Supertrait<'a, 'a> for () {
fn cast(&self, x: &'a str) -> &'a str {
x
}
}
impl<'a> Subtrait<'a, 'a> for () {}
fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> {
x //~ ERROR mismatched types
//[current]~^ ERROR mismatched types
}

fn transmute<'a, 'b>(x: &'a str) -> &'b str {
unsound(&()).cast(x)
}

fn main() {
let x;
{
let mut temp = String::from("hello there");
x = transmute(temp.as_str());
}
println!("{x}");
}

0 comments on commit c8f0f17

Please sign in to comment.