Skip to content

Add new solver / old solver opaque type tests #118717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions tests/ui/impl-trait/inference/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Inference tests on opaque types in defining items

When considering an opaque type within a body that is permitted to
define the hidden type for that opaque, we're expecting the new trait
solver to sometimes produce different results.

Sometimes this is due to the fact that the new trait solver considers
more cases to be defining, such as when defining the hidden type
allows an impl for some wrapper type to be matched.

In other cases, this is due to lazy normalization, which e.g. allows
the new trait solver to more consistently handle as a concrete type
the return value of...

```rust
id2<T>(_: T, x: T ) -> T { x }
```

...when it is called with a value of the opaque type and a value of
the corresponding hidden type.

However, the new trait solver is not yet done, and it does not
consistently produce the results we expect that it will once
complete.

As we work toward stabilizing type alias impl Trait (TAIT), we need to
plan for what the behavior of the new trait solver will be.
Similarly, since return position impl Trait (RPIT) is already stable
but will see inference differences with the new trait solver, we need
to begin to plan for that also.

To help enable this planning, this directory contains test cases that
define what the correct inference behavior should be when handling
opaue types.

Where the correct behavior does not match the behavior of either the
new or the old trait solver, we've chosen to mark that as a known
bug. For the new solver, we've done this since it is still a work in
progress and is expected to eventually model the correct behavior.
For the old solver, we've done this since the behavior is inconsistent
and often surprising, and since we may need to add future-incompat
lints or take other steps to prepare the ecosystem for the transition
to the new solver.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0391]: cycle detected when computing type of opaque `test::{opaque#0}`
--> $DIR/reveal-auto-trait-notsend-inner-id-left.rs:31:21
|
LL | fn test(n: bool) -> impl Sized {
| ^^^^^^^^^^
|
note: ...which requires type-checking `test`...
--> $DIR/reveal-auto-trait-notsend-inner-id-left.rs:33:61
|
LL | let _: OnWShow = (&&W(id2(test(!n), &() as *const ()))).show();
| ^^^^
= note: ...which requires evaluating trait selection obligation `&'a W<test::{opaque#0}>: OnWSend`...
= note: ...which again requires computing type of opaque `test::{opaque#0}`, completing the cycle
note: cycle used when computing type of `test::{opaque#0}`
--> $DIR/reveal-auto-trait-notsend-inner-id-left.rs:31:21
|
LL | fn test(n: bool) -> impl Sized {
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// edition:2021
// revisions: new old
// [new]compile-flags: -Ztrait-solver=next
// [old]compile-flags: -Ztrait-solver=classic
// [new]check-pass
// [old]known-bug: unknown

struct W<T>(T);

struct OnWShow;
trait OnW {
fn show(&self) -> OnWShow {
OnWShow
}
}

struct OnWSendShow;
trait OnWSend {
fn show(&self) -> OnWSendShow {
OnWSendShow
}
}

impl<T> OnW for W<T> {}
impl<T: Send> OnWSend for &W<T> {}

fn id2<T>(_: T, x: T) -> T {
x
}

fn test(n: bool) -> impl Sized {
let true = n else { return &() as *const () };
let _: OnWShow = (&&W(id2(test(!n), &() as *const ()))).show();
&() as *const ()
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// edition:2021
// revisions: new old
// [new]compile-flags: -Ztrait-solver=next
// [old]compile-flags: -Ztrait-solver=classic
// check-pass

struct W<T>(T);

struct OnWShow;
trait OnW {
fn show(&self) -> OnWShow {
OnWShow
}
}

struct OnWSendShow;
trait OnWSend {
fn show(&self) -> OnWSendShow {
OnWSendShow
}
}

impl<T> OnW for W<T> {}
impl<T: Send> OnWSend for &W<T> {}

fn id2<T>(_: T, x: T) -> T {
x
}

fn test(n: bool) -> impl Sized {
let true = n else { return &() as *const () };
let _: OnWShow = (&&W(id2(&() as *const (), test(!n)))).show();
&() as *const ()
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0391]: cycle detected when computing type of opaque `test::{opaque#0}`
--> $DIR/reveal-auto-trait-notsend-outer-id-left.rs:31:21
|
LL | fn test(n: bool) -> impl Sized {
| ^^^^^^^^^^
|
note: ...which requires type-checking `test`...
--> $DIR/reveal-auto-trait-notsend-outer-id-left.rs:33:64
|
LL | let _: OnWShow = id2(&&W(test(!n)), &&W(&() as *const ())).show();
| ^^^^
= note: ...which requires evaluating trait selection obligation `&'a W<test::{opaque#0}>: OnWSend`...
= note: ...which again requires computing type of opaque `test::{opaque#0}`, completing the cycle
note: cycle used when computing type of `test::{opaque#0}`
--> $DIR/reveal-auto-trait-notsend-outer-id-left.rs:31:21
|
LL | fn test(n: bool) -> impl Sized {
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// edition:2021
// revisions: new old
// [new]compile-flags: -Ztrait-solver=next
// [old]compile-flags: -Ztrait-solver=classic
// [new]check-pass
// [old]known-bug: unknown

struct W<T>(T);

struct OnWShow;
trait OnW {
fn show(&self) -> OnWShow {
OnWShow
}
}

struct OnWSendShow;
trait OnWSend {
fn show(&self) -> OnWSendShow {
OnWSendShow
}
}

impl<T> OnW for W<T> {}
impl<T: Send> OnWSend for &W<T> {}

fn id2<T>(_: T, x: T) -> T {
x
}

fn test(n: bool) -> impl Sized {
let true = n else { return &() as *const () };
let _: OnWShow = id2(&&W(test(!n)), &&W(&() as *const ())).show();
&() as *const ()
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// edition:2021
// revisions: new old
// [new]compile-flags: -Ztrait-solver=next
// [old]compile-flags: -Ztrait-solver=classic
// check-pass

struct W<T>(T);

struct OnWShow;
trait OnW {
fn show(&self) -> OnWShow {
OnWShow
}
}

struct OnWSendShow;
trait OnWSend {
fn show(&self) -> OnWSendShow {
OnWSendShow
}
}

impl<T> OnW for W<T> {}
impl<T: Send> OnWSend for &W<T> {}

fn id2<T>(_: T, x: T) -> T {
x
}

fn test(n: bool) -> impl Sized {
let true = n else { return &() as *const () };
let _: OnWShow = id2(&&W(&() as *const ()), &&W(test(!n))).show();
&() as *const ()
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0391]: cycle detected when computing type of opaque `test::{opaque#0}`
--> $DIR/reveal-auto-trait-notsend.rs:27:21
|
LL | fn test(n: bool) -> impl Sized {
| ^^^^^^^^^^
|
note: ...which requires type-checking `test`...
--> $DIR/reveal-auto-trait-notsend.rs:29:38
|
LL | let _: OnWShow = (&&W(test(!n))).show();
| ^^^^
= note: ...which requires evaluating trait selection obligation `&'a W<test::{opaque#0}>: OnWSend`...
= note: ...which again requires computing type of opaque `test::{opaque#0}`, completing the cycle
note: cycle used when computing type of `test::{opaque#0}`
--> $DIR/reveal-auto-trait-notsend.rs:27:21
|
LL | fn test(n: bool) -> impl Sized {
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// edition:2021
// revisions: new old
// [new]compile-flags: -Ztrait-solver=next
// [old]compile-flags: -Ztrait-solver=classic
// [new]check-pass
// [old]known-bug: unknown

struct W<T>(T);

struct OnWShow;
trait OnW {
fn show(&self) -> OnWShow {
OnWShow
}
}

struct OnWSendShow;
trait OnWSend {
fn show(&self) -> OnWSendShow {
OnWSendShow
}
}

impl<T> OnW for W<T> {}
impl<T: Send> OnWSend for &W<T> {}

fn test(n: bool) -> impl Sized {
let true = n else { return &() as *const () };
let _: OnWShow = (&&W(test(!n))).show();
&() as *const ()
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
error[E0308]: mismatched types
--> $DIR/reveal-auto-trait-send-inner-id-left.rs:33:26
|
LL | let _: OnWSendShow = (&&W(id2(test(!n), ()))).show();
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `OnWSendShow`, found `OnWShow`
| |
| expected due to this

error[E0391]: cycle detected when computing type of opaque `test::{opaque#0}`
--> $DIR/reveal-auto-trait-send-inner-id-left.rs:31:21
|
LL | fn test(n: bool) -> impl Sized {
| ^^^^^^^^^^
|
note: ...which requires type-checking `test`...
--> $DIR/reveal-auto-trait-send-inner-id-left.rs:33:51
|
LL | let _: OnWSendShow = (&&W(id2(test(!n), ()))).show();
| ^^^^
= note: ...which requires evaluating trait selection obligation `&'a W<test::{opaque#0}>: OnWSend`...
= note: ...which again requires computing type of opaque `test::{opaque#0}`, completing the cycle
note: cycle used when computing type of `test::{opaque#0}`
--> $DIR/reveal-auto-trait-send-inner-id-left.rs:31:21
|
LL | fn test(n: bool) -> impl Sized {
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0308, E0391.
For more information about an error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// edition:2021
// revisions: new old
// [new]compile-flags: -Ztrait-solver=next
// [old]compile-flags: -Ztrait-solver=classic
// [new]check-pass
// [old]known-bug: unknown

struct W<T>(T);

struct OnWShow;
trait OnW {
fn show(&self) -> OnWShow {
OnWShow
}
}

struct OnWSendShow;
trait OnWSend {
fn show(&self) -> OnWSendShow {
OnWSendShow
}
}

impl<T> OnW for W<T> {}
impl<T: Send> OnWSend for &W<T> {}

fn id2<T>(_: T, x: T) -> T {
x
}

fn test(n: bool) -> impl Sized {
let true = n else { return };
let _: OnWSendShow = (&&W(id2(test(!n), ()))).show();
}

fn main() {}
Loading