Skip to content

Commit

Permalink
Rollup merge of rust-lang#74392 - lcnr:const-generics-update, r=varkor
Browse files Browse the repository at this point in the history
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 rust-lang#61936
closes rust-lang#62878
closes rust-lang#63695
closes rust-lang#67144
closes rust-lang#68596
closes rust-lang#69816
closes rust-lang#70217
closes rust-lang#70507
closes rust-lang#70586
closes rust-lang#71348
closes rust-lang#71805
closes rust-lang#73120
closes rust-lang#73508
closes rust-lang#73730
closes rust-lang#74255
  • Loading branch information
Manishearth authored Jul 16, 2020
2 parents de757e2 + 8faeb0e commit 658d5d0
Show file tree
Hide file tree
Showing 13 changed files with 273 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions src/test/ui/const-generics/issues/issue-68596.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions src/test/ui/const-generics/issues/issue-73120.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 6 additions & 0 deletions src/test/ui/const-generics/issues/issue-73508.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions src/test/ui/const-generics/issues/issue-73508.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions src/test/ui/const-generics/issues/issue-74255.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 28 additions & 0 deletions src/test/ui/const-generics/type-dependent/issue-67144-1.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions src/test/ui/const-generics/type-dependent/issue-67144-2.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions src/test/ui/const-generics/type-dependent/issue-70217.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 33 additions & 0 deletions src/test/ui/const-generics/type-dependent/issue-70586.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 35 additions & 0 deletions src/test/ui/const-generics/type-dependent/issue-71348.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 41 additions & 0 deletions src/test/ui/const-generics/type-dependent/issue-71805.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions src/test/ui/const-generics/type-dependent/issue-73730.rs
Original file line number Diff line number Diff line change
@@ -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>();
}

0 comments on commit 658d5d0

Please sign in to comment.