Auto merge of #128776 - Bryanskiy:deep-reject-ctxt, r=lcnr
Use `DeepRejectCtxt` to quickly reject `ParamEnv` candidates The description is on the [zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types/topic/.5Basking.20for.20help.5D.20.60DeepRejectCtxt.60.20for.20param.20env.20candidates) r? `@lcnr`
This commit is contained in:
commit
26b5599e4d
16 changed files with 287 additions and 167 deletions
|
@ -4,7 +4,7 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::print::{FmtPrinter, Printer};
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
|
||||
use rustc_span::def_id::DefId;
|
||||
|
@ -317,7 +317,7 @@ impl<T> Trait<T> for X {
|
|||
{
|
||||
let mut has_matching_impl = false;
|
||||
tcx.for_each_relevant_impl(def_id, values.found, |did| {
|
||||
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
|
||||
if DeepRejectCtxt::relate_rigid_infer(tcx)
|
||||
.types_may_unify(values.found, tcx.type_of(did).skip_binder())
|
||||
{
|
||||
has_matching_impl = true;
|
||||
|
@ -338,7 +338,7 @@ impl<T> Trait<T> for X {
|
|||
{
|
||||
let mut has_matching_impl = false;
|
||||
tcx.for_each_relevant_impl(def_id, values.expected, |did| {
|
||||
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
|
||||
if DeepRejectCtxt::relate_rigid_infer(tcx)
|
||||
.types_may_unify(values.expected, tcx.type_of(did).skip_binder())
|
||||
{
|
||||
has_matching_impl = true;
|
||||
|
@ -358,7 +358,7 @@ impl<T> Trait<T> for X {
|
|||
{
|
||||
let mut has_matching_impl = false;
|
||||
tcx.for_each_relevant_impl(def_id, values.found, |did| {
|
||||
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
|
||||
if DeepRejectCtxt::relate_rigid_infer(tcx)
|
||||
.types_may_unify(values.found, tcx.type_of(did).skip_binder())
|
||||
{
|
||||
has_matching_impl = true;
|
||||
|
|
|
@ -15,7 +15,7 @@ use rustc_middle::bug;
|
|||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
|
||||
use rustc_middle::traits::specialization_graph::OverlapMode;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
pub use rustc_next_trait_solver::coherence::*;
|
||||
|
@ -96,7 +96,7 @@ pub fn overlapping_impls(
|
|||
// Before doing expensive operations like entering an inference context, do
|
||||
// a quick check via fast_reject to tell if the impl headers could possibly
|
||||
// unify.
|
||||
let drcx = DeepRejectCtxt::new(tcx, TreatParams::AsCandidateKey);
|
||||
let drcx = DeepRejectCtxt::relate_infer_infer(tcx);
|
||||
let impl1_ref = tcx.impl_trait_ref(impl1_def_id);
|
||||
let impl2_ref = tcx.impl_trait_ref(impl2_def_id);
|
||||
let may_overlap = match (impl1_ref, impl2_ref) {
|
||||
|
|
|
@ -13,6 +13,7 @@ use rustc_infer::traits::ObligationCauseCode;
|
|||
use rustc_middle::traits::select::OverflowError;
|
||||
pub use rustc_middle::traits::Reveal;
|
||||
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, Term, Ty, TyCtxt, Upcast};
|
||||
|
@ -886,6 +887,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
|
|||
potentially_unnormalized_candidates: bool,
|
||||
) {
|
||||
let infcx = selcx.infcx;
|
||||
let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx());
|
||||
for predicate in env_predicates {
|
||||
let bound_predicate = predicate.kind();
|
||||
if let ty::ClauseKind::Projection(data) = predicate.kind().skip_binder() {
|
||||
|
@ -894,6 +896,12 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
|
|||
continue;
|
||||
}
|
||||
|
||||
if !drcx
|
||||
.args_may_unify(obligation.predicate.args, data.skip_binder().projection_term.args)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let is_match = infcx.probe(|_| {
|
||||
selcx.match_projection_projections(
|
||||
obligation,
|
||||
|
|
|
@ -13,7 +13,7 @@ use hir::LangItem;
|
|||
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::{Obligation, ObligationCause, PolyTraitObligation, SelectionError};
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
@ -248,11 +248,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
.filter(|p| p.def_id() == stack.obligation.predicate.def_id())
|
||||
.filter(|p| p.polarity() == stack.obligation.predicate.polarity());
|
||||
|
||||
let drcx = DeepRejectCtxt::relate_rigid_rigid(self.tcx());
|
||||
let obligation_args = stack.obligation.predicate.skip_binder().trait_ref.args;
|
||||
// Keep only those bounds which may apply, and propagate overflow if it occurs.
|
||||
for bound in bounds {
|
||||
let bound_trait_ref = bound.map_bound(|t| t.trait_ref);
|
||||
if !drcx.args_may_unify(obligation_args, bound_trait_ref.skip_binder().args) {
|
||||
continue;
|
||||
}
|
||||
// FIXME(oli-obk): it is suspicious that we are dropping the constness and
|
||||
// polarity here.
|
||||
let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?;
|
||||
let wc = self.where_clause_may_apply(stack, bound_trait_ref)?;
|
||||
if wc.may_apply() {
|
||||
candidates.vec.push(ParamCandidate(bound));
|
||||
}
|
||||
|
@ -581,7 +587,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
let drcx = DeepRejectCtxt::new(self.tcx(), TreatParams::ForLookup);
|
||||
let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx());
|
||||
let obligation_args = obligation.predicate.skip_binder().trait_ref.args;
|
||||
self.tcx().for_each_relevant_impl(
|
||||
obligation.predicate.def_id(),
|
||||
|
|
|
@ -41,7 +41,7 @@ impl<'tcx> Children {
|
|||
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
|
||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
|
||||
if let Some(st) =
|
||||
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
|
||||
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer)
|
||||
{
|
||||
debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
|
||||
self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
|
||||
|
@ -58,7 +58,7 @@ impl<'tcx> Children {
|
|||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
|
||||
let vec: &mut Vec<DefId>;
|
||||
if let Some(st) =
|
||||
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
|
||||
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer)
|
||||
{
|
||||
debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
|
||||
vec = self.non_blanket_impls.get_mut(&st).unwrap();
|
||||
|
@ -279,7 +279,7 @@ impl<'tcx> Graph {
|
|||
let mut parent = trait_def_id;
|
||||
let mut last_lint = None;
|
||||
let simplified =
|
||||
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey);
|
||||
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer);
|
||||
|
||||
// Descend the specialization tree, where `parent` is the current parent node.
|
||||
loop {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue