Separate select calls that don't need a binder

This commit is contained in:
Michael Goulet 2023-07-03 22:23:37 +00:00
parent 36453456cb
commit 52f7384995
15 changed files with 58 additions and 44 deletions

View file

@ -4,7 +4,7 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
use rustc_infer::traits::util::supertraits;
use rustc_infer::traits::{
Obligation, PredicateObligation, Selection, SelectionResult, PolyTraitObligation,
Obligation, PolyTraitObligation, PredicateObligation, Selection, SelectionResult,
};
use rustc_middle::traits::solve::{CanonicalInput, Certainty, Goal};
use rustc_middle::traits::{

View file

@ -91,7 +91,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
for polarity in [true, false] {
let result = selcx.select(&Obligation::new(
let result = selcx.poly_select(&Obligation::new(
tcx,
ObligationCause::dummy(),
orig_env,
@ -292,7 +292,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
new_env,
pred,
));
let result = select.select(&obligation);
let result = select.poly_select(&obligation);
match result {
Ok(Some(ref impl_source)) => {

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_infer::infer::DefineOpaqueTypes;
use rustc_infer::traits::ProjectionCacheKey;
use rustc_infer::traits::{SelectionError, TraitEngine, PolyTraitObligation};
use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine};
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
@ -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)) => {
debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth);
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_substs =
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 _ = 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`,
// start out by selecting the predicate `T as TraitRef<...>`:
let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx()));
let trait_obligation = obligation.with(selcx.tcx(), poly_trait_ref);
let trait_ref = obligation.predicate.trait_ref(selcx.tcx());
let trait_obligation = obligation.with(selcx.tcx(), trait_ref);
let _ = selcx.infcx.commit_if_ok(|_| {
let impl_source = match selcx.select(&trait_obligation) {
Ok(Some(impl_source)) => impl_source,
@ -1802,7 +1801,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
if obligation.param_env.reveal() == Reveal::All {
// NOTE(eddyb) inference variables can resolve to parameters, so
// 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()
} else {
debug!(
@ -1821,11 +1820,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
let lang_items = selcx.tcx().lang_items();
if [lang_items.gen_trait(), lang_items.future_trait()].contains(&Some(poly_trait_ref.def_id()))
|| selcx.tcx().fn_trait_kind_from_def_id(poly_trait_ref.def_id()).is_some()
if [lang_items.gen_trait(), lang_items.future_trait()].contains(&Some(trait_ref.def_id))
|| selcx.tcx().fn_trait_kind_from_def_id(trait_ref.def_id).is_some()
{
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() {
ty::Bool
| ty::Char
@ -1860,7 +1859,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Infer(..)
| 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(
self_ty,
|ty| {
@ -1935,7 +1934,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
}
}
} else {
bug!("unexpected builtin trait with associated type: {poly_trait_ref:?}")
bug!("unexpected builtin trait with associated type: {trait_ref:?}")
}
}
super::ImplSource::Param(..) => {

View file

@ -10,7 +10,7 @@ use hir::def_id::DefId;
use hir::LangItem;
use rustc_hir as hir;
use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{Obligation, SelectionError, PolyTraitObligation};
use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
@ -20,7 +20,7 @@ use crate::traits::util;
use super::BuiltinImplConditions;
use super::SelectionCandidate::*;
use super::{SelectionCandidateSet, SelectionContext, PolyTraitObligationStack};
use super::{SelectionCandidateSet, SelectionContext, TraitObligationStack};
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(skip(self, stack), level = "debug")]

View file

@ -27,8 +27,8 @@ use crate::traits::vtable::{
use crate::traits::{
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
SelectionError, TraitNotObjectSafe, PolyTraitObligation, Unimplemented,
Obligation, ObligationCause, OutputTypeParameterMismatch, PolyTraitObligation,
PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, Unimplemented,
};
use super::BuiltinImplConditions;

View file

@ -15,8 +15,8 @@ use super::util::closure_trait_ref_and_return_type;
use super::wf;
use super::{
ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation,
ObligationCause, ObligationCauseCode, Overflow, PredicateObligation, Selection, SelectionError,
SelectionResult, PolyTraitObligation, TraitQueryMode,
ObligationCause, ObligationCauseCode, Overflow, PolyTraitObligation, PredicateObligation,
Selection, SelectionError, SelectionResult, TraitQueryMode,
};
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
@ -34,6 +34,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_infer::traits::TraitObligation;
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
@ -259,7 +260,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// Attempts to satisfy the obligation. If successful, this will affect the surrounding
/// type environment by performing unification.
#[instrument(level = "debug", skip(self), ret)]
pub fn select(
pub fn poly_select(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>> {
@ -293,6 +294,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
pub fn select(
&mut self,
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>,
@ -1471,7 +1484,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Ok(Some(candidate))
}
fn is_knowable<'o>(&mut self, stack: &PolyTraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
debug!("is_knowable(intercrate={:?})", self.is_intercrate());
if !self.is_intercrate() || stack.obligation.polarity() == ty::ImplPolarity::Negative {
@ -2929,9 +2942,9 @@ struct TraitObligationStackList<'o, 'tcx> {
head: Option<&'o TraitObligationStack<'o, 'tcx>>,
}
impl<'o, 'tcx> PolyTraitObligationStackList<'o, 'tcx> {
fn empty(cache: &'o ProvisionalEvaluationCache<'tcx>) -> PolyTraitObligationStackList<'o, 'tcx> {
PolyTraitObligationStackList { cache, head: None }
impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> {
fn empty(cache: &'o ProvisionalEvaluationCache<'tcx>) -> TraitObligationStackList<'o, 'tcx> {
TraitObligationStackList { cache, head: None }
}
fn with(r: &'o TraitObligationStack<'o, 'tcx>) -> TraitObligationStackList<'o, 'tcx> {