diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index beea1b4a28c9e..5383ab3547af2 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -394,8 +394,10 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>( typing_env: ty::TypingEnv<'tcx>, ) -> Result { let def = cid.instance.def.def_id(); - let is_static = tcx.is_static(def); + // #[type_const] don't have bodys + debug_assert!(!tcx.is_type_const(def), "CTFE tried to evaluate type-const: {:?}", def); + let is_static = tcx.is_static(def); let mut ecx = InterpCx::new( tcx, tcx.def_span(def), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a62826cd7cec0..4fcc7f064f3ff 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1379,9 +1379,8 @@ fn should_encode_const(def_kind: DefKind) -> bool { } fn should_encode_const_of_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: DefKind) -> bool { - matches!(def_kind, DefKind::Const | DefKind::AssocConst) - && find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) - // AssocConst ==> assoc item has value + // AssocConst ==> assoc item has value + tcx.is_type_const(def_id) && (!matches!(def_kind, DefKind::AssocConst) || assoc_item_has_value(tcx, def_id)) } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 79e85a243f400..b08d1d4bcf27d 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -18,6 +18,8 @@ pub(crate) fn thir_body( tcx: TyCtxt<'_>, owner_def: LocalDefId, ) -> Result<(&Steal>, ExprId), ErrorGuaranteed> { + debug_assert!(!tcx.is_type_const(owner_def.to_def_id()), "thir_body queried for type_const"); + let body = tcx.hir_body_owned_by(owner_def); let mut cx = ThirBuildCx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index b9323e91ca838..d9565e2dae0ef 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -209,7 +209,10 @@ impl<'tcx> ReachableContext<'tcx> { self.visit_nested_body(body); } } - + // For #[type_const] we want to evaluate the RHS. + hir::ItemKind::Const(_, _, _, init @ hir::ConstItemRhs::TypeConst(_)) => { + self.visit_const_item_rhs(init); + } hir::ItemKind::Const(_, _, _, init) => { // Only things actually ending up in the final constant value are reachable // for codegen. Everything else is only needed during const-eval, so even if diff --git a/tests/ui/const-generics/mgca/type_const-pub.rs b/tests/ui/const-generics/mgca/type_const-pub.rs new file mode 100644 index 0000000000000..fc5b1ce36a14b --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-pub.rs @@ -0,0 +1,10 @@ +//@ check-pass +// This previously caused an ICE when checking reachability of a pub const item +// This is because reachability also tried to evaluate the #[type_const] which +// requires the item have a body. #[type_const] do not have bodies. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +#[type_const] +pub const TYPE_CONST : usize = 1; +fn main() {}