diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_ty/src/traits/chalk.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 667 |
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. |
2 | use std::sync::Arc; | 2 | use std::{fmt, sync::Arc}; |
3 | 3 | ||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{ | 6 | use chalk_ir::{cast::Cast, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; |
7 | cast::Cast, family::ChalkIr, Identifier, Parameter, PlaceholderIndex, TypeId, TypeKindId, | ||
8 | TypeName, UniverseIndex, | ||
9 | }; | ||
10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; | ||
11 | use ra_db::CrateId; | ||
12 | 7 | ||
13 | use hir_def::{ | 8 | use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; |
14 | expr::Expr, lang_item::LangItemTarget, AssocItemId, AstItemDef, ContainerId, GenericDefId, | 9 | use ra_db::{ |
15 | ImplId, Lookup, TraitId, TypeAliasId, | 10 | salsa::{InternId, InternKey}, |
11 | CrateId, | ||
16 | }; | 12 | }; |
17 | use hir_expand::name; | ||
18 | |||
19 | use ra_db::salsa::{InternId, InternKey}; | ||
20 | 13 | ||
21 | use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; | 14 | use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; |
22 | use crate::{ | 15 | use 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)] |
28 | const UNKNOWN_TRAIT: chalk_ir::TraitId = | 21 | pub struct TypeFamily {} |
29 | chalk_ir::TraitId(chalk_ir::RawId { index: u32::max_value() }); | 22 | |
23 | impl 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 | |||
83 | impl chalk_ir::family::HasTypeFamily for TypeFamily { | ||
84 | type TypeFamily = Self; | ||
85 | } | ||
86 | |||
87 | pub type AssocTypeId = chalk_ir::AssocTypeId<TypeFamily>; | ||
88 | pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<TypeFamily>; | ||
89 | pub type TraitId = chalk_ir::TraitId<TypeFamily>; | ||
90 | pub type TraitDatum = chalk_rust_ir::TraitDatum<TypeFamily>; | ||
91 | pub type StructId = chalk_ir::StructId<TypeFamily>; | ||
92 | pub type StructDatum = chalk_rust_ir::StructDatum<TypeFamily>; | ||
93 | pub type ImplId = chalk_ir::ImplId<TypeFamily>; | ||
94 | pub type ImplDatum = chalk_rust_ir::ImplDatum<TypeFamily>; | ||
95 | pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId; | ||
96 | pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<TypeFamily>; | ||
30 | 97 | ||
31 | pub(super) trait ToChalk { | 98 | pub(super) trait ToChalk { |
32 | type Chalk; | 99 | type Chalk; |
@@ -42,21 +109,11 @@ where | |||
42 | } | 109 | } |
43 | 110 | ||
44 | impl ToChalk for Ty { | 111 | impl 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 | ||
137 | impl ToChalk for Substs { | 196 | impl 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 | ||
156 | impl ToChalk for TraitRef { | 218 | impl 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 | ||
172 | impl ToChalk for TraitId { | 234 | impl 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 | ||
184 | impl ToChalk for TypeCtor { | 246 | impl 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 | ||
196 | impl ToChalk for Impl { | 275 | impl 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 | ||
208 | impl ToChalk for TypeAliasId { | 287 | impl 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 | ||
220 | impl ToChalk for AssocTyValue { | 299 | impl 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 | ||
235 | impl ToChalk for GenericPredicate { | 311 | impl 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 | ||
281 | impl ToChalk for ProjectionTy { | 347 | impl 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 | ||
302 | impl ToChalk for super::ProjectionPredicate { | 368 | impl 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 | ||
317 | impl ToChalk for Obligation { | 383 | impl 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 | ||
350 | impl ToChalk for Arc<super::TraitEnvironment> { | 416 | impl 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 | ||
374 | impl<T: ToChalk> ToChalk for super::InEnvironment<T> | 441 | impl<T: ToChalk> ToChalk for super::InEnvironment<T> |
375 | where | 442 | where |
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 | ||
465 | impl 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 | |||
489 | impl 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 | |||
398 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { | 510 | fn 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 | ||
423 | impl<'a, DB> chalk_solve::RustIrDatabase<ChalkIr> for ChalkContext<'a, DB> | 534 | impl<'a, DB> chalk_solve::RustIrDatabase<TypeFamily> for ChalkContext<'a, DB> |
424 | where | 535 | where |
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 | ||
504 | pub(crate) fn associated_ty_data_query( | 601 | pub(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( | |||
529 | pub(crate) fn trait_datum_query( | 626 | pub(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( | |||
580 | pub(crate) fn struct_datum_query( | 659 | pub(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( | |||
612 | pub(crate) fn impl_datum_query( | 691 | pub(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 | ||
627 | fn impl_block_datum( | 705 | fn 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 | |||
691 | fn 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 | ||
706 | fn 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 | |||
763 | pub(crate) fn associated_ty_value_query( | 769 | pub(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 | ||
812 | fn 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 | |||
847 | fn 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 | |||
859 | fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T { | 812 | fn 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 | ||
866 | impl From<chalk_ir::StructId> for crate::TypeCtorId { | 819 | impl 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 | ||
872 | impl From<crate::TypeCtorId> for chalk_ir::StructId { | 825 | impl 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 | ||
878 | impl From<chalk_ir::ImplId> for crate::traits::GlobalImplId { | 831 | impl 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 | ||
884 | impl From<crate::traits::GlobalImplId> for chalk_ir::ImplId { | 837 | impl 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 | ||