Skip to content

Commit 593156a

Browse files
committed
Re-use InferenceTable by snapshotting in method resolution
1 parent 2898c42 commit 593156a

File tree

4 files changed

+48
-56
lines changed

4 files changed

+48
-56
lines changed

crates/hir-ty/src/autoderef.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,23 @@ pub(crate) fn autoderef_step(
113113
ty: Ty,
114114
explicit: bool,
115115
) -> Option<(AutoderefKind, Ty)> {
116-
if let Some(derefed) = builtin_deref(table, &ty, explicit) {
116+
if let Some(derefed) = builtin_deref(table.db, &ty, explicit) {
117117
Some((AutoderefKind::Builtin, table.resolve_ty_shallow(derefed)))
118118
} else {
119119
Some((AutoderefKind::Overloaded, deref_by_trait(table, ty)?))
120120
}
121121
}
122122

123123
pub(crate) fn builtin_deref<'ty>(
124-
table: &mut InferenceTable<'_>,
124+
db: &dyn HirDatabase,
125125
ty: &'ty Ty,
126126
explicit: bool,
127127
) -> Option<&'ty Ty> {
128128
match ty.kind(Interner) {
129129
TyKind::Ref(.., ty) => Some(ty),
130130
TyKind::Raw(.., ty) if explicit => Some(ty),
131131
&TyKind::Adt(chalk_ir::AdtId(adt), ref substs) => {
132-
if crate::lang_items::is_box(table.db, adt) {
132+
if crate::lang_items::is_box(db, adt) {
133133
substs.at(Interner, 0).ty(Interner)
134134
} else {
135135
None

crates/hir-ty/src/infer/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ impl InferenceContext<'_> {
657657
);
658658
}
659659
}
660-
if let Some(derefed) = builtin_deref(&mut self.table, &inner_ty, true) {
660+
if let Some(derefed) = builtin_deref(self.table.db, &inner_ty, true) {
661661
self.resolve_ty_shallow(derefed)
662662
} else {
663663
deref_by_trait(&mut self.table, inner_ty)

crates/hir-ty/src/infer/unify.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ pub(crate) struct InferenceTable<'a> {
243243
pub(crate) db: &'a dyn HirDatabase,
244244
pub(crate) trait_env: Arc<TraitEnvironment>,
245245
var_unification_table: ChalkInferenceTable,
246-
type_variable_table: Vec<TypeVariableFlags>,
246+
type_variable_table: SmallVec<[TypeVariableFlags; 16]>,
247247
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
248248
/// Double buffer used in [`Self::resolve_obligations_as_possible`] to cut down on
249249
/// temporary allocations.
@@ -252,8 +252,8 @@ pub(crate) struct InferenceTable<'a> {
252252

253253
pub(crate) struct InferenceTableSnapshot {
254254
var_table_snapshot: chalk_solve::infer::InferenceSnapshot<Interner>,
255+
type_variable_table: SmallVec<[TypeVariableFlags; 16]>,
255256
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
256-
type_variable_table_snapshot: Vec<TypeVariableFlags>,
257257
}
258258

259259
impl<'a> InferenceTable<'a> {
@@ -262,7 +262,7 @@ impl<'a> InferenceTable<'a> {
262262
db,
263263
trait_env,
264264
var_unification_table: ChalkInferenceTable::new(),
265-
type_variable_table: Vec::new(),
265+
type_variable_table: SmallVec::new(),
266266
pending_obligations: Vec::new(),
267267
resolve_obligations_buffer: Vec::new(),
268268
}
@@ -575,19 +575,15 @@ impl<'a> InferenceTable<'a> {
575575

576576
pub(crate) fn snapshot(&mut self) -> InferenceTableSnapshot {
577577
let var_table_snapshot = self.var_unification_table.snapshot();
578-
let type_variable_table_snapshot = self.type_variable_table.clone();
578+
let type_variable_table = self.type_variable_table.clone();
579579
let pending_obligations = self.pending_obligations.clone();
580-
InferenceTableSnapshot {
581-
var_table_snapshot,
582-
pending_obligations,
583-
type_variable_table_snapshot,
584-
}
580+
InferenceTableSnapshot { var_table_snapshot, pending_obligations, type_variable_table }
585581
}
586582

587583
#[tracing::instrument(skip_all)]
588584
pub(crate) fn rollback_to(&mut self, snapshot: InferenceTableSnapshot) {
589585
self.var_unification_table.rollback_to(snapshot.var_table_snapshot);
590-
self.type_variable_table = snapshot.type_variable_table_snapshot;
586+
self.type_variable_table = snapshot.type_variable_table;
591587
self.pending_obligations = snapshot.pending_obligations;
592588
}
593589

crates/hir-ty/src/method_resolution.rs

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -972,10 +972,9 @@ pub fn iterate_method_candidates_dyn(
972972

973973
deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| {
974974
iterate_method_candidates_with_autoref(
975+
&mut table,
975976
&receiver_ty,
976977
adj,
977-
db,
978-
env.clone(),
979978
traits_in_scope,
980979
visible_from_module,
981980
name,
@@ -1000,10 +999,9 @@ pub fn iterate_method_candidates_dyn(
1000999

10011000
#[tracing::instrument(skip_all, fields(name = ?name))]
10021001
fn iterate_method_candidates_with_autoref(
1002+
table: &mut InferenceTable<'_>,
10031003
receiver_ty: &Canonical<Ty>,
10041004
first_adjustment: ReceiverAdjustments,
1005-
db: &dyn HirDatabase,
1006-
env: Arc<TraitEnvironment>,
10071005
traits_in_scope: &FxHashSet<TraitId>,
10081006
visible_from_module: VisibleFromModule,
10091007
name: Option<&Name>,
@@ -1016,10 +1014,9 @@ fn iterate_method_candidates_with_autoref(
10161014

10171015
let mut iterate_method_candidates_by_receiver = move |receiver_ty, first_adjustment| {
10181016
iterate_method_candidates_by_receiver(
1017+
table,
10191018
receiver_ty,
10201019
first_adjustment,
1021-
db,
1022-
env.clone(),
10231020
traits_in_scope,
10241021
visible_from_module,
10251022
name,
@@ -1058,50 +1055,49 @@ fn iterate_method_candidates_with_autoref(
10581055

10591056
#[tracing::instrument(skip_all, fields(name = ?name))]
10601057
fn iterate_method_candidates_by_receiver(
1058+
table: &mut InferenceTable<'_>,
10611059
receiver_ty: &Canonical<Ty>,
10621060
receiver_adjustments: ReceiverAdjustments,
1063-
db: &dyn HirDatabase,
1064-
env: Arc<TraitEnvironment>,
10651061
traits_in_scope: &FxHashSet<TraitId>,
10661062
visible_from_module: VisibleFromModule,
10671063
name: Option<&Name>,
10681064
mut callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>,
10691065
) -> ControlFlow<()> {
1070-
let mut table = InferenceTable::new(db, env);
1071-
let receiver_ty = table.instantiate_canonical(receiver_ty.clone());
1072-
let snapshot = table.snapshot();
1073-
// We're looking for methods with *receiver* type receiver_ty. These could
1074-
// be found in any of the derefs of receiver_ty, so we have to go through
1075-
// that, including raw derefs.
1076-
let mut autoderef = autoderef::Autoderef::new(&mut table, receiver_ty.clone(), true);
1077-
while let Some((self_ty, _)) = autoderef.next() {
1078-
iterate_inherent_methods(
1079-
&self_ty,
1080-
autoderef.table,
1081-
name,
1082-
Some(&receiver_ty),
1083-
Some(receiver_adjustments.clone()),
1084-
visible_from_module,
1085-
&mut callback,
1086-
)?
1087-
}
1088-
1089-
table.rollback_to(snapshot);
1090-
1091-
let mut autoderef = autoderef::Autoderef::new(&mut table, receiver_ty.clone(), true);
1092-
while let Some((self_ty, _)) = autoderef.next() {
1093-
iterate_trait_method_candidates(
1094-
&self_ty,
1095-
autoderef.table,
1096-
traits_in_scope,
1097-
name,
1098-
Some(&receiver_ty),
1099-
Some(receiver_adjustments.clone()),
1100-
&mut callback,
1101-
)?
1102-
}
1066+
table.run_in_snapshot(|table| {
1067+
let receiver_ty = table.instantiate_canonical(receiver_ty.clone());
1068+
// We're looking for methods with *receiver* type receiver_ty. These could
1069+
// be found in any of the derefs of receiver_ty, so we have to go through
1070+
// that, including raw derefs.
1071+
table.run_in_snapshot(|table| {
1072+
let mut autoderef = autoderef::Autoderef::new(table, receiver_ty.clone(), true);
1073+
while let Some((self_ty, _)) = autoderef.next() {
1074+
iterate_inherent_methods(
1075+
&self_ty,
1076+
autoderef.table,
1077+
name,
1078+
Some(&receiver_ty),
1079+
Some(receiver_adjustments.clone()),
1080+
visible_from_module,
1081+
&mut callback,
1082+
)?
1083+
}
1084+
ControlFlow::Continue(())
1085+
})?;
11031086

1104-
ControlFlow::Continue(())
1087+
let mut autoderef = autoderef::Autoderef::new(table, receiver_ty.clone(), true);
1088+
while let Some((self_ty, _)) = autoderef.next() {
1089+
iterate_trait_method_candidates(
1090+
&self_ty,
1091+
autoderef.table,
1092+
traits_in_scope,
1093+
name,
1094+
Some(&receiver_ty),
1095+
Some(receiver_adjustments.clone()),
1096+
&mut callback,
1097+
)?
1098+
}
1099+
ControlFlow::Continue(())
1100+
})
11051101
}
11061102

11071103
#[tracing::instrument(skip_all, fields(name = ?name))]

0 commit comments

Comments
 (0)