Auto merge of #44275 - eddyb:deferred-ctfe, r=nikomatsakis

Evaluate fixed-length array length expressions lazily.

This is in preparation for polymorphic array lengths (aka `[T; T::A]`) and const generics.
We need deferred const-evaluation to break cycles when array types show up in positions which require knowing the array type to typeck the array length, e.g. the array type is in a `where` clause.

The final step - actually passing bounds in scope to array length expressions from the parent - is not done because it still produces cycles when *normalizing* `ParamEnv`s, and @nikomatsakis' in-progress lazy normalization work is needed to deal with that uniformly.

However, the changes here are still useful to unlock work on const generics, which @EpicatSupercell manifested interest in, and I might be mentoring them for that, but we need this baseline first.

r? @nikomatsakis cc @oli-obk
This commit is contained in:
bors 2017-09-12 04:14:07 +00:00
commit 3cb24bd37b
104 changed files with 1611 additions and 791 deletions

View file

@ -0,0 +1,15 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
type Array = [u32; { let x = 2; 5 }];
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^^ ERROR: blocks in constants are limited to items and tail expressions
pub fn main() {}

View file

@ -14,8 +14,4 @@ enum Foo {
//~^^ ERROR: blocks in constants are limited to items and tail expressions
}
type Array = [u32; { let x = 2; 5 }];
//~^ ERROR: blocks in constants are limited to items and tail expressions
//~^^ ERROR: blocks in constants are limited to items and tail expressions
pub fn main() {}

View file

@ -23,5 +23,5 @@ const fn f(x: usize) -> usize {
#[allow(unused_variables)]
fn main() {
let a : [i32; f(X)]; //~ NOTE for array length here
let a : [i32; f(X)]; //~ NOTE for constant expression here
}

View file

@ -20,5 +20,5 @@ const LEN: usize = ONE - TWO;
fn main() {
let a: [i8; LEN] = unimplemented!();
//~^ NOTE for array length here
//~^ NOTE for constant expression here
}

View file

@ -8,11 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern: unsupported cyclic reference between types/traits detected
#![feature(const_fn)]
struct Foo {
bytes: [u8; std::mem::size_of::<Foo>()]
//~^ ERROR unsupported cyclic reference between types/traits detected
}
fn main() {}

View file

@ -15,7 +15,4 @@ enum Delicious {
//~^ ERROR no associated item named `PIE` found for type `Delicious`
}
const FOO: [u32; u8::MIN as usize] = [];
//~^ ERROR no associated item named `MIN` found for type `u8`
fn main() {}

View file

@ -0,0 +1,14 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
const FOO: [u32; u8::MIN as usize] = [];
//~^ ERROR no associated item named `MIN` found for type `u8`
fn main() {}

View file

@ -21,8 +21,9 @@ impl Dim for Dim3 {
}
pub struct Vector<T, D: Dim> {
entries: [T; D::dim()]
entries: [T; D::dim()],
//~^ ERROR no function or associated item named `dim` found for type `D` in the current scope
_dummy: D,
}
fn main() {}

View file

@ -4,7 +4,7 @@ error[E0080]: constant evaluation error
11 | pub const FOO: usize = *&0;
| ^^^ unimplemented constant expression: deref operation
|
note: for repeat count here
note: for constant expression here
--> $DIR/issue_38875.rs:16:22
|
16 | let test_x = [0; issue_38875_b::FOO];