diff options
author | Lukas Wirth <[email protected]> | 2020-12-17 21:01:42 +0000 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2020-12-17 21:01:42 +0000 |
commit | fa65d6ba855fb2da68840b987bfdec258239a59b (patch) | |
tree | 64700d82eec8ab83912aa7d8eb752fe6becc7b7c /crates/hir_def/src | |
parent | c8c58d81eca78b322675afa053463e06c422cfbc (diff) |
Higher-ranked trait bounds for where clauses
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/generics.rs | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index 41134d23b..bb8fca009 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs | |||
@@ -62,6 +62,7 @@ pub struct GenericParams { | |||
62 | pub enum WherePredicate { | 62 | pub enum WherePredicate { |
63 | TypeBound { target: WherePredicateTypeTarget, bound: TypeBound }, | 63 | TypeBound { target: WherePredicateTypeTarget, bound: TypeBound }, |
64 | Lifetime { target: LifetimeRef, bound: LifetimeRef }, | 64 | Lifetime { target: LifetimeRef, bound: LifetimeRef }, |
65 | ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound }, | ||
65 | } | 66 | } |
66 | 67 | ||
67 | #[derive(Clone, PartialEq, Eq, Debug)] | 68 | #[derive(Clone, PartialEq, Eq, Debug)] |
@@ -69,7 +70,6 @@ pub enum WherePredicateTypeTarget { | |||
69 | TypeRef(TypeRef), | 70 | TypeRef(TypeRef), |
70 | /// For desugared where predicates that can directly refer to a type param. | 71 | /// For desugared where predicates that can directly refer to a type param. |
71 | TypeParam(LocalTypeParamId), | 72 | TypeParam(LocalTypeParamId), |
72 | // FIXME: ForLifetime(Vec<LifetimeParamId>, TypeRef) | ||
73 | } | 73 | } |
74 | 74 | ||
75 | #[derive(Default)] | 75 | #[derive(Default)] |
@@ -234,7 +234,7 @@ impl GenericParams { | |||
234 | for bound in | 234 | for bound in |
235 | node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) | 235 | node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) |
236 | { | 236 | { |
237 | self.add_where_predicate_from_bound(lower_ctx, bound, target.clone()); | 237 | self.add_where_predicate_from_bound(lower_ctx, bound, None, target.clone()); |
238 | } | 238 | } |
239 | } | 239 | } |
240 | 240 | ||
@@ -279,8 +279,25 @@ impl GenericParams { | |||
279 | } else { | 279 | } else { |
280 | continue; | 280 | continue; |
281 | }; | 281 | }; |
282 | |||
283 | let lifetimes: Option<Box<_>> = pred.generic_param_list().map(|param_list| { | ||
284 | // Higher-Ranked Trait Bounds | ||
285 | param_list | ||
286 | .lifetime_params() | ||
287 | .map(|lifetime_param| { | ||
288 | lifetime_param | ||
289 | .lifetime() | ||
290 | .map_or_else(Name::missing, |lt| Name::new_lifetime(<)) | ||
291 | }) | ||
292 | .collect() | ||
293 | }); | ||
282 | for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { | 294 | for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { |
283 | self.add_where_predicate_from_bound(lower_ctx, bound, target.clone()); | 295 | self.add_where_predicate_from_bound( |
296 | lower_ctx, | ||
297 | bound, | ||
298 | lifetimes.as_ref(), | ||
299 | target.clone(), | ||
300 | ); | ||
284 | } | 301 | } |
285 | } | 302 | } |
286 | } | 303 | } |
@@ -289,6 +306,7 @@ impl GenericParams { | |||
289 | &mut self, | 306 | &mut self, |
290 | lower_ctx: &LowerCtx, | 307 | lower_ctx: &LowerCtx, |
291 | bound: ast::TypeBound, | 308 | bound: ast::TypeBound, |
309 | hrtb_lifetimes: Option<&Box<[Name]>>, | ||
292 | target: Either<TypeRef, LifetimeRef>, | 310 | target: Either<TypeRef, LifetimeRef>, |
293 | ) { | 311 | ) { |
294 | if bound.question_mark_token().is_some() { | 312 | if bound.question_mark_token().is_some() { |
@@ -297,9 +315,16 @@ impl GenericParams { | |||
297 | } | 315 | } |
298 | let bound = TypeBound::from_ast(lower_ctx, bound); | 316 | let bound = TypeBound::from_ast(lower_ctx, bound); |
299 | let predicate = match (target, bound) { | 317 | let predicate = match (target, bound) { |
300 | (Either::Left(type_ref), bound) => WherePredicate::TypeBound { | 318 | (Either::Left(type_ref), bound) => match hrtb_lifetimes { |
301 | target: WherePredicateTypeTarget::TypeRef(type_ref), | 319 | Some(hrtb_lifetimes) => WherePredicate::ForLifetime { |
302 | bound, | 320 | lifetimes: hrtb_lifetimes.clone(), |
321 | target: WherePredicateTypeTarget::TypeRef(type_ref), | ||
322 | bound, | ||
323 | }, | ||
324 | None => WherePredicate::TypeBound { | ||
325 | target: WherePredicateTypeTarget::TypeRef(type_ref), | ||
326 | bound, | ||
327 | }, | ||
303 | }, | 328 | }, |
304 | (Either::Right(lifetime), TypeBound::Lifetime(bound)) => { | 329 | (Either::Right(lifetime), TypeBound::Lifetime(bound)) => { |
305 | WherePredicate::Lifetime { target: lifetime, bound } | 330 | WherePredicate::Lifetime { target: lifetime, bound } |