aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lib.rs
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/lib.rs
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/lib.rs')
-rw-r--r--crates/ra_hir_ty/src/lib.rs98
1 files changed, 89 insertions, 9 deletions
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 9fa8d3bdc..135976fcd 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -147,6 +147,12 @@ pub enum TypeCtor {
147 /// an **application type** like `(Iterator::Item)<T>`. 147 /// an **application type** like `(Iterator::Item)<T>`.
148 AssociatedType(TypeAliasId), 148 AssociatedType(TypeAliasId),
149 149
150 /// This represents a placeholder for an opaque type in situations where we
151 /// don't know the hidden type (i.e. currently almost always). This is
152 /// analogous to the `AssociatedType` type constructor. As with that one,
153 /// these are only produced by Chalk.
154 OpaqueType(OpaqueTyId),
155
150 /// The type of a specific closure. 156 /// The type of a specific closure.
151 /// 157 ///
152 /// The closure signature is stored in a `FnPtr` type in the first type 158 /// The closure signature is stored in a `FnPtr` type in the first type
@@ -194,6 +200,14 @@ impl TypeCtor {
194 let generic_params = generics(db.upcast(), type_alias.into()); 200 let generic_params = generics(db.upcast(), type_alias.into());
195 generic_params.len() 201 generic_params.len()
196 } 202 }
203 TypeCtor::OpaqueType(opaque_ty_id) => {
204 match opaque_ty_id {
205 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
206 let generic_params = generics(db.upcast(), func.into());
207 generic_params.len()
208 }
209 }
210 }
197 TypeCtor::FnPtr { num_args } => num_args as usize + 1, 211 TypeCtor::FnPtr { num_args } => num_args as usize + 1,
198 TypeCtor::Tuple { cardinality } => cardinality as usize, 212 TypeCtor::Tuple { cardinality } => cardinality as usize,
199 } 213 }
@@ -220,6 +234,11 @@ impl TypeCtor {
220 TypeCtor::AssociatedType(type_alias) => { 234 TypeCtor::AssociatedType(type_alias) => {
221 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate) 235 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate)
222 } 236 }
237 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
238 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
239 Some(func.lookup(db.upcast()).module(db.upcast()).krate)
240 }
241 },
223 } 242 }
224 } 243 }
225 244
@@ -241,6 +260,7 @@ impl TypeCtor {
241 TypeCtor::Adt(adt) => Some(adt.into()), 260 TypeCtor::Adt(adt) => Some(adt.into()),
242 TypeCtor::FnDef(callable) => Some(callable.into()), 261 TypeCtor::FnDef(callable) => Some(callable.into()),
243 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), 262 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
263 TypeCtor::OpaqueType(_impl_trait_id) => None,
244 } 264 }
245 } 265 }
246} 266}
@@ -254,6 +274,12 @@ pub struct ApplicationTy {
254 pub parameters: Substs, 274 pub parameters: Substs,
255} 275}
256 276
277#[derive(Clone, PartialEq, Eq, Debug, Hash)]
278pub struct OpaqueTy {
279 pub opaque_ty_id: OpaqueTyId,
280 pub parameters: Substs,
281}
282
257/// A "projection" type corresponds to an (unnormalized) 283/// A "projection" type corresponds to an (unnormalized)
258/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 284/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
259/// trait and all its parameters are fully known. 285/// trait and all its parameters are fully known.
@@ -308,6 +334,12 @@ pub enum Ty {
308 /// trait and all its parameters are fully known. 334 /// trait and all its parameters are fully known.
309 Projection(ProjectionTy), 335 Projection(ProjectionTy),
310 336
337 /// An opaque type (`impl Trait`).
338 ///
339 /// This is currently only used for return type impl trait; each instance of
340 /// `impl Trait` in a return type gets its own ID.
341 Opaque(OpaqueTy),
342
311 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) 343 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T)
312 /// {}` when we're type-checking the body of that function. In this 344 /// {}` when we're type-checking the body of that function. In this
313 /// situation, we know this stands for *some* type, but don't know the exact 345 /// situation, we know this stands for *some* type, but don't know the exact
@@ -332,12 +364,6 @@ pub enum Ty {
332 /// didn't seem worth the overhead yet. 364 /// didn't seem worth the overhead yet.
333 Dyn(Arc<[GenericPredicate]>), 365 Dyn(Arc<[GenericPredicate]>),
334 366
335 /// An opaque type (`impl Trait`).
336 ///
337 /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for
338 /// more.
339 Opaque(Arc<[GenericPredicate]>),
340
341 /// A placeholder for a type which could not be computed; this is propagated 367 /// A placeholder for a type which could not be computed; this is propagated
342 /// to avoid useless error messages. Doubles as a placeholder where type 368 /// to avoid useless error messages. Doubles as a placeholder where type
343 /// variables are inserted before type checking, since we want to try to 369 /// variables are inserted before type checking, since we want to try to
@@ -490,7 +516,7 @@ impl Deref for Substs {
490 } 516 }
491} 517}
492 518
493#[derive(Copy, Clone, PartialEq, Eq, Debug)] 519#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
494pub struct Binders<T> { 520pub struct Binders<T> {
495 pub num_binders: usize, 521 pub num_binders: usize,
496 pub value: T, 522 pub value: T,
@@ -534,6 +560,20 @@ impl<T: TypeWalk> Binders<T> {
534 } 560 }
535} 561}
536 562
563impl<T: TypeWalk> TypeWalk for Binders<T> {
564 fn walk(&self, f: &mut impl FnMut(&Ty)) {
565 self.value.walk(f);
566 }
567
568 fn walk_mut_binders(
569 &mut self,
570 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
571 binders: DebruijnIndex,
572 ) {
573 self.value.walk_mut_binders(f, binders.shifted_in())
574 }
575}
576
537/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. 577/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
538/// Name to be bikeshedded: TraitBound? TraitImplements? 578/// Name to be bikeshedded: TraitBound? TraitImplements?
539#[derive(Clone, PartialEq, Eq, Debug, Hash)] 579#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -947,11 +987,16 @@ impl TypeWalk for Ty {
947 t.walk(f); 987 t.walk(f);
948 } 988 }
949 } 989 }
950 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 990 Ty::Dyn(predicates) => {
951 for p in predicates.iter() { 991 for p in predicates.iter() {
952 p.walk(f); 992 p.walk(f);
953 } 993 }
954 } 994 }
995 Ty::Opaque(o_ty) => {
996 for t in o_ty.parameters.iter() {
997 t.walk(f);
998 }
999 }
955 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1000 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
956 } 1001 }
957 f(self); 1002 f(self);
@@ -969,13 +1014,48 @@ impl TypeWalk for Ty {
969 Ty::Projection(p_ty) => { 1014 Ty::Projection(p_ty) => {
970 p_ty.parameters.walk_mut_binders(f, binders); 1015 p_ty.parameters.walk_mut_binders(f, binders);
971 } 1016 }
972 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 1017 Ty::Dyn(predicates) => {
973 for p in make_mut_slice(predicates) { 1018 for p in make_mut_slice(predicates) {
974 p.walk_mut_binders(f, binders.shifted_in()); 1019 p.walk_mut_binders(f, binders.shifted_in());
975 } 1020 }
976 } 1021 }
1022 Ty::Opaque(o_ty) => {
1023 o_ty.parameters.walk_mut_binders(f, binders);
1024 }
977 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1025 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
978 } 1026 }
979 f(self, binders); 1027 f(self, binders);
980 } 1028 }
981} 1029}
1030
1031impl<T: TypeWalk> TypeWalk for Vec<T> {
1032 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1033 for t in self {
1034 t.walk(f);
1035 }
1036 }
1037 fn walk_mut_binders(
1038 &mut self,
1039 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1040 binders: DebruijnIndex,
1041 ) {
1042 for t in self {
1043 t.walk_mut_binders(f, binders);
1044 }
1045 }
1046}
1047
1048#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
1049pub enum OpaqueTyId {
1050 ReturnTypeImplTrait(hir_def::FunctionId, u16),
1051}
1052
1053#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1054pub struct ReturnTypeImplTraits {
1055 pub(crate) impl_traits: Vec<ReturnTypeImplTrait>,
1056}
1057
1058#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1059pub(crate) struct ReturnTypeImplTrait {
1060 pub(crate) bounds: Binders<Vec<GenericPredicate>>,
1061}