aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/traits/chalk.rs21
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs7
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs356
-rw-r--r--crates/hir_ty/src/traits/chalk/tls.rs108
5 files changed, 179 insertions, 319 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 367a1b98d..3b822d223 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -17,9 +17,9 @@ ena = "0.14.0"
17log = "0.4.8" 17log = "0.4.8"
18rustc-hash = "1.1.0" 18rustc-hash = "1.1.0"
19scoped-tls = "1" 19scoped-tls = "1"
20chalk-solve = { version = "0.34", default-features = false } 20chalk-solve = { version = "0.36", default-features = false }
21chalk-ir = "0.34" 21chalk-ir = "0.36"
22chalk-recursive = "0.34" 22chalk-recursive = "0.36"
23 23
24stdx = { path = "../stdx", version = "0.0.0" } 24stdx = { path = "../stdx", version = "0.0.0" }
25hir_def = { path = "../hir_def", version = "0.0.0" } 25hir_def = { path = "../hir_def", version = "0.0.0" }
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index cbe5cd7dd..a6c247f87 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName}; 6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg};
7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use base_db::{salsa::InternKey, CrateId}; 9use base_db::{salsa::InternKey, CrateId};
@@ -81,7 +81,10 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
81 81
82 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); 82 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
83 83
84 fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> { 84 fn binder_kind(
85 ty: &Ty,
86 binders: &CanonicalVarKinds<Interner>,
87 ) -> Option<chalk_ir::TyVariableKind> {
85 if let Ty::Bound(bv) = ty { 88 if let Ty::Bound(bv) = ty {
86 let binders = binders.as_slice(&Interner); 89 let binders = binders.as_slice(&Interner);
87 if bv.debruijn == DebruijnIndex::INNERMOST { 90 if bv.debruijn == DebruijnIndex::INNERMOST {
@@ -95,8 +98,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
95 98
96 let self_ty_fp = TyFingerprint::for_impl(&ty); 99 let self_ty_fp = TyFingerprint::for_impl(&ty);
97 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { 100 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) {
98 Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS, 101 Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS,
99 Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS, 102 Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS,
100 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), 103 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]),
101 }; 104 };
102 105
@@ -129,12 +132,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
129 debug!("impls_for_trait returned {} impls", result.len()); 132 debug!("impls_for_trait returned {} impls", result.len());
130 result 133 result
131 } 134 }
132 fn impl_provided_for( 135 fn impl_provided_for(&self, auto_trait_id: TraitId, kind: &chalk_ir::TyKind<Interner>) -> bool {
133 &self, 136 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, kind);
134 auto_trait_id: TraitId,
135 application_ty: &chalk_ir::ApplicationTy<Interner>,
136 ) -> bool {
137 debug!("impl_provided_for {:?}, {:?}", auto_trait_id, application_ty);
138 false // FIXME 137 false // FIXME
139 } 138 }
140 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { 139 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
@@ -466,7 +465,7 @@ pub(crate) fn struct_datum_query(
466 struct_id: AdtId, 465 struct_id: AdtId,
467) -> Arc<StructDatum> { 466) -> Arc<StructDatum> {
468 debug!("struct_datum {:?}", struct_id); 467 debug!("struct_datum {:?}", struct_id);
469 let type_ctor: TypeCtor = from_chalk(db, TypeName::Adt(struct_id)); 468 let type_ctor = TypeCtor::Adt(from_chalk(db, struct_id));
470 debug!("struct {:?} = {:?}", struct_id, type_ctor); 469 debug!("struct {:?} = {:?}", struct_id, type_ctor);
471 let num_params = type_ctor.num_ty_params(db); 470 let num_params = type_ctor.num_ty_params(db);
472 let upstream = type_ctor.krate(db) != Some(krate); 471 let upstream = type_ctor.krate(db) != Some(krate);
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs
index f9304b7d0..f65873872 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/traits/chalk/interner.rs
@@ -122,13 +122,6 @@ impl chalk_ir::interner::Interner for Interner {
122 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt))) 122 tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt)))
123 } 123 }
124 124
125 fn debug_application_ty(
126 application_ty: &chalk_ir::ApplicationTy<Interner>,
127 fmt: &mut fmt::Formatter<'_>,
128 ) -> Option<fmt::Result> {
129 tls::with_current_program(|prog| Some(prog?.debug_application_ty(application_ty, fmt)))
130 }
131
132 fn debug_substitution( 125 fn debug_substitution(
133 substitution: &chalk_ir::Substitution<Interner>, 126 substitution: &chalk_ir::Substitution<Interner>,
134 fmt: &mut fmt::Formatter<'_>, 127 fmt: &mut fmt::Formatter<'_>,
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index dd7affcec..58c337b40 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -5,7 +5,7 @@
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, 7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar,
8 TypeName, UniverseIndex, 8 UniverseIndex,
9}; 9};
10use chalk_solve::rust_ir; 10use chalk_solve::rust_ir;
11 11
@@ -32,7 +32,7 @@ impl ToChalk for Ty {
32 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), 32 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters),
33 TypeCtor::FnPtr { num_args: _, is_varargs } => { 33 TypeCtor::FnPtr { num_args: _, is_varargs } => {
34 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); 34 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
35 chalk_ir::TyData::Function(chalk_ir::FnPointer { 35 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
36 num_binders: 0, 36 num_binders: 0,
37 sig: chalk_ir::FnSig { 37 sig: chalk_ir::FnSig {
38 abi: (), 38 abi: (),
@@ -43,10 +43,68 @@ impl ToChalk for Ty {
43 }) 43 })
44 .intern(&Interner) 44 .intern(&Interner)
45 } 45 }
46 _ => { 46 TypeCtor::AssociatedType(type_alias) => {
47 let name = apply_ty.ctor.to_chalk(db); 47 let assoc_type = TypeAliasAsAssocType(type_alias);
48 let assoc_type_id = assoc_type.to_chalk(db);
48 let substitution = apply_ty.parameters.to_chalk(db); 49 let substitution = apply_ty.parameters.to_chalk(db);
49 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 50 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
51 }
52
53 TypeCtor::OpaqueType(impl_trait_id) => {
54 let id = impl_trait_id.to_chalk(db);
55 let substitution = apply_ty.parameters.to_chalk(db);
56 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
57 }
58
59 TypeCtor::ForeignType(type_alias) => {
60 let foreign_type = TypeAliasAsForeignType(type_alias);
61 let foreign_type_id = foreign_type.to_chalk(db);
62 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
63 }
64
65 TypeCtor::Bool => chalk_ir::TyKind::Scalar(Scalar::Bool).intern(&Interner),
66 TypeCtor::Char => chalk_ir::TyKind::Scalar(Scalar::Char).intern(&Interner),
67 TypeCtor::Int(int_ty) => {
68 chalk_ir::TyKind::Scalar(int_ty_to_chalk(int_ty)).intern(&Interner)
69 }
70 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
71 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
72 .intern(&Interner)
73 }
74 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
75 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
76 .intern(&Interner)
77 }
78
79 TypeCtor::Tuple { cardinality } => {
80 let substitution = apply_ty.parameters.to_chalk(db);
81 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner)
82 }
83 TypeCtor::RawPtr(mutability) => {
84 let ty = apply_ty.parameters[0].clone().to_chalk(db);
85 chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner)
86 }
87 TypeCtor::Slice => {
88 chalk_ir::TyKind::Slice(apply_ty.parameters[0].clone().to_chalk(db))
89 .intern(&Interner)
90 }
91 TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner),
92 TypeCtor::FnDef(callable_def) => {
93 let id = callable_def.to_chalk(db);
94 let substitution = apply_ty.parameters.to_chalk(db);
95 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
96 }
97 TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner),
98
99 TypeCtor::Closure { def, expr } => {
100 let closure_id = db.intern_closure((def, expr));
101 let substitution = apply_ty.parameters.to_chalk(db);
102 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner)
103 }
104
105 TypeCtor::Adt(adt_id) => {
106 let substitution = apply_ty.parameters.to_chalk(db);
107 chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner)
50 } 108 }
51 }, 109 },
52 Ty::Projection(proj_ty) => { 110 Ty::Projection(proj_ty) => {
@@ -67,7 +125,7 @@ impl ToChalk for Ty {
67 } 125 }
68 .to_ty::<Interner>(&Interner) 126 .to_ty::<Interner>(&Interner)
69 } 127 }
70 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner), 128 Ty::Bound(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
71 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 129 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
72 Ty::Dyn(predicates) => { 130 Ty::Dyn(predicates) => {
73 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 131 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
@@ -78,55 +136,45 @@ impl ToChalk for Ty {
78 bounds: make_binders(where_clauses, 1), 136 bounds: make_binders(where_clauses, 1),
79 lifetime: LifetimeData::Static.intern(&Interner), 137 lifetime: LifetimeData::Static.intern(&Interner),
80 }; 138 };
81 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 139 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
82 } 140 }
83 Ty::Opaque(opaque_ty) => { 141 Ty::Opaque(opaque_ty) => {
84 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); 142 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
85 let substitution = opaque_ty.parameters.to_chalk(db); 143 let substitution = opaque_ty.parameters.to_chalk(db);
86 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { 144 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
87 opaque_ty_id, 145 opaque_ty_id,
88 substitution, 146 substitution,
89 })) 147 }))
90 .intern(&Interner) 148 .intern(&Interner)
91 } 149 }
92 Ty::Unknown => { 150 Ty::Unknown => chalk_ir::TyKind::Error.intern(&Interner),
93 let substitution = chalk_ir::Substitution::empty(&Interner);
94 let name = TypeName::Error;
95 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
96 }
97 } 151 }
98 } 152 }
99 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 153 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
100 match chalk.data(&Interner).clone() { 154 match chalk.data(&Interner).kind.clone() {
101 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 155 chalk_ir::TyKind::Error => Ty::Unknown,
102 TypeName::Error => Ty::Unknown, 156 chalk_ir::TyKind::Array(ty, _size) => {
103 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution), 157 Ty::apply(TypeCtor::Array, Substs::single(from_chalk(db, ty)))
104 TypeName::Array => array_from_chalk(db, apply_ty.substitution), 158 }
105 _ => { 159 chalk_ir::TyKind::Placeholder(idx) => {
106 let ctor = from_chalk(db, apply_ty.name);
107 let parameters = from_chalk(db, apply_ty.substitution);
108 Ty::Apply(ApplicationTy { ctor, parameters })
109 }
110 },
111 chalk_ir::TyData::Placeholder(idx) => {
112 assert_eq!(idx.ui, UniverseIndex::ROOT); 160 assert_eq!(idx.ui, UniverseIndex::ROOT);
113 let interned_id = crate::db::GlobalTypeParamId::from_intern_id( 161 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
114 crate::salsa::InternId::from(idx.idx), 162 crate::salsa::InternId::from(idx.idx),
115 ); 163 );
116 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) 164 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id))
117 } 165 }
118 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => { 166 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
119 let associated_ty = 167 let associated_ty =
120 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0; 168 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0;
121 let parameters = from_chalk(db, proj.substitution); 169 let parameters = from_chalk(db, proj.substitution);
122 Ty::Projection(ProjectionTy { associated_ty, parameters }) 170 Ty::Projection(ProjectionTy { associated_ty, parameters })
123 } 171 }
124 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { 172 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
125 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); 173 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
126 let parameters = from_chalk(db, opaque_ty.substitution); 174 let parameters = from_chalk(db, opaque_ty.substitution);
127 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) 175 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
128 } 176 }
129 chalk_ir::TyData::Function(chalk_ir::FnPointer { 177 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
130 num_binders, 178 num_binders,
131 sig: chalk_ir::FnSig { variadic, .. }, 179 sig: chalk_ir::FnSig { variadic, .. },
132 substitution, 180 substitution,
@@ -145,9 +193,9 @@ impl ToChalk for Ty {
145 parameters, 193 parameters,
146 }) 194 })
147 } 195 }
148 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), 196 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx),
149 chalk_ir::TyData::InferenceVar(_iv, _kind) => Ty::Unknown, 197 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown,
150 chalk_ir::TyData::Dyn(where_clauses) => { 198 chalk_ir::TyKind::Dyn(where_clauses) => {
151 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); 199 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
152 let predicates = where_clauses 200 let predicates = where_clauses
153 .bounds 201 .bounds
@@ -157,10 +205,76 @@ impl ToChalk for Ty {
157 .collect(); 205 .collect();
158 Ty::Dyn(predicates) 206 Ty::Dyn(predicates)
159 } 207 }
208
209 chalk_ir::TyKind::Adt(struct_id, subst) => {
210 apply_ty_from_chalk(db, TypeCtor::Adt(struct_id.0), subst)
211 }
212 chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk(
213 db,
214 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0),
215 subst,
216 ),
217 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
218 apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst)
219 }
220
221 chalk_ir::TyKind::Scalar(Scalar::Bool) => Ty::simple(TypeCtor::Bool),
222 chalk_ir::TyKind::Scalar(Scalar::Char) => Ty::simple(TypeCtor::Char),
223 chalk_ir::TyKind::Scalar(Scalar::Int(int_ty)) => Ty::simple(TypeCtor::Int(IntTy {
224 signedness: Signedness::Signed,
225 bitness: bitness_from_chalk_int(int_ty),
226 })),
227 chalk_ir::TyKind::Scalar(Scalar::Uint(uint_ty)) => Ty::simple(TypeCtor::Int(IntTy {
228 signedness: Signedness::Unsigned,
229 bitness: bitness_from_chalk_uint(uint_ty),
230 })),
231 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
232 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }))
233 }
234 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
235 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }))
236 }
237 chalk_ir::TyKind::Tuple(cardinality, subst) => {
238 apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst)
239 }
240 chalk_ir::TyKind::Raw(mutability, ty) => {
241 Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty))
242 }
243 chalk_ir::TyKind::Slice(ty) => Ty::apply_one(TypeCtor::Slice, from_chalk(db, ty)),
244 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
245 Ty::apply_one(TypeCtor::Ref(from_chalk(db, mutability)), from_chalk(db, ty))
246 }
247 chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str),
248 chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never),
249
250 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
251 let callable_def = from_chalk(db, fn_def_id);
252 apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst)
253 }
254
255 chalk_ir::TyKind::Closure(id, subst) => {
256 let id: crate::db::ClosureId = id.into();
257 let (def, expr) = db.lookup_intern_closure(id);
258 apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst)
259 }
260
261 chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType(
262 from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0,
263 )),
264 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
265 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
160 } 266 }
161 } 267 }
162} 268}
163 269
270fn apply_ty_from_chalk(
271 db: &dyn HirDatabase,
272 ctor: TypeCtor,
273 subst: chalk_ir::Substitution<Interner>,
274) -> Ty {
275 Ty::Apply(ApplicationTy { ctor, parameters: from_chalk(db, subst) })
276}
277
164/// We currently don't model lifetimes, but Chalk does. So, we have to insert a 278/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
165/// fake lifetime here, because Chalks built-in logic may expect it to be there. 279/// fake lifetime here, because Chalks built-in logic may expect it to be there.
166fn ref_to_chalk( 280fn ref_to_chalk(
@@ -170,60 +284,21 @@ fn ref_to_chalk(
170) -> chalk_ir::Ty<Interner> { 284) -> chalk_ir::Ty<Interner> {
171 let arg = subst[0].clone().to_chalk(db); 285 let arg = subst[0].clone().to_chalk(db);
172 let lifetime = LifetimeData::Static.intern(&Interner); 286 let lifetime = LifetimeData::Static.intern(&Interner);
173 chalk_ir::ApplicationTy { 287 chalk_ir::TyKind::Ref(mutability.to_chalk(db), lifetime, arg).intern(&Interner)
174 name: TypeName::Ref(mutability.to_chalk(db)),
175 substitution: chalk_ir::Substitution::from_iter(
176 &Interner,
177 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
178 ),
179 }
180 .intern(&Interner)
181}
182
183/// Here we remove the lifetime from the type we got from Chalk.
184fn ref_from_chalk(
185 db: &dyn HirDatabase,
186 mutability: chalk_ir::Mutability,
187 subst: chalk_ir::Substitution<Interner>,
188) -> Ty {
189 let tys = subst
190 .iter(&Interner)
191 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
192 .collect();
193 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
194} 288}
195 289
196/// We currently don't model constants, but Chalk does. So, we have to insert a 290/// We currently don't model constants, but Chalk does. So, we have to insert a
197/// fake constant here, because Chalks built-in logic may expect it to be there. 291/// fake constant here, because Chalks built-in logic may expect it to be there.
198fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { 292fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
199 let arg = subst[0].clone().to_chalk(db); 293 let arg = subst[0].clone().to_chalk(db);
200 let usize_ty = chalk_ir::ApplicationTy { 294 let usize_ty =
201 name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)), 295 chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner);
202 substitution: chalk_ir::Substitution::empty(&Interner),
203 }
204 .intern(&Interner);
205 let const_ = chalk_ir::ConstData { 296 let const_ = chalk_ir::ConstData {
206 ty: usize_ty, 297 ty: usize_ty,
207 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), 298 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
208 } 299 }
209 .intern(&Interner); 300 .intern(&Interner);
210 chalk_ir::ApplicationTy { 301 chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
211 name: TypeName::Array,
212 substitution: chalk_ir::Substitution::from_iter(
213 &Interner,
214 vec![arg.cast(&Interner), const_.cast(&Interner)],
215 ),
216 }
217 .intern(&Interner)
218}
219
220/// Here we remove the const from the type we got from Chalk.
221fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
222 let tys = subst
223 .iter(&Interner)
224 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
225 .collect();
226 Ty::apply(TypeCtor::Array, Substs(tys))
227} 302}
228 303
229impl ToChalk for Substs { 304impl ToChalk for Substs {
@@ -288,124 +363,6 @@ impl ToChalk for OpaqueTyId {
288 } 363 }
289} 364}
290 365
291impl ToChalk for TypeCtor {
292 type Chalk = TypeName<Interner>;
293
294 fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> {
295 match self {
296 TypeCtor::AssociatedType(type_alias) => {
297 let assoc_type = TypeAliasAsAssocType(type_alias);
298 let assoc_type_id = assoc_type.to_chalk(db);
299 TypeName::AssociatedType(assoc_type_id)
300 }
301
302 TypeCtor::OpaqueType(impl_trait_id) => {
303 let id = impl_trait_id.to_chalk(db);
304 TypeName::OpaqueType(id)
305 }
306
307 TypeCtor::ForeignType(type_alias) => {
308 let foreign_type = TypeAliasAsForeignType(type_alias);
309 let foreign_type_id = foreign_type.to_chalk(db);
310 TypeName::Foreign(foreign_type_id)
311 }
312
313 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
314 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
315 TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
316 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
317 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
318 }
319 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
320 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
321 }
322
323 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
324 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
325 TypeCtor::Slice => TypeName::Slice,
326 TypeCtor::Array => TypeName::Array,
327 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
328 TypeCtor::Str => TypeName::Str,
329 TypeCtor::FnDef(callable_def) => {
330 let id = callable_def.to_chalk(db);
331 TypeName::FnDef(id)
332 }
333 TypeCtor::Never => TypeName::Never,
334
335 TypeCtor::Closure { def, expr } => {
336 let closure_id = db.intern_closure((def, expr));
337 TypeName::Closure(closure_id.into())
338 }
339
340 TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)),
341
342 TypeCtor::FnPtr { .. } => {
343 // This should not be reached, since Chalk doesn't represent
344 // function pointers with TypeName
345 unreachable!()
346 }
347 }
348 }
349
350 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
351 match type_name {
352 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0),
353 TypeName::AssociatedType(type_id) => {
354 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0)
355 }
356 TypeName::OpaqueType(opaque_type_id) => {
357 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
358 }
359
360 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
361 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
362 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy {
363 signedness: Signedness::Signed,
364 bitness: bitness_from_chalk_int(int_ty),
365 }),
366 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy {
367 signedness: Signedness::Unsigned,
368 bitness: bitness_from_chalk_uint(uint_ty),
369 }),
370 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
371 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })
372 }
373 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
374 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })
375 }
376 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 },
377 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)),
378 TypeName::Slice => TypeCtor::Slice,
379 TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)),
380 TypeName::Str => TypeCtor::Str,
381 TypeName::Never => TypeCtor::Never,
382
383 TypeName::FnDef(fn_def_id) => {
384 let callable_def = from_chalk(db, fn_def_id);
385 TypeCtor::FnDef(callable_def)
386 }
387 TypeName::Array => TypeCtor::Array,
388
389 TypeName::Closure(id) => {
390 let id: crate::db::ClosureId = id.into();
391 let (def, expr) = db.lookup_intern_closure(id);
392 TypeCtor::Closure { def, expr }
393 }
394
395 TypeName::Foreign(foreign_def_id) => {
396 TypeCtor::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0)
397 }
398
399 TypeName::Error => {
400 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
401 unreachable!()
402 }
403 TypeName::Generator(_) => unimplemented!(), // FIXME
404 TypeName::GeneratorWitness(_) => unimplemented!(), // FIXME
405 }
406 }
407}
408
409fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness { 366fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness {
410 use chalk_ir::UintTy; 367 use chalk_ir::UintTy;
411 368
@@ -677,9 +634,9 @@ where
677 .kinds 634 .kinds
678 .iter() 635 .iter()
679 .map(|k| match k { 636 .map(|k| match k {
680 TyKind::General => chalk_ir::TyKind::General, 637 TyKind::General => chalk_ir::TyVariableKind::General,
681 TyKind::Integer => chalk_ir::TyKind::Integer, 638 TyKind::Integer => chalk_ir::TyVariableKind::Integer,
682 TyKind::Float => chalk_ir::TyKind::Float, 639 TyKind::Float => chalk_ir::TyVariableKind::Float,
683 }) 640 })
684 .map(|tk| { 641 .map(|tk| {
685 chalk_ir::CanonicalVarKind::new( 642 chalk_ir::CanonicalVarKind::new(
@@ -700,9 +657,9 @@ where
700 .iter(&Interner) 657 .iter(&Interner)
701 .map(|k| match k.kind { 658 .map(|k| match k.kind {
702 chalk_ir::VariableKind::Ty(tk) => match tk { 659 chalk_ir::VariableKind::Ty(tk) => match tk {
703 chalk_ir::TyKind::General => TyKind::General, 660 chalk_ir::TyVariableKind::General => TyKind::General,
704 chalk_ir::TyKind::Integer => TyKind::Integer, 661 chalk_ir::TyVariableKind::Integer => TyKind::Integer,
705 chalk_ir::TyKind::Float => TyKind::Float, 662 chalk_ir::TyVariableKind::Float => TyKind::Float,
706 }, 663 },
707 chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"), 664 chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"),
708 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), 665 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"),
@@ -768,7 +725,8 @@ where
768 chalk_ir::Binders::new( 725 chalk_ir::Binders::new(
769 chalk_ir::VariableKinds::from_iter( 726 chalk_ir::VariableKinds::from_iter(
770 &Interner, 727 &Interner,
771 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), 728 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
729 .take(num_vars),
772 ), 730 ),
773 value, 731 value,
774 ) 732 )
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/traits/chalk/tls.rs
index b4568cff6..3c9766550 100644
--- a/crates/hir_ty/src/traits/chalk/tls.rs
+++ b/crates/hir_ty/src/traits/chalk/tls.rs
@@ -1,12 +1,12 @@
1//! Implementation of Chalk debug helper functions using TLS. 1//! Implementation of Chalk debug helper functions using TLS.
2use std::fmt; 2use std::fmt;
3 3
4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName}; 4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication};
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner, TypeAliasAsAssocType}; 7use super::{from_chalk, Interner, TypeAliasAsAssocType};
8use crate::{db::HirDatabase, CallableDefId, TypeCtor}; 8use crate::{db::HirDatabase, CallableDefId};
9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; 9use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId};
10 10
11pub use unsafe_tls::{set_current_program, with_current_program}; 11pub use unsafe_tls::{set_current_program, with_current_program};
12 12
@@ -18,94 +18,12 @@ impl DebugContext<'_> {
18 id: super::AdtId, 18 id: super::AdtId,
19 f: &mut fmt::Formatter<'_>, 19 f: &mut fmt::Formatter<'_>,
20 ) -> Result<(), fmt::Error> { 20 ) -> Result<(), fmt::Error> {
21 let type_ctor: TypeCtor = from_chalk(self.0, TypeName::Adt(id)); 21 let name = match id.0 {
22 match type_ctor { 22 AdtId::StructId(it) => self.0.struct_data(it).name.clone(),
23 TypeCtor::Bool => write!(f, "bool")?, 23 AdtId::UnionId(it) => self.0.union_data(it).name.clone(),
24 TypeCtor::Char => write!(f, "char")?, 24 AdtId::EnumId(it) => self.0.enum_data(it).name.clone(),
25 TypeCtor::Int(t) => write!(f, "{}", t)?, 25 };
26 TypeCtor::Float(t) => write!(f, "{}", t)?, 26 write!(f, "{}", name)
27 TypeCtor::Str => write!(f, "str")?,
28 TypeCtor::Slice => write!(f, "slice")?,
29 TypeCtor::Array => write!(f, "array")?,
30 TypeCtor::RawPtr(m) => write!(f, "*{}", m.as_keyword_for_ptr())?,
31 TypeCtor::Ref(m) => write!(f, "&{}", m.as_keyword_for_ref())?,
32 TypeCtor::Never => write!(f, "!")?,
33 TypeCtor::Tuple { .. } => {
34 write!(f, "()")?;
35 }
36 TypeCtor::FnPtr { .. } => {
37 write!(f, "fn")?;
38 }
39 TypeCtor::FnDef(def) => {
40 let name = match def {
41 CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(),
42 CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(),
43 CallableDefId::EnumVariantId(e) => {
44 let enum_data = self.0.enum_data(e.parent);
45 enum_data.variants[e.local_id].name.clone()
46 }
47 };
48 match def {
49 CallableDefId::FunctionId(_) => write!(f, "{{fn {}}}", name)?,
50 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {
51 write!(f, "{{ctor {}}}", name)?
52 }
53 }
54 }
55 TypeCtor::Adt(def_id) => {
56 let name = match def_id {
57 AdtId::StructId(it) => self.0.struct_data(it).name.clone(),
58 AdtId::UnionId(it) => self.0.union_data(it).name.clone(),
59 AdtId::EnumId(it) => self.0.enum_data(it).name.clone(),
60 };
61 write!(f, "{}", name)?;
62 }
63 TypeCtor::AssociatedType(type_alias) => {
64 let trait_ = match type_alias.lookup(self.0.upcast()).container {
65 AssocContainerId::TraitId(it) => it,
66 _ => panic!("not an associated type"),
67 };
68 let trait_name = self.0.trait_data(trait_).name.clone();
69 let name = self.0.type_alias_data(type_alias).name.clone();
70 write!(f, "{}::{}", trait_name, name)?;
71 }
72 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?;
75 }
76 crate::OpaqueTyId::AsyncBlockTypeImplTrait(def, idx) => {
77 write!(f, "{{impl trait of async block {} of {:?}}}", idx.into_raw(), def)?;
78 }
79 },
80 TypeCtor::ForeignType(type_alias) => {
81 let name = self.0.type_alias_data(type_alias).name.clone();
82 write!(f, "{}", name)?;
83 }
84 TypeCtor::Closure { def, expr } => {
85 write!(f, "{{closure {:?} in ", expr.into_raw())?;
86 match def {
87 DefWithBodyId::FunctionId(func) => {
88 write!(f, "fn {}", self.0.function_data(func).name)?
89 }
90 DefWithBodyId::StaticId(s) => {
91 if let Some(name) = self.0.static_data(s).name.as_ref() {
92 write!(f, "body of static {}", name)?;
93 } else {
94 write!(f, "body of unnamed static {:?}", s)?;
95 }
96 }
97 DefWithBodyId::ConstId(c) => {
98 if let Some(name) = self.0.const_data(c).name.as_ref() {
99 write!(f, "body of const {}", name)?;
100 } else {
101 write!(f, "body of unnamed const {:?}", c)?;
102 }
103 }
104 };
105 write!(f, "}}")?;
106 }
107 }
108 Ok(())
109 } 27 }
110 28
111 pub fn debug_trait_id( 29 pub fn debug_trait_id(
@@ -234,14 +152,6 @@ impl DebugContext<'_> {
234 write!(fmt, "{:?}", pci.debug(&Interner)) 152 write!(fmt, "{:?}", pci.debug(&Interner))
235 } 153 }
236 154
237 pub fn debug_application_ty(
238 &self,
239 application_ty: &chalk_ir::ApplicationTy<Interner>,
240 fmt: &mut fmt::Formatter<'_>,
241 ) -> Result<(), fmt::Error> {
242 write!(fmt, "{:?}", application_ty.debug(&Interner))
243 }
244
245 pub fn debug_substitution( 155 pub fn debug_substitution(
246 &self, 156 &self,
247 substitution: &chalk_ir::Substitution<Interner>, 157 substitution: &chalk_ir::Substitution<Interner>,