Skip to content

Commit 703ffca

Browse files
authored
Merge pull request #342 from yaahc/jane/intern-data
Add self param to intern_data
2 parents 1a41931 + 70aff78 commit 703ffca

File tree

17 files changed

+158
-109
lines changed

17 files changed

+158
-109
lines changed

chalk-engine/src/context.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,6 @@ pub trait Context: Clone + Debug {
144144

145145
fn canonical(u_canon: &Self::UCanonicalGoalInEnvironment) -> &Self::CanonicalGoalInEnvironment;
146146

147-
fn is_trivial_substitution(
148-
u_canon: &Self::UCanonicalGoalInEnvironment,
149-
canonical_subst: &Self::CanonicalAnswerSubst,
150-
) -> bool;
151-
152147
fn has_delayed_subgoals(canonical_subst: &Self::CanonicalAnswerSubst) -> bool;
153148

154149
fn num_universes(_: &Self::UCanonicalGoalInEnvironment) -> usize;
@@ -265,6 +260,12 @@ pub trait ContextOps<C: Context>: Sized + Clone + Debug + AggregateOps<C> {
265260

266261
/// Upcast this domain goal into a more general goal.
267262
fn into_goal(&self, domain_goal: C::DomainGoal) -> C::Goal;
263+
264+
fn is_trivial_substitution(
265+
&self,
266+
u_canon: &C::UCanonicalGoalInEnvironment,
267+
canonical_subst: &C::CanonicalAnswerSubst,
268+
) -> bool;
268269
}
269270

270271
/// Methods for combining solutions to yield an aggregate solution.

chalk-engine/src/logic.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,9 @@ impl<'forest, C: Context + 'forest, CO: ContextOps<C> + 'forest> SolveState<'for
14091409
// must be backed by an impl *eventually*).
14101410
let is_trivial_answer = {
14111411
!answer.ambiguous
1412-
&& C::is_trivial_substitution(&self.forest.tables[table].table_goal, &answer.subst)
1412+
&& self
1413+
.context
1414+
.is_trivial_substitution(&self.forest.tables[table].table_goal, &answer.subst)
14131415
&& C::empty_constraints(&answer.subst)
14141416
};
14151417

chalk-integration/src/program.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use chalk_ir::debug::Angle;
44
use chalk_ir::interner::ChalkIr;
55
use chalk_ir::tls;
66
use chalk_ir::{
7-
AliasTy, AssocTypeId, ImplId, Parameter, ProgramClause, StructId, TraitId, TyData, TypeName,
7+
AliasTy, AssocTypeId, ImplId, Parameter, ProgramClause, StructId, TraitId, Ty, TyData, TypeName,
88
};
99
use chalk_rust_ir::{
1010
AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, ImplDatum, ImplType, StructDatum,
@@ -120,6 +120,11 @@ impl tls::DebugContext for Program {
120120
Angle(&other_params)
121121
)
122122
}
123+
124+
fn debug_ty(&self, ty: &Ty<ChalkIr>, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
125+
let interner = self.interner();
126+
write!(fmt, "{:?}", ty.data(interner))
127+
}
123128
}
124129

125130
impl RustIrDatabase<ChalkIr> for Program {
@@ -162,6 +167,7 @@ impl RustIrDatabase<ChalkIr> for Program {
162167
trait_id: TraitId<ChalkIr>,
163168
parameters: &[Parameter<ChalkIr>],
164169
) -> Vec<ImplId<ChalkIr>> {
170+
let interner = self.interner();
165171
self.impl_data
166172
.iter()
167173
.filter(|(_, impl_datum)| {
@@ -170,6 +176,7 @@ impl RustIrDatabase<ChalkIr> for Program {
170176
assert_eq!(trait_ref.substitution.len(), parameters.len());
171177
<[_] as CouldMatch<[_]>>::could_match(
172178
&parameters,
179+
interner,
173180
&trait_ref.substitution.parameters(),
174181
)
175182
}
@@ -193,12 +200,13 @@ impl RustIrDatabase<ChalkIr> for Program {
193200
auto_trait_id: TraitId<ChalkIr>,
194201
struct_id: StructId<ChalkIr>,
195202
) -> bool {
203+
let interner = self.interner();
196204
// Look for an impl like `impl Send for Foo` where `Foo` is
197205
// the struct. See `push_auto_trait_impls` for more.
198206
self.impl_data.values().any(|impl_datum| {
199207
let impl_trait_ref = &impl_datum.binders.value.trait_ref;
200208
impl_trait_ref.trait_id == auto_trait_id
201-
&& match impl_trait_ref.self_type_parameter().data() {
209+
&& match impl_trait_ref.self_type_parameter().data(interner) {
202210
TyData::Apply(apply) => match apply.name {
203211
TypeName::Struct(id) => id == struct_id,
204212
_ => false,

chalk-ir/src/could_match.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,34 @@ use crate::zip::{Zip, Zipper};
33
use crate::*;
44

55
/// A fast check to see whether two things could ever possibly match.
6-
pub trait CouldMatch<T: ?Sized> {
7-
fn could_match(&self, other: &T) -> bool;
6+
pub trait CouldMatch<T: ?Sized + HasInterner> {
7+
fn could_match(&self, interner: &T::Interner, other: &T) -> bool;
88
}
99

10+
#[allow(unreachable_code, unused_variables)]
1011
impl<T, I> CouldMatch<T> for T
1112
where
1213
T: Zip<I> + ?Sized + HasInterner<Interner = I>,
1314
I: Interner,
1415
{
15-
fn could_match(&self, other: &T) -> bool {
16-
return Zip::zip_with(&mut MatchZipper, self, other).is_ok();
16+
fn could_match(&self, interner: &I, other: &T) -> bool {
17+
return Zip::zip_with(&mut MatchZipper { interner }, self, other).is_ok();
1718

18-
struct MatchZipper;
19+
struct MatchZipper<'i, I> {
20+
interner: &'i I,
21+
};
1922

20-
impl<I: Interner> Zipper<I> for MatchZipper {
23+
impl<I: Interner> Zipper<I> for MatchZipper<'_, I> {
2124
fn zip_tys(&mut self, a: &Ty<I>, b: &Ty<I>) -> Fallible<()> {
22-
let could_match = match (a.data(), b.data()) {
25+
let could_match = match (a.data(self.interner), b.data(self.interner)) {
2326
(&TyData::Apply(ref a), &TyData::Apply(ref b)) => {
2427
let names_could_match = a.name == b.name;
2528

2629
names_could_match
2730
&& a.substitution
2831
.iter()
2932
.zip(&b.substitution)
30-
.all(|(p_a, p_b)| p_a.could_match(&p_b))
33+
.all(|(p_a, p_b)| p_a.could_match(self.interner, &p_b))
3134
}
3235

3336
_ => true,
@@ -55,11 +58,13 @@ where
5558
}
5659

5760
impl<I: Interner> CouldMatch<DomainGoal<I>> for ProgramClause<I> {
58-
fn could_match(&self, other: &DomainGoal<I>) -> bool {
61+
fn could_match(&self, interner: &I, other: &DomainGoal<I>) -> bool {
5962
match self {
60-
ProgramClause::Implies(implication) => implication.consequence.could_match(other),
63+
ProgramClause::Implies(implication) => {
64+
implication.consequence.could_match(interner, other)
65+
}
6166

62-
ProgramClause::ForAll(clause) => clause.value.consequence.could_match(other),
67+
ProgramClause::ForAll(clause) => clause.value.consequence.could_match(interner, other),
6368
}
6469
}
6570
}

chalk-ir/src/debug.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ impl<I: Interner> Debug for AssocTypeId<I> {
2121
}
2222
}
2323

24+
impl<I: Interner> Debug for Ty<I> {
25+
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
26+
I::debug_ty(self, fmt).unwrap_or_else(|| unimplemented!())
27+
}
28+
}
29+
2430
impl Display for UniverseIndex {
2531
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
2632
write!(fmt, "U{}", self.counter)
@@ -42,11 +48,6 @@ impl<I: Interner> Debug for TypeName<I> {
4248
}
4349
}
4450
}
45-
impl<I: Interner> Debug for Ty<I> {
46-
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
47-
write!(fmt, "{:?}", self.data())
48-
}
49-
}
5051

5152
impl<I: Interner> Debug for TyData<I> {
5253
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {

chalk-ir/src/fold.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ where
303303
I: 'i,
304304
TI: 'i,
305305
{
306-
match self.data() {
306+
match self.data(folder.interner()) {
307307
TyData::BoundVar(depth) => {
308308
if *depth >= binders {
309309
folder.fold_free_var_ty(*depth - binders, binders)

chalk-ir/src/interner.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::Parameter;
77
use crate::ParameterData;
88
use crate::StructId;
99
use crate::TraitId;
10+
use crate::Ty;
1011
use crate::TyData;
1112
use chalk_engine::context::Context;
1213
use chalk_engine::ExClause;
@@ -132,13 +133,22 @@ pub trait Interner: Debug + Copy + Eq + Ord + Hash {
132133
/// if no info about current program is available from TLS).
133134
fn debug_alias(alias: &AliasTy<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result>;
134135

136+
/// Prints the debug representation of an type. To get good
137+
/// results, this requires inspecting TLS, and is difficult to
138+
/// code without reference to a specific interner (and hence
139+
/// fully known types).
140+
///
141+
/// Returns `None` to fallback to the default debug output (e.g.,
142+
/// if no info about current program is available from TLS).
143+
fn debug_ty(ty: &Ty<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result>;
144+
135145
/// Create an "interned" type from `ty`. This is not normally
136146
/// invoked directly; instead, you invoke `TyData::intern` (which
137147
/// will ultimately call this method).
138148
fn intern_ty(&self, ty: TyData<Self>) -> Self::InternedType;
139149

140150
/// Lookup the `TyData` from an interned type.
141-
fn ty_data(ty: &Self::InternedType) -> &TyData<Self>;
151+
fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a TyData<Self>;
142152

143153
/// Create an "interned" lifetime from `lifetime`. This is not
144154
/// normally invoked directly; instead, you invoke
@@ -272,11 +282,15 @@ mod default {
272282
tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
273283
}
274284

285+
fn debug_ty(alias: &Ty<ChalkIr>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
286+
tls::with_current_program(|prog| Some(prog?.debug_ty(alias, fmt)))
287+
}
288+
275289
fn intern_ty(&self, ty: TyData<ChalkIr>) -> Arc<TyData<ChalkIr>> {
276290
Arc::new(ty)
277291
}
278292

279-
fn ty_data(ty: &Arc<TyData<ChalkIr>>) -> &TyData<Self> {
293+
fn ty_data<'a>(&self, ty: &'a Arc<TyData<ChalkIr>>) -> &'a TyData<Self> {
280294
ty
281295
}
282296

chalk-ir/src/lib.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ impl<I: Interner> Ty<I> {
168168
}
169169
}
170170

171-
pub fn data(&self) -> &TyData<I> {
172-
I::ty_data(&self.interned)
171+
pub fn data(&self, interner: &I) -> &TyData<I> {
172+
I::ty_data(interner, &self.interned)
173173
}
174174

175175
pub fn from_env(&self) -> FromEnv<I> {
@@ -181,25 +181,25 @@ impl<I: Interner> Ty<I> {
181181
}
182182

183183
/// If this is a `TyData::BoundVar(d)`, returns `Some(d)` else `None`.
184-
pub fn bound(&self) -> Option<usize> {
185-
if let TyData::BoundVar(depth) = self.data() {
184+
pub fn bound(&self, interner: &I) -> Option<usize> {
185+
if let TyData::BoundVar(depth) = self.data(interner) {
186186
Some(*depth)
187187
} else {
188188
None
189189
}
190190
}
191191

192192
/// If this is a `TyData::InferenceVar(d)`, returns `Some(d)` else `None`.
193-
pub fn inference_var(&self) -> Option<InferenceVar> {
194-
if let TyData::InferenceVar(depth) = self.data() {
193+
pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
194+
if let TyData::InferenceVar(depth) = self.data(interner) {
195195
Some(*depth)
196196
} else {
197197
None
198198
}
199199
}
200200

201-
pub fn is_alias(&self) -> bool {
202-
match self.data() {
201+
pub fn is_alias(&self, interner: &I) -> bool {
202+
match self.data(interner) {
203203
TyData::Alias(..) => true,
204204
_ => false,
205205
}
@@ -1009,11 +1009,12 @@ pub struct UCanonical<T> {
10091009
impl<T> UCanonical<T> {
10101010
pub fn is_trivial_substitution<I: Interner>(
10111011
&self,
1012+
interner: &I,
10121013
canonical_subst: &Canonical<AnswerSubst<I>>,
10131014
) -> bool {
10141015
let subst = &canonical_subst.value.subst;
10151016
assert_eq!(self.canonical.binders.len(), subst.parameters().len());
1016-
subst.is_identity_subst()
1017+
subst.is_identity_subst(interner)
10171018
}
10181019
}
10191020

@@ -1293,11 +1294,11 @@ impl<I: Interner> Substitution<I> {
12931294
///
12941295
/// Basically, each value is mapped to a type or lifetime with its
12951296
/// same index.
1296-
pub fn is_identity_subst(&self) -> bool {
1297+
pub fn is_identity_subst(&self, interner: &I) -> bool {
12971298
self.iter()
12981299
.zip(0..)
12991300
.all(|(parameter, index)| match parameter.data() {
1300-
ParameterKind::Ty(ty) => match ty.data() {
1301+
ParameterKind::Ty(ty) => match ty.data(interner) {
13011302
TyData::BoundVar(depth) => index == *depth,
13021303
_ => false,
13031304
},

chalk-ir/src/tls.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::interner::ChalkIr;
2-
use crate::{AliasTy, AssocTypeId, StructId, TraitId};
2+
use crate::{AliasTy, AssocTypeId, StructId, TraitId, Ty};
33
use std::cell::RefCell;
44
use std::fmt;
55
use std::sync::Arc;
@@ -32,6 +32,8 @@ pub trait DebugContext {
3232
alias: &AliasTy<ChalkIr>,
3333
fmt: &mut fmt::Formatter<'_>,
3434
) -> Result<(), fmt::Error>;
35+
36+
fn debug_ty(&self, ty: &Ty<ChalkIr>, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error>;
3537
}
3638

3739
pub fn with_current_program<R>(op: impl FnOnce(Option<&Arc<dyn DebugContext>>) -> R) -> R {

chalk-solve/src/clauses.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn push_auto_trait_impls<I: Interner>(
7777
name: struct_id.cast(interner),
7878
substitution: builder.substitution_in_scope(),
7979
}
80-
.intern(builder.interner());
80+
.intern(interner);
8181

8282
// trait_ref = `MyStruct<...>: MyAutoTrait`
8383
let auto_trait_ref = TraitRef {
@@ -116,12 +116,13 @@ pub(crate) fn program_clauses_for_goal<'db, I: Interner>(
116116
goal,
117117
environment
118118
);
119+
let interner = db.interner();
119120

120121
let mut vec = vec![];
121122
vec.extend(db.custom_clauses());
122123
program_clauses_that_could_match(db, environment, goal, &mut vec);
123124
program_clauses_for_env(db, environment, &mut vec);
124-
vec.retain(|c| c.could_match(goal));
125+
vec.retain(|c| c.could_match(interner, goal));
125126

126127
debug!("vec = {:#?}", vec);
127128

@@ -138,6 +139,7 @@ fn program_clauses_that_could_match<I: Interner>(
138139
goal: &DomainGoal<I>,
139140
clauses: &mut Vec<ProgramClause<I>>,
140141
) {
142+
let interner = db.interner();
141143
let builder = &mut ClauseBuilder::new(db, clauses);
142144

143145
match goal {
@@ -158,7 +160,7 @@ fn program_clauses_that_could_match<I: Interner>(
158160
// the automatic impls for `Foo`.
159161
let trait_datum = db.trait_datum(trait_id);
160162
if trait_datum.is_auto_trait() {
161-
match trait_ref.self_type_parameter().data() {
163+
match trait_ref.self_type_parameter().data(interner) {
162164
TyData::Apply(apply) => {
163165
if let Some(struct_id) = db.as_struct_id(&apply.name) {
164166
push_auto_trait_impls(builder, trait_id, struct_id);
@@ -213,7 +215,7 @@ fn program_clauses_that_could_match<I: Interner>(
213215
// that goal, because they let us prove other things but
214216
// not `Clone`.
215217
let self_ty = trait_ref.self_type_parameter();
216-
if let TyData::Dyn(dyn_ty) = self_ty.data() {
218+
if let TyData::Dyn(dyn_ty) = self_ty.data(interner) {
217219
// In this arm, `self_ty` is the `dyn Fn(&u8)`,
218220
// and `bounded_ty` is the `exists<T> { .. }`
219221
// clauses shown above.
@@ -225,8 +227,7 @@ fn program_clauses_that_could_match<I: Interner>(
225227
// ```
226228
// forall<'a> { Implemented(dyn Fn(&u8): Fn<(&'a u8)>) }
227229
// ```
228-
let qwc = exists_qwc
229-
.substitute(db.interner(), &[self_ty.clone().cast(builder.interner())]);
230+
let qwc = exists_qwc.substitute(interner, &[self_ty.clone().cast(interner)]);
230231

231232
builder.push_binders(&qwc, |builder, wc| {
232233
builder.push_fact(wc);
@@ -338,7 +339,8 @@ fn match_ty<I: Interner>(
338339
environment: &Environment<I>,
339340
ty: &Ty<I>,
340341
) {
341-
match ty.data() {
342+
let interner = builder.interner();
343+
match ty.data(interner) {
342344
TyData::Apply(application_ty) => match_type_name(builder, application_ty.name),
343345
TyData::Placeholder(_) => {}
344346
TyData::Alias(alias_ty) => builder

0 commit comments

Comments
 (0)