Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
_ => false,
}
{
continue;
// MGCA doesn't have unnecessary DefIds
if !tcx.features().min_generic_const_args() {
continue;
}
}

if def_kind == DefKind::Field
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,16 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
}

fn visit_anon_const(&mut self, constant: &'a AnonConst) {
// `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so
// to avoid affecting stable we have to feature gate the not creating
// anon consts
if let MgcaDisambiguation::Direct = constant.mgca_disambiguation
&& self.resolver.tcx.features().min_generic_const_args()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the additional feature gate check necessary?

Copy link
Member Author

@BoxyUwU BoxyUwU Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, we can't set MgcaDisambiguation differently depending on whether the feature gate is enabled or not (as the parser doesn't have access to such information). So the enum is really a "if mgca is enabled, this should/shouldnt be an anon const", without mgca enabled the enum is basically meaningless

{
visit::walk_anon_const(self, constant);
return;
}

let parent = self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span);
self.with_parent(parent, |this| visit::walk_anon_const(this, constant));
}
Expand Down
5 changes: 3 additions & 2 deletions tests/ui/const-generics/mgca/explicit_anon_consts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#![feature(associated_const_equality, 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"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

annoying that I literally went out of my way to add test cases for the ICEing code to catch stuff like this but it just didn't matter because the ICE occurs during metadata encoding or sth instead of some kind of HIR validation step


struct Foo<const N: usize>;

Expand Down Expand Up @@ -66,5 +69,3 @@ struct Default3<const N: usize, const M: usize = const { N }>;
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}>;

fn main() {}
24 changes: 12 additions & 12 deletions tests/ui/const-generics/mgca/explicit_anon_consts.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: generic parameters may not be used in const operations
--> $DIR/explicit_anon_consts.rs:8:41
--> $DIR/explicit_anon_consts.rs:11:41
|
LL | type Adt3<const N: usize> = Foo<const { N }>;
| ^ cannot perform const operation using `N`
Expand All @@ -8,7 +8,7 @@ LL | type Adt3<const N: usize> = Foo<const { N }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/explicit_anon_consts.rs:16:42
--> $DIR/explicit_anon_consts.rs:19:42
|
LL | type Arr3<const N: usize> = [(); const { N }];
| ^ cannot perform const operation using `N`
Expand All @@ -17,7 +17,7 @@ LL | type Arr3<const N: usize> = [(); const { N }];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/explicit_anon_consts.rs:25:27
--> $DIR/explicit_anon_consts.rs:28:27
|
LL | let _3 = [(); const { N }];
| ^ cannot perform const operation using `N`
Expand All @@ -26,7 +26,7 @@ LL | let _3 = [(); const { N }];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/explicit_anon_consts.rs:37:46
--> $DIR/explicit_anon_consts.rs:40:46
|
LL | const ITEM3<const N: usize>: usize = const { N };
| ^ cannot perform const operation using `N`
Expand All @@ -35,7 +35,7 @@ LL | const ITEM3<const N: usize>: usize = const { N };
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/explicit_anon_consts.rs:55:31
--> $DIR/explicit_anon_consts.rs:58:31
|
LL | T3: Trait<ASSOC = const { N }>,
| ^ cannot perform const operation using `N`
Expand All @@ -44,7 +44,7 @@ LL | T3: Trait<ASSOC = const { N }>,
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/explicit_anon_consts.rs:64:58
--> $DIR/explicit_anon_consts.rs:67:58
|
LL | struct Default3<const N: usize, const M: usize = const { N }>;
| ^ cannot perform const operation using `N`
Expand All @@ -53,37 +53,37 @@ LL | struct Default3<const N: usize, const M: usize = const { N }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: complex const arguments must be placed inside of a `const` block
--> $DIR/explicit_anon_consts.rs:10:33
--> $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:18:34
--> $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:27:19
--> $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:40:38
--> $DIR/explicit_anon_consts.rs:43: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:57:23
--> $DIR/explicit_anon_consts.rs:60:23
|
LL | T4: Trait<ASSOC = { 1 + 1 }>,
| ^^^^^^^^^

error: complex const arguments must be placed inside of a `const` block
--> $DIR/explicit_anon_consts.rs:66:50
--> $DIR/explicit_anon_consts.rs:69:50
|
LL | struct Default4<const N: usize, const M: usize = { 1 + 1 }>;
| ^^^^^^^^^
Expand Down
24 changes: 24 additions & 0 deletions tests/ui/const-generics/mgca/unused_speculative_def_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![feature(min_generic_const_args, generic_const_exprs, generic_const_items)]
#![expect(incomplete_features)]

// Previously we would create a `DefId` to represent the const argument to `A`
// except it would go unused as it's a MGCA path const arg. We would also make
// a `DefId` for the `const { 1 }` anon const arg to `ERR` which would wind up
// with a `DefId` parent of the speculatively created `DefId` for the argument to
// `A`.
//
// This then caused Problems:tm: in the rest of the compiler that did not expect
// to encounter such nonsensical `DefId`s.
//
// The `ERR` path must fail to resolve as if it can be resolved then broken GCE
// logic will attempt to evaluate the constant directly which is wrong for
// `type_const`s which do not have bodies.

struct A<const N: usize>;

struct Foo {
field: A<{ ERR::<const { 1 }> }>,
//~^ ERROR: cannot find value `ERR` in this scope
}

fn main() {}
18 changes: 18 additions & 0 deletions tests/ui/const-generics/mgca/unused_speculative_def_id.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0425]: cannot find value `ERR` in this scope
--> $DIR/unused_speculative_def_id.rs:20:16
|
LL | field: A<{ ERR::<const { 1 }> }>,
| ^^^
|
--> $SRC_DIR/core/src/result.rs:LL:COL
|
= note: similarly named tuple variant `Err` defined here
help: a tuple variant with a similar name exists
|
LL - field: A<{ ERR::<const { 1 }> }>,
LL + field: A<{ Err::<const { 1 }> }>,
|

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0425`.
Loading