Skip to content

Commit 89821b7

Browse files
use adt_const_params to make simplify_type faster
1 parent 669e751 commit 89821b7

File tree

14 files changed

+95
-104
lines changed

14 files changed

+95
-104
lines changed

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,11 @@ impl<'tcx> InherentCollect<'tcx> {
9999
}
100100
}
101101

102-
if let Some(simp) = simplify_type(
103-
self.tcx,
104-
self_ty,
105-
TreatParams::AsCandidateKey,
106-
TreatProjections::AsCandidateKey,
107-
) {
102+
if let Some(simp) = simplify_type::<
103+
{ TreatParams::AsCandidateKey },
104+
{ TreatProjections::AsCandidateKey },
105+
>(self.tcx, self_ty)
106+
{
108107
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
109108
} else {
110109
bug!("unexpected self type: {:?}", self_ty);
@@ -164,12 +163,11 @@ impl<'tcx> InherentCollect<'tcx> {
164163
}
165164
}
166165

167-
if let Some(simp) = simplify_type(
168-
self.tcx,
169-
ty,
170-
TreatParams::AsCandidateKey,
171-
TreatProjections::AsCandidateKey,
172-
) {
166+
if let Some(simp) = simplify_type::<
167+
{ TreatParams::AsCandidateKey },
168+
{ TreatProjections::AsCandidateKey },
169+
>(self.tcx, ty)
170+
{
173171
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
174172
} else {
175173
bug!("unexpected primitive type: {:?}", ty);

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
700700
}
701701

702702
fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
703-
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey, TreatProjections::AsCandidateKey) else {
703+
let Some(simp) = simplify_type::<{TreatParams::AsCandidateKey}, {TreatProjections::AsCandidateKey}>(self.tcx, self_ty) else {
704704
bug!("unexpected incoherent type: {:?}", self_ty)
705705
};
706706
for &impl_def_id in self.tcx.incoherent_impls(simp) {

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,13 +1517,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15171517
.into_iter()
15181518
.any(|info| self.associated_value(info.def_id, item_name).is_some());
15191519
let found_assoc = |ty: Ty<'tcx>| {
1520-
simplify_type(tcx, ty, TreatParams::AsCandidateKey, TreatProjections::AsCandidateKey)
1521-
.and_then(|simp| {
1522-
tcx.incoherent_impls(simp)
1523-
.iter()
1524-
.find_map(|&id| self.associated_value(id, item_name))
1525-
})
1526-
.is_some()
1520+
simplify_type::<{ TreatParams::AsCandidateKey }, { TreatProjections::AsCandidateKey }>(
1521+
tcx, ty,
1522+
)
1523+
.and_then(|simp| {
1524+
tcx.incoherent_impls(simp)
1525+
.iter()
1526+
.find_map(|&id| self.associated_value(id, item_name))
1527+
})
1528+
.is_some()
15271529
};
15281530
let found_candidate = found_candidate
15291531
|| found_assoc(tcx.types.i8)
@@ -2646,12 +2648,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26462648
// FIXME: Even though negative bounds are not implemented, we could maybe handle
26472649
// cases where a positive bound implies a negative impl.
26482650
(candidates, Vec::new())
2649-
} else if let Some(simp_rcvr_ty) = simplify_type(
2650-
self.tcx,
2651-
rcvr_ty,
2652-
TreatParams::ForLookup,
2653-
TreatProjections::ForLookup,
2654-
) {
2651+
} else if let Some(simp_rcvr_ty) = simplify_type::<
2652+
{ TreatParams::ForLookup },
2653+
{ TreatProjections::ForLookup },
2654+
>(self.tcx, rcvr_ty)
2655+
{
26552656
let mut potential_candidates = Vec::new();
26562657
let mut explicitly_negative = Vec::new();
26572658
for candidate in candidates {
@@ -2664,12 +2665,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26642665
})
26652666
.any(|imp_did| {
26662667
let imp = self.tcx.impl_trait_ref(imp_did).unwrap().subst_identity();
2667-
let imp_simp = simplify_type(
2668-
self.tcx,
2669-
imp.self_ty(),
2670-
TreatParams::ForLookup,
2671-
TreatProjections::ForLookup,
2672-
);
2668+
let imp_simp = simplify_type::<
2669+
{ TreatParams::ForLookup },
2670+
{ TreatProjections::ForLookup },
2671+
>(self.tcx, imp.self_ty());
26732672
imp_simp.map_or(false, |s| s == simp_rcvr_ty)
26742673
})
26752674
{

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,12 +1855,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18551855
if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id) {
18561856
let trait_ref = trait_ref.subst_identity();
18571857

1858-
let simplified_self_ty = fast_reject::simplify_type(
1859-
self.tcx,
1860-
trait_ref.self_ty(),
1861-
TreatParams::AsCandidateKey,
1862-
TreatProjections::AsCandidateKey,
1863-
);
1858+
let simplified_self_ty = fast_reject::simplify_type::<
1859+
{ TreatParams::AsCandidateKey },
1860+
{ TreatProjections::AsCandidateKey },
1861+
>(self.tcx, trait_ref.self_ty());
18641862

18651863
fx_hash_map
18661864
.entry(trait_ref.def_id)

compiler/rustc_middle/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
//! This API is completely unstable and subject to change.
2424
2525
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
26+
#![allow(incomplete_features)]
27+
#![feature(adt_const_params)]
2628
#![feature(allocator_api)]
2729
#![feature(array_windows)]
2830
#![feature(assert_matches)]

compiler/rustc_middle/src/ty/fast_reject.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,13 @@ pub enum TreatProjections {
103103
/// is only correct if they are fully normalized.
104104
///
105105
/// ¹ meaning that if the outermost layers are different, then the whole types are also different.
106-
pub fn simplify_type<'tcx>(
106+
pub fn simplify_type<
107+
'tcx,
108+
const TREAT_PARAMS: TreatParams,
109+
const TREAT_PROJECTIONS: TreatProjections,
110+
>(
107111
tcx: TyCtxt<'tcx>,
108112
ty: Ty<'tcx>,
109-
treat_params: TreatParams,
110-
treat_projections: TreatProjections,
111113
) -> Option<SimplifiedType> {
112114
match *ty.kind() {
113115
ty::Bool => Some(BoolSimplifiedType),
@@ -135,11 +137,11 @@ pub fn simplify_type<'tcx>(
135137
ty::Tuple(tys) => Some(TupleSimplifiedType(tys.len())),
136138
ty::FnPtr(f) => Some(FunctionSimplifiedType(f.skip_binder().inputs().len())),
137139
ty::Placeholder(..) => Some(PlaceholderSimplifiedType),
138-
ty::Param(_) => match treat_params {
140+
ty::Param(_) => match TREAT_PARAMS {
139141
TreatParams::ForLookup => Some(PlaceholderSimplifiedType),
140142
TreatParams::AsCandidateKey => None,
141143
},
142-
ty::Alias(..) => match treat_projections {
144+
ty::Alias(..) => match TREAT_PROJECTIONS {
143145
TreatProjections::ForLookup if !ty.needs_infer() => Some(PlaceholderSimplifiedType),
144146
TreatProjections::NextSolverLookup => Some(PlaceholderSimplifiedType),
145147
TreatProjections::AsCandidateKey | TreatProjections::ForLookup => None,

compiler/rustc_middle/src/ty/trait_def.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -124,23 +124,23 @@ impl<'tcx> TyCtxt<'tcx> {
124124
self_ty: Ty<'tcx>,
125125
f: impl FnMut(DefId),
126126
) {
127-
self.for_each_relevant_impl_treating_projections(
127+
self.for_each_relevant_impl_treating_projections::<{ TreatProjections::ForLookup }>(
128128
trait_def_id,
129129
self_ty,
130-
TreatProjections::ForLookup,
131130
f,
132131
)
133132
}
134133

135-
pub fn for_each_relevant_impl_treating_projections(
134+
pub fn for_each_relevant_impl_treating_projections<
135+
const TREAT_PROJECTIONS: TreatProjections,
136+
>(
136137
self,
137138
trait_def_id: DefId,
138139
self_ty: Ty<'tcx>,
139-
treat_projections: TreatProjections,
140140
mut f: impl FnMut(DefId),
141141
) {
142142
let _: Option<()> =
143-
self.find_map_relevant_impl(trait_def_id, self_ty, treat_projections, |did| {
143+
self.find_map_relevant_impl::<_, TREAT_PROJECTIONS>(trait_def_id, self_ty, |did| {
144144
f(did);
145145
None
146146
});
@@ -153,12 +153,11 @@ impl<'tcx> TyCtxt<'tcx> {
153153
self_ty: Ty<'tcx>,
154154
) -> impl Iterator<Item = DefId> + 'tcx {
155155
let impls = self.trait_impls_of(trait_def_id);
156-
if let Some(simp) = fast_reject::simplify_type(
157-
self,
158-
self_ty,
159-
TreatParams::AsCandidateKey,
160-
TreatProjections::AsCandidateKey,
161-
) {
156+
if let Some(simp) = fast_reject::simplify_type::<
157+
{ TreatParams::AsCandidateKey },
158+
{ TreatProjections::AsCandidateKey },
159+
>(self, self_ty)
160+
{
162161
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
163162
return impls.iter().copied();
164163
}
@@ -171,11 +170,10 @@ impl<'tcx> TyCtxt<'tcx> {
171170
/// the first non-none value.
172171
///
173172
/// `trait_def_id` MUST BE the `DefId` of a trait.
174-
pub fn find_map_relevant_impl<T>(
173+
pub fn find_map_relevant_impl<T, const TREAT_PROJECTIONS: TreatProjections>(
175174
self,
176175
trait_def_id: DefId,
177176
self_ty: Ty<'tcx>,
178-
treat_projections: TreatProjections,
179177
mut f: impl FnMut(DefId) -> Option<T>,
180178
) -> Option<T> {
181179
// FIXME: This depends on the set of all impls for the trait. That is
@@ -195,8 +193,10 @@ impl<'tcx> TyCtxt<'tcx> {
195193
// whose outer level is not a parameter or projection. Especially for things like
196194
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
197195
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
198-
if let Some(simp) =
199-
fast_reject::simplify_type(self, self_ty, TreatParams::ForLookup, treat_projections)
196+
if let Some(simp) = fast_reject::simplify_type::<
197+
{ TreatParams::ForLookup },
198+
TREAT_PROJECTIONS,
199+
>(self, self_ty)
200200
{
201201
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
202202
for &impl_def_id in impls {
@@ -258,12 +258,11 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
258258
continue;
259259
}
260260

261-
if let Some(simplified_self_ty) = fast_reject::simplify_type(
262-
tcx,
263-
impl_self_ty,
264-
TreatParams::AsCandidateKey,
265-
TreatProjections::AsCandidateKey,
266-
) {
261+
if let Some(simplified_self_ty) = fast_reject::simplify_type::<
262+
{ TreatParams::AsCandidateKey },
263+
{ TreatProjections::AsCandidateKey },
264+
>(tcx, impl_self_ty)
265+
{
267266
impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
268267
} else {
269268
impls.blanket_impls.push(impl_def_id);

compiler/rustc_middle/src/ty/util.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,10 @@ impl<'tcx> TyCtxt<'tcx> {
364364
self.ensure().coherent_trait(drop_trait);
365365

366366
let ty = self.type_of(adt_did).subst_identity();
367-
let (did, constness) = self.find_map_relevant_impl(
367+
// FIXME: This could also be some other mode, like "unexpected"
368+
let (did, constness) = self.find_map_relevant_impl::<_, { TreatProjections::ForLookup }>(
368369
drop_trait,
369370
ty,
370-
// FIXME: This could also be some other mode, like "unexpected"
371-
TreatProjections::ForLookup,
372371
|impl_did| {
373372
if let Some(item_id) = self.associated_item_def_ids(impl_did).first() {
374373
if validate(self, impl_did).is_ok() {

compiler/rustc_trait_selection/src/solve/assembly.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
300300
candidates: &mut Vec<Candidate<'tcx>>,
301301
) {
302302
let tcx = self.tcx();
303-
tcx.for_each_relevant_impl_treating_projections(
303+
tcx.for_each_relevant_impl_treating_projections::<{ TreatProjections::NextSolverLookup }>(
304304
goal.predicate.trait_def_id(tcx),
305305
goal.predicate.self_ty(),
306-
TreatProjections::NextSolverLookup,
307306
|impl_def_id| match G::consider_impl_candidate(self, goal, impl_def_id) {
308307
Ok(result) => candidates
309308
.push(Candidate { source: CandidateSource::Impl(impl_def_id), result }),

compiler/rustc_trait_selection/src/solve/trait_goals.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
140140
// `instantiate_constituent_tys_for_auto_trait` returns nothing for
141141
// projection types anyways. So it doesn't really matter what we do
142142
// here, and this is faster.
143-
if let Some(def_id) = ecx.tcx().find_map_relevant_impl(
144-
goal.predicate.def_id(),
145-
goal.predicate.self_ty(),
146-
TreatProjections::NextSolverLookup,
147-
Some,
148-
) {
143+
if let Some(def_id) =
144+
ecx.tcx().find_map_relevant_impl::<_, { TreatProjections::NextSolverLookup }>(
145+
goal.predicate.def_id(),
146+
goal.predicate.self_ty(),
147+
Some,
148+
)
149+
{
149150
debug!(?def_id, ?goal, "disqualified auto-trait implementation");
150151
return Err(NoSolution);
151152
}

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,10 +1800,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
18001800
})
18011801
.and_then(|(trait_assoc_item, id)| {
18021802
let trait_assoc_ident = trait_assoc_item.ident(self.tcx);
1803-
self.tcx.find_map_relevant_impl(
1803+
self.tcx.find_map_relevant_impl::<_, { TreatProjections::ForLookup }>(
18041804
id,
18051805
proj.projection_ty.self_ty(),
1806-
TreatProjections::ForLookup,
18071806
|did| {
18081807
self.tcx
18091808
.associated_items(did)
@@ -2182,10 +2181,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
21822181
trait_ref: &ty::PolyTraitRef<'tcx>,
21832182
) -> bool {
21842183
let get_trait_impl = |trait_def_id| {
2185-
self.tcx.find_map_relevant_impl(
2184+
self.tcx.find_map_relevant_impl::<_, { TreatProjections::ForLookup }>(
21862185
trait_def_id,
21872186
trait_ref.skip_binder().self_ty(),
2188-
TreatProjections::ForLookup,
21892187
Some,
21902188
)
21912189
};

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -781,12 +781,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
781781

782782
ty::Adt(..) => {
783783
// Find a custom `impl Drop` impl, if it exists
784-
let relevant_impl = self.tcx().find_map_relevant_impl(
785-
self.tcx().require_lang_item(LangItem::Drop, None),
786-
obligation.predicate.skip_binder().trait_ref.self_ty(),
787-
TreatProjections::ForLookup,
788-
Some,
789-
);
784+
let relevant_impl =
785+
self.tcx().find_map_relevant_impl::<_, { TreatProjections::ForLookup }>(
786+
self.tcx().require_lang_item(LangItem::Drop, None),
787+
obligation.predicate.skip_binder().trait_ref.self_ty(),
788+
Some,
789+
);
790790

791791
if let Some(impl_def_id) = relevant_impl {
792792
// Check that `impl Drop` is actually const, if there is a custom impl

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

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,11 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
4949
/// Insert an impl into this set of children without comparing to any existing impls.
5050
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
5151
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
52-
if let Some(st) = fast_reject::simplify_type(
53-
tcx,
54-
trait_ref.self_ty(),
55-
TreatParams::AsCandidateKey,
56-
TreatProjections::AsCandidateKey,
57-
) {
52+
if let Some(st) = fast_reject::simplify_type::<
53+
{ TreatParams::AsCandidateKey },
54+
{ TreatProjections::AsCandidateKey },
55+
>(tcx, trait_ref.self_ty())
56+
{
5857
debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
5958
self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
6059
} else {
@@ -69,12 +68,11 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
6968
fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
7069
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
7170
let vec: &mut Vec<DefId>;
72-
if let Some(st) = fast_reject::simplify_type(
73-
tcx,
74-
trait_ref.self_ty(),
75-
TreatParams::AsCandidateKey,
76-
TreatProjections::AsCandidateKey,
77-
) {
71+
if let Some(st) = fast_reject::simplify_type::<
72+
{ TreatParams::AsCandidateKey },
73+
{ TreatProjections::AsCandidateKey },
74+
>(tcx, trait_ref.self_ty())
75+
{
7876
debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
7977
vec = self.non_blanket_impls.get_mut(&st).unwrap();
8078
} else {
@@ -310,12 +308,10 @@ impl<'tcx> GraphExt<'tcx> for Graph {
310308

311309
let mut parent = trait_def_id;
312310
let mut last_lint = None;
313-
let simplified = fast_reject::simplify_type(
314-
tcx,
315-
trait_ref.self_ty(),
316-
TreatParams::AsCandidateKey,
317-
TreatProjections::AsCandidateKey,
318-
);
311+
let simplified = fast_reject::simplify_type::<
312+
{ TreatParams::AsCandidateKey },
313+
{ TreatProjections::AsCandidateKey },
314+
>(tcx, trait_ref.self_ty());
319315

320316
// Descend the specialization tree, where `parent` is the current parent node.
321317
loop {

0 commit comments

Comments
 (0)