mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Separate select calls that don't need a binder
This commit is contained in:
parent
36453456cb
commit
52f7384995
@ -10,7 +10,7 @@ use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceC
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
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_span::{sym, Span, Symbol};
|
||||
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 poly_trait_pred =
|
||||
Binder::dummy(trait_ref).with_constness(ty::BoundConstness::ConstIfConst);
|
||||
let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
|
||||
let obligation =
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, poly_trait_pred);
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||
|
||||
let implsrc = {
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
@ -776,11 +775,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
}
|
||||
// Closure: Fn{Once|Mut}
|
||||
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() =>
|
||||
{
|
||||
let ty::Closure(closure_def_id, substs) =
|
||||
*poly_trait_pred.self_ty().no_bound_vars().unwrap().kind()
|
||||
*trait_ref.self_ty().kind()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
@ -840,7 +839,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
tcx,
|
||||
ObligationCause::dummy_with_span(*fn_span),
|
||||
param_env,
|
||||
poly_trait_pred,
|
||||
trait_ref,
|
||||
);
|
||||
|
||||
// improve diagnostics by showing what failed. Our requirements are stricter this time
|
||||
|
@ -10,8 +10,8 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
||||
use rustc_middle::mir::{self, CallSource};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
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::{Binder, TraitRef};
|
||||
use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
@ -137,12 +137,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
}
|
||||
}
|
||||
Adt(..) => {
|
||||
let obligation = Obligation::new(
|
||||
tcx,
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
Binder::dummy(trait_ref),
|
||||
);
|
||||
let obligation =
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
|
@ -659,7 +659,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
|
||||
match selcx.poly_select(&obligation.with(selcx.tcx(), trait_pred)) {
|
||||
// Uncertain or unimplemented.
|
||||
Ok(None) => {
|
||||
if trait_pred.def_id() == unsize_did {
|
||||
|
@ -1982,7 +1982,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.tcx,
|
||||
traits::ObligationCause::dummy(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(trait_ref),
|
||||
trait_ref,
|
||||
);
|
||||
match SelectionContext::new(&self).select(&obligation) {
|
||||
Ok(Some(traits::ImplSource::UserDefined(impl_source))) => {
|
||||
|
@ -1441,8 +1441,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
trait_ref: ty::TraitRef<'tcx>,
|
||||
) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> {
|
||||
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, predicate);
|
||||
let obligation = traits::Obligation::new(self.tcx, cause, self.param_env, trait_ref);
|
||||
traits::SelectionContext::new(self).select(&obligation)
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@ impl<'tcx, P> From<Obligation<'tcx, P>> for solve::Goal<'tcx, P> {
|
||||
}
|
||||
|
||||
pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
|
||||
pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>;
|
||||
pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
|
||||
|
||||
impl<'tcx> PredicateObligation<'tcx> {
|
||||
|
@ -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> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
|
||||
|
@ -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::{
|
||||
|
@ -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)) => {
|
||||
|
@ -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()))
|
||||
|
@ -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(..) => {
|
||||
|
@ -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")]
|
||||
|
@ -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;
|
||||
|
@ -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> {
|
||||
|
@ -35,7 +35,7 @@ pub fn codegen_select_candidate<'tcx>(
|
||||
let obligation_cause = ObligationCause::dummy();
|
||||
let obligation = Obligation::new(tcx, obligation_cause, param_env, trait_ref);
|
||||
|
||||
let selection = match selcx.select(&obligation) {
|
||||
let selection = match selcx.poly_select(&obligation) {
|
||||
Ok(Some(selection)) => selection,
|
||||
Ok(None) => return Err(CodegenObligationError::Ambiguity),
|
||||
Err(Unimplemented) => return Err(CodegenObligationError::Unimplemented),
|
||||
|
Loading…
Reference in New Issue
Block a user