Skip to content

Commit 5592c40

Browse files
committed
Test all the things
1 parent e673a9e commit 5592c40

13 files changed

+278
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//! Check that const eval can use the size of opaque types.
2+
// check-pass
3+
use std::mem;
4+
fn returns_opaque() -> impl Sized {
5+
0u8
6+
}
7+
8+
struct NamedOpaqueType {
9+
data: [mem::MaybeUninit<u8>; size_of_fut(returns_opaque)],
10+
}
11+
12+
const fn size_of_fut<FUT>(x: fn() -> FUT) -> usize {
13+
mem::size_of::<FUT>()
14+
}
15+
16+
fn main() {}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//! Check that array lengths can observe associated types of opaque types
2+
// check-pass
3+
trait MyTrait: Copy {
4+
const ASSOC: usize;
5+
}
6+
7+
impl MyTrait for u8 {
8+
const ASSOC: usize = 32;
9+
}
10+
11+
const fn yeet() -> impl MyTrait {
12+
0u8
13+
}
14+
15+
const fn output<T: MyTrait>(_: T) -> usize {
16+
<T as MyTrait>::ASSOC
17+
}
18+
19+
fn main() {
20+
let x = [0u8; output(yeet())];
21+
println!("{:?}", x);
22+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//! check that const eval can observe associated types of opaque types.
2+
// check-pass
3+
trait MyTrait: Copy {
4+
const ASSOC: usize;
5+
}
6+
7+
impl MyTrait for u8 {
8+
const ASSOC: usize = 32;
9+
}
10+
11+
const fn yeet() -> impl MyTrait {
12+
0u8
13+
}
14+
15+
const fn output<T: MyTrait>(_: T) -> usize {
16+
<T as MyTrait>::ASSOC
17+
}
18+
19+
#[repr(usize)]
20+
enum Foo {
21+
Bar = output(yeet()),
22+
}
23+
24+
fn main() {
25+
println!("{}", Foo::Bar as usize);
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! Check that pattern matching can observe the hidden type of opaque types.
2+
// check-pass
3+
trait MyTrait: Copy {
4+
const ASSOC: u8;
5+
}
6+
7+
impl MyTrait for () {
8+
const ASSOC: u8 = 0;
9+
}
10+
11+
const fn yeet() -> impl MyTrait {}
12+
13+
const fn output<T: MyTrait>(_: T) -> u8 {
14+
<T as MyTrait>::ASSOC
15+
}
16+
17+
const CT: u8 = output(yeet());
18+
19+
fn main() {
20+
match 0 {
21+
CT => (),
22+
1.. => (),
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// This causes a query cycle due to using `Reveal::All`,
2+
// in #119821 const eval was changed to always use `Reveal::All`
3+
//
4+
// See that PR for more details.
5+
use std::mem::transmute;
6+
fn foo() -> impl Sized {
7+
//~^ ERROR cycle detected when computing type of
8+
unsafe {
9+
transmute::<_, u8>(foo());
10+
}
11+
0u8
12+
}
13+
14+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0391]: cycle detected when computing type of `foo::{opaque#0}`
2+
--> $DIR/in-defining-scope.rs:6:13
3+
|
4+
LL | fn foo() -> impl Sized {
5+
| ^^^^^^^^^^
6+
|
7+
note: ...which requires computing type of opaque `foo::{opaque#0}`...
8+
--> $DIR/in-defining-scope.rs:6:13
9+
|
10+
LL | fn foo() -> impl Sized {
11+
| ^^^^^^^^^^
12+
note: ...which requires type-checking `foo`...
13+
--> $DIR/in-defining-scope.rs:6:1
14+
|
15+
LL | fn foo() -> impl Sized {
16+
| ^^^^^^^^^^^^^^^^^^^^^^
17+
= note: ...which requires computing layout of `foo::{opaque#0}`...
18+
= note: ...which requires normalizing `foo::{opaque#0}`...
19+
= note: ...which again requires computing type of `foo::{opaque#0}`, completing the cycle
20+
note: cycle used when checking that `foo::{opaque#0}` is well-formed
21+
--> $DIR/in-defining-scope.rs:6:13
22+
|
23+
LL | fn foo() -> impl Sized {
24+
| ^^^^^^^^^^
25+
= 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
26+
27+
error: aborting due to 1 previous error
28+
29+
For more information about this error, try `rustc --explain E0391`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! Check that typeck can observe the size of an opaque type.
2+
// check-pass
3+
use std::mem::transmute;
4+
fn foo() -> impl Sized {
5+
0u8
6+
}
7+
8+
fn main() {
9+
unsafe {
10+
transmute::<_, u8>(foo());
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//! Regression test for revealing associated types through specialization during const eval.
2+
// check-pass
3+
#![feature(specialization)]
4+
//~^ WARNING the feature `specialization` is incomplete and may not be safe to use
5+
6+
trait Foo {
7+
const ASSOC: usize;
8+
}
9+
10+
impl Foo for u32 {
11+
default const ASSOC: usize = 0;
12+
}
13+
14+
fn foo() -> [u8; 0] {
15+
[0; <u32 as Foo>::ASSOC]
16+
}
17+
18+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/default-assoc-const.rs:6:12
3+
|
4+
LL | #![feature(specialization)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: consider using `min_specialization` instead, which is more stable and complete
9+
= note: `#[warn(incomplete_features)]` on by default
10+
11+
warning: 1 warning emitted
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//! Regression test showing that we can access assoicated types during const eval,
2+
//! even if they rely on specialization.
3+
// check-pass
4+
#![feature(specialization)]
5+
//~^ WARNING the feature `specialization` is incomplete and may not be safe to use
6+
7+
trait Foo {
8+
type Assoc: Trait;
9+
}
10+
11+
impl<T> Foo for Vec<T> {
12+
default type Assoc = u32;
13+
}
14+
15+
trait Trait {
16+
const ASSOC: usize;
17+
}
18+
19+
impl Trait for u32 {
20+
const ASSOC: usize = 0;
21+
}
22+
23+
fn foo() -> [u8; 0] {
24+
[0; <<Vec<u32> as Foo>::Assoc as Trait>::ASSOC]
25+
}
26+
27+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/default-assoc-type.rs:6:12
3+
|
4+
LL | #![feature(specialization)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: consider using `min_specialization` instead, which is more stable and complete
9+
= note: `#[warn(incomplete_features)]` on by default
10+
11+
warning: 1 warning emitted
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//! We evaluate `1 + 2` with `Reveal::All` during typeck, causing
2+
//! us to to get the concrete type of `Bar` while computing it.
3+
//! This again requires type checking `foo`.
4+
#![feature(type_alias_impl_trait)]
5+
type Bar = impl Sized;
6+
//~^ ERROR: cycle
7+
//~| ERROR: cycle
8+
9+
fn foo() -> Bar
10+
where
11+
Bar: Send,
12+
{
13+
[0; 1 + 2]
14+
}
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error[E0391]: cycle detected when computing type of `Bar::{opaque#0}`
2+
--> $DIR/in-where-clause.rs:5:12
3+
|
4+
LL | type Bar = impl Sized;
5+
| ^^^^^^^^^^
6+
|
7+
note: ...which requires computing type of opaque `Bar::{opaque#0}`...
8+
--> $DIR/in-where-clause.rs:5:12
9+
|
10+
LL | type Bar = impl Sized;
11+
| ^^^^^^^^^^
12+
note: ...which requires type-checking `foo`...
13+
--> $DIR/in-where-clause.rs:9:1
14+
|
15+
LL | / fn foo() -> Bar
16+
LL | | where
17+
LL | | Bar: Send,
18+
| |______________^
19+
= note: ...which requires revealing opaque types in `[Binder { value: TraitPredicate(<Bar as core::marker::Send>, polarity:Positive), bound_vars: [] }]`...
20+
= note: ...which again requires computing type of `Bar::{opaque#0}`, completing the cycle
21+
note: cycle used when checking that `Bar::{opaque#0}` is well-formed
22+
--> $DIR/in-where-clause.rs:5:12
23+
|
24+
LL | type Bar = impl Sized;
25+
| ^^^^^^^^^^
26+
= 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
27+
28+
error[E0391]: cycle detected when computing type of opaque `Bar::{opaque#0}`
29+
--> $DIR/in-where-clause.rs:5:12
30+
|
31+
LL | type Bar = impl Sized;
32+
| ^^^^^^^^^^
33+
|
34+
note: ...which requires type-checking `foo`...
35+
--> $DIR/in-where-clause.rs:13:9
36+
|
37+
LL | [0; 1 + 2]
38+
| ^^^^^
39+
= note: ...which requires evaluating trait selection obligation `Bar: core::marker::Send`...
40+
= note: ...which again requires computing type of opaque `Bar::{opaque#0}`, completing the cycle
41+
note: cycle used when computing type of `Bar::{opaque#0}`
42+
--> $DIR/in-where-clause.rs:5:12
43+
|
44+
LL | type Bar = impl Sized;
45+
| ^^^^^^^^^^
46+
= 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
47+
48+
error: aborting due to 2 previous errors
49+
50+
For more information about this error, try `rustc --explain E0391`.

0 commit comments

Comments
 (0)