diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits')
5 files changed, 24 insertions, 341 deletions
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<PredicateObligations<'tcx>, 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<DefId>, - ) -> Result<PredicateObligations<'tcx>, 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())) } |
