Rollup merge of #74392 - lcnr:const-generics-update, r=varkor

const generics triage

I went through all const generics issues and closed all issues which are already fixed.

Some issues already have a regression test but were not closed. Also doing this as part of this PR.

uff r? @eddyb @varkor

closes #61936
closes #62878
closes #63695
closes #67144
closes #68596
closes #69816
closes #70217
closes #70507
closes #70586
closes #71348
closes #71805
closes #73120
closes #73508
closes #73730
closes #74255
This commit is contained in:
Manish Goregaokar 2020-07-16 11:19:00 -07:00 committed by GitHub
commit c354524254
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 273 additions and 0 deletions

View File

@ -0,0 +1,14 @@
#![feature(const_generics)]
// All of these three items must be in `lib2` to reproduce the error
pub trait TypeFn {
type Output;
}
pub struct GenericType<const B: i8>;
// Removing the braces around `42` resolves the crash
impl TypeFn for GenericType<{ 42 }> {
type Output = ();
}

View File

@ -0,0 +1,18 @@
// check-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
pub struct S(u8);
impl S {
pub fn get<const A: u8>(&self) -> &u8 {
&self.0
}
}
fn main() {
const A: u8 = 5;
let s = S(0);
s.get::<A>();
}

View File

@ -0,0 +1,8 @@
// check-pass
// aux-build:const_generic_issues_lib.rs
extern crate const_generic_issues_lib as lib2;
fn unused_function(
_: <lib2::GenericType<42> as lib2::TypeFn>::Output
) {}
fn main() {}

View File

@ -0,0 +1,6 @@
#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
pub const fn func_name<const X: *const u32>() {}
//~^ ERROR using raw pointers
fn main() {}

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-73508.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 raw pointers as const generic parameters is forbidden
--> $DIR/issue-73508.rs:3:33
|
LL | pub const fn func_name<const X: *const u32>() {}
| ^^^^^^^^^^
error: aborting due to previous error; 1 warning emitted

View File

@ -0,0 +1,18 @@
// check-pass
#![feature(const_generics)]
#![allow(dead_code, incomplete_features)]
#[derive(PartialEq, Eq)]
enum IceEnum {
Variant
}
struct IceStruct;
impl IceStruct {
fn ice_struct_fn<const I: IceEnum>() {}
}
fn main() {
IceStruct::ice_struct_fn::<{IceEnum::Variant}>();
}

View File

@ -0,0 +1,28 @@
// check-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
struct X;
impl X {
pub fn getn<const N: usize>(&self) -> [u8; N] {
getn::<N>()
}
}
fn getn<const N: usize>() -> [u8; N] {
unsafe {
std::mem::zeroed()
}
}
fn main() {
// works
let [a,b,c] = getn::<3>();
// cannot pattern-match on an array without a fixed length
let [a,b,c] = X.getn::<3>();
// mismatched types, expected array `[u8; 3]` found array `[u8; _]`
let arr: [u8; 3] = X.getn::<3>();
}

View File

@ -0,0 +1,22 @@
// check-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
struct A<const N: usize>;
struct X;
impl X {
fn inner<const N: usize>() -> A<N> {
outer::<N>()
}
}
fn outer<const N: usize>() -> A<N> {
A
}
fn main() {
let i: A<3usize> = outer::<3usize>();
let o: A<3usize> = X::inner::<3usize>();
}

View File

@ -0,0 +1,16 @@
// check-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
struct Struct<const N: usize>;
impl<const N: usize> Struct<N> {
fn method<const M: usize>(&self) {}
}
fn test<const N: usize, const M: usize>(x: Struct<N>) {
Struct::<N>::method::<M>(&x);
x.method::<N>();
}
fn main() {}

View File

@ -0,0 +1,33 @@
// check-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
use std::marker::PhantomData;
// This namespace is necessary for the ICE to trigger
struct Namespace;
impl Namespace {
pub fn const_chunks_exact<T, const N: usize>() -> ConstChunksExact<'static, T, N> {
ConstChunksExact { inner: PhantomData }
}
}
#[derive(Debug)]
pub struct ConstChunksExact<'a, T, const N: usize> {
inner: PhantomData<&'a T>
}
impl <'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> {
type Item = &'a [T; N];
fn next(&mut self) -> Option<Self::Item> {
unreachable!()
}
}
fn main() {
let mut chunks = Namespace::const_chunks_exact::<i32, 3usize>();
let _next: &[i32; 3] = chunks.next().unwrap();
}

View File

@ -0,0 +1,35 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
struct Foo {
i: i32,
}
trait Get<'a, const N: &'static str> {
type Target: 'a;
fn get(&'a self) -> &'a Self::Target;
}
impl Foo {
fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
where
Self: Get<'a, N>,
{
self.get()
}
}
impl<'a> Get<'a, "int"> for Foo {
type Target = i32;
fn get(&'a self) -> &'a Self::Target {
&self.i
}
}
fn main() {
let foo = Foo { i: 123 };
assert_eq!(foo.ask::<"int">(), &123);
}

View File

@ -0,0 +1,41 @@
// run-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
use std::mem::MaybeUninit;
trait CollectSlice<'a>: Iterator {
fn inner_array<const N: usize>(&mut self) -> [Self::Item; N];
fn collect_array<const N: usize>(&mut self) -> [Self::Item; N] {
let result = self.inner_array();
assert!(self.next().is_none());
result
}
}
impl<'a, I: ?Sized> CollectSlice<'a> for I
where
I: Iterator,
{
fn inner_array<const N: usize>(&mut self) -> [Self::Item; N] {
let mut result: [MaybeUninit<Self::Item>; N] =
unsafe { MaybeUninit::uninit().assume_init() };
let mut count = 0;
for (dest, item) in result.iter_mut().zip(self) {
*dest = MaybeUninit::new(item);
count += 1;
}
assert_eq!(N, count);
let temp_ptr: *const [MaybeUninit<Self::Item>; N] = &result;
unsafe { std::ptr::read(temp_ptr as *const [Self::Item; N]) }
}
}
fn main() {
let mut foos = [0u64; 9].iter().cloned();
let _bar: [u64; 9] = foos.collect_array::<9_usize>();
}

View File

@ -0,0 +1,17 @@
// check-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
trait Foo<'a, A>: Iterator<Item=A> {
fn bar<const N: usize>(&mut self) -> *const [A; N];
}
impl<'a, A, I: ?Sized> Foo<'a, A> for I where I: Iterator<Item=A> {
fn bar<const N: usize>(&mut self) -> *const [A; N] {
std::ptr::null()
}
}
fn main() {
(0_u8 .. 10).bar::<10_usize>();
}