parse array lengths without mgca shenanigans
This commit is contained in:
parent
23a44d3c70
commit
01703e30c0
11 changed files with 21 additions and 243 deletions
|
|
@ -1622,16 +1622,8 @@ impl<'a> Parser<'a> {
|
|||
let first_expr = self.parse_expr()?;
|
||||
if self.eat(exp!(Semi)) {
|
||||
// Repeating array syntax: `[ 0; 512 ]`
|
||||
let count = if self.eat_keyword(exp!(Const)) {
|
||||
// While we could just disambiguate `Direct` from `AnonConst` by
|
||||
// treating all const block exprs as `AnonConst`, that would
|
||||
// complicate the DefCollector and likely all other visitors.
|
||||
// So we strip the const blockiness and just store it as a block
|
||||
// in the AST with the extra disambiguator on the AnonConst
|
||||
self.parse_mgca_const_block(false)?
|
||||
} else {
|
||||
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?
|
||||
};
|
||||
let count =
|
||||
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?;
|
||||
self.expect(close)?;
|
||||
ExprKind::Repeat(first_expr, count)
|
||||
} else if self.eat(exp!(Comma)) {
|
||||
|
|
|
|||
|
|
@ -658,16 +658,8 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
let ty = if self.eat(exp!(Semi)) {
|
||||
let mut length = if self.eat_keyword(exp!(Const)) {
|
||||
// While we could just disambiguate `Direct` from `AnonConst` by
|
||||
// treating all const block exprs as `AnonConst`, that would
|
||||
// complicate the DefCollector and likely all other visitors.
|
||||
// So we strip the const blockiness and just store it as a block
|
||||
// in the AST with the extra disambiguator on the AnonConst
|
||||
self.parse_mgca_const_block(false)?
|
||||
} else {
|
||||
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?
|
||||
};
|
||||
let mut length =
|
||||
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?;
|
||||
|
||||
if let Err(e) = self.expect(exp!(CloseBracket)) {
|
||||
// Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
|
||||
|
|
|
|||
7
src/tools/rustfmt/tests/source/issue-6788.rs
Normal file
7
src/tools/rustfmt/tests/source/issue-6788.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fn foo() {
|
||||
let a = [(); const { let x = 1; x }];
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let x = [(); const { 1 }];
|
||||
}
|
||||
10
src/tools/rustfmt/tests/target/issue-6788.rs
Normal file
10
src/tools/rustfmt/tests/target/issue-6788.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fn foo() {
|
||||
let a = [(); const {
|
||||
let x = 1;
|
||||
x
|
||||
}];
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let x = [(); const { 1 }];
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
#![feature(generic_const_items, min_generic_const_args)]
|
||||
#![expect(incomplete_features)]
|
||||
// library crates exercise weirder code paths around
|
||||
// DefIds which were created for const args.
|
||||
#![crate_type = "lib"]
|
||||
|
||||
struct Foo<const N: usize>;
|
||||
|
||||
type Adt1<const N: usize> = Foo<N>;
|
||||
type Adt2<const N: usize> = Foo<{ N }>;
|
||||
type Adt3<const N: usize> = Foo<const { N }>;
|
||||
//~^ ERROR: generic parameters may not be used in const operations
|
||||
type Adt4<const N: usize> = Foo<{ 1 + 1 }>;
|
||||
//~^ ERROR: complex const arguments must be placed inside of a `const` block
|
||||
type Adt5<const N: usize> = Foo<const { 1 + 1 }>;
|
||||
|
||||
type Arr<const N: usize> = [(); N];
|
||||
type Arr2<const N: usize> = [(); { N }];
|
||||
type Arr3<const N: usize> = [(); const { N }];
|
||||
//~^ ERROR: generic parameters may not be used in const operations
|
||||
type Arr4<const N: usize> = [(); 1 + 1];
|
||||
//~^ ERROR: complex const arguments must be placed inside of a `const` block
|
||||
type Arr5<const N: usize> = [(); const { 1 + 1 }];
|
||||
|
||||
fn repeats<const N: usize>() -> [(); N] {
|
||||
let _1 = [(); N];
|
||||
let _2 = [(); { N }];
|
||||
let _3 = [(); const { N }];
|
||||
//~^ ERROR: generic parameters may not be used in const operations
|
||||
let _4 = [(); 1 + 1];
|
||||
//~^ ERROR: complex const arguments must be placed inside of a `const` block
|
||||
let _5 = [(); const { 1 + 1 }];
|
||||
let _6: [(); const { N }] = todo!();
|
||||
//~^ ERROR: generic parameters may not be used in const operations
|
||||
}
|
||||
|
||||
#[type_const]
|
||||
const ITEM1<const N: usize>: usize = N;
|
||||
#[type_const]
|
||||
const ITEM2<const N: usize>: usize = { N };
|
||||
#[type_const]
|
||||
const ITEM3<const N: usize>: usize = const { N };
|
||||
//~^ ERROR: generic parameters may not be used in const operations
|
||||
#[type_const]
|
||||
const ITEM4<const N: usize>: usize = { 1 + 1 };
|
||||
//~^ ERROR: complex const arguments must be placed inside of a `const` block
|
||||
#[type_const]
|
||||
const ITEM5<const N: usize>: usize = const { 1 + 1};
|
||||
|
||||
trait Trait {
|
||||
#[type_const]
|
||||
const ASSOC: usize;
|
||||
}
|
||||
|
||||
fn ace_bounds<
|
||||
const N: usize,
|
||||
// We skip the T1 case because it doesn't resolve
|
||||
// T1: Trait<ASSOC = N>,
|
||||
T2: Trait<ASSOC = { N }>,
|
||||
T3: Trait<ASSOC = const { N }>,
|
||||
//~^ ERROR: generic parameters may not be used in const operations
|
||||
T4: Trait<ASSOC = { 1 + 1 }>,
|
||||
//~^ ERROR: complex const arguments must be placed inside of a `const` block
|
||||
T5: Trait<ASSOC = const { 1 + 1 }>,
|
||||
>() {}
|
||||
|
||||
struct Default1<const N: usize, const M: usize = N>;
|
||||
struct Default2<const N: usize, const M: usize = { N }>;
|
||||
struct Default3<const N: usize, const M: usize = const { N }>;
|
||||
//~^ ERROR: generic parameters may not be used in const operations
|
||||
struct Default4<const N: usize, const M: usize = { 1 + 1 }>;
|
||||
//~^ ERROR: complex const arguments must be placed inside of a `const` block
|
||||
struct Default5<const N: usize, const M: usize = const { 1 + 1}>;
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/explicit_anon_consts.rs:13:33
|
||||
|
|
||||
LL | type Adt4<const N: usize> = Foo<{ 1 + 1 }>;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/explicit_anon_consts.rs:21:34
|
||||
|
|
||||
LL | type Arr4<const N: usize> = [(); 1 + 1];
|
||||
| ^^^^^
|
||||
|
||||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/explicit_anon_consts.rs:30:19
|
||||
|
|
||||
LL | let _4 = [(); 1 + 1];
|
||||
| ^^^^^
|
||||
|
||||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/explicit_anon_consts.rs:45:38
|
||||
|
|
||||
LL | const ITEM4<const N: usize>: usize = { 1 + 1 };
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/explicit_anon_consts.rs:62:23
|
||||
|
|
||||
LL | T4: Trait<ASSOC = { 1 + 1 }>,
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/explicit_anon_consts.rs:71:50
|
||||
|
|
||||
LL | struct Default4<const N: usize, const M: usize = { 1 + 1 }>;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/explicit_anon_consts.rs:42:46
|
||||
|
|
||||
LL | const ITEM3<const N: usize>: usize = const { N };
|
||||
| ^
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/explicit_anon_consts.rs:60:31
|
||||
|
|
||||
LL | T3: Trait<ASSOC = const { N }>,
|
||||
| ^
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/explicit_anon_consts.rs:69:58
|
||||
|
|
||||
LL | struct Default3<const N: usize, const M: usize = const { N }>;
|
||||
| ^
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/explicit_anon_consts.rs:28:27
|
||||
|
|
||||
LL | let _3 = [(); const { N }];
|
||||
| ^
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/explicit_anon_consts.rs:33:26
|
||||
|
|
||||
LL | let _6: [(); const { N }] = todo!();
|
||||
| ^
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/explicit_anon_consts.rs:11:41
|
||||
|
|
||||
LL | type Adt3<const N: usize> = Foo<const { N }>;
|
||||
| ^
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/explicit_anon_consts.rs:19:42
|
||||
|
|
||||
LL | type Arr3<const N: usize> = [(); const { N }];
|
||||
| ^
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#![feature(min_generic_const_args)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
struct S<const N: usize>([(); N]);
|
||||
|
||||
impl<const N: usize> S<N> {
|
||||
fn foo() -> [(); const { let _: Self = loop {}; 1 }] {
|
||||
//~^ ERROR generic `Self`
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
error: generic `Self` types are currently not permitted in anonymous constants
|
||||
--> $DIR/selftyalias-containing-param.rs:7:37
|
||||
|
|
||||
LL | fn foo() -> [(); const { let _: Self = loop {}; 1 }] {
|
||||
| ^^^^
|
||||
|
|
||||
note: not a concrete type
|
||||
--> $DIR/selftyalias-containing-param.rs:6:22
|
||||
|
|
||||
LL | impl<const N: usize> S<N> {
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#![feature(min_generic_const_args)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
trait Tr<const N: usize> {
|
||||
fn foo() -> [(); const { let _: Self; 1 }];
|
||||
//~^ ERROR generic parameters
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/selftyparam.rs:5:37
|
||||
|
|
||||
LL | fn foo() -> [(); const { let _: Self; 1 }];
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
//@ check-pass
|
||||
// This test should compile without an ICE.
|
||||
#![expect(incomplete_features)]
|
||||
#![feature(min_generic_const_args)]
|
||||
|
||||
pub struct A;
|
||||
|
||||
pub trait Array {
|
||||
#[type_const]
|
||||
const LEN: usize;
|
||||
fn arr() -> [u8; Self::LEN];
|
||||
}
|
||||
|
||||
impl Array for A {
|
||||
#[type_const]
|
||||
const LEN: usize = 4;
|
||||
|
||||
#[allow(unused_braces)]
|
||||
fn arr() -> [u8; const { Self::LEN }] {
|
||||
return [0u8; const { Self::LEN }];
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = A::arr();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue