add const generic tests
This commit is contained in:
parent
567ad7455d
commit
2111d6f276
15 changed files with 333 additions and 0 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
47
src/test/ui/const-generics/type-dependent/issue-61936.rs
Normal file
47
src/test/ui/const-generics/type-dependent/issue-61936.rs
Normal 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])
|
||||
}
|
||||
}
|
||||
17
src/test/ui/const-generics/type-dependent/issue-63695.rs
Normal file
17
src/test/ui/const-generics/type-dependent/issue-63695.rs
Normal 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);
|
||||
}
|
||||
20
src/test/ui/const-generics/type-dependent/issue-69816.rs
Normal file
20
src/test/ui/const-generics/type-dependent/issue-69816.rs
Normal 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]);
|
||||
}
|
||||
47
src/test/ui/const-generics/type-dependent/issue-70507.rs
Normal file
47
src/test/ui/const-generics/type-dependent/issue-70507.rs
Normal 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());
|
||||
}
|
||||
}
|
||||
24
src/test/ui/const-generics/type-dependent/issue-71382.rs
Normal file
24
src/test/ui/const-generics/type-dependent/issue-71382.rs
Normal 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);
|
||||
}
|
||||
17
src/test/ui/const-generics/type-dependent/issue-71382.stderr
Normal file
17
src/test/ui/const-generics/type-dependent/issue-71382.stderr
Normal 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
|
||||
|
||||
24
src/test/ui/const-generics/type-dependent/non-local.rs
Normal file
24
src/test/ui/const-generics/type-dependent/non-local.rs
Normal 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);
|
||||
}
|
||||
12
src/test/ui/const-generics/type-dependent/qpath.rs
Normal file
12
src/test/ui/const-generics/type-dependent/qpath.rs
Normal 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);
|
||||
}
|
||||
12
src/test/ui/const-generics/type-dependent/simple.rs
Normal file
12
src/test/ui/const-generics/type-dependent/simple.rs
Normal 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);
|
||||
}
|
||||
12
src/test/ui/const-generics/type-dependent/type-mismatch.rs
Normal file
12
src/test/ui/const-generics/type-dependent/type-mismatch.rs
Normal 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
|
||||
}
|
||||
|
|
@ -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`.
|
||||
7
src/test/ui/const-generics/unknown_adt.rs
Normal file
7
src/test/ui/const-generics/unknown_adt.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
let _: UnknownStruct<7>;
|
||||
//~^ ERROR cannot find type `UnknownStruct`
|
||||
}
|
||||
9
src/test/ui/const-generics/unknown_adt.stderr
Normal file
9
src/test/ui/const-generics/unknown_adt.stderr
Normal 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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue