Rollup merge of #150025 - BoxyUwU:mgca_no_unused_defids, r=oli-obk

dont create unnecessary `DefId`s under mgca

Fixes rust-lang/rust#149977
Fixes rust-lang/rust#148838

Accidentally left this out of rust-lang/rust#149136 even though being able to do this was a large part of the point of the PR :3

First ICE was caused by the fact that we create a defid but never lower the nodeid associated with it to a hirid which later parts of the compiler can't handle.

See test for second ICE

r? oli-obk
This commit is contained in:
Jonathan Brouwer 2025-12-16 20:21:09 +01:00 committed by GitHub
commit 9308518af9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 71 additions and 15 deletions

View file

@ -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

View file

@ -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()
{
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));
}

View file

@ -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"]
struct Foo<const N: usize>;
@ -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() {}

View file

@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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 }>;
| ^^^^^^^^^

View file

@ -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() {}

View file

@ -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`.