diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-05 16:46:28 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-05 16:46:28 +0100 |
commit | 2a3ab7f3b4b6f1917a55025d54ac39b0a0642b6e (patch) | |
tree | c8aa32697a5c7910f8ebbcacf6e06d088bfca833 /crates/ra_hir_ty/src/lib.rs | |
parent | f133159ec0b5037b58a26f52f8b37c545872dc7d (diff) | |
parent | 0d2328f3eaf69c6a50fe6c1e946257bd3503d751 (diff) |
Merge #4689
4689: Implement return position impl trait / opaque type support r=matklad a=flodiebold
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.
Co-authored-by: Florian Diebold <[email protected]>
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/lib.rs')
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 98 |
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)] | ||
278 | pub 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)] |
494 | pub struct Binders<T> { | 520 | pub 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 | ||
563 | impl<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 | |||
1031 | impl<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)] | ||
1049 | pub enum OpaqueTyId { | ||
1050 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | ||
1051 | } | ||
1052 | |||
1053 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
1054 | pub struct ReturnTypeImplTraits { | ||
1055 | pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, | ||
1056 | } | ||
1057 | |||
1058 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
1059 | pub(crate) struct ReturnTypeImplTrait { | ||
1060 | pub(crate) bounds: Binders<Vec<GenericPredicate>>, | ||
1061 | } | ||