Skip to content

Commit 70cf325

Browse files
committed
Rollup merge of #59355 - varkor:const-param-struct-ice, r=petrochenkov
Fix ICE with const generic param in struct Fixes #59340. r? @petrochenkov
2 parents cb2dde6 + 5032643 commit 70cf325

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

src/librustc_resolve/lib.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
814814
debug!("(resolving function) entering function");
815815
let (rib_kind, asyncness) = match function_kind {
816816
FnKind::ItemFn(_, ref header, ..) =>
817-
(ItemRibKind, header.asyncness.node),
817+
(FnItemRibKind, header.asyncness.node),
818818
FnKind::Method(_, ref sig, _, _) =>
819819
(TraitOrImplItemRibKind, sig.header.asyncness.node),
820820
FnKind::Closure(_) =>
@@ -950,6 +950,10 @@ enum RibKind<'a> {
950950
/// upvars).
951951
TraitOrImplItemRibKind,
952952

953+
/// We passed through a function definition. Disallow upvars.
954+
/// Permit only those const parameters that are specified in the function's generics.
955+
FnItemRibKind,
956+
953957
/// We passed through an item scope. Disallow upvars.
954958
ItemRibKind,
955959

@@ -3863,7 +3867,7 @@ impl<'a> Resolver<'a> {
38633867
seen.insert(node_id, depth);
38643868
}
38653869
}
3866-
ItemRibKind | TraitOrImplItemRibKind => {
3870+
ItemRibKind | FnItemRibKind | TraitOrImplItemRibKind => {
38673871
// This was an attempt to access an upvar inside a
38683872
// named function item. This is not allowed, so we
38693873
// report an error.
@@ -3897,7 +3901,7 @@ impl<'a> Resolver<'a> {
38973901
ConstantItemRibKind => {
38983902
// Nothing to do. Continue.
38993903
}
3900-
ItemRibKind => {
3904+
ItemRibKind | FnItemRibKind => {
39013905
// This was an attempt to use a type parameter outside its scope.
39023906
if record_used {
39033907
resolve_error(
@@ -3912,12 +3916,15 @@ impl<'a> Resolver<'a> {
39123916
}
39133917
}
39143918
Def::ConstParam(..) => {
3915-
// A const param is always declared in a signature, which is always followed by
3916-
// some kind of function rib kind (specifically, ItemRibKind in the case of a
3917-
// normal function), so we can skip the first rib as it will be guaranteed to
3918-
// (spuriously) conflict with the const param.
3919-
for rib in &ribs[1..] {
3920-
if let ItemRibKind = rib.kind {
3919+
let mut ribs = ribs.iter().peekable();
3920+
if let Some(Rib { kind: FnItemRibKind, .. }) = ribs.peek() {
3921+
// When declaring const parameters inside function signatures, the first rib
3922+
// is always a `FnItemRibKind`. In this case, we can skip it, to avoid it
3923+
// (spuriously) conflicting with the const param.
3924+
ribs.next();
3925+
}
3926+
for rib in ribs {
3927+
if let ItemRibKind | FnItemRibKind = rib.kind {
39213928
// This was an attempt to use a const parameter outside its scope.
39223929
if record_used {
39233930
resolve_error(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
3+
4+
struct S<const C: u8>(C); //~ ERROR expected type, found const parameter
5+
6+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/struct-with-invalid-const-param.rs:1:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
7+
error[E0573]: expected type, found const parameter `C`
8+
--> $DIR/struct-with-invalid-const-param.rs:4:23
9+
|
10+
LL | struct S<const C: u8>(C);
11+
| ^ help: a struct with a similar name exists: `S`
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0573`.

0 commit comments

Comments
 (0)