aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/chalk.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs667
1 files changed, 310 insertions, 357 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 35de37e6b..555930c9b 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -1,32 +1,99 @@
1//! Conversion code from/to Chalk. 1//! Conversion code from/to Chalk.
2use std::sync::Arc; 2use std::{fmt, sync::Arc};
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{ 6use chalk_ir::{cast::Cast, Parameter, PlaceholderIndex, TypeName, UniverseIndex};
7 cast::Cast, family::ChalkIr, Identifier, Parameter, PlaceholderIndex, TypeId, TypeKindId,
8 TypeName, UniverseIndex,
9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11use ra_db::CrateId;
12 7
13use hir_def::{ 8use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
14 expr::Expr, lang_item::LangItemTarget, AssocItemId, AstItemDef, ContainerId, GenericDefId, 9use ra_db::{
15 ImplId, Lookup, TraitId, TypeAliasId, 10 salsa::{InternId, InternKey},
11 CrateId,
16}; 12};
17use hir_expand::name;
18
19use ra_db::salsa::{InternId, InternKey};
20 13
21use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 14use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
22use crate::{ 15use crate::{
23 db::HirDatabase, display::HirDisplay, ApplicationTy, GenericPredicate, ImplTy, ProjectionTy, 16 db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate,
24 Substs, TraitRef, Ty, TypeCtor, TypeWalk, 17 ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
25}; 18};
26 19
27/// This represents a trait whose name we could not resolve. 20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
28const UNKNOWN_TRAIT: chalk_ir::TraitId = 21pub struct TypeFamily {}
29 chalk_ir::TraitId(chalk_ir::RawId { index: u32::max_value() }); 22
23impl chalk_ir::family::TypeFamily for TypeFamily {
24 type InternedType = Box<chalk_ir::TyData<Self>>;
25 type InternedLifetime = chalk_ir::LifetimeData<Self>;
26 type InternedParameter = chalk_ir::ParameterData<Self>;
27 type DefId = InternId;
28
29 // FIXME: implement these
30 fn debug_struct_id(
31 _type_kind_id: chalk_ir::StructId<Self>,
32 _fmt: &mut fmt::Formatter<'_>,
33 ) -> Option<fmt::Result> {
34 None
35 }
36
37 fn debug_trait_id(
38 _type_kind_id: chalk_ir::TraitId<Self>,
39 _fmt: &mut fmt::Formatter<'_>,
40 ) -> Option<fmt::Result> {
41 None
42 }
43
44 fn debug_assoc_type_id(
45 _id: chalk_ir::AssocTypeId<Self>,
46 _fmt: &mut fmt::Formatter<'_>,
47 ) -> Option<fmt::Result> {
48 None
49 }
50
51 fn debug_projection(
52 _projection: &chalk_ir::ProjectionTy<Self>,
53 _fmt: &mut fmt::Formatter<'_>,
54 ) -> Option<fmt::Result> {
55 None
56 }
57
58 fn intern_ty(ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> {
59 Box::new(ty)
60 }
61
62 fn ty_data(ty: &Box<chalk_ir::TyData<Self>>) -> &chalk_ir::TyData<Self> {
63 ty
64 }
65
66 fn intern_lifetime(lifetime: chalk_ir::LifetimeData<Self>) -> chalk_ir::LifetimeData<Self> {
67 lifetime
68 }
69
70 fn lifetime_data(lifetime: &chalk_ir::LifetimeData<Self>) -> &chalk_ir::LifetimeData<Self> {
71 lifetime
72 }
73
74 fn intern_parameter(parameter: chalk_ir::ParameterData<Self>) -> chalk_ir::ParameterData<Self> {
75 parameter
76 }
77
78 fn parameter_data(parameter: &chalk_ir::ParameterData<Self>) -> &chalk_ir::ParameterData<Self> {
79 parameter
80 }
81}
82
83impl chalk_ir::family::HasTypeFamily for TypeFamily {
84 type TypeFamily = Self;
85}
86
87pub type AssocTypeId = chalk_ir::AssocTypeId<TypeFamily>;
88pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<TypeFamily>;
89pub type TraitId = chalk_ir::TraitId<TypeFamily>;
90pub type TraitDatum = chalk_rust_ir::TraitDatum<TypeFamily>;
91pub type StructId = chalk_ir::StructId<TypeFamily>;
92pub type StructDatum = chalk_rust_ir::StructDatum<TypeFamily>;
93pub type ImplId = chalk_ir::ImplId<TypeFamily>;
94pub type ImplDatum = chalk_rust_ir::ImplDatum<TypeFamily>;
95pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId;
96pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<TypeFamily>;
30 97
31pub(super) trait ToChalk { 98pub(super) trait ToChalk {
32 type Chalk; 99 type Chalk;
@@ -42,21 +109,11 @@ where
42} 109}
43 110
44impl ToChalk for Ty { 111impl ToChalk for Ty {
45 type Chalk = chalk_ir::Ty<ChalkIr>; 112 type Chalk = chalk_ir::Ty<TypeFamily>;
46 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<ChalkIr> { 113 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<TypeFamily> {
47 match self { 114 match self {
48 Ty::Apply(apply_ty) => { 115 Ty::Apply(apply_ty) => {
49 let name = match apply_ty.ctor { 116 let name = apply_ty.ctor.to_chalk(db);
50 TypeCtor::AssociatedType(type_alias) => {
51 let type_id = type_alias.to_chalk(db);
52 TypeName::AssociatedType(type_id)
53 }
54 _ => {
55 // other TypeCtors get interned and turned into a chalk StructId
56 let struct_id = apply_ty.ctor.to_chalk(db);
57 TypeName::TypeKindId(struct_id.into())
58 }
59 };
60 let parameters = apply_ty.parameters.to_chalk(db); 117 let parameters = apply_ty.parameters.to_chalk(db);
61 chalk_ir::ApplicationTy { name, parameters }.cast().intern() 118 chalk_ir::ApplicationTy { name, parameters }.cast().intern()
62 } 119 }
@@ -66,17 +123,30 @@ impl ToChalk for Ty {
66 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast().intern() 123 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast().intern()
67 } 124 }
68 Ty::Param { idx, .. } => { 125 Ty::Param { idx, .. } => {
69 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty::<ChalkIr>() 126 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }
127 .to_ty::<TypeFamily>()
70 } 128 }
71 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), 129 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(),
72 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 130 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
73 Ty::Dyn(predicates) => { 131 Ty::Dyn(predicates) => {
74 let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); 132 let where_clauses = predicates
75 chalk_ir::TyData::Dyn(make_binders(where_clauses, 1)).intern() 133 .iter()
134 .filter(|p| !p.is_error())
135 .cloned()
136 .map(|p| p.to_chalk(db))
137 .collect();
138 let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) };
139 chalk_ir::TyData::Dyn(bounded_ty).intern()
76 } 140 }
77 Ty::Opaque(predicates) => { 141 Ty::Opaque(predicates) => {
78 let where_clauses = predicates.iter().cloned().map(|p| p.to_chalk(db)).collect(); 142 let where_clauses = predicates
79 chalk_ir::TyData::Opaque(make_binders(where_clauses, 1)).intern() 143 .iter()
144 .filter(|p| !p.is_error())
145 .cloned()
146 .map(|p| p.to_chalk(db))
147 .collect();
148 let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) };
149 chalk_ir::TyData::Opaque(bounded_ty).intern()
80 } 150 }
81 Ty::Unknown => { 151 Ty::Unknown => {
82 let parameters = Vec::new(); 152 let parameters = Vec::new();
@@ -85,30 +155,19 @@ impl ToChalk for Ty {
85 } 155 }
86 } 156 }
87 } 157 }
88 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<ChalkIr>) -> Self { 158 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<TypeFamily>) -> Self {
89 match chalk.data().clone() { 159 match chalk.data().clone() {
90 chalk_ir::TyData::Apply(apply_ty) => { 160 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
91 // FIXME this is kind of hacky due to the fact that 161 TypeName::Error => Ty::Unknown,
92 // TypeName::Placeholder is a Ty::Param on our side 162 _ => {
93 match apply_ty.name { 163 let ctor = from_chalk(db, apply_ty.name);
94 TypeName::TypeKindId(TypeKindId::StructId(struct_id)) => { 164 let parameters = from_chalk(db, apply_ty.parameters);
95 let ctor = from_chalk(db, struct_id); 165 Ty::Apply(ApplicationTy { ctor, parameters })
96 let parameters = from_chalk(db, apply_ty.parameters);
97 Ty::Apply(ApplicationTy { ctor, parameters })
98 }
99 TypeName::AssociatedType(type_id) => {
100 let ctor = TypeCtor::AssociatedType(from_chalk(db, type_id));
101 let parameters = from_chalk(db, apply_ty.parameters);
102 Ty::Apply(ApplicationTy { ctor, parameters })
103 }
104 TypeName::Error => Ty::Unknown,
105 // FIXME handle TypeKindId::Trait/Type here
106 TypeName::TypeKindId(_) => unimplemented!(),
107 TypeName::Placeholder(idx) => {
108 assert_eq!(idx.ui, UniverseIndex::ROOT);
109 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() }
110 }
111 } 166 }
167 },
168 chalk_ir::TyData::Placeholder(idx) => {
169 assert_eq!(idx.ui, UniverseIndex::ROOT);
170 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() }
112 } 171 }
113 chalk_ir::TyData::Projection(proj) => { 172 chalk_ir::TyData::Projection(proj) => {
114 let associated_ty = from_chalk(db, proj.associated_ty_id); 173 let associated_ty = from_chalk(db, proj.associated_ty_id);
@@ -119,15 +178,15 @@ impl ToChalk for Ty {
119 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32), 178 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32),
120 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, 179 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
121 chalk_ir::TyData::Dyn(where_clauses) => { 180 chalk_ir::TyData::Dyn(where_clauses) => {
122 assert_eq!(where_clauses.binders.len(), 1); 181 assert_eq!(where_clauses.bounds.binders.len(), 1);
123 let predicates = 182 let predicates =
124 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); 183 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect();
125 Ty::Dyn(predicates) 184 Ty::Dyn(predicates)
126 } 185 }
127 chalk_ir::TyData::Opaque(where_clauses) => { 186 chalk_ir::TyData::Opaque(where_clauses) => {
128 assert_eq!(where_clauses.binders.len(), 1); 187 assert_eq!(where_clauses.bounds.binders.len(), 1);
129 let predicates = 188 let predicates =
130 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); 189 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect();
131 Ty::Opaque(predicates) 190 Ty::Opaque(predicates)
132 } 191 }
133 } 192 }
@@ -135,18 +194,21 @@ impl ToChalk for Ty {
135} 194}
136 195
137impl ToChalk for Substs { 196impl ToChalk for Substs {
138 type Chalk = Vec<chalk_ir::Parameter<ChalkIr>>; 197 type Chalk = Vec<chalk_ir::Parameter<TypeFamily>>;
139 198
140 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<ChalkIr>> { 199 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<TypeFamily>> {
141 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() 200 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect()
142 } 201 }
143 202
144 fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter<ChalkIr>>) -> Substs { 203 fn from_chalk(
204 db: &impl HirDatabase,
205 parameters: Vec<chalk_ir::Parameter<TypeFamily>>,
206 ) -> Substs {
145 let tys = parameters 207 let tys = parameters
146 .into_iter() 208 .into_iter()
147 .map(|p| match p { 209 .map(|p| match p.ty() {
148 chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty), 210 Some(ty) => from_chalk(db, ty.clone()),
149 chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(), 211 None => unimplemented!(),
150 }) 212 })
151 .collect(); 213 .collect();
152 Substs(tys) 214 Substs(tys)
@@ -154,88 +216,102 @@ impl ToChalk for Substs {
154} 216}
155 217
156impl ToChalk for TraitRef { 218impl ToChalk for TraitRef {
157 type Chalk = chalk_ir::TraitRef<ChalkIr>; 219 type Chalk = chalk_ir::TraitRef<TypeFamily>;
158 220
159 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<ChalkIr> { 221 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<TypeFamily> {
160 let trait_id = self.trait_.to_chalk(db); 222 let trait_id = self.trait_.to_chalk(db);
161 let parameters = self.substs.to_chalk(db); 223 let parameters = self.substs.to_chalk(db);
162 chalk_ir::TraitRef { trait_id, parameters } 224 chalk_ir::TraitRef { trait_id, parameters }
163 } 225 }
164 226
165 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<ChalkIr>) -> Self { 227 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<TypeFamily>) -> Self {
166 let trait_ = from_chalk(db, trait_ref.trait_id); 228 let trait_ = from_chalk(db, trait_ref.trait_id);
167 let substs = from_chalk(db, trait_ref.parameters); 229 let substs = from_chalk(db, trait_ref.parameters);
168 TraitRef { trait_, substs } 230 TraitRef { trait_, substs }
169 } 231 }
170} 232}
171 233
172impl ToChalk for TraitId { 234impl ToChalk for hir_def::TraitId {
173 type Chalk = chalk_ir::TraitId; 235 type Chalk = TraitId;
174 236
175 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { 237 fn to_chalk(self, _db: &impl HirDatabase) -> TraitId {
176 chalk_ir::TraitId(id_to_chalk(self)) 238 chalk_ir::TraitId(self.as_intern_id())
177 } 239 }
178 240
179 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId { 241 fn from_chalk(_db: &impl HirDatabase, trait_id: TraitId) -> hir_def::TraitId {
180 id_from_chalk(trait_id.0) 242 InternKey::from_intern_id(trait_id.0)
181 } 243 }
182} 244}
183 245
184impl ToChalk for TypeCtor { 246impl ToChalk for TypeCtor {
185 type Chalk = chalk_ir::StructId; 247 type Chalk = TypeName<TypeFamily>;
186 248
187 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::StructId { 249 fn to_chalk(self, db: &impl HirDatabase) -> TypeName<TypeFamily> {
188 db.intern_type_ctor(self).into() 250 match self {
251 TypeCtor::AssociatedType(type_alias) => {
252 let type_id = type_alias.to_chalk(db);
253 TypeName::AssociatedType(type_id)
254 }
255 _ => {
256 // other TypeCtors get interned and turned into a chalk StructId
257 let struct_id = db.intern_type_ctor(self).into();
258 TypeName::Struct(struct_id)
259 }
260 }
189 } 261 }
190 262
191 fn from_chalk(db: &impl HirDatabase, struct_id: chalk_ir::StructId) -> TypeCtor { 263 fn from_chalk(db: &impl HirDatabase, type_name: TypeName<TypeFamily>) -> TypeCtor {
192 db.lookup_intern_type_ctor(struct_id.into()) 264 match type_name {
265 TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
266 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
267 TypeName::Error => {
268 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
269 unreachable!()
270 }
271 }
193 } 272 }
194} 273}
195 274
196impl ToChalk for Impl { 275impl ToChalk for Impl {
197 type Chalk = chalk_ir::ImplId; 276 type Chalk = ImplId;
198 277
199 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ImplId { 278 fn to_chalk(self, db: &impl HirDatabase) -> ImplId {
200 db.intern_chalk_impl(self).into() 279 db.intern_chalk_impl(self).into()
201 } 280 }
202 281
203 fn from_chalk(db: &impl HirDatabase, impl_id: chalk_ir::ImplId) -> Impl { 282 fn from_chalk(db: &impl HirDatabase, impl_id: ImplId) -> Impl {
204 db.lookup_intern_chalk_impl(impl_id.into()) 283 db.lookup_intern_chalk_impl(impl_id.into())
205 } 284 }
206} 285}
207 286
208impl ToChalk for TypeAliasId { 287impl ToChalk for TypeAliasId {
209 type Chalk = chalk_ir::TypeId; 288 type Chalk = AssocTypeId;
210 289
211 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { 290 fn to_chalk(self, _db: &impl HirDatabase) -> AssocTypeId {
212 chalk_ir::TypeId(id_to_chalk(self)) 291 chalk_ir::AssocTypeId(self.as_intern_id())
213 } 292 }
214 293
215 fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAliasId { 294 fn from_chalk(_db: &impl HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId {
216 id_from_chalk(type_alias_id.0) 295 InternKey::from_intern_id(type_alias_id.0)
217 } 296 }
218} 297}
219 298
220impl ToChalk for AssocTyValue { 299impl ToChalk for AssocTyValue {
221 type Chalk = chalk_rust_ir::AssociatedTyValueId; 300 type Chalk = AssociatedTyValueId;
222 301
223 fn to_chalk(self, db: &impl HirDatabase) -> chalk_rust_ir::AssociatedTyValueId { 302 fn to_chalk(self, db: &impl HirDatabase) -> AssociatedTyValueId {
224 db.intern_assoc_ty_value(self).into() 303 db.intern_assoc_ty_value(self).into()
225 } 304 }
226 305
227 fn from_chalk( 306 fn from_chalk(db: &impl HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue {
228 db: &impl HirDatabase,
229 assoc_ty_value_id: chalk_rust_ir::AssociatedTyValueId,
230 ) -> AssocTyValue {
231 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into()) 307 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into())
232 } 308 }
233} 309}
234 310
235impl ToChalk for GenericPredicate { 311impl ToChalk for GenericPredicate {
236 type Chalk = chalk_ir::QuantifiedWhereClause<ChalkIr>; 312 type Chalk = chalk_ir::QuantifiedWhereClause<TypeFamily>;
237 313
238 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<ChalkIr> { 314 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<TypeFamily> {
239 match self { 315 match self {
240 GenericPredicate::Implemented(trait_ref) => { 316 GenericPredicate::Implemented(trait_ref) => {
241 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 317 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
@@ -247,26 +323,16 @@ impl ToChalk for GenericPredicate {
247 }), 323 }),
248 0, 324 0,
249 ), 325 ),
250 GenericPredicate::Error => { 326 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
251 let impossible_trait_ref = chalk_ir::TraitRef {
252 trait_id: UNKNOWN_TRAIT,
253 parameters: vec![Ty::Unknown.to_chalk(db).cast()],
254 };
255 make_binders(chalk_ir::WhereClause::Implemented(impossible_trait_ref), 0)
256 }
257 } 327 }
258 } 328 }
259 329
260 fn from_chalk( 330 fn from_chalk(
261 db: &impl HirDatabase, 331 db: &impl HirDatabase,
262 where_clause: chalk_ir::QuantifiedWhereClause<ChalkIr>, 332 where_clause: chalk_ir::QuantifiedWhereClause<TypeFamily>,
263 ) -> GenericPredicate { 333 ) -> GenericPredicate {
264 match where_clause.value { 334 match where_clause.value {
265 chalk_ir::WhereClause::Implemented(tr) => { 335 chalk_ir::WhereClause::Implemented(tr) => {
266 if tr.trait_id == UNKNOWN_TRAIT {
267 // FIXME we need an Error enum on the Chalk side to avoid this
268 return GenericPredicate::Error;
269 }
270 GenericPredicate::Implemented(from_chalk(db, tr)) 336 GenericPredicate::Implemented(from_chalk(db, tr))
271 } 337 }
272 chalk_ir::WhereClause::ProjectionEq(projection_eq) => { 338 chalk_ir::WhereClause::ProjectionEq(projection_eq) => {
@@ -279,9 +345,9 @@ impl ToChalk for GenericPredicate {
279} 345}
280 346
281impl ToChalk for ProjectionTy { 347impl ToChalk for ProjectionTy {
282 type Chalk = chalk_ir::ProjectionTy<ChalkIr>; 348 type Chalk = chalk_ir::ProjectionTy<TypeFamily>;
283 349
284 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<ChalkIr> { 350 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<TypeFamily> {
285 chalk_ir::ProjectionTy { 351 chalk_ir::ProjectionTy {
286 associated_ty_id: self.associated_ty.to_chalk(db), 352 associated_ty_id: self.associated_ty.to_chalk(db),
287 parameters: self.parameters.to_chalk(db), 353 parameters: self.parameters.to_chalk(db),
@@ -290,7 +356,7 @@ impl ToChalk for ProjectionTy {
290 356
291 fn from_chalk( 357 fn from_chalk(
292 db: &impl HirDatabase, 358 db: &impl HirDatabase,
293 projection_ty: chalk_ir::ProjectionTy<ChalkIr>, 359 projection_ty: chalk_ir::ProjectionTy<TypeFamily>,
294 ) -> ProjectionTy { 360 ) -> ProjectionTy {
295 ProjectionTy { 361 ProjectionTy {
296 associated_ty: from_chalk(db, projection_ty.associated_ty_id), 362 associated_ty: from_chalk(db, projection_ty.associated_ty_id),
@@ -300,31 +366,31 @@ impl ToChalk for ProjectionTy {
300} 366}
301 367
302impl ToChalk for super::ProjectionPredicate { 368impl ToChalk for super::ProjectionPredicate {
303 type Chalk = chalk_ir::Normalize<ChalkIr>; 369 type Chalk = chalk_ir::Normalize<TypeFamily>;
304 370
305 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<ChalkIr> { 371 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<TypeFamily> {
306 chalk_ir::Normalize { 372 chalk_ir::Normalize {
307 projection: self.projection_ty.to_chalk(db), 373 projection: self.projection_ty.to_chalk(db),
308 ty: self.ty.to_chalk(db), 374 ty: self.ty.to_chalk(db),
309 } 375 }
310 } 376 }
311 377
312 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<ChalkIr>) -> Self { 378 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<TypeFamily>) -> Self {
313 unimplemented!() 379 unimplemented!()
314 } 380 }
315} 381}
316 382
317impl ToChalk for Obligation { 383impl ToChalk for Obligation {
318 type Chalk = chalk_ir::DomainGoal<ChalkIr>; 384 type Chalk = chalk_ir::DomainGoal<TypeFamily>;
319 385
320 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<ChalkIr> { 386 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<TypeFamily> {
321 match self { 387 match self {
322 Obligation::Trait(tr) => tr.to_chalk(db).cast(), 388 Obligation::Trait(tr) => tr.to_chalk(db).cast(),
323 Obligation::Projection(pr) => pr.to_chalk(db).cast(), 389 Obligation::Projection(pr) => pr.to_chalk(db).cast(),
324 } 390 }
325 } 391 }
326 392
327 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<ChalkIr>) -> Self { 393 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<TypeFamily>) -> Self {
328 unimplemented!() 394 unimplemented!()
329 } 395 }
330} 396}
@@ -348,16 +414,17 @@ where
348} 414}
349 415
350impl ToChalk for Arc<super::TraitEnvironment> { 416impl ToChalk for Arc<super::TraitEnvironment> {
351 type Chalk = chalk_ir::Environment<ChalkIr>; 417 type Chalk = chalk_ir::Environment<TypeFamily>;
352 418
353 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<ChalkIr> { 419 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<TypeFamily> {
354 let mut clauses = Vec::new(); 420 let mut clauses = Vec::new();
355 for pred in &self.predicates { 421 for pred in &self.predicates {
356 if pred.is_error() { 422 if pred.is_error() {
357 // for env, we just ignore errors 423 // for env, we just ignore errors
358 continue; 424 continue;
359 } 425 }
360 let program_clause: chalk_ir::ProgramClause<ChalkIr> = pred.clone().to_chalk(db).cast(); 426 let program_clause: chalk_ir::ProgramClause<TypeFamily> =
427 pred.clone().to_chalk(db).cast();
361 clauses.push(program_clause.into_from_env_clause()); 428 clauses.push(program_clause.into_from_env_clause());
362 } 429 }
363 chalk_ir::Environment::new().add_clauses(clauses) 430 chalk_ir::Environment::new().add_clauses(clauses)
@@ -365,7 +432,7 @@ impl ToChalk for Arc<super::TraitEnvironment> {
365 432
366 fn from_chalk( 433 fn from_chalk(
367 _db: &impl HirDatabase, 434 _db: &impl HirDatabase,
368 _env: chalk_ir::Environment<ChalkIr>, 435 _env: chalk_ir::Environment<TypeFamily>,
369 ) -> Arc<super::TraitEnvironment> { 436 ) -> Arc<super::TraitEnvironment> {
370 unimplemented!() 437 unimplemented!()
371 } 438 }
@@ -373,7 +440,7 @@ impl ToChalk for Arc<super::TraitEnvironment> {
373 440
374impl<T: ToChalk> ToChalk for super::InEnvironment<T> 441impl<T: ToChalk> ToChalk for super::InEnvironment<T>
375where 442where
376 T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = ChalkIr>, 443 T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = TypeFamily>,
377{ 444{
378 type Chalk = chalk_ir::InEnvironment<T::Chalk>; 445 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
379 446
@@ -395,6 +462,51 @@ where
395 } 462 }
396} 463}
397 464
465impl ToChalk for builtin::BuiltinImplData {
466 type Chalk = ImplDatum;
467
468 fn to_chalk(self, db: &impl HirDatabase) -> ImplDatum {
469 let impl_type = chalk_rust_ir::ImplType::External;
470 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect();
471
472 let impl_datum_bound =
473 chalk_rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses };
474 let associated_ty_value_ids =
475 self.assoc_ty_values.into_iter().map(|v| v.to_chalk(db)).collect();
476 chalk_rust_ir::ImplDatum {
477 binders: make_binders(impl_datum_bound, self.num_vars),
478 impl_type,
479 polarity: chalk_rust_ir::Polarity::Positive,
480 associated_ty_value_ids,
481 }
482 }
483
484 fn from_chalk(_db: &impl HirDatabase, _data: ImplDatum) -> Self {
485 unimplemented!()
486 }
487}
488
489impl ToChalk for builtin::BuiltinImplAssocTyValueData {
490 type Chalk = AssociatedTyValue;
491
492 fn to_chalk(self, db: &impl HirDatabase) -> AssociatedTyValue {
493 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: self.value.to_chalk(db) };
494
495 chalk_rust_ir::AssociatedTyValue {
496 associated_ty_id: self.assoc_ty_id.to_chalk(db),
497 impl_id: self.impl_.to_chalk(db),
498 value: make_binders(value_bound, self.num_vars),
499 }
500 }
501
502 fn from_chalk(
503 _db: &impl HirDatabase,
504 _data: AssociatedTyValue,
505 ) -> builtin::BuiltinImplAssocTyValueData {
506 unimplemented!()
507 }
508}
509
398fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { 510fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
399 chalk_ir::Binders { 511 chalk_ir::Binders {
400 value, 512 value,
@@ -406,46 +518,46 @@ fn convert_where_clauses(
406 db: &impl HirDatabase, 518 db: &impl HirDatabase,
407 def: GenericDefId, 519 def: GenericDefId,
408 substs: &Substs, 520 substs: &Substs,
409) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> { 521) -> Vec<chalk_ir::QuantifiedWhereClause<TypeFamily>> {
410 let generic_predicates = db.generic_predicates(def); 522 let generic_predicates = db.generic_predicates(def);
411 let mut result = Vec::with_capacity(generic_predicates.len()); 523 let mut result = Vec::with_capacity(generic_predicates.len());
412 for pred in generic_predicates.iter() { 524 for pred in generic_predicates.iter() {
413 if pred.is_error() { 525 if pred.is_error() {
414 // HACK: Return just the single predicate (which is always false 526 // skip errored predicates completely
415 // anyway), otherwise Chalk can easily get into slow situations 527 continue;
416 return vec![pred.clone().subst(substs).to_chalk(db)];
417 } 528 }
418 result.push(pred.clone().subst(substs).to_chalk(db)); 529 result.push(pred.clone().subst(substs).to_chalk(db));
419 } 530 }
420 result 531 result
421} 532}
422 533
423impl<'a, DB> chalk_solve::RustIrDatabase<ChalkIr> for ChalkContext<'a, DB> 534impl<'a, DB> chalk_solve::RustIrDatabase<TypeFamily> for ChalkContext<'a, DB>
424where 535where
425 DB: HirDatabase, 536 DB: HirDatabase,
426{ 537{
427 fn associated_ty_data(&self, id: TypeId) -> Arc<AssociatedTyDatum<ChalkIr>> { 538 fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> {
428 self.db.associated_ty_data(id) 539 self.db.associated_ty_data(id)
429 } 540 }
430 fn trait_datum(&self, trait_id: chalk_ir::TraitId) -> Arc<TraitDatum<ChalkIr>> { 541 fn trait_datum(&self, trait_id: TraitId) -> Arc<TraitDatum> {
431 self.db.trait_datum(self.krate, trait_id) 542 self.db.trait_datum(self.krate, trait_id)
432 } 543 }
433 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum<ChalkIr>> { 544 fn struct_datum(&self, struct_id: StructId) -> Arc<StructDatum> {
434 self.db.struct_datum(self.krate, struct_id) 545 self.db.struct_datum(self.krate, struct_id)
435 } 546 }
436 fn impl_datum(&self, impl_id: chalk_ir::ImplId) -> Arc<ImplDatum<ChalkIr>> { 547 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
437 self.db.impl_datum(self.krate, impl_id) 548 self.db.impl_datum(self.krate, impl_id)
438 } 549 }
439 fn impls_for_trait( 550 fn impls_for_trait(
440 &self, 551 &self,
441 trait_id: chalk_ir::TraitId, 552 trait_id: TraitId,
442 parameters: &[Parameter<ChalkIr>], 553 parameters: &[Parameter<TypeFamily>],
443 ) -> Vec<chalk_ir::ImplId> { 554 ) -> Vec<ImplId> {
444 debug!("impls_for_trait {:?}", trait_id); 555 debug!("impls_for_trait {:?}", trait_id);
445 if trait_id == UNKNOWN_TRAIT { 556 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
446 return Vec::new(); 557
447 } 558 // Note: Since we're using impls_for_trait, only impls where the trait
448 let trait_: TraitId = from_chalk(self.db, trait_id); 559 // can be resolved should ever reach Chalk. `impl_datum` relies on that
560 // and will panic if the trait can't be resolved.
449 let mut result: Vec<_> = self 561 let mut result: Vec<_> = self
450 .db 562 .db
451 .impls_for_trait(self.krate, trait_.into()) 563 .impls_for_trait(self.krate, trait_.into())
@@ -456,62 +568,47 @@ where
456 .collect(); 568 .collect();
457 569
458 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref().clone()); 570 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref().clone());
459 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty { 571
460 for &fn_trait in 572 builtin::get_builtin_impls(self.db, self.krate, &ty, trait_, |i| {
461 [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() 573 result.push(i.to_chalk(self.db))
462 { 574 });
463 if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) {
464 if trait_ == actual_trait {
465 let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait };
466 result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db));
467 }
468 }
469 }
470 }
471 575
472 debug!("impls_for_trait returned {} impls", result.len()); 576 debug!("impls_for_trait returned {} impls", result.len());
473 result 577 result
474 } 578 }
475 fn impl_provided_for( 579 fn impl_provided_for(&self, auto_trait_id: TraitId, struct_id: StructId) -> bool {
476 &self,
477 auto_trait_id: chalk_ir::TraitId,
478 struct_id: chalk_ir::StructId,
479 ) -> bool {
480 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id); 580 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, struct_id);
481 false // FIXME 581 false // FIXME
482 } 582 }
483 fn type_name(&self, _id: TypeKindId) -> Identifier { 583 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
484 unimplemented!()
485 }
486 fn associated_ty_value(
487 &self,
488 id: chalk_rust_ir::AssociatedTyValueId,
489 ) -> Arc<AssociatedTyValue<ChalkIr>> {
490 self.db.associated_ty_value(self.krate.into(), id) 584 self.db.associated_ty_value(self.krate.into(), id)
491 } 585 }
492 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> { 586 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<TypeFamily>> {
493 vec![] 587 vec![]
494 } 588 }
495 fn local_impls_to_coherence_check( 589 fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec<ImplId> {
496 &self,
497 _trait_id: chalk_ir::TraitId,
498 ) -> Vec<chalk_ir::ImplId> {
499 // We don't do coherence checking (yet) 590 // We don't do coherence checking (yet)
500 unimplemented!() 591 unimplemented!()
501 } 592 }
593 fn as_struct_id(&self, id: &TypeName<TypeFamily>) -> Option<StructId> {
594 match id {
595 TypeName::Struct(struct_id) => Some(*struct_id),
596 _ => None,
597 }
598 }
502} 599}
503 600
504pub(crate) fn associated_ty_data_query( 601pub(crate) fn associated_ty_data_query(
505 db: &impl HirDatabase, 602 db: &impl HirDatabase,
506 id: TypeId, 603 id: AssocTypeId,
507) -> Arc<AssociatedTyDatum<ChalkIr>> { 604) -> Arc<AssociatedTyDatum> {
508 debug!("associated_ty_data {:?}", id); 605 debug!("associated_ty_data {:?}", id);
509 let type_alias: TypeAliasId = from_chalk(db, id); 606 let type_alias: TypeAliasId = from_chalk(db, id);
510 let trait_ = match type_alias.lookup(db).container { 607 let trait_ = match type_alias.lookup(db).container {
511 ContainerId::TraitId(t) => t, 608 AssocContainerId::TraitId(t) => t,
512 _ => panic!("associated type not in trait"), 609 _ => panic!("associated type not in trait"),
513 }; 610 };
514 let generic_params = db.generic_params(type_alias.into()); 611 let generic_params = generics(db, type_alias.into());
515 let bound_data = chalk_rust_ir::AssociatedTyDatumBound { 612 let bound_data = chalk_rust_ir::AssociatedTyDatumBound {
516 // FIXME add bounds and where clauses 613 // FIXME add bounds and where clauses
517 bounds: vec![], 614 bounds: vec![],
@@ -521,7 +618,7 @@ pub(crate) fn associated_ty_data_query(
521 trait_id: trait_.to_chalk(db), 618 trait_id: trait_.to_chalk(db),
522 id, 619 id,
523 name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), 620 name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()),
524 binders: make_binders(bound_data, generic_params.count_params_including_parent()), 621 binders: make_binders(bound_data, generic_params.len()),
525 }; 622 };
526 Arc::new(datum) 623 Arc::new(datum)
527} 624}
@@ -529,35 +626,17 @@ pub(crate) fn associated_ty_data_query(
529pub(crate) fn trait_datum_query( 626pub(crate) fn trait_datum_query(
530 db: &impl HirDatabase, 627 db: &impl HirDatabase,
531 krate: CrateId, 628 krate: CrateId,
532 trait_id: chalk_ir::TraitId, 629 trait_id: TraitId,
533) -> Arc<TraitDatum<ChalkIr>> { 630) -> Arc<TraitDatum> {
534 debug!("trait_datum {:?}", trait_id); 631 debug!("trait_datum {:?}", trait_id);
535 if trait_id == UNKNOWN_TRAIT { 632 let trait_: hir_def::TraitId = from_chalk(db, trait_id);
536 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses: Vec::new() };
537
538 let flags = chalk_rust_ir::TraitFlags {
539 auto: false,
540 marker: false,
541 upstream: true,
542 fundamental: false,
543 non_enumerable: true,
544 coinductive: false,
545 };
546 return Arc::new(TraitDatum {
547 id: trait_id,
548 binders: make_binders(trait_datum_bound, 1),
549 flags,
550 associated_ty_ids: vec![],
551 });
552 }
553 let trait_: TraitId = from_chalk(db, trait_id);
554 let trait_data = db.trait_data(trait_); 633 let trait_data = db.trait_data(trait_);
555 debug!("trait {:?} = {:?}", trait_id, trait_data.name); 634 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
556 let generic_params = db.generic_params(trait_.into()); 635 let generic_params = generics(db, trait_.into());
557 let bound_vars = Substs::bound_vars(&generic_params); 636 let bound_vars = Substs::bound_vars(&generic_params);
558 let flags = chalk_rust_ir::TraitFlags { 637 let flags = chalk_rust_ir::TraitFlags {
559 auto: trait_data.auto, 638 auto: trait_data.auto,
560 upstream: trait_.module(db).krate != krate, 639 upstream: trait_.lookup(db).container.module(db).krate != krate,
561 non_enumerable: true, 640 non_enumerable: true,
562 coinductive: false, // only relevant for Chalk testing 641 coinductive: false, // only relevant for Chalk testing
563 // FIXME set these flags correctly 642 // FIXME set these flags correctly
@@ -580,17 +659,17 @@ pub(crate) fn trait_datum_query(
580pub(crate) fn struct_datum_query( 659pub(crate) fn struct_datum_query(
581 db: &impl HirDatabase, 660 db: &impl HirDatabase,
582 krate: CrateId, 661 krate: CrateId,
583 struct_id: chalk_ir::StructId, 662 struct_id: StructId,
584) -> Arc<StructDatum<ChalkIr>> { 663) -> Arc<StructDatum> {
585 debug!("struct_datum {:?}", struct_id); 664 debug!("struct_datum {:?}", struct_id);
586 let type_ctor: TypeCtor = from_chalk(db, struct_id); 665 let type_ctor: TypeCtor = from_chalk(db, TypeName::Struct(struct_id));
587 debug!("struct {:?} = {:?}", struct_id, type_ctor); 666 debug!("struct {:?} = {:?}", struct_id, type_ctor);
588 let num_params = type_ctor.num_ty_params(db); 667 let num_params = type_ctor.num_ty_params(db);
589 let upstream = type_ctor.krate(db) != Some(krate); 668 let upstream = type_ctor.krate(db) != Some(krate);
590 let where_clauses = type_ctor 669 let where_clauses = type_ctor
591 .as_generic_def() 670 .as_generic_def()
592 .map(|generic_def| { 671 .map(|generic_def| {
593 let generic_params = db.generic_params(generic_def.into()); 672 let generic_params = generics(db, generic_def.into());
594 let bound_vars = Substs::bound_vars(&generic_params); 673 let bound_vars = Substs::bound_vars(&generic_params);
595 convert_where_clauses(db, generic_def, &bound_vars) 674 convert_where_clauses(db, generic_def, &bound_vars)
596 }) 675 })
@@ -612,35 +691,34 @@ pub(crate) fn struct_datum_query(
612pub(crate) fn impl_datum_query( 691pub(crate) fn impl_datum_query(
613 db: &impl HirDatabase, 692 db: &impl HirDatabase,
614 krate: CrateId, 693 krate: CrateId,
615 impl_id: chalk_ir::ImplId, 694 impl_id: ImplId,
616) -> Arc<ImplDatum<ChalkIr>> { 695) -> Arc<ImplDatum> {
617 let _p = ra_prof::profile("impl_datum"); 696 let _p = ra_prof::profile("impl_datum");
618 debug!("impl_datum {:?}", impl_id); 697 debug!("impl_datum {:?}", impl_id);
619 let impl_: Impl = from_chalk(db, impl_id); 698 let impl_: Impl = from_chalk(db, impl_id);
620 match impl_ { 699 match impl_ {
621 Impl::ImplBlock(impl_block) => impl_block_datum(db, krate, impl_id, impl_block), 700 Impl::ImplBlock(impl_block) => impl_block_datum(db, krate, impl_id, impl_block),
622 Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), 701 _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)),
623 } 702 }
624 .unwrap_or_else(invalid_impl_datum)
625} 703}
626 704
627fn impl_block_datum( 705fn impl_block_datum(
628 db: &impl HirDatabase, 706 db: &impl HirDatabase,
629 krate: CrateId, 707 krate: CrateId,
630 chalk_id: chalk_ir::ImplId, 708 chalk_id: ImplId,
631 impl_id: ImplId, 709 impl_id: hir_def::ImplId,
632) -> Option<Arc<ImplDatum<ChalkIr>>> { 710) -> Arc<ImplDatum> {
633 let trait_ref = match db.impl_ty(impl_id) { 711 let trait_ref = db
634 ImplTy::TraitRef(it) => it, 712 .impl_trait(impl_id)
635 ImplTy::Inherent(_) => return None, 713 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk
636 }; 714 .expect("invalid impl passed to Chalk");
637 let impl_data = db.impl_data(impl_id); 715 let impl_data = db.impl_data(impl_id);
638 716
639 let generic_params = db.generic_params(impl_id.into()); 717 let generic_params = generics(db, impl_id.into());
640 let bound_vars = Substs::bound_vars(&generic_params); 718 let bound_vars = Substs::bound_vars(&generic_params);
641 let trait_ref = trait_ref.subst(&bound_vars); 719 let trait_ref = trait_ref.subst(&bound_vars);
642 let trait_ = trait_ref.trait_; 720 let trait_ = trait_ref.trait_;
643 let impl_type = if impl_id.module(db).krate == krate { 721 let impl_type = if impl_id.lookup(db).container.module(db).krate == krate {
644 chalk_rust_ir::ImplType::Local 722 chalk_rust_ir::ImplType::Local
645 } else { 723 } else {
646 chalk_rust_ir::ImplType::External 724 chalk_rust_ir::ImplType::External
@@ -685,94 +763,20 @@ fn impl_block_datum(
685 polarity, 763 polarity,
686 associated_ty_value_ids, 764 associated_ty_value_ids,
687 }; 765 };
688 Some(Arc::new(impl_datum))
689}
690
691fn invalid_impl_datum() -> Arc<ImplDatum<ChalkIr>> {
692 let trait_ref = chalk_ir::TraitRef {
693 trait_id: UNKNOWN_TRAIT,
694 parameters: vec![chalk_ir::TyData::BoundVar(0).cast().intern().cast()],
695 };
696 let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses: Vec::new() };
697 let impl_datum = ImplDatum {
698 binders: make_binders(impl_datum_bound, 1),
699 impl_type: chalk_rust_ir::ImplType::External,
700 polarity: chalk_rust_ir::Polarity::Positive,
701 associated_ty_value_ids: Vec::new(),
702 };
703 Arc::new(impl_datum) 766 Arc::new(impl_datum)
704} 767}
705 768
706fn closure_fn_trait_impl_datum(
707 db: &impl HirDatabase,
708 krate: CrateId,
709 data: super::ClosureFnTraitImplData,
710) -> Option<Arc<ImplDatum<ChalkIr>>> {
711 // for some closure |X, Y| -> Z:
712 // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V }
713
714 let trait_ = get_fn_trait(db, krate, data.fn_trait)?; // get corresponding fn trait
715
716 // validate FnOnce trait, since we need it in the assoc ty value definition
717 // and don't want to return a valid value only to find out later that FnOnce
718 // is broken
719 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
720 let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name::OUTPUT_TYPE)?;
721
722 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
723 Expr::Lambda { args, .. } => args.len() as u16,
724 _ => {
725 log::warn!("closure for closure type {:?} not found", data);
726 0
727 }
728 };
729
730 let arg_ty = Ty::apply(
731 TypeCtor::Tuple { cardinality: num_args },
732 Substs::builder(num_args as usize).fill_with_bound_vars(0).build(),
733 );
734 let sig_ty = Ty::apply(
735 TypeCtor::FnPtr { num_args },
736 Substs::builder(num_args as usize + 1).fill_with_bound_vars(0).build(),
737 );
738
739 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty);
740
741 let trait_ref = TraitRef {
742 trait_: trait_.into(),
743 substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(),
744 };
745
746 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()).to_chalk(db);
747
748 let impl_type = chalk_rust_ir::ImplType::External;
749
750 let impl_datum_bound = chalk_rust_ir::ImplDatumBound {
751 trait_ref: trait_ref.to_chalk(db),
752 where_clauses: Vec::new(),
753 };
754 let impl_datum = ImplDatum {
755 binders: make_binders(impl_datum_bound, num_args as usize + 1),
756 impl_type,
757 polarity: chalk_rust_ir::Polarity::Positive,
758 associated_ty_value_ids: vec![output_ty_id],
759 };
760 Some(Arc::new(impl_datum))
761}
762
763pub(crate) fn associated_ty_value_query( 769pub(crate) fn associated_ty_value_query(
764 db: &impl HirDatabase, 770 db: &impl HirDatabase,
765 krate: CrateId, 771 krate: CrateId,
766 id: chalk_rust_ir::AssociatedTyValueId, 772 id: AssociatedTyValueId,
767) -> Arc<chalk_rust_ir::AssociatedTyValue<ChalkIr>> { 773) -> Arc<AssociatedTyValue> {
768 let data: AssocTyValue = from_chalk(db, id); 774 let data: AssocTyValue = from_chalk(db, id);
769 match data { 775 match data {
770 AssocTyValue::TypeAlias(type_alias) => { 776 AssocTyValue::TypeAlias(type_alias) => {
771 type_alias_associated_ty_value(db, krate, type_alias) 777 type_alias_associated_ty_value(db, krate, type_alias)
772 } 778 }
773 AssocTyValue::ClosureFnTraitImplOutput(data) => { 779 _ => Arc::new(builtin::associated_ty_value(db, krate, data).to_chalk(db)),
774 closure_fn_trait_output_assoc_ty_value(db, krate, data)
775 }
776 } 780 }
777} 781}
778 782
@@ -780,24 +784,20 @@ fn type_alias_associated_ty_value(
780 db: &impl HirDatabase, 784 db: &impl HirDatabase,
781 _krate: CrateId, 785 _krate: CrateId,
782 type_alias: TypeAliasId, 786 type_alias: TypeAliasId,
783) -> Arc<AssociatedTyValue<ChalkIr>> { 787) -> Arc<AssociatedTyValue> {
784 let type_alias_data = db.type_alias_data(type_alias); 788 let type_alias_data = db.type_alias_data(type_alias);
785 let impl_id = match type_alias.lookup(db).container { 789 let impl_id = match type_alias.lookup(db).container {
786 ContainerId::ImplId(it) => it, 790 AssocContainerId::ImplId(it) => it,
787 _ => panic!("assoc ty value should be in impl"), 791 _ => panic!("assoc ty value should be in impl"),
788 }; 792 };
789 793
790 let trait_ref = match db.impl_ty(impl_id) { 794 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved
791 ImplTy::TraitRef(it) => it,
792 // we don't return any assoc ty values if the impl'd trait can't be resolved
793 ImplTy::Inherent(_) => panic!("assoc ty value should not exist"),
794 };
795 795
796 let assoc_ty = db 796 let assoc_ty = db
797 .trait_data(trait_ref.trait_) 797 .trait_data(trait_ref.trait_)
798 .associated_type_by_name(&type_alias_data.name) 798 .associated_type_by_name(&type_alias_data.name)
799 .expect("assoc ty value should not exist"); // validated when building the impl data as well 799 .expect("assoc ty value should not exist"); // validated when building the impl data as well
800 let generic_params = db.generic_params(impl_id.into()); 800 let generic_params = generics(db, impl_id.into());
801 let bound_vars = Substs::bound_vars(&generic_params); 801 let bound_vars = Substs::bound_vars(&generic_params);
802 let ty = db.ty(type_alias.into()).subst(&bound_vars); 802 let ty = db.ty(type_alias.into()).subst(&bound_vars);
803 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; 803 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
@@ -809,53 +809,6 @@ fn type_alias_associated_ty_value(
809 Arc::new(value) 809 Arc::new(value)
810} 810}
811 811
812fn closure_fn_trait_output_assoc_ty_value(
813 db: &impl HirDatabase,
814 krate: CrateId,
815 data: super::ClosureFnTraitImplData,
816) -> Arc<AssociatedTyValue<ChalkIr>> {
817 let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db);
818
819 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
820 Expr::Lambda { args, .. } => args.len() as u16,
821 _ => {
822 log::warn!("closure for closure type {:?} not found", data);
823 0
824 }
825 };
826
827 let output_ty = Ty::Bound(num_args.into());
828
829 let fn_once_trait =
830 get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist");
831
832 let output_ty_id = db
833 .trait_data(fn_once_trait)
834 .associated_type_by_name(&name::OUTPUT_TYPE)
835 .expect("assoc ty value should not exist");
836
837 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: output_ty.to_chalk(db) };
838
839 let value = chalk_rust_ir::AssociatedTyValue {
840 associated_ty_id: output_ty_id.to_chalk(db),
841 impl_id,
842 value: make_binders(value_bound, num_args as usize + 1),
843 };
844 Arc::new(value)
845}
846
847fn get_fn_trait(
848 db: &impl HirDatabase,
849 krate: CrateId,
850 fn_trait: super::FnTrait,
851) -> Option<TraitId> {
852 let target = db.lang_item(krate, fn_trait.lang_item_name().into())?;
853 match target {
854 LangItemTarget::TraitId(t) => Some(t),
855 _ => None,
856 }
857}
858
859fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T { 812fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T {
860 T::from_intern_id(InternId::from(chalk_id.index)) 813 T::from_intern_id(InternId::from(chalk_id.index))
861} 814}
@@ -863,27 +816,27 @@ fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId {
863 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } 816 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() }
864} 817}
865 818
866impl From<chalk_ir::StructId> for crate::TypeCtorId { 819impl From<StructId> for crate::TypeCtorId {
867 fn from(struct_id: chalk_ir::StructId) -> Self { 820 fn from(struct_id: StructId) -> Self {
868 id_from_chalk(struct_id.0) 821 InternKey::from_intern_id(struct_id.0)
869 } 822 }
870} 823}
871 824
872impl From<crate::TypeCtorId> for chalk_ir::StructId { 825impl From<crate::TypeCtorId> for StructId {
873 fn from(type_ctor_id: crate::TypeCtorId) -> Self { 826 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
874 chalk_ir::StructId(id_to_chalk(type_ctor_id)) 827 chalk_ir::StructId(type_ctor_id.as_intern_id())
875 } 828 }
876} 829}
877 830
878impl From<chalk_ir::ImplId> for crate::traits::GlobalImplId { 831impl From<ImplId> for crate::traits::GlobalImplId {
879 fn from(impl_id: chalk_ir::ImplId) -> Self { 832 fn from(impl_id: ImplId) -> Self {
880 id_from_chalk(impl_id.0) 833 InternKey::from_intern_id(impl_id.0)
881 } 834 }
882} 835}
883 836
884impl From<crate::traits::GlobalImplId> for chalk_ir::ImplId { 837impl From<crate::traits::GlobalImplId> for ImplId {
885 fn from(impl_id: crate::traits::GlobalImplId) -> Self { 838 fn from(impl_id: crate::traits::GlobalImplId) -> Self {
886 chalk_ir::ImplId(id_to_chalk(impl_id)) 839 chalk_ir::ImplId(impl_id.as_intern_id())
887 } 840 }
888} 841}
889 842