Skip to content

Commit ea686db

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 76ed7a1 + 95b9dc1 commit ea686db

File tree

9 files changed

+299
-134
lines changed

9 files changed

+299
-134
lines changed

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

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_data_structures::sso::SsoHashSet;
12
use rustc_middle::traits::solve::Goal;
23
use rustc_middle::ty::relate::{
34
Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances,
@@ -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: SsoHashSet<(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 infcx.next_trait_solver() && 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,10 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
160171
}
161172
}
162173

174+
if infcx.next_trait_solver() {
175+
assert!(self.cache.insert((self.ambient_variance, a, b)));
176+
}
177+
163178
Ok(a)
164179
}
165180

compiler/rustc_infer/src/infer/resolve.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
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;
@@ -15,12 +16,13 @@ use super::{FixupError, FixupResult, InferCtxt};
1516
/// points for correctness.
1617
pub struct OpportunisticVarResolver<'a, 'tcx> {
1718
infcx: &'a InferCtxt<'tcx>,
19+
cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
1820
}
1921

2022
impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> {
2123
#[inline]
2224
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
23-
OpportunisticVarResolver { infcx }
25+
OpportunisticVarResolver { infcx, cache: Default::default() }
2426
}
2527
}
2628

@@ -33,9 +35,13 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticVarResolver<'a, 'tcx> {
3335
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
3436
if !t.has_non_region_infer() {
3537
t // micro-optimize -- if there is nothing in this type that this fold affects...
38+
} else if let Some(&ty) = self.cache.get(&t) {
39+
return ty;
3640
} else {
37-
let t = self.infcx.shallow_resolve(t);
38-
t.super_fold_with(self)
41+
let shallow = self.infcx.shallow_resolve(t);
42+
let res = shallow.super_fold_with(self);
43+
assert!(self.cache.insert(t, res).is_none());
44+
res
3945
}
4046
}
4147

compiler/rustc_middle/src/ty/fold.rs

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

166167
delegate: D,
168+
169+
cache: SsoHashMap<(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

@@ -191,15 +194,22 @@ where
191194
}
192195

193196
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
194-
match *t.kind() {
197+
if let Some(&ty) = self.cache.get(&(self.current_index, t)) {
198+
return ty;
199+
}
200+
201+
let res = match *t.kind() {
195202
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
196203
let ty = self.delegate.replace_ty(bound_ty);
197204
debug_assert!(!ty.has_vars_bound_above(ty::INNERMOST));
198205
ty::fold::shift_vars(self.tcx, ty, self.current_index.as_u32())
199206
}
200207
_ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
201208
_ => t,
202-
}
209+
};
210+
211+
assert!(self.cache.insert((self.current_index, t), res).is_none());
212+
res
203213
}
204214

205215
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {

0 commit comments

Comments
 (0)