Skip to content

Commit 5b6592d

Browse files
committed
Auto merge of rust-lang#130821 - lcnr:nalgebra-hang-2, r=<try>
caching? CACHING! Fixes the new minimization of the hang in nalgebra and nalgebra itself :3 this is a bit iffy, especially the cache in `TypeRelating`. I believe all the caches are correct, but would like to provide an easily verifiable abstraction for caching visitors if possible. Don't think I can extend that one to `TypeRelating` however. The first commit removes region uniquification, reintroducing the ICE from rust-lang/trait-system-refactor-initiative#27. This does not affect coherence and I would like to fix this by introducing OR-region constraints - [x] add test of the new nalgebra minimization, it's different from this - [ ] add an abstraction for caching type visitors r? `@compiler-errors`
2 parents 58420a0 + 7bf456d commit 5b6592d

File tree

11 files changed

+364
-132
lines changed

11 files changed

+364
-132
lines changed

compiler/rustc_infer/src/infer/relate/type_relating.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_middle::ty::relate::{
44
};
55
use rustc_middle::ty::{self, Ty, TyCtxt, TyVar};
66
use rustc_span::Span;
7+
use rustc_type_ir::data_structures::DelayedSet;
78
use tracing::{debug, instrument};
89

910
use super::combine::CombineFields;
@@ -16,6 +17,7 @@ pub struct TypeRelating<'combine, 'a, 'tcx> {
1617
fields: &'combine mut CombineFields<'a, 'tcx>,
1718
structurally_relate_aliases: StructurallyRelateAliases,
1819
ambient_variance: ty::Variance,
20+
cache: DelayedSet<(ty::Variance, Ty<'tcx>, Ty<'tcx>)>,
1921
}
2022

2123
impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
@@ -24,7 +26,12 @@ impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
2426
structurally_relate_aliases: StructurallyRelateAliases,
2527
ambient_variance: ty::Variance,
2628
) -> TypeRelating<'combine, 'infcx, 'tcx> {
27-
TypeRelating { fields: f, structurally_relate_aliases, ambient_variance }
29+
TypeRelating {
30+
fields: f,
31+
structurally_relate_aliases,
32+
ambient_variance,
33+
cache: Default::default(),
34+
}
2835
}
2936
}
3037

@@ -78,6 +85,10 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
7885
let a = infcx.shallow_resolve(a);
7986
let b = infcx.shallow_resolve(b);
8087

88+
if self.cache.contains(&(self.ambient_variance, a, b)) {
89+
return Ok(a);
90+
}
91+
8192
match (a.kind(), b.kind()) {
8293
(&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
8394
match self.ambient_variance {
@@ -160,6 +171,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
160171
}
161172
}
162173

174+
assert!(self.cache.insert((self.ambient_variance, a, b)));
175+
163176
Ok(a)
164177
}
165178

compiler/rustc_infer/src/infer/resolve.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use rustc_data_structures::sso::SsoHashMap;
12
use rustc_middle::bug;
23
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
34
use rustc_middle::ty::visit::TypeVisitableExt;
45
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
6+
use rustc_type_ir::data_structures::DelayedMap;
57

68
use super::{FixupError, FixupResult, InferCtxt};
79

@@ -15,12 +17,13 @@ use super::{FixupError, FixupResult, InferCtxt};
1517
/// points for correctness.
1618
pub struct OpportunisticVarResolver<'a, 'tcx> {
1719
infcx: &'a InferCtxt<'tcx>,
20+
cache: DelayedMap<Ty<'tcx>, Ty<'tcx>>,
1821
}
1922

2023
impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> {
2124
#[inline]
2225
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
23-
OpportunisticVarResolver { infcx }
26+
OpportunisticVarResolver { infcx, cache: Default::default() }
2427
}
2528
}
2629

@@ -33,9 +36,13 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticVarResolver<'a, 'tcx> {
3336
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
3437
if !t.has_non_region_infer() {
3538
t // micro-optimize -- if there is nothing in this type that this fold affects...
39+
} else if let Some(&ty) = self.cache.get(&t) {
40+
return ty;
3641
} else {
37-
let t = self.infcx.shallow_resolve(t);
38-
t.super_fold_with(self)
42+
let shallow = self.infcx.shallow_resolve(t);
43+
let res = shallow.super_fold_with(self);
44+
assert!(self.cache.insert(t, res));
45+
res
3946
}
4047
}
4148

compiler/rustc_middle/src/ty/fold.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rustc_data_structures::fx::FxIndexMap;
22
use rustc_hir::def_id::DefId;
3+
use rustc_type_ir::data_structures::DelayedMap;
34
pub use rustc_type_ir::fold::{
45
FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region, shift_vars,
56
};
@@ -164,11 +165,13 @@ struct BoundVarReplacer<'tcx, D> {
164165
current_index: ty::DebruijnIndex,
165166

166167
delegate: D,
168+
169+
cache: DelayedMap<(ty::DebruijnIndex, Ty<'tcx>), Ty<'tcx>>,
167170
}
168171

169172
impl<'tcx, D: BoundVarReplacerDelegate<'tcx>> BoundVarReplacer<'tcx, D> {
170173
fn new(tcx: TyCtxt<'tcx>, delegate: D) -> Self {
171-
BoundVarReplacer { tcx, current_index: ty::INNERMOST, delegate }
174+
BoundVarReplacer { tcx, current_index: ty::INNERMOST, delegate, cache: Default::default() }
172175
}
173176
}
174177

@@ -197,7 +200,15 @@ where
197200
debug_assert!(!ty.has_vars_bound_above(ty::INNERMOST));
198201
ty::fold::shift_vars(self.tcx, ty, self.current_index.as_u32())
199202
}
200-
_ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
203+
_ if t.has_vars_bound_at_or_above(self.current_index) => {
204+
if let Some(&ty) = self.cache.get(&(self.current_index, t)) {
205+
return ty;
206+
}
207+
208+
let res = t.super_fold_with(self);
209+
assert!(self.cache.insert((self.current_index, t), res));
210+
res
211+
}
201212
_ => t,
202213
}
203214
}

0 commit comments

Comments
 (0)