1
Fork 0

Auto merge of #113308 - compiler-errors:poly-select, r=lcnr

Split `SelectionContext::select` into fns that take a binder and don't

*most* usages of `SelectionContext::select` don't need to use a binder, but wrap them in a dummy because of the signature. Let's split this out into `SelectionContext::{select,poly_select}` and limit the usages of the latter.

Right now, we only have 3 places where we're calling `poly_select` -- fulfillment, internally within the old solver, and the auto-trait finder.

r? `@lcnr`
This commit is contained in:
bors 2023-07-07 10:32:42 +00:00
commit 1a449dcfd2
21 changed files with 125 additions and 112 deletions

View file

@ -10,7 +10,7 @@ use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceC
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
use rustc_middle::ty::{Binder, TraitRef, TypeVisitableExt}; use rustc_middle::ty::{TraitRef, TypeVisitableExt};
use rustc_mir_dataflow::{self, Analysis}; use rustc_mir_dataflow::{self, Analysis};
use rustc_span::{sym, Span, Symbol}; use rustc_span::{sym, Span, Symbol};
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
@ -755,10 +755,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
} }
let trait_ref = TraitRef::from_method(tcx, trait_id, substs); let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
let poly_trait_pred = let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
Binder::dummy(trait_ref).with_constness(ty::BoundConstness::ConstIfConst);
let obligation = let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, poly_trait_pred); Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
let implsrc = { let implsrc = {
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
@ -776,11 +775,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
} }
// Closure: Fn{Once|Mut} // Closure: Fn{Once|Mut}
Ok(Some(ImplSource::Builtin(_))) Ok(Some(ImplSource::Builtin(_)))
if poly_trait_pred.self_ty().skip_binder().is_closure() if trait_ref.self_ty().is_closure()
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() => && tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
{ {
let ty::Closure(closure_def_id, substs) = let ty::Closure(closure_def_id, substs) =
*poly_trait_pred.self_ty().no_bound_vars().unwrap().kind() *trait_ref.self_ty().kind()
else { else {
unreachable!() unreachable!()
}; };
@ -840,7 +839,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
tcx, tcx,
ObligationCause::dummy_with_span(*fn_span), ObligationCause::dummy_with_span(*fn_span),
param_env, param_env,
poly_trait_pred, trait_ref,
); );
// improve diagnostics by showing what failed. Our requirements are stricter this time // improve diagnostics by showing what failed. Our requirements are stricter this time

View file

@ -10,8 +10,8 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::{self, CallSource}; use rustc_middle::mir::{self, CallSource};
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::TraitRef;
use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty}; use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
use rustc_middle::ty::{Binder, TraitRef};
use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind}; use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -137,12 +137,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
} }
} }
Adt(..) => { Adt(..) => {
let obligation = Obligation::new( let obligation =
tcx, Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
ObligationCause::dummy(),
param_env,
Binder::dummy(trait_ref),
);
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx); let mut selcx = SelectionContext::new(&infcx);

View file

@ -632,9 +632,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
while !queue.is_empty() { while !queue.is_empty() {
let obligation = queue.remove(0); let obligation = queue.remove(0);
debug!("coerce_unsized resolve step: {:?}", obligation); debug!("coerce_unsized resolve step: {:?}", obligation);
let bound_predicate = obligation.predicate.kind(); let trait_pred = match obligation.predicate.kind().no_bound_vars() {
let trait_pred = match bound_predicate.skip_binder() { Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)))
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred))
if traits.contains(&trait_pred.def_id()) => if traits.contains(&trait_pred.def_id()) =>
{ {
if unsize_did == trait_pred.def_id() { if unsize_did == trait_pred.def_id() {
@ -652,7 +651,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
has_unsized_tuple_coercion = true; has_unsized_tuple_coercion = true;
} }
} }
bound_predicate.rebind(trait_pred) trait_pred
} }
_ => { _ => {
coercion.obligations.push(obligation); coercion.obligations.push(obligation);
@ -664,8 +663,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
Ok(None) => { Ok(None) => {
if trait_pred.def_id() == unsize_did { if trait_pred.def_id() == unsize_did {
let trait_pred = self.resolve_vars_if_possible(trait_pred); let trait_pred = self.resolve_vars_if_possible(trait_pred);
let self_ty = trait_pred.skip_binder().self_ty(); let self_ty = trait_pred.self_ty();
let unsize_ty = trait_pred.skip_binder().trait_ref.substs[1].expect_ty(); let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty();
debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_pred); debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_pred);
match (self_ty.kind(), unsize_ty.kind()) { match (self_ty.kind(), unsize_ty.kind()) {
(&ty::Infer(ty::TyVar(v)), ty::Dynamic(..)) (&ty::Infer(ty::TyVar(v)), ty::Dynamic(..))

View file

@ -1982,7 +1982,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx, self.tcx,
traits::ObligationCause::dummy(), traits::ObligationCause::dummy(),
self.param_env, self.param_env,
ty::Binder::dummy(trait_ref), trait_ref,
); );
match SelectionContext::new(&self).select(&obligation) { match SelectionContext::new(&self).select(&obligation) {
Ok(Some(traits::ImplSource::UserDefined(impl_source))) => { Ok(Some(traits::ImplSource::UserDefined(impl_source))) => {

View file

@ -1441,8 +1441,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,
) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> { ) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> {
let cause = traits::ObligationCause::misc(self.span, self.body_id); let cause = traits::ObligationCause::misc(self.span, self.body_id);
let predicate = ty::Binder::dummy(trait_ref); let obligation = traits::Obligation::new(self.tcx, cause, self.param_env, trait_ref);
let obligation = traits::Obligation::new(self.tcx, cause, self.param_env, predicate);
traits::SelectionContext::new(self).select(&obligation) traits::SelectionContext::new(self).select(&obligation)
} }

View file

@ -62,7 +62,8 @@ impl<'tcx, P> From<Obligation<'tcx, P>> for solve::Goal<'tcx, P> {
} }
pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>; pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>;
pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
impl<'tcx> PredicateObligation<'tcx> { impl<'tcx> PredicateObligation<'tcx> {
/// Flips the polarity of the inner predicate. /// Flips the polarity of the inner predicate.
@ -86,7 +87,7 @@ impl<'tcx> PredicateObligation<'tcx> {
} }
} }
impl<'tcx> TraitObligation<'tcx> { impl<'tcx> PolyTraitObligation<'tcx> {
/// Returns `true` if the trait predicate is considered `const` in its ParamEnv. /// Returns `true` if the trait predicate is considered `const` in its ParamEnv.
pub fn is_const(&self) -> bool { pub fn is_const(&self) -> bool {
matches!( matches!(
@ -193,7 +194,7 @@ impl<'tcx> FulfillmentError<'tcx> {
} }
} }
impl<'tcx> TraitObligation<'tcx> { impl<'tcx> PolyTraitObligation<'tcx> {
pub fn polarity(&self) -> ty::ImplPolarity { pub fn polarity(&self) -> ty::ImplPolarity {
self.predicate.skip_binder().polarity self.predicate.skip_binder().polarity
} }

View file

@ -318,11 +318,11 @@ impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) {
} }
} }
impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>) {
type CacheSelector = DefaultCacheSelector<Self>; type CacheSelector = DefaultCacheSelector<Self>;
fn default_span(&self, tcx: TyCtxt<'_>) -> Span { fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
tcx.def_span(self.1.def_id()) tcx.def_span(self.1.def_id)
} }
} }

View file

@ -1278,7 +1278,7 @@ rustc_queries! {
} }
query codegen_select_candidate( query codegen_select_candidate(
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) key: (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>)
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
cache_on_disk_if { true } cache_on_disk_if { true }
desc { |tcx| "computing candidate for `{}`", key.1 } desc { |tcx| "computing candidate for `{}`", key.1 }

View file

@ -1306,6 +1306,13 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
} }
} }
impl<'tcx> ToPredicate<'tcx, TraitPredicate<'tcx>> for TraitRef<'tcx> {
#[inline(always)]
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> TraitPredicate<'tcx> {
self.without_const()
}
}
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitRef<'tcx> { impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitRef<'tcx> {
#[inline(always)] #[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {

View file

@ -31,12 +31,12 @@ fn custom_coerce_unsize_info<'tcx>(
source_ty: Ty<'tcx>, source_ty: Ty<'tcx>,
target_ty: Ty<'tcx>, target_ty: Ty<'tcx>,
) -> CustomCoerceUnsized { ) -> CustomCoerceUnsized {
let trait_ref = ty::Binder::dummy(ty::TraitRef::from_lang_item( let trait_ref = ty::TraitRef::from_lang_item(
tcx.tcx, tcx.tcx,
LangItem::CoerceUnsized, LangItem::CoerceUnsized,
tcx.span, tcx.span,
[source_ty, target_ty], [source_ty, target_ty],
)); );
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) { match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {

View file

@ -4,7 +4,7 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
use rustc_infer::traits::util::supertraits; use rustc_infer::traits::util::supertraits;
use rustc_infer::traits::{ use rustc_infer::traits::{
Obligation, PredicateObligation, Selection, SelectionResult, TraitObligation, Obligation, PolyTraitObligation, PredicateObligation, Selection, SelectionResult,
}; };
use rustc_middle::traits::solve::{CanonicalInput, Certainty, Goal}; use rustc_middle::traits::solve::{CanonicalInput, Certainty, Goal};
use rustc_middle::traits::{ use rustc_middle::traits::{
@ -23,14 +23,14 @@ use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, V
pub trait InferCtxtSelectExt<'tcx> { pub trait InferCtxtSelectExt<'tcx> {
fn select_in_new_trait_solver( fn select_in_new_trait_solver(
&self, &self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>>; ) -> SelectionResult<'tcx, Selection<'tcx>>;
} }
impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> { impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
fn select_in_new_trait_solver( fn select_in_new_trait_solver(
&self, &self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>> { ) -> SelectionResult<'tcx, Selection<'tcx>> {
assert!(self.next_trait_solver()); assert!(self.next_trait_solver());

View file

@ -95,7 +95,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
tcx, tcx,
ObligationCause::dummy(), ObligationCause::dummy(),
orig_env, orig_env,
ty::Binder::dummy(ty::TraitPredicate { ty::TraitPredicate {
trait_ref, trait_ref,
constness: ty::BoundConstness::NotConst, constness: ty::BoundConstness::NotConst,
polarity: if polarity { polarity: if polarity {
@ -103,7 +103,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
} else { } else {
ImplPolarity::Negative ImplPolarity::Negative
}, },
}), },
)); ));
if let Ok(Some(ImplSource::UserDefined(_))) = result { if let Ok(Some(ImplSource::UserDefined(_))) = result {
debug!( debug!(
@ -292,7 +292,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
new_env, new_env,
pred, pred,
)); ));
let result = select.select(&obligation); let result = select.poly_select(&obligation);
match result { match result {
Ok(Some(ref impl_source)) => { Ok(Some(ref impl_source)) => {

View file

@ -1,7 +1,7 @@
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::infer::{InferCtxt, LateBoundRegionConversionTime}; use rustc_infer::infer::{InferCtxt, LateBoundRegionConversionTime};
use rustc_infer::traits::util::elaborate; use rustc_infer::traits::util::elaborate;
use rustc_infer::traits::{Obligation, ObligationCause, TraitObligation}; use rustc_infer::traits::{Obligation, ObligationCause, PolyTraitObligation};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -14,7 +14,7 @@ pub enum Ambiguity {
pub fn recompute_applicable_impls<'tcx>( pub fn recompute_applicable_impls<'tcx>(
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Vec<Ambiguity> { ) -> Vec<Ambiguity> {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let param_env = obligation.param_env; let param_env = obligation.param_env;

View file

@ -4,7 +4,7 @@ use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::traits::ProjectionCacheKey; use rustc_infer::traits::ProjectionCacheKey;
use rustc_infer::traits::{SelectionError, TraitEngine, TraitObligation}; use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine};
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::error::{ExpectedFound, TypeError};
@ -667,7 +667,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
fn process_trait_obligation( fn process_trait_obligation(
&mut self, &mut self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
trait_obligation: TraitObligation<'tcx>, trait_obligation: PolyTraitObligation<'tcx>,
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>, stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> { ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
let infcx = self.selcx.infcx; let infcx = self.selcx.infcx;
@ -683,7 +683,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
} }
} }
match self.selcx.select(&trait_obligation) { match self.selcx.poly_select(&trait_obligation) {
Ok(Some(impl_source)) => { Ok(Some(impl_source)) => {
debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth); debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth);
ProcessResult::Changed(mk_pending(impl_source.nested_obligations())) ProcessResult::Changed(mk_pending(impl_source.nested_obligations()))

View file

@ -1545,7 +1545,6 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
let trait_def_id = tcx.parent(trait_fn_def_id); let trait_def_id = tcx.parent(trait_fn_def_id);
let trait_substs = let trait_substs =
obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id)); obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
// FIXME(named-returns): Binders
let trait_predicate = ty::TraitRef::new(tcx, trait_def_id, trait_substs); let trait_predicate = ty::TraitRef::new(tcx, trait_def_id, trait_substs);
let _ = selcx.infcx.commit_if_ok(|_| { let _ = selcx.infcx.commit_if_ok(|_| {
@ -1747,8 +1746,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// If we are resolving `<T as TraitRef<...>>::Item == Type`, // If we are resolving `<T as TraitRef<...>>::Item == Type`,
// start out by selecting the predicate `T as TraitRef<...>`: // start out by selecting the predicate `T as TraitRef<...>`:
let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx())); let trait_ref = obligation.predicate.trait_ref(selcx.tcx());
let trait_obligation = obligation.with(selcx.tcx(), poly_trait_ref); let trait_obligation = obligation.with(selcx.tcx(), trait_ref);
let _ = selcx.infcx.commit_if_ok(|_| { let _ = selcx.infcx.commit_if_ok(|_| {
let impl_source = match selcx.select(&trait_obligation) { let impl_source = match selcx.select(&trait_obligation) {
Ok(Some(impl_source)) => impl_source, Ok(Some(impl_source)) => impl_source,
@ -1802,7 +1801,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
if obligation.param_env.reveal() == Reveal::All { if obligation.param_env.reveal() == Reveal::All {
// NOTE(eddyb) inference variables can resolve to parameters, so // NOTE(eddyb) inference variables can resolve to parameters, so
// assume `poly_trait_ref` isn't monomorphic, if it contains any. // assume `poly_trait_ref` isn't monomorphic, if it contains any.
let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(poly_trait_ref); let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref);
!poly_trait_ref.still_further_specializable() !poly_trait_ref.still_further_specializable()
} else { } else {
debug!( debug!(
@ -1821,11 +1820,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
let lang_items = selcx.tcx().lang_items(); let lang_items = selcx.tcx().lang_items();
if [lang_items.gen_trait(), lang_items.future_trait()].contains(&Some(poly_trait_ref.def_id())) if [lang_items.gen_trait(), lang_items.future_trait()].contains(&Some(trait_ref.def_id))
|| selcx.tcx().fn_trait_kind_from_def_id(poly_trait_ref.def_id()).is_some() || selcx.tcx().fn_trait_kind_from_def_id(trait_ref.def_id).is_some()
{ {
true true
} else if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) { } else if lang_items.discriminant_kind_trait() == Some(trait_ref.def_id) {
match self_ty.kind() { match self_ty.kind() {
ty::Bool ty::Bool
| ty::Char | ty::Char
@ -1860,7 +1859,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Infer(..) | ty::Infer(..)
| ty::Error(_) => false, | ty::Error(_) => false,
} }
} else if lang_items.pointee_trait() == Some(poly_trait_ref.def_id()) { } else if lang_items.pointee_trait() == Some(trait_ref.def_id) {
let tail = selcx.tcx().struct_tail_with_normalize( let tail = selcx.tcx().struct_tail_with_normalize(
self_ty, self_ty,
|ty| { |ty| {
@ -1935,7 +1934,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
} }
} }
} else { } else {
bug!("unexpected builtin trait with associated type: {poly_trait_ref:?}") bug!("unexpected builtin trait with associated type: {trait_ref:?}")
} }
} }
super::ImplSource::Param(..) => { super::ImplSource::Param(..) => {

View file

@ -10,7 +10,7 @@ use hir::def_id::DefId;
use hir::LangItem; use hir::LangItem;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TypeVisitableExt};
@ -137,7 +137,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(level = "debug", skip(self, candidates))] #[instrument(level = "debug", skip(self, candidates))]
fn assemble_candidates_from_projected_tys( fn assemble_candidates_from_projected_tys(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// Before we go into the whole placeholder thing, just // Before we go into the whole placeholder thing, just
@ -206,7 +206,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn assemble_generator_candidates( fn assemble_generator_candidates(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// Okay to skip binder because the substs on generator types never // Okay to skip binder because the substs on generator types never
@ -231,7 +231,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn assemble_future_candidates( fn assemble_future_candidates(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
let self_ty = obligation.self_ty().skip_binder(); let self_ty = obligation.self_ty().skip_binder();
@ -254,7 +254,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// unified during the confirmation step. /// unified during the confirmation step.
fn assemble_closure_candidates( fn assemble_closure_candidates(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
let Some(kind) = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()) else { let Some(kind) = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()) else {
@ -292,7 +292,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// Implements one of the `Fn()` family for a fn pointer. /// Implements one of the `Fn()` family for a fn pointer.
fn assemble_fn_pointer_candidates( fn assemble_fn_pointer_candidates(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// We provide impl of all fn traits for fn pointers. // We provide impl of all fn traits for fn pointers.
@ -334,7 +334,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(level = "debug", skip(self, candidates))] #[instrument(level = "debug", skip(self, candidates))]
fn assemble_candidates_from_impls( fn assemble_candidates_from_impls(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// Essentially any user-written impl will match with an error type, // Essentially any user-written impl will match with an error type,
@ -390,7 +390,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn reject_fn_ptr_impls( fn reject_fn_ptr_impls(
&mut self, &mut self,
impl_def_id: DefId, impl_def_id: DefId,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
impl_self_ty: Ty<'tcx>, impl_self_ty: Ty<'tcx>,
) -> bool { ) -> bool {
// Let `impl<T: FnPtr> Trait for Vec<T>` go through the normal rejection path. // Let `impl<T: FnPtr> Trait for Vec<T>` go through the normal rejection path.
@ -475,7 +475,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn assemble_candidates_from_auto_impls( fn assemble_candidates_from_auto_impls(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// Okay to skip binder here because the tests we do below do not involve bound regions. // Okay to skip binder here because the tests we do below do not involve bound regions.
@ -544,7 +544,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// Searches for impls that might apply to `obligation`. /// Searches for impls that might apply to `obligation`.
fn assemble_candidates_from_object_ty( fn assemble_candidates_from_object_ty(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
debug!( debug!(
@ -668,7 +668,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// Searches for unsizing that might apply to `obligation`. /// Searches for unsizing that might apply to `obligation`.
fn assemble_candidates_for_unsizing( fn assemble_candidates_for_unsizing(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// We currently never consider higher-ranked obligations e.g. // We currently never consider higher-ranked obligations e.g.
@ -782,7 +782,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(level = "debug", skip(self, obligation, candidates))] #[instrument(level = "debug", skip(self, obligation, candidates))]
fn assemble_candidates_for_transmutability( fn assemble_candidates_for_transmutability(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
if obligation.predicate.has_non_region_param() { if obligation.predicate.has_non_region_param() {
@ -800,7 +800,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(level = "debug", skip(self, obligation, candidates))] #[instrument(level = "debug", skip(self, obligation, candidates))]
fn assemble_candidates_for_trait_alias( fn assemble_candidates_for_trait_alias(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// Okay to skip binder here because the tests we do below do not involve bound regions. // Okay to skip binder here because the tests we do below do not involve bound regions.
@ -837,7 +837,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn assemble_const_destruct_candidates( fn assemble_const_destruct_candidates(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// If the predicate is `~const Destruct` in a non-const environment, we don't actually need // If the predicate is `~const Destruct` in a non-const environment, we don't actually need
@ -924,7 +924,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn assemble_candidate_for_tuple( fn assemble_candidate_for_tuple(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
@ -966,7 +966,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn assemble_candidate_for_pointer_like( fn assemble_candidate_for_pointer_like(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
// The regions of a type don't affect the size of the type // The regions of a type don't affect the size of the type
@ -991,7 +991,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn assemble_candidates_for_fn_ptr_trait( fn assemble_candidates_for_fn_ptr_trait(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>,
) { ) {
let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); let self_ty = self.infcx.shallow_resolve(obligation.self_ty());

View file

@ -27,8 +27,8 @@ use crate::traits::vtable::{
use crate::traits::{ use crate::traits::{
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, Obligation, ObligationCause, OutputTypeParameterMismatch, PolyTraitObligation,
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, Unimplemented,
}; };
use super::BuiltinImplConditions; use super::BuiltinImplConditions;
@ -42,7 +42,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub(super) fn confirm_candidate( pub(super) fn confirm_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
candidate: SelectionCandidate<'tcx>, candidate: SelectionCandidate<'tcx>,
) -> Result<Selection<'tcx>, SelectionError<'tcx>> { ) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
let mut impl_src = match candidate { let mut impl_src = match candidate {
@ -148,7 +148,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_projection_candidate( fn confirm_projection_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
idx: usize, idx: usize,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let tcx = self.tcx(); let tcx = self.tcx();
@ -215,7 +215,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_param_candidate( fn confirm_param_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
param: ty::PolyTraitRef<'tcx>, param: ty::PolyTraitRef<'tcx>,
) -> Vec<PredicateObligation<'tcx>> { ) -> Vec<PredicateObligation<'tcx>> {
debug!(?obligation, ?param, "confirm_param_candidate"); debug!(?obligation, ?param, "confirm_param_candidate");
@ -238,7 +238,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_builtin_candidate( fn confirm_builtin_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
has_nested: bool, has_nested: bool,
) -> Vec<PredicateObligation<'tcx>> { ) -> Vec<PredicateObligation<'tcx>> {
debug!(?obligation, ?has_nested, "confirm_builtin_candidate"); debug!(?obligation, ?has_nested, "confirm_builtin_candidate");
@ -279,13 +279,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn confirm_transmutability_candidate( fn confirm_transmutability_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
use rustc_transmute::{Answer, Condition}; use rustc_transmute::{Answer, Condition};
#[instrument(level = "debug", skip(tcx, obligation, predicate))] #[instrument(level = "debug", skip(tcx, obligation, predicate))]
fn flatten_answer_tree<'tcx>( fn flatten_answer_tree<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
predicate: TraitPredicate<'tcx>, predicate: TraitPredicate<'tcx>,
cond: Condition<rustc_transmute::layout::rustc::Ref<'tcx>>, cond: Condition<rustc_transmute::layout::rustc::Ref<'tcx>>,
) -> Vec<PredicateObligation<'tcx>> { ) -> Vec<PredicateObligation<'tcx>> {
@ -375,7 +375,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// 2. For each where-clause `C` declared on `Foo`, `[Self => X] C` holds. /// 2. For each where-clause `C` declared on `Foo`, `[Self => X] C` holds.
fn confirm_auto_impl_candidate( fn confirm_auto_impl_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
debug!(?obligation, "confirm_auto_impl_candidate"); debug!(?obligation, "confirm_auto_impl_candidate");
@ -387,7 +387,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// See `confirm_auto_impl_candidate`. /// See `confirm_auto_impl_candidate`.
fn vtable_auto_impl( fn vtable_auto_impl(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
trait_def_id: DefId, trait_def_id: DefId,
nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>, nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
) -> Vec<PredicateObligation<'tcx>> { ) -> Vec<PredicateObligation<'tcx>> {
@ -426,7 +426,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_impl_candidate( fn confirm_impl_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
impl_def_id: DefId, impl_def_id: DefId,
) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> { ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
debug!(?obligation, ?impl_def_id, "confirm_impl_candidate"); debug!(?obligation, ?impl_def_id, "confirm_impl_candidate");
@ -481,7 +481,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_object_candidate( fn confirm_object_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
index: usize, index: usize,
) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let tcx = self.tcx(); let tcx = self.tcx();
@ -655,7 +655,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_fn_pointer_candidate( fn confirm_fn_pointer_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
is_const: bool, is_const: bool,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
debug!(?obligation, "confirm_fn_pointer_candidate"); debug!(?obligation, "confirm_fn_pointer_candidate");
@ -714,7 +714,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_trait_alias_candidate( fn confirm_trait_alias_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Vec<PredicateObligation<'tcx>> { ) -> Vec<PredicateObligation<'tcx>> {
debug!(?obligation, "confirm_trait_alias_candidate"); debug!(?obligation, "confirm_trait_alias_candidate");
@ -739,7 +739,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_generator_candidate( fn confirm_generator_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
// Okay to skip binder because the substs on generator types never // Okay to skip binder because the substs on generator types never
// touch bound regions, they just capture the in-scope // touch bound regions, they just capture the in-scope
@ -778,7 +778,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_future_candidate( fn confirm_future_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
// Okay to skip binder because the substs on generator types never // Okay to skip binder because the substs on generator types never
// touch bound regions, they just capture the in-scope // touch bound regions, they just capture the in-scope
@ -809,7 +809,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn confirm_closure_candidate( fn confirm_closure_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let kind = self let kind = self
.tcx() .tcx()
@ -865,7 +865,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(skip(self), level = "trace")] #[instrument(skip(self), level = "trace")]
fn confirm_poly_trait_refs( fn confirm_poly_trait_refs(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
self_ty_trait_ref: ty::PolyTraitRef<'tcx>, self_ty_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let obligation_trait_ref = obligation.predicate.to_poly_trait_ref(); let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
@ -900,7 +900,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_trait_upcasting_unsize_candidate( fn confirm_trait_upcasting_unsize_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
idx: usize, idx: usize,
) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let tcx = self.tcx(); let tcx = self.tcx();
@ -1004,7 +1004,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_builtin_unsize_candidate( fn confirm_builtin_unsize_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let tcx = self.tcx(); let tcx = self.tcx();
@ -1213,7 +1213,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_const_destruct_candidate( fn confirm_const_destruct_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
impl_def_id: Option<DefId>, impl_def_id: Option<DefId>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
// `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop` // `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`

View file

@ -15,8 +15,8 @@ use super::util::closure_trait_ref_and_return_type;
use super::wf; use super::wf;
use super::{ use super::{
ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation, ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation,
ObligationCause, ObligationCauseCode, Overflow, PredicateObligation, Selection, SelectionError, ObligationCause, ObligationCauseCode, Overflow, PolyTraitObligation, PredicateObligation,
SelectionResult, TraitObligation, TraitQueryMode, Selection, SelectionError, SelectionResult, TraitQueryMode,
}; };
use crate::infer::{InferCtxt, InferOk, TypeFreshener}; use crate::infer::{InferCtxt, InferOk, TypeFreshener};
@ -34,6 +34,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_infer::traits::TraitObligation;
use rustc_middle::dep_graph::{DepKind, DepNodeIndex}; use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::abstract_const::NotConstEvaluatable;
@ -122,7 +123,7 @@ pub struct SelectionContext<'cx, 'tcx> {
// A stack that walks back up the stack frame. // A stack that walks back up the stack frame.
struct TraitObligationStack<'prev, 'tcx> { struct TraitObligationStack<'prev, 'tcx> {
obligation: &'prev TraitObligation<'tcx>, obligation: &'prev PolyTraitObligation<'tcx>,
/// The trait predicate from `obligation` but "freshened" with the /// The trait predicate from `obligation` but "freshened" with the
/// selection-context's freshener. Used to check for recursion. /// selection-context's freshener. Used to check for recursion.
@ -259,9 +260,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// Attempts to satisfy the obligation. If successful, this will affect the surrounding /// Attempts to satisfy the obligation. If successful, this will affect the surrounding
/// type environment by performing unification. /// type environment by performing unification.
#[instrument(level = "debug", skip(self), ret)] #[instrument(level = "debug", skip(self), ret)]
pub fn select( pub fn poly_select(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>> { ) -> SelectionResult<'tcx, Selection<'tcx>> {
if self.infcx.next_trait_solver() { if self.infcx.next_trait_solver() {
return self.infcx.select_in_new_trait_solver(obligation); return self.infcx.select_in_new_trait_solver(obligation);
@ -293,9 +294,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
} }
fn select_from_obligation( pub fn select(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &TraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>> {
self.poly_select(&Obligation {
cause: obligation.cause.clone(),
param_env: obligation.param_env,
predicate: ty::Binder::dummy(obligation.predicate),
recursion_depth: obligation.recursion_depth,
})
}
fn select_from_obligation(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
debug_assert!(!obligation.predicate.has_escaping_bound_vars()); debug_assert!(!obligation.predicate.has_escaping_bound_vars());
@ -612,7 +625,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation: PredicateObligation<'tcx>, obligation: PredicateObligation<'tcx>,
) -> Result<EvaluationResult, OverflowError> { ) -> Result<EvaluationResult, OverflowError> {
debug_assert!(!self.infcx.next_trait_solver()); debug_assert!(!self.infcx.next_trait_solver());
// `previous_stack` stores a `TraitObligation`, while `obligation` is // `previous_stack` stores a `PolyTraitObligation`, while `obligation` is
// a `PredicateObligation`. These are distinct types, so we can't // a `PredicateObligation`. These are distinct types, so we can't
// use any `Option` combinator method that would force them to be // use any `Option` combinator method that would force them to be
// the same. // the same.
@ -973,7 +986,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn evaluate_trait_predicate_recursively<'o>( fn evaluate_trait_predicate_recursively<'o>(
&mut self, &mut self,
previous_stack: TraitObligationStackList<'o, 'tcx>, previous_stack: TraitObligationStackList<'o, 'tcx>,
mut obligation: TraitObligation<'tcx>, mut obligation: PolyTraitObligation<'tcx>,
) -> Result<EvaluationResult, OverflowError> { ) -> Result<EvaluationResult, OverflowError> {
if !self.is_intercrate() if !self.is_intercrate()
&& obligation.is_global() && obligation.is_global()
@ -1379,7 +1392,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn filter_impls( fn filter_impls(
&mut self, &mut self,
candidates: Vec<SelectionCandidate<'tcx>>, candidates: Vec<SelectionCandidate<'tcx>>,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Vec<SelectionCandidate<'tcx>> { ) -> Vec<SelectionCandidate<'tcx>> {
trace!("{candidates:#?}"); trace!("{candidates:#?}");
let tcx = self.tcx(); let tcx = self.tcx();
@ -1442,7 +1455,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn filter_reservation_impls( fn filter_reservation_impls(
&mut self, &mut self,
candidate: SelectionCandidate<'tcx>, candidate: SelectionCandidate<'tcx>,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
let tcx = self.tcx(); let tcx = self.tcx();
// Treat reservation impls as ambiguity. // Treat reservation impls as ambiguity.
@ -1614,7 +1627,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(level = "debug", skip(self), ret)] #[instrument(level = "debug", skip(self), ret)]
fn match_projection_obligation_against_definition_bounds( fn match_projection_obligation_against_definition_bounds(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> { ) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> {
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
let placeholder_trait_predicate = let placeholder_trait_predicate =
@ -1677,7 +1690,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// variables or placeholders, the normalized bound is returned. /// variables or placeholders, the normalized bound is returned.
fn match_normalize_trait_ref( fn match_normalize_trait_ref(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
trait_bound: ty::PolyTraitRef<'tcx>, trait_bound: ty::PolyTraitRef<'tcx>,
placeholder_trait_ref: ty::TraitRef<'tcx>, placeholder_trait_ref: ty::TraitRef<'tcx>,
) -> Result<Option<ty::PolyTraitRef<'tcx>>, ()> { ) -> Result<Option<ty::PolyTraitRef<'tcx>>, ()> {
@ -2078,7 +2091,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
impl<'tcx> SelectionContext<'_, 'tcx> { impl<'tcx> SelectionContext<'_, 'tcx> {
fn sized_conditions( fn sized_conditions(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> BuiltinImplConditions<'tcx> { ) -> BuiltinImplConditions<'tcx> {
use self::BuiltinImplConditions::{Ambiguous, None, Where}; use self::BuiltinImplConditions::{Ambiguous, None, Where};
@ -2138,7 +2151,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
fn copy_clone_conditions( fn copy_clone_conditions(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> BuiltinImplConditions<'tcx> { ) -> BuiltinImplConditions<'tcx> {
// NOTE: binder moved to (*) // NOTE: binder moved to (*)
let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
@ -2414,7 +2427,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
fn rematch_impl( fn rematch_impl(
&mut self, &mut self,
impl_def_id: DefId, impl_def_id: DefId,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Normalized<'tcx, SubstsRef<'tcx>> { ) -> Normalized<'tcx, SubstsRef<'tcx>> {
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
match self.match_impl(impl_def_id, impl_trait_ref, obligation) { match self.match_impl(impl_def_id, impl_trait_ref, obligation) {
@ -2452,7 +2465,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
&mut self, &mut self,
impl_def_id: DefId, impl_def_id: DefId,
impl_trait_ref: EarlyBinder<ty::TraitRef<'tcx>>, impl_trait_ref: EarlyBinder<ty::TraitRef<'tcx>>,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> { ) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
let placeholder_obligation = let placeholder_obligation =
self.infcx.instantiate_binder_with_placeholders(obligation.predicate); self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
@ -2510,7 +2523,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
/// result from the normalization. /// result from the normalization.
fn match_where_clause_trait_ref( fn match_where_clause_trait_ref(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
where_clause_trait_ref: ty::PolyTraitRef<'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, ()> { ) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
self.match_poly_trait_ref(obligation, where_clause_trait_ref) self.match_poly_trait_ref(obligation, where_clause_trait_ref)
@ -2521,7 +2534,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn match_poly_trait_ref( fn match_poly_trait_ref(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
poly_trait_ref: ty::PolyTraitRef<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, ()> { ) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
self.infcx self.infcx
@ -2547,7 +2560,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
fn push_stack<'o>( fn push_stack<'o>(
&mut self, &mut self,
previous_stack: TraitObligationStackList<'o, 'tcx>, previous_stack: TraitObligationStackList<'o, 'tcx>,
obligation: &'o TraitObligation<'tcx>, obligation: &'o PolyTraitObligation<'tcx>,
) -> TraitObligationStack<'o, 'tcx> { ) -> TraitObligationStack<'o, 'tcx> {
let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener); let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener);
@ -2566,7 +2579,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn closure_trait_ref_unnormalized( fn closure_trait_ref_unnormalized(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
) -> ty::PolyTraitRef<'tcx> { ) -> ty::PolyTraitRef<'tcx> {
let closure_sig = substs.as_closure().sig(); let closure_sig = substs.as_closure().sig();

View file

@ -362,7 +362,7 @@ pub(crate) fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>(
let trait_ref = ty::TraitRef::new(tcx, unsize_trait_did, [source, target]); let trait_ref = ty::TraitRef::new(tcx, unsize_trait_did, [source, target]);
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) { match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => {
implsrc_traitcasting.vtable_vptr_slot implsrc_traitcasting.vtable_vptr_slot
} }

View file

@ -22,7 +22,7 @@ use rustc_trait_selection::traits::{
/// This also expects that `trait_ref` is fully normalized. /// This also expects that `trait_ref` is fully normalized.
pub fn codegen_select_candidate<'tcx>( pub fn codegen_select_candidate<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>), (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>),
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
// We expect the input to be fully normalized. // We expect the input to be fully normalized.
debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref)); debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref));

View file

@ -80,7 +80,7 @@ fn resolve_associated_item<'tcx>(
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs); let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
let vtbl = match tcx.codegen_select_candidate((param_env, ty::Binder::dummy(trait_ref))) { let vtbl = match tcx.codegen_select_candidate((param_env, trait_ref)) {
Ok(vtbl) => vtbl, Ok(vtbl) => vtbl,
Err(CodegenObligationError::Ambiguity) => { Err(CodegenObligationError::Ambiguity) => {
let reported = tcx.sess.delay_span_bug( let reported = tcx.sess.delay_span_bug(