add const generic tests

This commit is contained in:
Bastian Kauschke 2020-07-02 22:06:14 +02:00
parent 567ad7455d
commit 2111d6f276
15 changed files with 333 additions and 0 deletions

View file

@ -0,0 +1,36 @@
#![feature(const_generics)]
#![allow(incomplete_features)]
pub struct Struct<const N: usize>(());
impl<const N: usize> Struct<N> {
pub fn new() -> Self {
Struct(())
}
pub fn same_ty<const M: usize>(&self) -> (usize, usize) {
(N, M)
}
pub fn different_ty<const M: u8>(&self) -> (usize, u8) {
(N, M)
}
pub fn containing_ty<T, const M: u8>(&self) -> (usize, u8) {
(std::mem::size_of::<T>() + N, M)
}
pub fn we_have_to_go_deeper<const M: usize>(&self) -> Struct<M> {
Struct(())
}
}
pub trait Foo {
fn foo<const M: usize>(&self) -> usize;
}
impl Foo for Struct<7> {
fn foo<const M: usize>(&self) -> usize {
M
}
}

View file

@ -0,0 +1,26 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
#![feature(const_fn)]
struct Foo;
impl Foo {
fn foo<const N: usize>(&self) -> usize {
let f = self;
f.bar::<{
let f = Foo;
f.bar::<7>()
}>() + N
}
const fn bar<const M: usize>(&self) -> usize {
M
}
}
fn main() {
let f = Foo;
assert_eq!(f.foo::<13>(), 20)
}

View file

@ -0,0 +1,47 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
trait SliceExt<T: Clone> {
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>;
}
impl <T: Clone> SliceExt<T> for [T] {
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N> {
ArrayWindows{ idx: 0, slice: &self }
}
}
struct ArrayWindows<'a, T, const N: usize> {
slice: &'a [T],
idx: usize,
}
impl <'a, T: Clone, const N: usize> Iterator for ArrayWindows<'a, T, N> {
type Item = [T; N];
fn next(&mut self) -> Option<Self::Item> {
let mut res = unsafe{ std::mem::zeroed() };
let mut ptr = &mut res as *mut [T; N] as *mut T;
for i in 0..N {
match self.slice[i..].get(i) {
None => return None,
Some(elem) => unsafe { std::ptr::write_volatile(ptr, elem.clone())},
};
ptr = ptr.wrapping_add(1);
self.idx += 1;
}
Some(res)
}
}
const FOUR: usize = 4;
fn main() {
let v: Vec<usize> = vec![100; 0usize];
for array in v.as_slice().array_windows::<FOUR>() {
assert_eq!(array, [0, 0, 0, 0])
}
}

View file

@ -0,0 +1,17 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
trait T {
fn test<const A: i32>(&self) -> i32 { A }
}
struct S();
impl T for S {}
fn main() {
let foo = S();
assert_eq!(foo.test::<8i32>(), 8);
assert_eq!(foo.test::<16i32>(), 16);
}

View file

@ -0,0 +1,20 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
trait IterExt: Sized + Iterator {
fn default_for_size<const N: usize>(self) -> [Self::Item; N]
where
[Self::Item; N]: Default,
{
Default::default()
}
}
impl<T: Iterator> IterExt for T {}
fn main(){
const N: usize = 10;
let arr = (0u32..10).default_for_size::<N>();
assert_eq!(arr, [0; 10]);
}

View file

@ -0,0 +1,47 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
trait ConstChunksExactTrait<T> {
fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}>;
}
impl <T> ConstChunksExactTrait<T> for [T] {
fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}> {
assert!(N != 0);
let rem = self.len() % N;
let len = self.len() - rem;
let (fst, _) = self.split_at(len);
ConstChunksExact { v: fst, }
}
}
struct ConstChunksExact<'a, T: 'a, const N: usize> {
v: &'a [T],
}
impl <'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {N}> {
type Item = &'a [T; N];
fn next(&mut self) -> Option<Self::Item> {
if self.v.len() < N {
None
} else {
let (fst, snd) = self.v.split_at(N);
self.v = snd;
let ptr = fst.as_ptr() as *const _;
Some(unsafe { &*ptr})
}
}
}
fn main() {
let slice = &[1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].iter();
for a in slice.const_chunks_exact::<3>() {
assert_eq!(a, iter.next().unwrap());
}
}

View file

@ -0,0 +1,24 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete
struct Test;
fn pass() -> u8 {
42
}
impl Test {
pub fn call_me(&self) -> u8 {
self.test::<pass>()
}
fn test<const FN: fn() -> u8>(&self) -> u8 {
//~^ ERROR using function pointers as const generic parameters is forbidden
FN()
}
}
fn main() {
let x = Test;
assert_eq!(x.call_me(), 42);
}

View file

@ -0,0 +1,17 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-71382.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
error: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71382.rs:15:23
|
LL | fn test<const FN: fn() -> u8>(&self) -> u8 {
| ^^^^^^^^^^
error: aborting due to previous error; 1 warning emitted

View file

@ -0,0 +1,24 @@
// aux-build:type_dependent_lib.rs
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
extern crate type_dependent_lib;
use type_dependent_lib::*;
fn main() {
let s = Struct::<42>::new();
assert_eq!(s.same_ty::<7>(), (42, 7));
assert_eq!(s.different_ty::<19>(), (42, 19));
assert_eq!(Struct::<1337>::new().different_ty::<96>(), (1337, 96));
assert_eq!(
Struct::<18>::new()
.we_have_to_go_deeper::<19>()
.containing_ty::<Option<u32>, 3>(),
(27, 3),
);
let s = Struct::<7>::new();
assert_eq!(s.foo::<18>(), 18);
}

View file

@ -0,0 +1,12 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
struct A;
impl A {
fn foo<const N: usize>() -> usize { N + 1 }
}
fn main() {
assert_eq!(A::foo::<7>(), 8);
}

View file

@ -0,0 +1,12 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
struct R;
impl R {
fn method<const N: u8>(&self) -> u8 { N }
}
fn main() {
assert_eq!(R.method::<1u8>(), 1);
}

View file

@ -0,0 +1,12 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete
struct R;
impl R {
fn method<const N: u8>(&self) -> u8 { N }
}
fn main() {
assert_eq!(R.method::<1u16>(), 1);
//~^ ERROR mismatched types
}

View file

@ -0,0 +1,23 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/type-mismatch.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
error[E0308]: mismatched types
--> $DIR/type-mismatch.rs:10:27
|
LL | assert_eq!(R.method::<1u16>(), 1);
| ^^^^ expected `u8`, found `u16`
|
help: change the type of the numeric literal from `u16` to `u8`
|
LL | assert_eq!(R.method::<1u8>(), 1);
| ^^^
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0308`.

View file

@ -0,0 +1,7 @@
#![feature(const_generics)]
#![allow(incomplete_features)]
fn main() {
let _: UnknownStruct<7>;
//~^ ERROR cannot find type `UnknownStruct`
}

View file

@ -0,0 +1,9 @@
error[E0412]: cannot find type `UnknownStruct` in this scope
--> $DIR/unknown_adt.rs:5:12
|
LL | let _: UnknownStruct<7>;
| ^^^^^^^^^^^^^ not found in this scope
error: aborting due to previous error
For more information about this error, try `rustc --explain E0412`.