From 4d390de4a3de9e73a51f1edfcecaf8519d94b3ee Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 16:02:20 +0000 Subject: [PATCH] Add a helper function for checking whether a default function in a trait can be treated as `const` --- compiler/rustc_const_eval/src/const_eval/machine.rs | 3 +-- .../src/transform/check_consts/check.rs | 12 +++++------- .../src/transform/check_consts/mod.rs | 4 ++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 ++---- compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 5 +++++ compiler/rustc_ty_utils/src/ty.rs | 6 ++++-- 7 files changed, 20 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 8bd8280497c..ac529bf152f 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -278,8 +278,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, // at all. if !ecx.tcx.is_const_fn_raw(def.did) { // allow calling functions inside a trait marked with #[const_trait]. - if !matches!(ecx.tcx.trait_of_item(def.did), Some(trait_id) if ecx.tcx.has_attr(trait_id, sym::const_trait)) - { + if !ecx.tcx.is_const_default_method(def.did) { // We certainly do *not* want to actually call the fn // though, so be sure we return here. throw_unsup_format!("calling non-const function `{}`", instance) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 57c073cca4d..458f733df10 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -872,13 +872,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let is_intrinsic = tcx.is_intrinsic(callee); if !tcx.is_const_fn_raw(callee) { - if tcx.trait_of_item(callee).is_some() { - if let Some(callee_trait) = tcx.trait_of_item(callee) && tcx.has_attr(callee_trait, sym::const_trait) { - // To get to here we must have already found a const impl for the - // trait, but for it to still be non-const can be that the impl is - // using default method bodies. - nonconst_call_permission = true; - } + if tcx.is_const_default_method(callee) { + // To get to here we must have already found a const impl for the + // trait, but for it to still be non-const can be that the impl is + // using default method bodies. + nonconst_call_permission = true; } if !nonconst_call_permission { diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 32cabb1f899..25b420bed17 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::mir; use rustc_middle::ty::{self, TyCtxt}; -use rustc_span::{sym, Symbol}; +use rustc_span::Symbol; pub use self::qualifs::Qualif; @@ -87,7 +87,7 @@ pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // A default body in a `#[const_trait]` is not const-stable because const // trait fns currently cannot be const-stable. We shouldn't // restrict default bodies to only call const-stable functions. - if let Some(trait_id) = tcx.trait_of_item(def_id) && tcx.has_attr(trait_id, sym::const_trait) { + if tcx.is_const_default_method(def_id) { return false; } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 3e647f4a50e..dad5247b2c4 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -892,10 +892,8 @@ fn should_encode_mir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> (bool, bool) { || tcx.codegen_fn_attrs(def_id).requests_inline()) && tcx.sess.opts.output_types.should_codegen(); // The function has a `const` modifier or is in a `#[const_trait]`. - let mut is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id()); - if let Some(trait_) = tcx.trait_of_item(def_id.to_def_id()) { - is_const_fn = is_const_fn || tcx.has_attr(trait_, sym::const_trait); - } + let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id()) + || tcx.is_const_default_method(def_id.to_def_id()); let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir; (is_const_fn, needs_inline || always_encode_mir) } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 6d7a8a46df1..97f429cfd3f 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -494,7 +494,7 @@ impl<'hir> Map<'hir> { BodyOwnerKind::Fn if self.tcx.is_const_fn_raw(def_id.to_def_id()) => { ConstContext::ConstFn } - BodyOwnerKind::Fn if matches!(self.tcx.trait_of_item(def_id.to_def_id()), Some(trait_id) if self.tcx.has_attr(trait_id, sym::const_trait)) => { + BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id.to_def_id()) => { ConstContext::ConstFn } BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b61a3827602..831a788343d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2301,6 +2301,11 @@ impl<'tcx> TyCtxt<'tcx> { matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..)) && self.impl_constness(def_id) == hir::Constness::Const } + + #[inline] + pub fn is_const_default_method(self, def_id: DefId) -> bool { + matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait)) + } } /// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition. diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index b52ee817509..a18ddd42183 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -5,7 +5,7 @@ use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{ self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, }; -use rustc_span::{sym, Span}; +use rustc_span::Span; use rustc_trait_selection::traits; fn sized_constraint_for_ty<'tcx>( @@ -152,7 +152,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let constness = match hir_id { Some(hir_id) => match tcx.hir().get(hir_id) { - hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) if matches!(tcx.trait_of_item(def_id), Some(trait_id) if tcx.has_attr(trait_id, sym::const_trait)) => { + hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) + if tcx.is_const_default_method(def_id) => + { hir::Constness::Const }