Skip to content

Commit 0cd118d

Browse files
Rollup merge of #78916 - lcnr:const-generics-tests, r=varkor
extend const generics test suite should implement most of #78433, especially all parts of [the hackmd](https://hackmd.io/WnFmN4MjRCqAjGmYfYcu2A?view) which I did not explicitly mention in that issue. r? ``@varkor``
2 parents 55794e4 + a9eacf3 commit 0cd118d

23 files changed

+1126
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// check-pass
2+
// edition:2018
3+
#![feature(min_const_generics)]
4+
trait ValidTrait {}
5+
6+
/// This has docs
7+
pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]> {
8+
loop {}
9+
}
10+
11+
pub trait Trait<const N: usize> {}
12+
impl Trait<1> for u8 {}
13+
impl Trait<2> for u8 {}
14+
impl<const N: usize> Trait<N> for [u8; N] {}
15+
16+
/// This also has docs
17+
pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N> {
18+
loop {}
19+
}
20+
21+
/// Document all the functions
22+
pub async fn a_sink<const N: usize>(v: [u8; N]) -> impl Trait<N> {
23+
loop {}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// edition:2018
2+
#![feature(min_const_generics)]
3+
4+
pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]> {
5+
[[0; N]; N].iter().copied()
6+
}
7+
8+
pub struct ExternTy<const N: usize> {
9+
pub inner: [u8; N],
10+
}
11+
12+
pub type TyAlias<const N: usize> = ExternTy<N>;
13+
14+
pub trait WTrait<const N: usize, const M: usize> {
15+
fn hey<const P: usize>() -> usize {
16+
N + M + P
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// edition:2018
2+
// aux-build: extern_crate.rs
3+
#![feature(min_const_generics)]
4+
#![crate_name = "foo"]
5+
6+
extern crate extern_crate;
7+
// @has foo/fn.extern_fn.html '//pre[@class="rust fn"]' \
8+
// 'pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]>'
9+
pub use extern_crate::extern_fn;
10+
// @has foo/struct.ExternTy.html '//pre[@class="rust struct"]' \
11+
// 'pub struct ExternTy<const N: usize> {'
12+
pub use extern_crate::ExternTy;
13+
// @has foo/type.TyAlias.html '//pre[@class="rust typedef"]' \
14+
// 'type TyAlias<const N: usize> = ExternTy<N>;'
15+
pub use extern_crate::TyAlias;
16+
// @has foo/trait.WTrait.html '//pre[@class="rust trait"]' \
17+
// 'pub trait WTrait<const N: usize, const M: usize>'
18+
// @has - '//*[@class="rust trait"]' 'fn hey<const P: usize>() -> usize'
19+
pub use extern_crate::WTrait;
20+
21+
// @has foo/trait.Trait.html '//pre[@class="rust trait"]' \
22+
// 'pub trait Trait<const N: usize>'
23+
// @has - '//*[@id="impl-Trait%3C1_usize%3E-for-u8"]//code' 'impl Trait<1_usize> for u8'
24+
// @has - '//*[@id="impl-Trait%3C2_usize%3E-for-u8"]//code' 'impl Trait<2_usize> for u8'
25+
// @has - '//*[@id="impl-Trait%3C{1%20+%202}%3E-for-u8"]//code' 'impl Trait<{1 + 2}> for u8'
26+
// @has - '//*[@id="impl-Trait%3CN%3E-for-%5Bu8%3B%20N%5D"]//code' \
27+
// 'impl<const N: usize> Trait<N> for [u8; N]'
28+
pub trait Trait<const N: usize> {}
29+
impl Trait<1> for u8 {}
30+
impl Trait<2> for u8 {}
31+
impl Trait<{1 + 2}> for u8 {}
32+
impl<const N: usize> Trait<N> for [u8; N] {}
33+
34+
// @has foo/struct.Foo.html '//pre[@class="rust struct"]' \
35+
// 'pub struct Foo<const N: usize> where u8: Trait<N>'
36+
pub struct Foo<const N: usize> where u8: Trait<N>;
37+
// @has foo/struct.Bar.html '//pre[@class="rust struct"]' 'pub struct Bar<T, const N: usize>(_)'
38+
pub struct Bar<T, const N: usize>([T; N]);
39+
40+
// @has foo/struct.Foo.html '//h3[@id="impl"]/code' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
41+
impl<const M: usize> Foo<M> where u8: Trait<M> {
42+
// @has - '//*[@id="associatedconstant.FOO_ASSOC"]' 'pub const FOO_ASSOC: usize'
43+
pub const FOO_ASSOC: usize = M + 13;
44+
45+
// @has - '//*[@id="method.hey"]' 'pub fn hey<const N: usize>(&self) -> Bar<u8, N>'
46+
pub fn hey<const N: usize>(&self) -> Bar<u8, N> {
47+
Bar([0; N])
48+
}
49+
}
50+
51+
// @has foo/struct.Bar.html '//h3[@id="impl"]/code' 'impl<const M: usize> Bar<u8, M>'
52+
impl<const M: usize> Bar<u8, M> {
53+
// @has - '//*[@id="method.hey"]' \
54+
// 'pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N>'
55+
pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N> {
56+
Foo
57+
}
58+
}
59+
60+
// @has foo/fn.test.html '//pre[@class="rust fn"]' \
61+
// 'pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N>'
62+
pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N> {
63+
2u8
64+
}
65+
66+
// @has foo/fn.a_sink.html '//pre[@class="rust fn"]' \
67+
// 'pub async fn a_sink<const N: usize>(v: [u8; N]) -> impl Trait<N>'
68+
pub async fn a_sink<const N: usize>(v: [u8; N]) -> impl Trait<N> {
69+
v
70+
}
71+
72+
// @has foo/fn.b_sink.html '//pre[@class="rust fn"]' \
73+
// 'pub async fn b_sink<const N: usize>(__arg0: impl Trait<N>)'
74+
// FIXME(const_generics): This should be `_` not `__arg0`.
75+
pub async fn b_sink<const N: usize>(_: impl Trait<N>) {}
76+
77+
// @has foo/fn.concrete.html '//pre[@class="rust fn"]' \
78+
// 'pub fn concrete() -> [u8; 22]'
79+
pub fn concrete() -> [u8; 3 + std::mem::size_of::<u64>() << 1] {
80+
Default::default()
81+
}
82+
83+
// @has foo/type.Faz.html '//pre[@class="rust typedef"]' \
84+
// 'type Faz<const N: usize> = [u8; N];'
85+
pub type Faz<const N: usize> = [u8; N];
86+
// @has foo/type.Fiz.html '//pre[@class="rust typedef"]' \
87+
// 'type Fiz<const N: usize> = [[u8; N]; 48];'
88+
pub type Fiz<const N: usize> = [[u8; N]; 3 << 4];
89+
90+
macro_rules! define_me {
91+
($t:tt<$q:tt>) => {
92+
pub struct $t<const $q: usize>([u8; $q]);
93+
}
94+
}
95+
96+
// @has foo/struct.Foz.html '//pre[@class="rust struct"]' \
97+
// 'pub struct Foz<const N: usize>(_);'
98+
define_me!(Foz<N>);
99+
100+
trait Q {
101+
const ASSOC: usize;
102+
}
103+
104+
impl<const N: usize> Q for [u8; N] {
105+
const ASSOC: usize = N;
106+
}
107+
108+
// @has foo/fn.q_user.html '//pre[@class="rust fn"]' \
109+
// 'pub fn q_user() -> [u8; 13]'
110+
pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {
111+
[0; <[u8; 13] as Q>::ASSOC]
112+
}
113+
114+
// @has foo/union.Union.html '//pre[@class="rust union"]' \
115+
// 'pub union Union<const N: usize>'
116+
pub union Union<const N: usize> {
117+
// @has - //pre "pub arr: [u8; N]"
118+
pub arr: [u8; N],
119+
// @has - //pre "pub another_arr: [(); N]"
120+
pub another_arr: [(); N],
121+
}
122+
123+
// @has foo/enum.Enum.html '//pre[@class="rust enum"]' \
124+
// 'pub enum Enum<const N: usize>'
125+
pub enum Enum<const N: usize> {
126+
// @has - //pre "Variant([u8; N])"
127+
Variant([u8; N]),
128+
// @has - //pre "EmptyVariant"
129+
EmptyVariant,
130+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
2+
--> $DIR/associated-type-bound-fail.rs:14:5
3+
|
4+
LL | type Assoc: Bar<N>;
5+
| ------ required by this bound in `Foo::Assoc`
6+
...
7+
LL | type Assoc = u16;
8+
| ^^^^^^^^^^^^^^^^^ the trait `Bar<N>` is not implemented for `u16`
9+
|
10+
= help: the following implementations were found:
11+
<u16 as Bar<3_usize>>
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
2+
--> $DIR/associated-type-bound-fail.rs:14:5
3+
|
4+
LL | type Assoc: Bar<N>;
5+
| ------ required by this bound in `Foo::Assoc`
6+
...
7+
LL | type Assoc = u16;
8+
| ^^^^^^^^^^^^^^^^^ the trait `Bar<N>` is not implemented for `u16`
9+
|
10+
= help: the following implementations were found:
11+
<u16 as Bar<3_usize>>
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// revisions: full min
2+
#![cfg_attr(full, allow(incomplete_features))]
3+
#![cfg_attr(full, feature(const_generics))]
4+
#![cfg_attr(min, feature(min_const_generics))]
5+
6+
trait Bar<const N: usize> {}
7+
8+
trait Foo<const N: usize> {
9+
type Assoc: Bar<N>;
10+
}
11+
12+
impl Bar<3> for u16 {}
13+
impl<const N: usize> Foo<N> for i16 {
14+
type Assoc = u16; //~ ERROR the trait bound `u16: Bar<N>`
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// run-pass
2+
// revisions: full min
3+
#![cfg_attr(full, allow(incomplete_features))]
4+
#![cfg_attr(full, feature(const_generics))]
5+
#![cfg_attr(min, feature(min_const_generics))]
6+
7+
trait Bar<const N: usize> {}
8+
9+
trait Foo<const N: usize> {
10+
type Assoc: Bar<N>;
11+
}
12+
13+
impl<const N: usize> Bar<N> for u8 {}
14+
impl Bar<3> for u16 {}
15+
16+
impl<const N: usize> Foo<N> for i8 {
17+
type Assoc = u8;
18+
}
19+
20+
impl Foo<3> for i16 {
21+
type Assoc = u16;
22+
}
23+
24+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// edition:2018
2+
#![cfg_attr(full, feature(const_generics))]
3+
#![cfg_attr(full, allow(incomplete_features))]
4+
#![cfg_attr(min, feature(min_const_generics))]
5+
6+
pub trait Foo<const N: usize> {}
7+
struct Local;
8+
impl<const N: usize> Foo<N> for Local {}
9+
10+
pub fn out_foo<const N: usize>() -> impl Foo<N> { Local }
11+
pub fn in_foo<const N: usize>(_: impl Foo<N>) {}
12+
13+
pub async fn async_simple<const N: usize>(_: [u8; N]) {}
14+
pub async fn async_out_foo<const N: usize>() -> impl Foo<N> { Local }
15+
pub async fn async_in_foo<const N: usize>(_: impl Foo<N>) {}
16+
17+
pub trait Bar<const N: usize> {
18+
type Assoc: Foo<N>;
19+
}

0 commit comments

Comments
 (0)