Skip to content

Commit cd6d788

Browse files
Merge #4060
4060: Update Chalk, and cache Chalk env elaboration through a query r=matklad a=flodiebold This should fix some of the worst performance problems. Co-authored-by: Florian Diebold <[email protected]>
2 parents 2e0b7b0 + 0be68a4 commit cd6d788

File tree

6 files changed

+170
-35
lines changed

6 files changed

+170
-35
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_hir_ty/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ test_utils = { path = "../test_utils" }
2727

2828
scoped-tls = "1"
2929

30-
chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
31-
chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
32-
chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
30+
chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" }
31+
chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" }
32+
chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" }
3333

3434
[dev-dependencies]
3535
insta = "0.16.0"

crates/ra_hir_ty/src/db.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
107107
krate: CrateId,
108108
goal: crate::Canonical<crate::InEnvironment<crate::Obligation>>,
109109
) -> Option<crate::traits::Solution>;
110+
111+
#[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]
112+
fn program_clauses_for_chalk_env(
113+
&self,
114+
krate: CrateId,
115+
env: chalk_ir::Environment<chalk::Interner>,
116+
) -> chalk_ir::ProgramClauses<chalk::Interner>;
110117
}
111118

112119
fn infer_wait(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {

crates/ra_hir_ty/src/traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ fn solution_from_chalk(
225225
None => unimplemented!(),
226226
})
227227
.collect();
228-
let result = Canonical { value, num_vars: subst.binders.len() };
228+
let result = Canonical { value, num_vars: subst.binders.len(&Interner) };
229229
SolutionVariables(result)
230230
};
231231
match solution {

crates/ra_hir_ty/src/traits/chalk.rs

Lines changed: 123 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::{fmt, sync::Arc};
44
use log::debug;
55

66
use chalk_ir::{
7-
cast::Cast, fold::shift::Shift, Goal, GoalData, Parameter, PlaceholderIndex, TypeName,
8-
UniverseIndex,
7+
cast::Cast, fold::shift::Shift, interner::HasInterner, Goal, GoalData, Parameter,
8+
PlaceholderIndex, TypeName, UniverseIndex,
99
};
1010

1111
use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
@@ -33,8 +33,10 @@ impl chalk_ir::interner::Interner for Interner {
3333
type InternedGoals = Vec<Goal<Self>>;
3434
type InternedSubstitution = Vec<Parameter<Self>>;
3535
type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
36-
type InternedProgramClauses = Vec<chalk_ir::ProgramClause<Self>>;
36+
type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
3737
type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
38+
type InternedParameterKinds = Vec<chalk_ir::ParameterKind<()>>;
39+
type InternedCanonicalVarKinds = Vec<chalk_ir::ParameterKind<UniverseIndex>>;
3840
type Identifier = TypeAliasId;
3941
type DefId = InternId;
4042

@@ -60,6 +62,27 @@ impl chalk_ir::interner::Interner for Interner {
6062
tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
6163
}
6264

65+
fn debug_projection_ty(
66+
proj: &chalk_ir::ProjectionTy<Interner>,
67+
fmt: &mut fmt::Formatter<'_>,
68+
) -> Option<fmt::Result> {
69+
tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
70+
}
71+
72+
fn debug_opaque_ty(
73+
opaque_ty: &chalk_ir::OpaqueTy<Interner>,
74+
fmt: &mut fmt::Formatter<'_>,
75+
) -> Option<fmt::Result> {
76+
tls::with_current_program(|prog| Some(prog?.debug_opaque_ty(opaque_ty, fmt)))
77+
}
78+
79+
fn debug_opaque_ty_id(
80+
opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
81+
fmt: &mut fmt::Formatter<'_>,
82+
) -> Option<fmt::Result> {
83+
tls::with_current_program(|prog| Some(prog?.debug_opaque_ty_id(opaque_ty_id, fmt)))
84+
}
85+
6386
fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
6487
tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt)))
6588
}
@@ -202,15 +225,15 @@ impl chalk_ir::interner::Interner for Interner {
202225
fn intern_program_clauses(
203226
&self,
204227
data: impl IntoIterator<Item = chalk_ir::ProgramClause<Self>>,
205-
) -> Vec<chalk_ir::ProgramClause<Self>> {
228+
) -> Arc<[chalk_ir::ProgramClause<Self>]> {
206229
data.into_iter().collect()
207230
}
208231

209232
fn program_clauses_data<'a>(
210233
&self,
211-
clauses: &'a Vec<chalk_ir::ProgramClause<Self>>,
234+
clauses: &'a Arc<[chalk_ir::ProgramClause<Self>]>,
212235
) -> &'a [chalk_ir::ProgramClause<Self>] {
213-
clauses
236+
&clauses
214237
}
215238

216239
fn intern_quantified_where_clauses(
@@ -226,6 +249,34 @@ impl chalk_ir::interner::Interner for Interner {
226249
) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
227250
clauses
228251
}
252+
253+
fn intern_parameter_kinds(
254+
&self,
255+
data: impl IntoIterator<Item = chalk_ir::ParameterKind<()>>,
256+
) -> Self::InternedParameterKinds {
257+
data.into_iter().collect()
258+
}
259+
260+
fn parameter_kinds_data<'a>(
261+
&self,
262+
parameter_kinds: &'a Self::InternedParameterKinds,
263+
) -> &'a [chalk_ir::ParameterKind<()>] {
264+
&parameter_kinds
265+
}
266+
267+
fn intern_canonical_var_kinds(
268+
&self,
269+
data: impl IntoIterator<Item = chalk_ir::ParameterKind<UniverseIndex>>,
270+
) -> Self::InternedCanonicalVarKinds {
271+
data.into_iter().collect()
272+
}
273+
274+
fn canonical_var_kinds_data<'a>(
275+
&self,
276+
canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
277+
) -> &'a [chalk_ir::ParameterKind<UniverseIndex>] {
278+
&canonical_var_kinds
279+
}
229280
}
230281

231282
impl chalk_ir::interner::HasInterner for Interner {
@@ -268,9 +319,12 @@ impl ToChalk for Ty {
268319
Ty::Projection(proj_ty) => {
269320
let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
270321
let substitution = proj_ty.parameters.to_chalk(db);
271-
chalk_ir::AliasTy { associated_ty_id, substitution }
272-
.cast(&Interner)
273-
.intern(&Interner)
322+
chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
323+
associated_ty_id,
324+
substitution,
325+
})
326+
.cast(&Interner)
327+
.intern(&Interner)
274328
}
275329
Ty::Placeholder(id) => {
276330
let interned_id = db.intern_type_param_id(id);
@@ -314,16 +368,17 @@ impl ToChalk for Ty {
314368
);
315369
Ty::Placeholder(db.lookup_intern_type_param_id(interned_id))
316370
}
317-
chalk_ir::TyData::Alias(proj) => {
371+
chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => {
318372
let associated_ty = from_chalk(db, proj.associated_ty_id);
319373
let parameters = from_chalk(db, proj.substitution);
320374
Ty::Projection(ProjectionTy { associated_ty, parameters })
321375
}
376+
chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(),
322377
chalk_ir::TyData::Function(_) => unimplemented!(),
323378
chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx),
324379
chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
325380
chalk_ir::TyData::Dyn(where_clauses) => {
326-
assert_eq!(where_clauses.bounds.binders.len(), 1);
381+
assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
327382
let predicates = where_clauses
328383
.bounds
329384
.skip_binders()
@@ -404,6 +459,7 @@ impl ToChalk for TypeCtor {
404459
match type_name {
405460
TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
406461
TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
462+
TypeName::OpaqueType(_) => unreachable!(),
407463
TypeName::Error => {
408464
// this should not be reached, since we don't represent TypeName::Error with TypeCtor
409465
unreachable!()
@@ -460,7 +516,8 @@ impl ToChalk for GenericPredicate {
460516
}
461517
GenericPredicate::Projection(projection_pred) => {
462518
let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner);
463-
let alias = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner);
519+
let projection = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner);
520+
let alias = chalk_ir::AliasTy::Projection(projection);
464521
make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0)
465522
}
466523
GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
@@ -481,7 +538,13 @@ impl ToChalk for GenericPredicate {
481538
GenericPredicate::Implemented(from_chalk(db, tr))
482539
}
483540
chalk_ir::WhereClause::AliasEq(projection_eq) => {
484-
let projection_ty = from_chalk(db, projection_eq.alias);
541+
let projection_ty = from_chalk(
542+
db,
543+
match projection_eq.alias {
544+
chalk_ir::AliasTy::Projection(p) => p,
545+
_ => unimplemented!(),
546+
},
547+
);
485548
let ty = from_chalk(db, projection_eq.ty);
486549
GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty })
487550
}
@@ -490,18 +553,18 @@ impl ToChalk for GenericPredicate {
490553
}
491554

492555
impl ToChalk for ProjectionTy {
493-
type Chalk = chalk_ir::AliasTy<Interner>;
556+
type Chalk = chalk_ir::ProjectionTy<Interner>;
494557

495-
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasTy<Interner> {
496-
chalk_ir::AliasTy {
558+
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
559+
chalk_ir::ProjectionTy {
497560
associated_ty_id: self.associated_ty.to_chalk(db),
498561
substitution: self.parameters.to_chalk(db),
499562
}
500563
}
501564

502565
fn from_chalk(
503566
db: &dyn HirDatabase,
504-
projection_ty: chalk_ir::AliasTy<Interner>,
567+
projection_ty: chalk_ir::ProjectionTy<Interner>,
505568
) -> ProjectionTy {
506569
ProjectionTy {
507570
associated_ty: from_chalk(db, projection_ty.associated_ty_id),
@@ -514,7 +577,10 @@ impl ToChalk for super::ProjectionPredicate {
514577
type Chalk = chalk_ir::AliasEq<Interner>;
515578

516579
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
517-
chalk_ir::AliasEq { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) }
580+
chalk_ir::AliasEq {
581+
alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)),
582+
ty: self.ty.to_chalk(db),
583+
}
518584
}
519585

520586
fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self {
@@ -540,17 +606,24 @@ impl ToChalk for Obligation {
540606
impl<T> ToChalk for Canonical<T>
541607
where
542608
T: ToChalk,
609+
T::Chalk: HasInterner<Interner = Interner>,
543610
{
544611
type Chalk = chalk_ir::Canonical<T::Chalk>;
545612

546613
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
547614
let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT);
548615
let value = self.value.to_chalk(db);
549-
chalk_ir::Canonical { value, binders: vec![parameter; self.num_vars] }
616+
chalk_ir::Canonical {
617+
value,
618+
binders: chalk_ir::CanonicalVarKinds::from(&Interner, vec![parameter; self.num_vars]),
619+
}
550620
}
551621

552622
fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
553-
Canonical { num_vars: canonical.binders.len(), value: from_chalk(db, canonical.value) }
623+
Canonical {
624+
num_vars: canonical.binders.len(&Interner),
625+
value: from_chalk(db, canonical.value),
626+
}
554627
}
555628
}
556629

@@ -649,9 +722,15 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData {
649722
}
650723
}
651724

652-
fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
725+
fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
726+
where
727+
T: HasInterner<Interner = Interner>,
728+
{
653729
chalk_ir::Binders::new(
654-
std::iter::repeat(chalk_ir::ParameterKind::Ty(())).take(num_vars).collect(),
730+
chalk_ir::ParameterKinds::from(
731+
&Interner,
732+
std::iter::repeat(chalk_ir::ParameterKind::Ty(())).take(num_vars),
733+
),
655734
value,
656735
)
657736
}
@@ -799,6 +878,28 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
799878
// FIXME tell Chalk about well-known traits (here and in trait_datum)
800879
None
801880
}
881+
882+
fn program_clauses_for_env(
883+
&self,
884+
environment: &chalk_ir::Environment<Interner>,
885+
) -> chalk_ir::ProgramClauses<Interner> {
886+
self.db.program_clauses_for_chalk_env(self.krate, environment.clone())
887+
}
888+
889+
fn opaque_ty_data(
890+
&self,
891+
_id: chalk_ir::OpaqueTyId<Interner>,
892+
) -> Arc<chalk_rust_ir::OpaqueTyDatum<Interner>> {
893+
unimplemented!()
894+
}
895+
}
896+
897+
pub(crate) fn program_clauses_for_chalk_env_query(
898+
db: &dyn HirDatabase,
899+
krate: CrateId,
900+
environment: chalk_ir::Environment<Interner>,
901+
) -> chalk_ir::ProgramClauses<Interner> {
902+
chalk_solve::program_clauses_for_env(&ChalkContext { db, krate }, &environment)
802903
}
803904

804905
pub(crate) fn associated_ty_data_query(

0 commit comments

Comments
 (0)