From 6f6f91ab828abf38244715183ef3fd19b3b2b32f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 20 Oct 2024 13:39:52 +0000 Subject: [PATCH] Rip out old effects var handling code from traits --- .../src/check_consts/qualifs.rs | 53 +---- compiler/rustc_hir_typeck/src/callee.rs | 35 +--- compiler/rustc_middle/src/traits/select.rs | 7 +- compiler/rustc_middle/src/ty/util.rs | 18 -- .../rustc_mir_build/src/build/matches/test.rs | 7 +- .../src/thir/pattern/const_to_pat.rs | 12 +- .../src/error_reporting/traits/suggestions.rs | 4 +- .../src/traits/project.rs | 36 +--- .../src/traits/select/candidate_assembly.rs | 112 +--------- .../src/traits/select/confirmation.rs | 191 +----------------- .../src/traits/select/mod.rs | 15 +- .../rustc_trait_selection/src/traits/util.rs | 11 +- .../src/implied_bounds_in_impls.rs | 9 - src/tools/clippy/clippy_utils/src/ty.rs | 15 +- 14 files changed, 34 insertions(+), 491 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 7358a6c6d22..547030a1854 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -6,13 +6,10 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::*; -use rustc_middle::traits::BuiltinImplSource; use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty}; use rustc_middle::{bug, mir}; -use rustc_trait_selection::traits::{ - ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext, -}; -use tracing::{instrument, trace}; +use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; +use tracing::instrument; use super::ConstCx; @@ -195,50 +192,8 @@ impl Qualif for NeedsNonConstDrop { return false; } - // 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.has_host_param(destruct_def_id) || !cx.tcx.features().effects { - return NeedsDrop::in_any_value_of_ty(cx, ty); - } - - let obligation = Obligation::new( - cx.tcx, - ObligationCause::dummy_with_span(cx.body.span), - cx.param_env, - ty::TraitRef::new(cx.tcx, destruct_def_id, [ - ty::GenericArg::from(ty), - ty::GenericArg::from(cx.tcx.expected_host_effect_param_for_body(cx.def_id())), - ]), - ); - - let infcx = cx.tcx.infer_ctxt().build(); - let mut selcx = SelectionContext::new(&infcx); - let Some(impl_src) = selcx.select(&obligation).ok().flatten() else { - // If we couldn't select a const destruct candidate, then it's bad - return true; - }; - - trace!(?impl_src); - - if !matches!( - impl_src, - ImplSource::Builtin(BuiltinImplSource::Misc, _) | ImplSource::Param(_) - ) { - // If our const destruct candidate is not ConstDestruct or implied by the param env, - // then it's bad - return true; - } - - if impl_src.borrow_nested_obligations().is_empty() { - return false; - } - - // If we had any errors, then it's bad - let ocx = ObligationCtxt::new(&infcx); - ocx.register_obligations(impl_src.nested_obligations()); - let errors = ocx.select_all_or_error(); - !errors.is_empty() + // FIXME(effects): Reimplement const drop checking. + NeedsDrop::in_any_value_of_ty(cx, ty) } fn in_adt_inherently<'tcx>( diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 13ba615d4c9..fa6a86c6911 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -537,40 +537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // This check is here because there is currently no way to express a trait bound for `FnDef` types only. if let ty::FnDef(def_id, _args) = *arg_ty.kind() { - let fn_once_def_id = - 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.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( - self.tcx, - self.misc(span), - self.param_env, - ty::TraitRef::new(self.tcx, fn_once_def_id, [ - arg_ty.into(), - fn_sig.inputs()[0].into(), - const_param, - ]), - )); - - self.register_predicate(traits::Obligation::new( - self.tcx, - self.misc(span), - self.param_env, - ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new( - self.tcx, - fn_once_output_def_id, - [arg_ty.into(), fn_sig.inputs()[0].into(), const_param], - ), - term: fn_sig.output().into(), - }, - )); - - self.select_obligations_where_possible(|_| {}); - } else if idx == 0 && !self.tcx.is_const_fn_raw(def_id) { + if idx == 0 && !self.tcx.is_const_fn_raw(def_id) { self.dcx().emit_err(errors::ConstSelectMustBeConst { span }); } } else { diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 66035464fa5..05556ae38a8 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -161,9 +161,7 @@ pub enum SelectionCandidate<'tcx> { /// Implementation of a `Fn`-family trait by one of the anonymous /// types generated for a fn pointer type (e.g., `fn(int) -> int`) - FnPointerCandidate { - fn_host_effect: ty::Const<'tcx>, - }, + FnPointerCandidate, TraitAliasCandidate, @@ -180,9 +178,6 @@ pub enum SelectionCandidate<'tcx> { BuiltinObjectCandidate, BuiltinUnsizeCandidate, - - /// Implementation of `const Destruct`, optionally from a custom `impl const Drop`. - ConstDestructCandidate(Option), } /// The result of trait evaluation. The order is important diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 0a917120b3b..9a3049f3be6 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -907,24 +907,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// Constructs generic args for an item, optionally appending a const effect param type - pub fn with_opt_host_effect_param( - self, - caller_def_id: LocalDefId, - callee_def_id: DefId, - args: impl IntoIterator>>, - ) -> ty::GenericArgsRef<'tcx> { - let generics = self.generics_of(callee_def_id); - assert_eq!(generics.parent, None); - - let opt_const_param = generics - .host_effect_index - .is_some() - .then(|| ty::GenericArg::from(self.expected_host_effect_param_for_body(caller_def_id))); - - self.mk_args_from_iter(args.into_iter().map(|arg| arg.into()).chain(opt_const_param)) - } - /// Expand any [weak alias types][weak] contained within the given `value`. /// /// This should be used over other normalization routines in situations where diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 020c202f965..7170aebee7d 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -454,12 +454,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); - let method = trait_method( - self.tcx, - eq_def_id, - sym::eq, - self.tcx.with_opt_host_effect_param(self.def_id, eq_def_id, [compare_ty, compare_ty]), - ); + let method = trait_method(self.tcx, eq_def_id, sym::eq, [compare_ty, compare_ty]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); 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 2c3611afca9..0dfa9168f7c 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 @@ -43,7 +43,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } struct ConstToPat<'tcx> { - id: hir::HirId, span: Span, param_env: ty::ParamEnv<'tcx>, @@ -62,7 +61,6 @@ impl<'tcx> ConstToPat<'tcx> { ) -> Self { trace!(?pat_ctxt.typeck_results.hir_owner); ConstToPat { - id, span, infcx, param_env: pat_ctxt.param_env, @@ -149,15 +147,7 @@ impl<'tcx> ConstToPat<'tcx> { tcx, ObligationCause::dummy(), self.param_env, - ty::TraitRef::new_from_args( - tcx, - partial_eq_trait_id, - tcx.with_opt_host_effect_param( - tcx.hir().enclosing_body_owner(self.id), - partial_eq_trait_id, - [ty, ty], - ), - ), + ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]), ); // This *could* accept a type that isn't actually `PartialEq`, because region bounds get diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 733baaa99e5..677905a3085 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3701,12 +3701,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } _ => None, }; - // Also add host param, if present - let host = self.tcx.generics_of(trait_pred.def_id()).host_effect_index.map(|idx| trait_pred.skip_binder().trait_ref.args[idx]); let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { trait_ref: ty::TraitRef::new(self.tcx, trait_pred.def_id(), - [field_ty].into_iter().chain(trait_args).chain(host), + [field_ty].into_iter().chain(trait_args), ), ..*tr }); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 7f7c9bced18..cc634b65a0b 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1642,24 +1642,9 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>( sig, ); - let host_effect_param = match *fn_type.kind() { - ty::FnDef(def_id, args) => tcx - .generics_of(def_id) - .host_effect_index - .map_or(tcx.consts.true_, |idx| args.const_at(idx)), - ty::FnPtr(..) => tcx.consts.true_, - _ => unreachable!("only expected FnPtr or FnDef in `confirm_fn_pointer_candidate`"), - }; - - confirm_callable_candidate( - selcx, - obligation, - sig, - util::TupleArgumentsFlag::Yes, - host_effect_param, - ) - .with_addl_obligations(nested) - .with_addl_obligations(obligations) + confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes) + .with_addl_obligations(nested) + .with_addl_obligations(obligations) } fn confirm_closure_candidate<'cx, 'tcx>( @@ -1739,16 +1724,9 @@ fn confirm_closure_candidate<'cx, 'tcx>( debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate"); - confirm_callable_candidate( - selcx, - obligation, - closure_sig, - util::TupleArgumentsFlag::No, - // FIXME(effects): This doesn't handle const closures correctly! - selcx.tcx().consts.true_, - ) - .with_addl_obligations(nested) - .with_addl_obligations(obligations) + confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No) + .with_addl_obligations(nested) + .with_addl_obligations(obligations) } fn confirm_callable_candidate<'cx, 'tcx>( @@ -1756,7 +1734,6 @@ fn confirm_callable_candidate<'cx, 'tcx>( obligation: &ProjectionTermObligation<'tcx>, fn_sig: ty::PolyFnSig<'tcx>, flag: util::TupleArgumentsFlag, - fn_host_effect: ty::Const<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1771,7 +1748,6 @@ fn confirm_callable_candidate<'cx, 'tcx>( obligation.predicate.self_ty(), fn_sig, flag, - fn_host_effect, ) .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate { projection_term: ty::AliasTerm::new_from_args(tcx, fn_once_output_def_id, trait_ref.args), diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index aa313a526c1..ac38c9e24a2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -543,23 +543,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Provide an impl, but only for suitable `fn` pointers. ty::FnPtr(sig_tys, hdr) => { if sig_tys.with(hdr).is_fn_trait_compatible() { - candidates - .vec - .push(FnPointerCandidate { fn_host_effect: self.tcx().consts.true_ }); + candidates.vec.push(FnPointerCandidate); } } // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396). - ty::FnDef(def_id, args) => { + ty::FnDef(def_id, _args) => { let tcx = self.tcx(); if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible() && tcx.codegen_fn_attrs(def_id).target_features.is_empty() { - candidates.vec.push(FnPointerCandidate { - fn_host_effect: tcx - .generics_of(def_id) - .host_effect_index - .map_or(tcx.consts.true_, |idx| args.const_at(idx)), - }); + candidates.vec.push(FnPointerCandidate); } } _ => {} @@ -1170,103 +1163,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn assemble_const_destruct_candidates( &mut self, - obligation: &PolyTraitObligation<'tcx>, + _obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - // If the predicate is `~const Destruct` in a non-const environment, we don't actually need - // to check anything. We'll short-circuit checking any obligations in confirmation, too. - let Some(host_effect_index) = - self.tcx().generics_of(obligation.predicate.def_id()).host_effect_index - else { - candidates.vec.push(BuiltinCandidate { has_nested: false }); - return; - }; - // If the obligation has `host = true`, then the obligation is non-const and it's always - // trivially implemented. - if obligation.predicate.skip_binder().trait_ref.args.const_at(host_effect_index) - == self.tcx().consts.true_ - { - candidates.vec.push(BuiltinCandidate { has_nested: false }); - return; - } - - let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); - match self_ty.kind() { - ty::Alias(..) - | ty::Dynamic(..) - | ty::Error(_) - | ty::Bound(..) - | ty::Param(_) - | ty::Placeholder(_) => { - // We don't know if these are `~const Destruct`, at least - // not structurally... so don't push a candidate. - } - - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Infer(ty::IntVar(_)) - | ty::Infer(ty::FloatVar(_)) - | ty::Str - | ty::RawPtr(_, _) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Never - | ty::Foreign(_) - | ty::Array(..) - | ty::Pat(..) - | ty::Slice(_) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(..) - | ty::Tuple(_) - | ty::CoroutineWitness(..) => { - // These are built-in, and cannot have a custom `impl const Destruct`. - candidates.vec.push(ConstDestructCandidate(None)); - } - - ty::Adt(..) => { - let mut relevant_impl = None; - self.tcx().for_each_relevant_impl( - self.tcx().require_lang_item(LangItem::Drop, None), - obligation.predicate.skip_binder().trait_ref.self_ty(), - |impl_def_id| { - if let Some(old_impl_def_id) = relevant_impl { - self.tcx() - .dcx() - .struct_span_err( - self.tcx().def_span(impl_def_id), - "multiple drop impls found", - ) - .with_span_note( - self.tcx().def_span(old_impl_def_id), - "other impl here", - ) - .delay_as_bug(); - } - - relevant_impl = Some(impl_def_id); - }, - ); - - if let Some(impl_def_id) = relevant_impl { - // Check that `impl Drop` is actually const, if there is a custom impl - if self.tcx().constness(impl_def_id) == hir::Constness::Const { - candidates.vec.push(ConstDestructCandidate(Some(impl_def_id))); - } - } else { - // Otherwise check the ADT like a built-in type (structurally) - candidates.vec.push(ConstDestructCandidate(None)); - } - } - - ty::Infer(_) => { - candidates.ambiguous = true; - } - } + // FIXME(effects): Destruct is not const yet, and it is implemented + // by all types today in non-const setting. + candidates.vec.push(BuiltinCandidate { has_nested: false }); } fn assemble_candidate_for_tuple( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 0ba3b4e6e55..1764777ee69 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -28,9 +28,9 @@ use super::{BuiltinImplConditions, PredicateObligations, SelectionContext}; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::util::{self, closure_trait_ref_and_return_type}; use crate::traits::{ - ImplDerivedCause, ImplSource, ImplSourceUserDefinedData, Normalized, Obligation, - ObligationCause, PolyTraitObligation, PredicateObligation, Selection, SelectionError, - SignatureMismatch, TraitDynIncompatible, TraitObligation, Unimplemented, + ImplSource, ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause, + PolyTraitObligation, PredicateObligation, Selection, SelectionError, SignatureMismatch, + TraitDynIncompatible, TraitObligation, Unimplemented, }; impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { @@ -109,8 +109,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator) } - FnPointerCandidate { fn_host_effect } => { - let data = self.confirm_fn_pointer_candidate(obligation, fn_host_effect)?; + FnPointerCandidate => { + let data = self.confirm_fn_pointer_candidate(obligation)?; ImplSource::Builtin(BuiltinImplSource::Misc, data) } @@ -131,11 +131,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { TraitUpcastingUnsizeCandidate(idx) => { self.confirm_trait_upcasting_unsize_candidate(obligation, idx)? } - - ConstDestructCandidate(def_id) => { - let data = self.confirm_const_destruct_candidate(obligation, def_id)?; - ImplSource::Builtin(BuiltinImplSource::Misc, data) - } }; // The obligations returned by confirmation are recursively evaluated @@ -708,7 +703,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_fn_pointer_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - fn_host_effect: ty::Const<'tcx>, ) -> Result, SelectionError<'tcx>> { debug!(?obligation, "confirm_fn_pointer_candidate"); let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); @@ -722,7 +716,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self_ty, sig, util::TupleArgumentsFlag::Yes, - fn_host_effect, ) .map_bound(|(trait_ref, _)| trait_ref); @@ -904,11 +897,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty: Ty<'_> = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let trait_ref = match *self_ty.kind() { - ty::Closure(..) => self.closure_trait_ref_unnormalized( - self_ty, - obligation.predicate.def_id(), - self.tcx().consts.true_, - ), + ty::Closure(..) => { + self.closure_trait_ref_unnormalized(self_ty, obligation.predicate.def_id()) + } ty::CoroutineClosure(_, args) => { args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| { ty::TraitRef::new(self.tcx(), obligation.predicate.def_id(), [ @@ -1341,170 +1332,4 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => bug!("source: {source}, target: {target}"), }) } - - fn confirm_const_destruct_candidate( - &mut self, - obligation: &PolyTraitObligation<'tcx>, - impl_def_id: Option, - ) -> Result, SelectionError<'tcx>> { - let Some(host_effect_index) = - self.tcx().generics_of(obligation.predicate.def_id()).host_effect_index - else { - bug!() - }; - let host_effect_param: ty::GenericArg<'tcx> = - obligation.predicate.skip_binder().trait_ref.args.const_at(host_effect_index).into(); - - let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None); - - let tcx = self.tcx(); - let self_ty = obligation.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); - - let mut nested = PredicateObligations::new(); - let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived); - - // If we have a custom `impl const Drop`, then - // first check it like a regular impl candidate. - // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand. - if let Some(impl_def_id) = impl_def_id { - let mut new_obligation = obligation.clone(); - new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| { - trait_pred.trait_ref.def_id = drop_trait; - trait_pred - }); - let args = self.rematch_impl(impl_def_id, &new_obligation); - debug!(?args, "impl args"); - - let cause = obligation.derived_cause(|derived| { - ObligationCauseCode::ImplDerived(Box::new(ImplDerivedCause { - derived, - impl_or_alias_def_id: impl_def_id, - impl_def_predicate_index: None, - span: obligation.cause.span, - })) - }); - let obligations = ensure_sufficient_stack(|| { - self.vtable_impl( - impl_def_id, - args, - &cause, - new_obligation.recursion_depth + 1, - new_obligation.param_env, - obligation.predicate, - ) - }); - nested.extend(obligations.nested); - } - - // We want to confirm the ADT's fields if we have an ADT - let mut stack = match *self_ty.skip_binder().kind() { - ty::Adt(def, args) => def.all_fields().map(|f| f.ty(tcx, args)).collect(), - _ => vec![self_ty.skip_binder()], - }; - - while let Some(nested_ty) = stack.pop() { - match *nested_ty.kind() { - // We know these types are trivially drop - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Infer(ty::IntVar(_)) - | ty::Infer(ty::FloatVar(_)) - | ty::Str - | ty::RawPtr(_, _) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Never - | ty::Foreign(_) => {} - - // `ManuallyDrop` is trivially drop - ty::Adt(def, _) if def.is_manually_drop() => {} - - // These types are built-in, so we can fast-track by registering - // nested predicates for their constituent type(s) - ty::Array(ty, _) | ty::Slice(ty) | ty::Pat(ty, _) => { - stack.push(ty); - } - ty::Tuple(tys) => { - stack.extend(tys.iter()); - } - ty::Closure(_, args) => { - stack.push(args.as_closure().tupled_upvars_ty()); - } - ty::Coroutine(_, args) => { - let coroutine = args.as_coroutine(); - stack.extend([coroutine.tupled_upvars_ty(), coroutine.witness()]); - } - ty::CoroutineWitness(def_id, args) => { - let tcx = self.tcx(); - stack.extend(tcx.bound_coroutine_hidden_types(def_id).map(|bty| { - self.infcx.enter_forall_and_leak_universe(bty.instantiate(tcx, args)) - })) - } - - // If we have a projection type, make sure to normalize it so we replace it - // with a fresh infer variable - ty::Alias(ty::Projection | ty::Inherent, ..) => { - let predicate = normalize_with_depth_to( - self, - obligation.param_env, - cause.clone(), - obligation.recursion_depth + 1, - self_ty.rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef::new( - self.tcx(), - self.tcx().require_lang_item(LangItem::Destruct, Some(cause.span)), - [nested_ty.into(), host_effect_param], - ), - polarity: ty::PredicatePolarity::Positive, - }), - &mut nested, - ); - - nested.push(Obligation::with_depth( - tcx, - cause.clone(), - obligation.recursion_depth + 1, - obligation.param_env, - predicate, - )); - } - - // If we have any other type (e.g. an ADT), just register a nested obligation - // since it's either not `const Drop` (and we raise an error during selection), - // or it's an ADT (and we need to check for a custom impl during selection) - ty::Error(_) - | ty::Dynamic(..) - | ty::CoroutineClosure(..) - | ty::Param(_) - | ty::Bound(..) - | ty::Adt(..) - | ty::Alias(ty::Opaque | ty::Weak, _) - | ty::Infer(_) - | ty::Placeholder(_) => { - let predicate = self_ty.rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef::new( - self.tcx(), - self.tcx().require_lang_item(LangItem::Destruct, Some(cause.span)), - [nested_ty.into(), host_effect_param], - ), - polarity: ty::PredicatePolarity::Positive, - }); - - nested.push(Obligation::with_depth( - tcx, - cause.clone(), - obligation.recursion_depth + 1, - obligation.param_env, - predicate, - )); - } - } - } - - Ok(nested) - } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 621babe9104..4757430a21c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1831,12 +1831,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { (TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => DropVictim::No, // (*) - (BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => { - DropVictim::Yes - } - (_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => { - DropVictim::No - } + (BuiltinCandidate { has_nested: false }, _) => DropVictim::Yes, + (_, BuiltinCandidate { has_nested: false }) => DropVictim::No, (ParamCandidate(other), ParamCandidate(victim)) => { let same_except_bound_vars = other.skip_binder().trait_ref @@ -1855,11 +1851,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } - // Drop otherwise equivalent non-const fn pointer candidates - (FnPointerCandidate { .. }, FnPointerCandidate { fn_host_effect }) => { - DropVictim::drop_if(*fn_host_effect == self.tcx().consts.true_) - } - ( ParamCandidate(other_cand), ImplCandidate(..) @@ -2766,7 +2757,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { &mut self, self_ty: Ty<'tcx>, fn_trait_def_id: DefId, - fn_host_effect: ty::Const<'tcx>, ) -> ty::PolyTraitRef<'tcx> { let ty::Closure(_, args) = *self_ty.kind() else { bug!("expected closure, found {self_ty}"); @@ -2779,7 +2769,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { self_ty, closure_sig, util::TupleArgumentsFlag::No, - fn_host_effect, ) .map_bound(|(trait_ref, _)| trait_ref) } diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index aed2e3d61aa..b7a2f20b769 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -215,22 +215,13 @@ pub(crate) fn closure_trait_ref_and_return_type<'tcx>( self_ty: Ty<'tcx>, sig: ty::PolyFnSig<'tcx>, tuple_arguments: TupleArgumentsFlag, - fn_host_effect: ty::Const<'tcx>, ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> { assert!(!self_ty.has_escaping_bound_vars()); let arguments_tuple = match tuple_arguments { TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => Ty::new_tup(tcx, sig.skip_binder().inputs()), }; - let trait_ref = if tcx.has_host_param(fn_trait_def_id) { - ty::TraitRef::new(tcx, fn_trait_def_id, [ - ty::GenericArg::from(self_ty), - ty::GenericArg::from(arguments_tuple), - ty::GenericArg::from(fn_host_effect), - ]) - } else { - ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty, arguments_tuple]) - }; + let trait_ref = ty::TraitRef::new(tcx, fn_trait_def_id, [self_ty, arguments_tuple]); sig.map_bound(|sig| (trait_ref, sig.output())) } diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index f4c00d8287d..00f83237224 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -190,15 +190,6 @@ fn is_same_generics<'tcx>( .enumerate() .skip(1) // skip `Self` implicit arg .all(|(arg_index, arg)| { - if [ - implied_by_generics.host_effect_index, - implied_generics.host_effect_index, - ] - .contains(&Some(arg_index)) - { - // skip host effect params in determining whether generics are same - return true; - } if let Some(ty) = arg.as_type() { if let &ty::Param(ty::ParamTy { index, .. }) = ty.kind() // `index == 0` means that it's referring to `Self`, diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index b7a3569ccf0..cab16b4927d 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -274,23 +274,10 @@ pub fn implements_trait_with_env_from_iter<'tcx>( .map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into())) .collect::>(); - // If an effect arg was not specified, we need to specify it. - let effect_arg = if tcx - .generics_of(trait_id) - .host_effect_index - .is_some_and(|x| args.get(x - 1).is_none()) - { - Some(GenericArg::from(callee_id.map_or(tcx.consts.true_, |def_id| { - tcx.expected_host_effect_param_for_body(def_id) - }))) - } else { - None - }; - let trait_ref = TraitRef::new( tcx, trait_id, - [GenericArg::from(ty)].into_iter().chain(args).chain(effect_arg), + [GenericArg::from(ty)].into_iter().chain(args), ); debug_assert_matches!(