From 2ffe3b1e70a55867de5c85b9cb24cb1a2a3d6162 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 10 Dec 2024 10:12:36 +0000 Subject: [PATCH] Move impl constness into impl trait header --- .../src/const_eval/fn_queries.rs | 21 +++++++++++-------- compiler/rustc_hir_analysis/src/collect.rs | 19 +++++++++-------- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 ++----- compiler/rustc_middle/src/query/mod.rs | 3 ++- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 9 ++++---- compiler/rustc_middle/src/ty/util.rs | 2 +- .../src/traits/effects.rs | 4 +++- 8 files changed, 35 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index c70ed141cd046..f5396c62433fb 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -4,16 +4,21 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; -fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { +fn parent_impl_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { let parent_id = tcx.local_parent(def_id); - matches!(tcx.def_kind(parent_id), DefKind::Impl { .. }) - && tcx.constness(parent_id) == hir::Constness::Const + if matches!(tcx.def_kind(parent_id), DefKind::Impl { .. }) + && let Some(header) = tcx.impl_trait_header(parent_id) + { + header.constness + } else { + hir::Constness::NotConst + } } -/// Checks whether an item is considered to be `const`. If it is a constructor, anonymous const, -/// const block, const item or associated const, it is const. If it is a trait impl/function, +/// Checks whether an item is considered to be `const`. If it is a constructor, it is const. +/// If it is an assoc method or function, /// return if it has a `const` modifier. If it is an intrinsic, report whether said intrinsic -/// has a `rustc_const_{un,}stable` attribute. Otherwise, return `Constness::NotConst`. +/// has a `rustc_const_{un,}stable` attribute. Otherwise, panic. fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { let node = tcx.hir_node_by_def_id(def_id); @@ -22,7 +27,6 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => { hir::Constness::Const } - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness, hir::Node::ForeignItem(_) => { // Foreign items cannot be evaluated at compile-time. hir::Constness::NotConst @@ -36,8 +40,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { // If the function itself is not annotated with `const`, it may still be a `const fn` // if it resides in a const trait impl. - let is_const = is_parent_const_impl_raw(tcx, def_id); - if is_const { hir::Constness::Const } else { hir::Constness::NotConst } + parent_impl_constness(tcx, def_id) } else { tcx.dcx().span_bug( tcx.def_span(def_id), diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 96d2714252af9..debfe6af0fbf9 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1611,7 +1611,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option, - is_const: bool, + constness: hir::Constness, hir_trait_ref: &hir::TraitRef<'_>, -) -> Option { - if !is_const { - return None; +) { + if let hir::Constness::NotConst = constness { + return; } - let trait_def_id = hir_trait_ref.trait_def_id()?; + let Some(trait_def_id) = hir_trait_ref.trait_def_id() else { return }; if tcx.is_const_trait(trait_def_id) { - return None; + return; } let trait_name = tcx.item_name(trait_def_id).to_string(); @@ -1650,14 +1651,14 @@ fn check_impl_constness( ), (false, _) | (_, false) => (None, ""), }; - Some(tcx.dcx().emit_err(errors::ConstImplForNonConstTrait { + tcx.dcx().emit_err(errors::ConstImplForNonConstTrait { trait_ref_span: hir_trait_ref.path.span, trait_name, local_trait_span, suggestion_pre, marking: (), adding: (), - })) + }); } fn polarity_of_impl( diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b3105a086479d..e67db5d347836 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1264,11 +1264,7 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool { fn should_encode_constness(def_kind: DefKind) -> bool { match def_kind { - DefKind::Fn - | DefKind::AssocFn - | DefKind::Closure - | DefKind::Impl { of_trait: true } - | DefKind::Ctor(_, CtorKind::Fn) => true, + DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Ctor(_, CtorKind::Fn) => true, DefKind::Struct | DefKind::Union @@ -1280,7 +1276,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool { | DefKind::Static { .. } | DefKind::TyAlias | DefKind::OpaqueTy - | DefKind::Impl { of_trait: false } + | DefKind::Impl { .. } | DefKind::ForeignTy | DefKind::ConstParam | DefKind::InlineConst diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ec44801ea9155..a9efa656a66d8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -746,7 +746,8 @@ rustc_queries! { desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } } - /// Returns the constness of functions and impls. + /// Returns the constness of function-like things (tuple struct/variant constructors, functions, + /// methods) /// /// Will ICE if used on things that are always const or never const. /// diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2841470d24878..db1a479f58019 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3141,7 +3141,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Whether the trait impl is marked const. This does not consider stability or feature gates. pub fn is_const_trait_impl(self, def_id: DefId) -> bool { self.def_kind(def_id) == DefKind::Impl { of_trait: true } - && self.constness(def_id) == hir::Constness::Const + && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const } pub fn intrinsic(self, def_id: impl IntoQueryParam + Copy) -> Option { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4f08d9e4251f7..41287685bab20 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -253,6 +253,7 @@ pub struct ImplTraitHeader<'tcx> { pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>, pub polarity: ImplPolarity, pub safety: hir::Safety, + pub constness: hir::Constness, } #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)] @@ -2004,11 +2005,9 @@ impl<'tcx> TyCtxt<'tcx> { let def_id: DefId = def_id.into(); match self.def_kind(def_id) { DefKind::Impl { of_trait: true } => { - self.constness(def_id) == hir::Constness::Const - && self.is_const_trait( - self.trait_id_of_impl(def_id) - .expect("expected trait for trait implementation"), - ) + let header = self.impl_trait_header(def_id).unwrap(); + header.constness == hir::Constness::Const + && self.is_const_trait(header.trait_ref.skip_binder().def_id) } DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => { self.constness(def_id) == hir::Constness::Const diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b9a45ea3c2c5a..fda9898ed5666 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -389,7 +389,7 @@ impl<'tcx> TyCtxt<'tcx> { .delay_as_bug(); } - dtor_candidate = Some((*item_id, self.constness(impl_did))); + dtor_candidate = Some((*item_id, self.impl_trait_header(impl_did).unwrap().constness)); }); let (did, constness) = dtor_candidate?; diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 07fb2efb7fed3..b17a489a857db 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -128,7 +128,9 @@ fn evaluate_host_effect_from_selection_candiate<'tcx>( Err(_) => Err(EvaluationFailure::NoSolution), Ok(Some(source)) => match source { ImplSource::UserDefined(impl_) => { - if tcx.constness(impl_.impl_def_id) != hir::Constness::Const { + if tcx.impl_trait_header(impl_.impl_def_id).unwrap().constness + != hir::Constness::Const + { return Err(EvaluationFailure::NoSolution); }