Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c190066

Browse files
committedSep 3, 2024
Auto merge of rust-lang#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`
2 parents d6c8169 + c51953f commit c190066

File tree

16 files changed

+272
-152
lines changed

16 files changed

+272
-152
lines changed
 

‎compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ impl<'tcx> InherentCollect<'tcx> {
9393
}
9494
}
9595

96-
if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) {
96+
if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer)
97+
{
9798
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
9899
} else {
99100
bug!("unexpected self type: {:?}", self_ty);
@@ -132,7 +133,7 @@ impl<'tcx> InherentCollect<'tcx> {
132133
}
133134
}
134135

135-
if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::AsCandidateKey) {
136+
if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::InstantiateWithInfer) {
136137
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
137138
} else {
138139
bug!("unexpected primitive type: {:?}", ty);

‎compiler/rustc_hir_typeck/src/method/probe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
715715
}
716716

717717
fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
718-
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) else {
718+
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else {
719719
bug!("unexpected incoherent type: {:?}", self_ty)
720720
};
721721
for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter().flatten() {

‎compiler/rustc_hir_typeck/src/method/suggest.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -2235,8 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22352235
let target_ty = self
22362236
.autoderef(sugg_span, rcvr_ty)
22372237
.find(|(rcvr_ty, _)| {
2238-
DeepRejectCtxt::new(self.tcx, TreatParams::ForLookup)
2239-
.types_may_unify(*rcvr_ty, impl_ty)
2238+
DeepRejectCtxt::relate_rigid_infer(self.tcx).types_may_unify(*rcvr_ty, impl_ty)
22402239
})
22412240
.map_or(impl_ty, |(ty, _)| ty)
22422241
.peel_refs();
@@ -2498,7 +2497,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24982497
.into_iter()
24992498
.any(|info| self.associated_value(info.def_id, item_name).is_some());
25002499
let found_assoc = |ty: Ty<'tcx>| {
2501-
simplify_type(tcx, ty, TreatParams::AsCandidateKey)
2500+
simplify_type(tcx, ty, TreatParams::InstantiateWithInfer)
25022501
.and_then(|simp| {
25032502
tcx.incoherent_impls(simp)
25042503
.into_iter()
@@ -3963,7 +3962,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39633962
// cases where a positive bound implies a negative impl.
39643963
(candidates, Vec::new())
39653964
} else if let Some(simp_rcvr_ty) =
3966-
simplify_type(self.tcx, rcvr_ty, TreatParams::ForLookup)
3965+
simplify_type(self.tcx, rcvr_ty, TreatParams::AsRigid)
39673966
{
39683967
let mut potential_candidates = Vec::new();
39693968
let mut explicitly_negative = Vec::new();
@@ -3981,7 +3980,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39813980
.any(|header| {
39823981
let imp = header.trait_ref.instantiate_identity();
39833982
let imp_simp =
3984-
simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
3983+
simplify_type(self.tcx, imp.self_ty(), TreatParams::AsRigid);
39853984
imp_simp.is_some_and(|s| s == simp_rcvr_ty)
39863985
})
39873986
{

‎compiler/rustc_metadata/src/rmeta/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2033,7 +2033,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
20332033
let simplified_self_ty = fast_reject::simplify_type(
20342034
self.tcx,
20352035
trait_ref.self_ty(),
2036-
TreatParams::AsCandidateKey,
2036+
TreatParams::InstantiateWithInfer,
20372037
);
20382038
trait_impls
20392039
.entry(trait_ref.def_id)

‎compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
426426
let simp = ty::fast_reject::simplify_type(
427427
tcx,
428428
self_ty,
429-
ty::fast_reject::TreatParams::ForLookup,
429+
ty::fast_reject::TreatParams::AsRigid,
430430
)
431431
.unwrap();
432432
consider_impls_for_simplified_type(simp);

‎compiler/rustc_middle/src/ty/fast_reject.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ pub use rustc_type_ir::fast_reject::*;
33

44
use super::TyCtxt;
55

6-
pub type DeepRejectCtxt<'tcx> = rustc_type_ir::fast_reject::DeepRejectCtxt<TyCtxt<'tcx>>;
6+
pub type DeepRejectCtxt<
7+
'tcx,
8+
const INSTANTIATE_LHS_WITH_INFER: bool,
9+
const INSTANTIATE_RHS_WITH_INFER: bool,
10+
> = rustc_type_ir::fast_reject::DeepRejectCtxt<
11+
TyCtxt<'tcx>,
12+
INSTANTIATE_LHS_WITH_INFER,
13+
INSTANTIATE_RHS_WITH_INFER,
14+
>;
715

816
pub type SimplifiedType = rustc_type_ir::fast_reject::SimplifiedType<DefId>;

‎compiler/rustc_middle/src/ty/trait_def.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,9 @@ impl<'tcx> TyCtxt<'tcx> {
168168
// whose outer level is not a parameter or projection. Especially for things like
169169
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
170170
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
171-
// Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
172-
// `TreatParams::AsCandidateKey` while actually adding them.
173-
if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::ForLookup) {
171+
// Note that we're using `TreatParams::AsRigid` to query `non_blanket_impls` while using
172+
// `TreatParams::InstantiateWithInfer` while actually adding them.
173+
if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsRigid) {
174174
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
175175
for &impl_def_id in impls {
176176
f(impl_def_id);
@@ -190,7 +190,9 @@ impl<'tcx> TyCtxt<'tcx> {
190190
self_ty: Ty<'tcx>,
191191
) -> impl Iterator<Item = DefId> + 'tcx {
192192
let impls = self.trait_impls_of(trait_def_id);
193-
if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) {
193+
if let Some(simp) =
194+
fast_reject::simplify_type(self, self_ty, TreatParams::InstantiateWithInfer)
195+
{
194196
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
195197
return impls.iter().copied();
196198
}
@@ -239,7 +241,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
239241
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
240242

241243
if let Some(simplified_self_ty) =
242-
fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::AsCandidateKey)
244+
fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::InstantiateWithInfer)
243245
{
244246
impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
245247
} else {

‎compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mod inherent;
33
mod opaque_types;
44
mod weak_types;
55

6-
use rustc_type_ir::fast_reject::{DeepRejectCtxt, TreatParams};
6+
use rustc_type_ir::fast_reject::DeepRejectCtxt;
77
use rustc_type_ir::inherent::*;
88
use rustc_type_ir::lang_items::TraitSolverLangItem;
99
use rustc_type_ir::{self as ty, Interner, NormalizesTo, Upcast as _};
@@ -106,6 +106,12 @@ where
106106
if let Some(projection_pred) = assumption.as_projection_clause() {
107107
if projection_pred.projection_def_id() == goal.predicate.def_id() {
108108
let cx = ecx.cx();
109+
if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
110+
goal.predicate.alias.args,
111+
projection_pred.skip_binder().projection_term.args,
112+
) {
113+
return Err(NoSolution);
114+
}
109115
ecx.probe_trait_candidate(source).enter(|ecx| {
110116
let assumption_projection_pred =
111117
ecx.instantiate_binder_with_infer(projection_pred);
@@ -144,7 +150,7 @@ where
144150

145151
let goal_trait_ref = goal.predicate.alias.trait_ref(cx);
146152
let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
147-
if !DeepRejectCtxt::new(ecx.cx(), TreatParams::ForLookup).args_may_unify(
153+
if !DeepRejectCtxt::relate_rigid_infer(ecx.cx()).args_may_unify(
148154
goal.predicate.alias.trait_ref(cx).args,
149155
impl_trait_ref.skip_binder().args,
150156
) {

‎compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use rustc_ast_ir::Movability;
44
use rustc_type_ir::data_structures::IndexSet;
5-
use rustc_type_ir::fast_reject::{DeepRejectCtxt, TreatParams};
5+
use rustc_type_ir::fast_reject::DeepRejectCtxt;
66
use rustc_type_ir::inherent::*;
77
use rustc_type_ir::lang_items::TraitSolverLangItem;
88
use rustc_type_ir::visit::TypeVisitableExt as _;
@@ -47,7 +47,7 @@ where
4747
let cx = ecx.cx();
4848

4949
let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
50-
if !DeepRejectCtxt::new(ecx.cx(), TreatParams::ForLookup)
50+
if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
5151
.args_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args)
5252
{
5353
return Err(NoSolution);
@@ -124,6 +124,13 @@ where
124124
if trait_clause.def_id() == goal.predicate.def_id()
125125
&& trait_clause.polarity() == goal.predicate.polarity
126126
{
127+
if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
128+
goal.predicate.trait_ref.args,
129+
trait_clause.skip_binder().trait_ref.args,
130+
) {
131+
return Err(NoSolution);
132+
}
133+
127134
ecx.probe_trait_candidate(source).enter(|ecx| {
128135
let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
129136
ecx.eq(

‎compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_hir as hir;
44
use rustc_hir::def::DefKind;
55
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
66
use rustc_middle::ty::error::{ExpectedFound, TypeError};
7-
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
7+
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
88
use rustc_middle::ty::print::{FmtPrinter, Printer};
99
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
1010
use rustc_span::def_id::DefId;
@@ -317,7 +317,7 @@ impl<T> Trait<T> for X {
317317
{
318318
let mut has_matching_impl = false;
319319
tcx.for_each_relevant_impl(def_id, values.found, |did| {
320-
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
320+
if DeepRejectCtxt::relate_rigid_infer(tcx)
321321
.types_may_unify(values.found, tcx.type_of(did).skip_binder())
322322
{
323323
has_matching_impl = true;
@@ -338,7 +338,7 @@ impl<T> Trait<T> for X {
338338
{
339339
let mut has_matching_impl = false;
340340
tcx.for_each_relevant_impl(def_id, values.expected, |did| {
341-
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
341+
if DeepRejectCtxt::relate_rigid_infer(tcx)
342342
.types_may_unify(values.expected, tcx.type_of(did).skip_binder())
343343
{
344344
has_matching_impl = true;
@@ -358,7 +358,7 @@ impl<T> Trait<T> for X {
358358
{
359359
let mut has_matching_impl = false;
360360
tcx.for_each_relevant_impl(def_id, values.found, |did| {
361-
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
361+
if DeepRejectCtxt::relate_rigid_infer(tcx)
362362
.types_may_unify(values.found, tcx.type_of(did).skip_binder())
363363
{
364364
has_matching_impl = true;

‎compiler/rustc_trait_selection/src/traits/coherence.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_middle::bug;
1515
use rustc_middle::traits::query::NoSolution;
1616
use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
1717
use rustc_middle::traits::specialization_graph::OverlapMode;
18-
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
18+
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
1919
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
2020
use rustc_middle::ty::{self, Ty, TyCtxt};
2121
pub use rustc_next_trait_solver::coherence::*;
@@ -95,7 +95,7 @@ pub fn overlapping_impls(
9595
// Before doing expensive operations like entering an inference context, do
9696
// a quick check via fast_reject to tell if the impl headers could possibly
9797
// unify.
98-
let drcx = DeepRejectCtxt::new(tcx, TreatParams::AsCandidateKey);
98+
let drcx = DeepRejectCtxt::relate_infer_infer(tcx);
9999
let impl1_ref = tcx.impl_trait_ref(impl1_def_id);
100100
let impl2_ref = tcx.impl_trait_ref(impl2_def_id);
101101
let may_overlap = match (impl1_ref, impl2_ref) {

‎compiler/rustc_trait_selection/src/traits/project.rs

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_infer::traits::ObligationCauseCode;
1313
use rustc_middle::traits::select::OverflowError;
1414
pub use rustc_middle::traits::Reveal;
1515
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
16+
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
1617
use rustc_middle::ty::fold::TypeFoldable;
1718
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
1819
use rustc_middle::ty::{self, Term, Ty, TyCtxt, Upcast};
@@ -886,6 +887,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
886887
potentially_unnormalized_candidates: bool,
887888
) {
888889
let infcx = selcx.infcx;
890+
let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx());
889891
for predicate in env_predicates {
890892
let bound_predicate = predicate.kind();
891893
if let ty::ClauseKind::Projection(data) = predicate.kind().skip_binder() {
@@ -894,6 +896,12 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
894896
continue;
895897
}
896898

899+
if !drcx
900+
.args_may_unify(obligation.predicate.args, data.skip_binder().projection_term.args)
901+
{
902+
continue;
903+
}
904+
897905
let is_match = infcx.probe(|_| {
898906
selcx.match_projection_projections(
899907
obligation,

‎compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use hir::LangItem;
1313
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
1414
use rustc_hir as hir;
1515
use rustc_infer::traits::{Obligation, ObligationCause, PolyTraitObligation, SelectionError};
16-
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
16+
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
1717
use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt};
1818
use rustc_middle::{bug, span_bug};
1919
use tracing::{debug, instrument, trace};
@@ -248,11 +248,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
248248
.filter(|p| p.def_id() == stack.obligation.predicate.def_id())
249249
.filter(|p| p.polarity() == stack.obligation.predicate.polarity());
250250

251+
let drcx = DeepRejectCtxt::relate_rigid_rigid(self.tcx());
252+
let obligation_args = stack.obligation.predicate.skip_binder().trait_ref.args;
251253
// Keep only those bounds which may apply, and propagate overflow if it occurs.
252254
for bound in bounds {
255+
let bound_trait_ref = bound.map_bound(|t| t.trait_ref);
256+
if !drcx.args_may_unify(obligation_args, bound_trait_ref.skip_binder().args) {
257+
continue;
258+
}
253259
// FIXME(oli-obk): it is suspicious that we are dropping the constness and
254260
// polarity here.
255-
let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?;
261+
let wc = self.where_clause_may_apply(stack, bound_trait_ref)?;
256262
if wc.may_apply() {
257263
candidates.vec.push(ParamCandidate(bound));
258264
}
@@ -581,7 +587,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
581587
return;
582588
}
583589

584-
let drcx = DeepRejectCtxt::new(self.tcx(), TreatParams::ForLookup);
590+
let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx());
585591
let obligation_args = obligation.predicate.skip_binder().trait_ref.args;
586592
self.tcx().for_each_relevant_impl(
587593
obligation.predicate.def_id(),

‎compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl<'tcx> Children {
4141
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
4242
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
4343
if let Some(st) =
44-
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
44+
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer)
4545
{
4646
debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
4747
self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
@@ -58,7 +58,7 @@ impl<'tcx> Children {
5858
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
5959
let vec: &mut Vec<DefId>;
6060
if let Some(st) =
61-
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
61+
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer)
6262
{
6363
debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
6464
vec = self.non_blanket_impls.get_mut(&st).unwrap();
@@ -279,7 +279,7 @@ impl<'tcx> Graph {
279279
let mut parent = trait_def_id;
280280
let mut last_lint = None;
281281
let simplified =
282-
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey);
282+
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer);
283283

284284
// Descend the specialization tree, where `parent` is the current parent node.
285285
loop {
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.