From 653076c76960316dc6a88a88c020bb07072a35fe Mon Sep 17 00:00:00 2001 From: khyperia <953151+khyperia@users.noreply.github.com> Date: Fri, 18 Sep 2026 09:15:10 +0200 Subject: [PATCH] yeet AliasConstKind::opt_def_id --- .../rustc_hir_analysis/src/check/check.rs | 20 ++++++-- .../src/hir_ty_lowering/mod.rs | 48 +++++++++---------- compiler/rustc_middle/src/thir.rs | 2 +- .../rustc_middle/src/ty/abstract_const.rs | 11 +++-- .../src/thir/pattern/check_match.rs | 3 +- .../src/thir/pattern/const_to_pat.rs | 2 +- .../src/unstable/convert/stable/ty.rs | 10 ++-- compiler/rustc_type_ir/src/const_kind.rs | 10 ---- .../mgca/inherent-alias-default.rs | 15 ++++++ tests/ui/thir-print/str-patterns.stdout | 4 +- 10 files changed, 77 insertions(+), 48 deletions(-) create mode 100644 tests/ui/const-generics/mgca/inherent-alias-default.rs diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 705bb780a3ecf..52b69e6050a32 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -775,9 +775,23 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), if has_default { // need to store default and type of default let ct = tcx.const_param_default(param.def_id).skip_binder(); - if let ty::ConstKind::Alias(_, alias_const) = ct.kind() - && let Some(def_id) = alias_const.kind.opt_def_id() - { + if let ty::ConstKind::Alias(_, alias_const) = ct.kind() { + let def_id = match alias_const.kind { + ty::AliasConstKind::Projection { def_id } => def_id, + ty::AliasConstKind::InherentSelf { def_id } => { + // NOTE: typically, InherentSelf is illegal to pass to type_of, + // because the generic args are incorrect (type_of expects impl-form + // arguments). However, we are just checking ensure_ok().type_of(), + // we are not instantiating the result, so it's OK here. + def_id + } + ty::AliasConstKind::InherentImpl { .. } => span_bug!( + tcx.def_span(param.def_id), + "const_param_default should return an unnormalized constant, which should always be InherentSelf, not InherentImpl" + ), + ty::AliasConstKind::Free { def_id } => def_id, + ty::AliasConstKind::Anon { def_id } => def_id, + }; tcx.ensure_ok().type_of(def_id); } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index e89caa6aeff8c..ecfe5d3c2c7c2 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1480,9 +1480,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { )? { TypeRelativePath::AssocItem(alias_term) => { let alias_ct = alias_term.expect_ct(); - if let Some(def_id) = alias_ct.kind.opt_def_id() { - self.check_const_item_in_type_system(def_id, span)?; - } + self.check_const_item_in_type_system(alias_ct.kind, span)?; let ct = Const::new_alias(tcx, ty::IsRigid::No, alias_ct); let ct = self.check_param_uses_if_mcg(ct, span, false); Ok(ct) @@ -1948,13 +1946,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { item_segment, ty::AssocTag::Const, )?; - self.check_const_item_in_type_system(item_def_id, span)?; - let alias_const = ty::AliasConst::new( - tcx, - ty::AliasConstKind::Projection { def_id: item_def_id }, - item_args, - ); - Ok(Const::new_alias(tcx, ty::IsRigid::No, alias_const)) + let kind = ty::AliasConstKind::Projection { def_id: item_def_id }; + self.check_const_item_in_type_system(kind, span)?; + let alias = ty::AliasConst::new(tcx, kind, item_args); + Ok(Const::new_alias(tcx, ty::IsRigid::No, alias)) } /// Lower a [resolved][hir::QPath::Resolved] (type-level) associated item path. @@ -2879,7 +2874,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_const_param(def_id, hir_id) } Res::Def(DefKind::Const, did) => { - if let Err(guar) = self.check_const_item_in_type_system(did, span) { + let kind = ty::AliasConstKind::Free { def_id: did }; + if let Err(guar) = self.check_const_item_in_type_system(kind, span) { return Const::new_error(self.tcx(), guar); } @@ -2888,11 +2884,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let _ = self .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None); let args = self.lower_generic_args_of_path_segment(span, did, segment); - ty::Const::new_alias( - tcx, - ty::IsRigid::No, - ty::AliasConst::new(tcx, ty::AliasConstKind::Free { def_id: did }, args), - ) + let alias = ty::AliasConst::new(tcx, kind, args); + ty::Const::new_alias(tcx, ty::IsRigid::No, alias) } Res::Def(kind @ DefKind::Ctor(ctor_of, CtorKind::Const), did) => { assert_eq!(opt_self_ty, None); @@ -3126,18 +3119,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// `def_id` is a const item used in the type system. Checks if that's OK. fn check_const_item_in_type_system( &self, - def_id: DefId, + alias_const: ty::AliasConstKind<'tcx>, span: Span, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - if tcx.features().generic_const_args() || tcx.is_direct_const(def_id) { + if tcx.features().generic_const_args() || alias_const.is_direct_const(tcx) { Ok(()) } else { let mut err = self .dcx() .struct_span_err(span, "use of `const` in the type system not marked as direct"); - if let Some(local_def_id) = def_id.as_local() { - if let Some(body_id) = tcx.hir_node_by_def_id(local_def_id).body_id() { + let hir_node = match alias_const { + ty::AliasConstKind::Projection { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } + | ty::AliasConstKind::Free { def_id } + | ty::AliasConstKind::Anon { def_id } => { + def_id.as_local().map(|id| tcx.hir_node_by_def_id(id)) + } + }; + if let Some(hir_node) = hir_node { + if let Some(body_id) = hir_node.body_id() { let body_span = tcx.hir_body(body_id).value.span; err.multipart_suggestion( @@ -3148,10 +3150,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ], Applicability::MaybeIncorrect, ); - } else if let DefKind::AssocConst = tcx.def_kind(def_id) - && let DefKind::Trait = tcx.def_kind(tcx.parent(def_id)) - { - let node = tcx.hir_node_by_def_id(local_def_id).expect_trait_item(); + } else if let ty::AliasConstKind::Projection { .. } = alias_const { + let node = hir_node.expect_trait_item(); let sp = node.span.shrink_to_lo(); err.span_suggestion_verbose( sp, diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index fe7b1bf493051..b20dfe68d98e2 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -661,7 +661,7 @@ pub struct PatExtra<'tcx> { /// /// This is used by some diagnostics for non-exhaustive matches, to map /// the pattern node back to the `DefId` of its original constant. - pub expanded_const: Option, + pub expanded_const: Option>, /// User-written types that must be preserved into MIR so that they can be /// checked. diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 2853c43ae079d..2227841923514 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -52,9 +52,14 @@ impl<'tcx> TyCtxt<'tcx> { } fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> { let ct = match c.kind() { - ty::ConstKind::Alias(_, alias_const) - if let Some(def_id) = alias_const.kind.opt_def_id() => - { + ty::ConstKind::Alias(_, alias_const) => { + let def_id = match alias_const.kind { + ty::AliasConstKind::Projection { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } + | ty::AliasConstKind::Free { def_id } + | ty::AliasConstKind::Anon { def_id } => def_id, + }; match self.tcx.thir_abstract_const(def_id) { Err(e) => ty::Const::new_error(self.tcx, e), Ok(Some(bac)) => { diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index befe4d67253a3..3414ee751585c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1229,8 +1229,7 @@ fn is_const_pat_that_looks_like_binding<'tcx>(tcx: TyCtxt<'tcx>, pat: &Pat<'tcx> // The pattern must be a named constant, and the name that appears in // the pattern's source text must resemble a plain identifier without any // `::` namespace separators or other non-identifier characters. - if let Some(def_id) = try { pat.extra.as_deref()?.expanded_const? } - && tcx.def_kind(def_id) == DefKind::Const + if let ty::AliasConstKind::Free { def_id } = pat.extra.as_deref()?.expanded_const? && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(pat.span) && snippet.chars().all(|c| c.is_alphanumeric() || c == '_') { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 55eef6006f278..e24ef5ea5b52d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -224,7 +224,7 @@ impl<'tcx> ConstToPat<'tcx> { // Mark the pattern to indicate that it is the result of lowering a named // constant. This is used for diagnostics. - thir_pat.extra.get_or_insert_default().expanded_const = alias_const.kind.opt_def_id(); + thir_pat.extra.get_or_insert_default().expanded_const = Some(alias_const.kind); thir_pat } diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index ad1aa1b47132a..c3eebccb6b762 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -557,9 +557,13 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { } ty::ConstKind::Param(param) => crate::ty::TyConstKind::Param(param.stable(tables, cx)), ty::ConstKind::Alias(_, alias_const) => { - let Some(def_id) = alias_const.kind.opt_def_id() else { - // FIXME: implement (both AliasTy and AliasConst will be needing this soon) - panic!("non-defid alias consts are not supported by rustc_public at the moment") + // rustc_public must change its API once we introduce a variant without a def_id. + let def_id = match alias_const.kind { + ty::AliasConstKind::Projection { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } + | ty::AliasConstKind::Free { def_id } + | ty::AliasConstKind::Anon { def_id } => def_id, }; crate::ty::TyConstKind::Unevaluated( tables.const_def(def_id), diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index dd0578610a2a0..f66322e034814 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -160,16 +160,6 @@ impl AliasConstKind { AliasConstKind::Anon { def_id } => interner.def_span(def_id.into()), } } - - pub fn opt_def_id(self) -> Option { - match self { - AliasConstKind::Projection { def_id } => Some(def_id.into()), - AliasConstKind::InherentSelf { def_id } => Some(def_id.into()), - AliasConstKind::InherentImpl { def_id } => Some(def_id.into()), - AliasConstKind::Free { def_id } => Some(def_id.into()), - AliasConstKind::Anon { def_id } => Some(def_id.into()), - } - } } rustc_index::newtype_index! { diff --git a/tests/ui/const-generics/mgca/inherent-alias-default.rs b/tests/ui/const-generics/mgca/inherent-alias-default.rs new file mode 100644 index 0000000000000..9ba6d1d15e856 --- /dev/null +++ b/tests/ui/const-generics/mgca/inherent-alias-default.rs @@ -0,0 +1,15 @@ +//@ check-pass +//! rustc_hir_analysis::check_item_type does type_of() on the default value. This is wonky, because +//! the generic args are in Self format at that point, not in impl format, so the result can't be +//! used with the Self-format args. However, it does not instantiate the result, it just does +//! ensure_ok(). This test just makes sure that codepath is hit in tests. +#![feature(min_generic_const_args, inherent_associated_types)] + +struct Struct(T1, T2, T3); +impl Struct { + const INHERENT: usize = core::direct_const_arg!(2); +} + +struct WithDefault::INHERENT) }>; + +fn main() {} diff --git a/tests/ui/thir-print/str-patterns.stdout b/tests/ui/thir-print/str-patterns.stdout index da1f86b8fc591..61bcbaef5029a 100644 --- a/tests/ui/thir-print/str-patterns.stdout +++ b/tests/ui/thir-print/str-patterns.stdout @@ -46,7 +46,9 @@ Thir { extra: Some( PatExtra { expanded_const: Some( - DefId(0:4 ~ str_patterns[fc71]::CONSTANT), + Free { + def_id: DefId(0:4 ~ str_patterns[fc71]::CONSTANT), + }, ), ascriptions: [], },