Skip to content

Commit 2111d6f

Browse files
committed
add const generic tests
1 parent 567ad74 commit 2111d6f

15 files changed

+333
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![feature(const_generics)]
2+
#![allow(incomplete_features)]
3+
4+
pub struct Struct<const N: usize>(());
5+
6+
impl<const N: usize> Struct<N> {
7+
pub fn new() -> Self {
8+
Struct(())
9+
}
10+
11+
pub fn same_ty<const M: usize>(&self) -> (usize, usize) {
12+
(N, M)
13+
}
14+
15+
pub fn different_ty<const M: u8>(&self) -> (usize, u8) {
16+
(N, M)
17+
}
18+
19+
pub fn containing_ty<T, const M: u8>(&self) -> (usize, u8) {
20+
(std::mem::size_of::<T>() + N, M)
21+
}
22+
23+
pub fn we_have_to_go_deeper<const M: usize>(&self) -> Struct<M> {
24+
Struct(())
25+
}
26+
}
27+
28+
pub trait Foo {
29+
fn foo<const M: usize>(&self) -> usize;
30+
}
31+
32+
impl Foo for Struct<7> {
33+
fn foo<const M: usize>(&self) -> usize {
34+
M
35+
}
36+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// run-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
#![feature(const_fn)]
5+
6+
struct Foo;
7+
8+
impl Foo {
9+
fn foo<const N: usize>(&self) -> usize {
10+
let f = self;
11+
f.bar::<{
12+
let f = Foo;
13+
f.bar::<7>()
14+
}>() + N
15+
}
16+
17+
const fn bar<const M: usize>(&self) -> usize {
18+
M
19+
}
20+
}
21+
22+
fn main() {
23+
let f = Foo;
24+
25+
assert_eq!(f.foo::<13>(), 20)
26+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// run-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
trait SliceExt<T: Clone> {
6+
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>;
7+
}
8+
9+
impl <T: Clone> SliceExt<T> for [T] {
10+
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N> {
11+
ArrayWindows{ idx: 0, slice: &self }
12+
}
13+
}
14+
15+
struct ArrayWindows<'a, T, const N: usize> {
16+
slice: &'a [T],
17+
idx: usize,
18+
}
19+
20+
impl <'a, T: Clone, const N: usize> Iterator for ArrayWindows<'a, T, N> {
21+
type Item = [T; N];
22+
fn next(&mut self) -> Option<Self::Item> {
23+
let mut res = unsafe{ std::mem::zeroed() };
24+
let mut ptr = &mut res as *mut [T; N] as *mut T;
25+
26+
for i in 0..N {
27+
match self.slice[i..].get(i) {
28+
None => return None,
29+
Some(elem) => unsafe { std::ptr::write_volatile(ptr, elem.clone())},
30+
};
31+
ptr = ptr.wrapping_add(1);
32+
self.idx += 1;
33+
}
34+
35+
Some(res)
36+
}
37+
}
38+
39+
const FOUR: usize = 4;
40+
41+
fn main() {
42+
let v: Vec<usize> = vec![100; 0usize];
43+
44+
for array in v.as_slice().array_windows::<FOUR>() {
45+
assert_eq!(array, [0, 0, 0, 0])
46+
}
47+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
trait T {
6+
fn test<const A: i32>(&self) -> i32 { A }
7+
}
8+
9+
struct S();
10+
11+
impl T for S {}
12+
13+
fn main() {
14+
let foo = S();
15+
assert_eq!(foo.test::<8i32>(), 8);
16+
assert_eq!(foo.test::<16i32>(), 16);
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// run-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
trait IterExt: Sized + Iterator {
6+
fn default_for_size<const N: usize>(self) -> [Self::Item; N]
7+
where
8+
[Self::Item; N]: Default,
9+
{
10+
Default::default()
11+
}
12+
}
13+
14+
impl<T: Iterator> IterExt for T {}
15+
16+
fn main(){
17+
const N: usize = 10;
18+
let arr = (0u32..10).default_for_size::<N>();
19+
assert_eq!(arr, [0; 10]);
20+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// run-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
trait ConstChunksExactTrait<T> {
6+
fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}>;
7+
}
8+
9+
impl <T> ConstChunksExactTrait<T> for [T] {
10+
fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}> {
11+
assert!(N != 0);
12+
let rem = self.len() % N;
13+
let len = self.len() - rem;
14+
let (fst, _) = self.split_at(len);
15+
ConstChunksExact { v: fst, }
16+
}
17+
}
18+
19+
struct ConstChunksExact<'a, T: 'a, const N: usize> {
20+
v: &'a [T],
21+
}
22+
23+
impl <'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {N}> {
24+
type Item = &'a [T; N];
25+
26+
fn next(&mut self) -> Option<Self::Item> {
27+
if self.v.len() < N {
28+
None
29+
} else {
30+
let (fst, snd) = self.v.split_at(N);
31+
32+
self.v = snd;
33+
let ptr = fst.as_ptr() as *const _;
34+
Some(unsafe { &*ptr})
35+
}
36+
}
37+
}
38+
39+
fn main() {
40+
let slice = &[1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10];
41+
42+
let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].iter();
43+
44+
for a in slice.const_chunks_exact::<3>() {
45+
assert_eq!(a, iter.next().unwrap());
46+
}
47+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete
3+
4+
struct Test;
5+
6+
fn pass() -> u8 {
7+
42
8+
}
9+
10+
impl Test {
11+
pub fn call_me(&self) -> u8 {
12+
self.test::<pass>()
13+
}
14+
15+
fn test<const FN: fn() -> u8>(&self) -> u8 {
16+
//~^ ERROR using function pointers as const generic parameters is forbidden
17+
FN()
18+
}
19+
}
20+
21+
fn main() {
22+
let x = Test;
23+
assert_eq!(x.call_me(), 42);
24+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/issue-71382.rs:1:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
9+
10+
error: using function pointers as const generic parameters is forbidden
11+
--> $DIR/issue-71382.rs:15:23
12+
|
13+
LL | fn test<const FN: fn() -> u8>(&self) -> u8 {
14+
| ^^^^^^^^^^
15+
16+
error: aborting due to previous error; 1 warning emitted
17+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// aux-build:type_dependent_lib.rs
2+
// run-pass
3+
#![feature(const_generics)]
4+
#![allow(incomplete_features)]
5+
6+
extern crate type_dependent_lib;
7+
8+
use type_dependent_lib::*;
9+
10+
fn main() {
11+
let s = Struct::<42>::new();
12+
assert_eq!(s.same_ty::<7>(), (42, 7));
13+
assert_eq!(s.different_ty::<19>(), (42, 19));
14+
assert_eq!(Struct::<1337>::new().different_ty::<96>(), (1337, 96));
15+
assert_eq!(
16+
Struct::<18>::new()
17+
.we_have_to_go_deeper::<19>()
18+
.containing_ty::<Option<u32>, 3>(),
19+
(27, 3),
20+
);
21+
22+
let s = Struct::<7>::new();
23+
assert_eq!(s.foo::<18>(), 18);
24+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// run-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
struct A;
6+
impl A {
7+
fn foo<const N: usize>() -> usize { N + 1 }
8+
}
9+
10+
fn main() {
11+
assert_eq!(A::foo::<7>(), 8);
12+
}

0 commit comments

Comments
 (0)