aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/chalk
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-03-04 22:00:44 +0000
committerFlorian Diebold <[email protected]>2020-06-05 16:08:27 +0100
commit02962b374ecefd6f2a75956f4fb18806531d1d51 (patch)
tree7c807d6a09db7e485ea39c3e67331b99829a364c /crates/ra_hir_ty/src/traits/chalk
parent9c52f527a1cef7d39c2b1c55b49dc5459d392a4d (diff)
Implement return position impl trait / opaque type support
This is working, but I'm not that happy with how the lowering works. We might need an additional representation between `TypeRef` and `Ty` where names are resolved and `impl Trait` bounds are separated out, but things like inference variables don't exist and `impl Trait` is always represented the same way. Also note that this doesn't implement correct handling of RPIT *inside* the function (which involves turning the `impl Trait`s into variables and creating obligations for them). That intermediate representation might help there as well.
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/interner.rs2
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/mapping.rs45
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/tls.rs5
3 files changed, 47 insertions, 5 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs
index e27074ba6..56aab640c 100644
--- a/crates/ra_hir_ty/src/traits/chalk/interner.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs
@@ -22,6 +22,8 @@ pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interne
22pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 22pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
23pub type FnDefId = chalk_ir::FnDefId<Interner>; 23pub type FnDefId = chalk_ir::FnDefId<Interner>;
24pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; 24pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
25pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
26pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
25 27
26impl chalk_ir::interner::Interner for Interner { 28impl chalk_ir::interner::Interner for Interner {
27 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc? 29 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc?
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
index 5f6daf842..834360430 100644
--- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
@@ -16,8 +16,8 @@ use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, 17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain},
18 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, 18 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation},
19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, 19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, 20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
21}; 21};
22 22
23use super::interner::*; 23use super::interner::*;
@@ -68,7 +68,16 @@ impl ToChalk for Ty {
68 let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) }; 68 let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) };
69 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 69 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
70 } 70 }
71 Ty::Opaque(_) | Ty::Unknown => { 71 Ty::Opaque(opaque_ty) => {
72 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
73 let substitution = opaque_ty.parameters.to_chalk(db);
74 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
75 opaque_ty_id,
76 substitution,
77 }))
78 .intern(&Interner)
79 }
80 Ty::Unknown => {
72 let substitution = chalk_ir::Substitution::empty(&Interner); 81 let substitution = chalk_ir::Substitution::empty(&Interner);
73 let name = TypeName::Error; 82 let name = TypeName::Error;
74 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 83 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
@@ -98,7 +107,11 @@ impl ToChalk for Ty {
98 let parameters = from_chalk(db, proj.substitution); 107 let parameters = from_chalk(db, proj.substitution);
99 Ty::Projection(ProjectionTy { associated_ty, parameters }) 108 Ty::Projection(ProjectionTy { associated_ty, parameters })
100 } 109 }
101 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(), 110 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
111 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
112 let parameters = from_chalk(db, opaque_ty.substitution);
113 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
114 }
102 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { 115 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => {
103 let parameters: Substs = from_chalk(db, substitution); 116 let parameters: Substs = from_chalk(db, substitution);
104 Ty::Apply(ApplicationTy { 117 Ty::Apply(ApplicationTy {
@@ -204,6 +217,21 @@ impl ToChalk for hir_def::TraitId {
204 } 217 }
205} 218}
206 219
220impl ToChalk for OpaqueTyId {
221 type Chalk = chalk_ir::OpaqueTyId<Interner>;
222
223 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::OpaqueTyId<Interner> {
224 db.intern_impl_trait_id(self).into()
225 }
226
227 fn from_chalk(
228 db: &dyn HirDatabase,
229 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
230 ) -> OpaqueTyId {
231 db.lookup_intern_impl_trait_id(opaque_ty_id.into())
232 }
233}
234
207impl ToChalk for TypeCtor { 235impl ToChalk for TypeCtor {
208 type Chalk = TypeName<Interner>; 236 type Chalk = TypeName<Interner>;
209 237
@@ -214,6 +242,11 @@ impl ToChalk for TypeCtor {
214 TypeName::AssociatedType(type_id) 242 TypeName::AssociatedType(type_id)
215 } 243 }
216 244
245 TypeCtor::OpaqueType(impl_trait_id) => {
246 let id = impl_trait_id.to_chalk(db);
247 TypeName::OpaqueType(id)
248 }
249
217 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), 250 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
218 TypeCtor::Char => TypeName::Scalar(Scalar::Char), 251 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
219 TypeCtor::Int(Uncertain::Known(int_ty)) => TypeName::Scalar(int_ty_to_chalk(int_ty)), 252 TypeCtor::Int(Uncertain::Known(int_ty)) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
@@ -252,7 +285,9 @@ impl ToChalk for TypeCtor {
252 match type_name { 285 match type_name {
253 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), 286 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
254 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 287 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
255 TypeName::OpaqueType(_) => unreachable!(), 288 TypeName::OpaqueType(opaque_type_id) => {
289 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
290 }
256 291
257 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool, 292 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
258 TypeName::Scalar(Scalar::Char) => TypeCtor::Char, 293 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs
index d88828c7c..556af7098 100644
--- a/crates/ra_hir_ty/src/traits/chalk/tls.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs
@@ -69,6 +69,11 @@ impl DebugContext<'_> {
69 let name = self.0.type_alias_data(type_alias).name.clone(); 69 let name = self.0.type_alias_data(type_alias).name.clone();
70 write!(f, "{}::{}", trait_name, name)?; 70 write!(f, "{}::{}", trait_name, name)?;
71 } 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 },
72 TypeCtor::Closure { def, expr } => { 77 TypeCtor::Closure { def, expr } => {
73 write!(f, "{{closure {:?} in ", expr.into_raw())?; 78 write!(f, "{{closure {:?} in ", expr.into_raw())?;
74 match def { 79 match def {