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:
commit
c354524254
@ -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 = ();
|
||||
}
|
18
src/test/ui/const-generics/issues/issue-68596.rs
Normal file
18
src/test/ui/const-generics/issues/issue-68596.rs
Normal 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>();
|
||||
}
|
8
src/test/ui/const-generics/issues/issue-73120.rs
Normal file
8
src/test/ui/const-generics/issues/issue-73120.rs
Normal 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() {}
|
6
src/test/ui/const-generics/issues/issue-73508.rs
Normal file
6
src/test/ui/const-generics/issues/issue-73508.rs
Normal 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() {}
|
17
src/test/ui/const-generics/issues/issue-73508.stderr
Normal file
17
src/test/ui/const-generics/issues/issue-73508.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-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
|
||||
|
18
src/test/ui/const-generics/issues/issue-74255.rs
Normal file
18
src/test/ui/const-generics/issues/issue-74255.rs
Normal 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}>();
|
||||
}
|
28
src/test/ui/const-generics/type-dependent/issue-67144-1.rs
Normal file
28
src/test/ui/const-generics/type-dependent/issue-67144-1.rs
Normal 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>();
|
||||
}
|
22
src/test/ui/const-generics/type-dependent/issue-67144-2.rs
Normal file
22
src/test/ui/const-generics/type-dependent/issue-67144-2.rs
Normal 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>();
|
||||
}
|
16
src/test/ui/const-generics/type-dependent/issue-70217.rs
Normal file
16
src/test/ui/const-generics/type-dependent/issue-70217.rs
Normal 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() {}
|
33
src/test/ui/const-generics/type-dependent/issue-70586.rs
Normal file
33
src/test/ui/const-generics/type-dependent/issue-70586.rs
Normal 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();
|
||||
}
|
35
src/test/ui/const-generics/type-dependent/issue-71348.rs
Normal file
35
src/test/ui/const-generics/type-dependent/issue-71348.rs
Normal 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);
|
||||
}
|
41
src/test/ui/const-generics/type-dependent/issue-71805.rs
Normal file
41
src/test/ui/const-generics/type-dependent/issue-71805.rs
Normal 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>();
|
||||
}
|
17
src/test/ui/const-generics/type-dependent/issue-73730.rs
Normal file
17
src/test/ui/const-generics/type-dependent/issue-73730.rs
Normal 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>();
|
||||
}
|
Loading…
Reference in New Issue
Block a user