diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 7e1cbfe66674c..1efa52df5817b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -157,9 +157,7 @@ impl Qualif for NeedsNonConstDrop { // FIXME(effects): If `destruct` is not a `const_trait`, // or effects are disabled in this crate, then give up. let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span)); - if cx.tcx.generics_of(destruct_def_id).host_effect_index.is_none() - || !cx.tcx.features().effects - { + if !cx.tcx.has_host_param(destruct_def_id) || !cx.tcx.features().effects { return NeedsDrop::in_any_value_of_ty(cx, ty); } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 8939c2ddea54e..fc61467df0142 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -490,11 +490,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.require_lang_item(hir::LangItem::FnOnce, Some(span)); let fn_once_output_def_id = self.tcx.require_lang_item(hir::LangItem::FnOnceOutput, Some(span)); - if self.tcx.generics_of(fn_once_def_id).host_effect_index.is_none() { - if idx == 0 && !self.tcx.is_const_fn_raw(def_id) { - self.dcx().emit_err(errors::ConstSelectMustBeConst { span }); - } - } else { + if self.tcx.has_host_param(fn_once_def_id) { let const_param: ty::GenericArg<'tcx> = ([self.tcx.consts.false_, self.tcx.consts.true_])[idx].into(); self.register_predicate(traits::Obligation::new( @@ -523,6 +519,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); self.select_obligations_where_possible(|_| {}); + } else if idx == 0 && !self.tcx.is_const_fn_raw(def_id) { + self.dcx().emit_err(errors::ConstSelectMustBeConst { span }); } } else { self.dcx().emit_err(errors::ConstSelectMustBeFn { span, ty: arg_ty }); diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b9c75bd205b24..f2a33429bd760 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1,7 +1,7 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::query::Providers; +use crate::query::{IntoQueryParam, Providers}; use crate::ty::layout::IntegerExt; use crate::ty::{ self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -786,6 +786,13 @@ impl<'tcx> TyCtxt<'tcx> { || self.extern_crate(key.as_def_id()).is_some_and(|e| e.is_direct()) } + /// Whether the item has a host effect param. This is different from `TyCtxt::is_const`, + /// because the item must also be "maybe const", and the crate where the item is + /// defined must also have the effects feature enabled. + pub fn has_host_param(self, def_id: impl IntoQueryParam) -> bool { + self.generics_of(def_id).host_effect_index.is_some() + } + pub fn expected_host_effect_param_for_body(self, def_id: impl Into) -> ty::Const<'tcx> { let def_id = def_id.into(); // FIXME(effects): This is suspicious and should probably not be done, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 19eae93df9c87..c40ed10e52ff3 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -271,7 +271,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => Ty::new_tup(tcx, sig.skip_binder().inputs()), }; - let trait_ref = if tcx.generics_of(fn_trait_def_id).host_effect_index.is_some() { + let trait_ref = if tcx.has_host_param(fn_trait_def_id) { ty::TraitRef::new( tcx, fn_trait_def_id,