Skip to content

Commit 2a868a9

Browse files
committed
Also check InlineConst and Closure defs nested in enum discriminants
1 parent 4f803b4 commit 2a868a9

3 files changed

Lines changed: 46 additions & 5 deletions

File tree

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,16 +504,34 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
504504
fn anon_const_forbids_generic_params(&self) -> Option<ForbidParamContext> {
505505
let tcx = self.tcx();
506506
let parent_def_id = self.item_def_id();
507-
if tcx.def_kind(parent_def_id) != DefKind::AnonConst {
508-
return None;
509-
}
510-
match tcx.anon_const_kind(parent_def_id) {
507+
508+
// Inline consts and closures can be nested inside anon consts that forbid generic
509+
// params (e.g. an enum discriminant). Walk up the def parent chain to find the
510+
// nearest enclosing AnonConst and use that to determine the context.
511+
let anon_const_def_id = match tcx.def_kind(parent_def_id) {
512+
DefKind::AnonConst => parent_def_id,
513+
DefKind::InlineConst | DefKind::Closure => {
514+
let mut current = tcx.local_parent(parent_def_id);
515+
loop {
516+
match tcx.def_kind(current) {
517+
DefKind::AnonConst => break current,
518+
DefKind::InlineConst | DefKind::Closure => {
519+
current = tcx.local_parent(current);
520+
}
521+
_ => return None,
522+
}
523+
}
524+
}
525+
_ => return None,
526+
};
527+
528+
match tcx.anon_const_kind(anon_const_def_id) {
511529
ty::AnonConstKind::MCG => Some(ForbidParamContext::ConstArgument),
512530
ty::AnonConstKind::NonTypeSystem => {
513531
// NonTypeSystem anon consts only have accessible generic parameters in specific
514532
// positions (ty patterns and field defaults — see `generics_of`). In all other
515533
// positions (e.g. enum discriminants) generic parameters are not in scope.
516-
if tcx.generics_of(parent_def_id).count() == 0 {
534+
if tcx.generics_of(anon_const_def_id).count() == 0 {
517535
Some(ForbidParamContext::EnumDiscriminant)
518536
} else {
519537
None
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ check-fail
2+
// Test that `Self` is rejected even when nested inside an inline const
3+
// or closure within an enum discriminant. Regression test for issue #154281.
4+
#![feature(sized_hierarchy)]
5+
6+
use std::marker::PointeeSized;
7+
8+
#[repr(usize)]
9+
enum What<T: PointeeSized> {
10+
X = const { { let _: *mut Self; 1_usize } },
11+
//~^ ERROR generic `Self` types are not permitted in enum discriminant values
12+
Y(*mut T),
13+
}
14+
15+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: generic `Self` types are not permitted in enum discriminant values
2+
--> $DIR/generic-self-in-discr-inline-const.rs:10:31
3+
|
4+
LL | X = const { { let _: *mut Self; 1_usize } },
5+
| ^^^^
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)