diff options
author | Florian Diebold <[email protected]> | 2019-08-13 22:09:08 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-08-22 18:33:00 +0100 |
commit | 16a7d8cc850002b427fdc8d21ccde81caaed7902 (patch) | |
tree | 7f3c43cf9e83d479edc7f9b4849dae5fbd0f356d /crates/ra_hir/src/ty/lower.rs | |
parent | 08e5d394dfbca28b15ed5dc772d55d48f87c3f54 (diff) |
Add `impl Trait` and `dyn Trait` types
- refactor bounds handling in the AST a bit
- add HIR for bounds
- add `Ty::Dyn` and `Ty::Opaque` variants and lower `dyn Trait` / `impl Trait`
syntax to them
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 65 |
1 files changed, 54 insertions, 11 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index debedcbb8..47d161277 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | path::{GenericArg, PathSegment}, | 17 | path::{GenericArg, PathSegment}, |
18 | resolve::{Resolution, Resolver}, | 18 | resolve::{Resolution, Resolver}, |
19 | ty::AdtDef, | 19 | ty::AdtDef, |
20 | type_ref::TypeRef, | 20 | type_ref::{TypeBound, TypeRef}, |
21 | BuiltinType, Const, Enum, EnumVariant, Function, HirDatabase, ModuleDef, Path, Static, Struct, | 21 | BuiltinType, Const, Enum, EnumVariant, Function, HirDatabase, ModuleDef, Path, Static, Struct, |
22 | StructField, Trait, TypeAlias, Union, | 22 | StructField, Trait, TypeAlias, Union, |
23 | }; | 23 | }; |
@@ -58,6 +58,22 @@ impl Ty { | |||
58 | let sig = Substs(inner_tys.into()); | 58 | let sig = Substs(inner_tys.into()); |
59 | Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) | 59 | Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) |
60 | } | 60 | } |
61 | TypeRef::DynTrait(bounds) => { | ||
62 | let self_ty = Ty::Bound(0); | ||
63 | let predicates = bounds | ||
64 | .iter() | ||
65 | .map(|b| GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())) | ||
66 | .collect::<Vec<_>>(); | ||
67 | Ty::Dyn(predicates.into()) | ||
68 | } | ||
69 | TypeRef::ImplTrait(bounds) => { | ||
70 | let self_ty = Ty::Bound(0); | ||
71 | let predicates = bounds | ||
72 | .iter() | ||
73 | .map(|b| GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())) | ||
74 | .collect::<Vec<_>>(); | ||
75 | Ty::Opaque(predicates.into()) | ||
76 | } | ||
61 | TypeRef::Error => Ty::Unknown, | 77 | TypeRef::Error => Ty::Unknown, |
62 | } | 78 | } |
63 | } | 79 | } |
@@ -310,13 +326,46 @@ impl TraitRef { | |||
310 | TraitRef { trait_, substs } | 326 | TraitRef { trait_, substs } |
311 | } | 327 | } |
312 | 328 | ||
313 | pub(crate) fn for_where_predicate( | 329 | pub(crate) fn from_where_predicate( |
314 | db: &impl HirDatabase, | 330 | db: &impl HirDatabase, |
315 | resolver: &Resolver, | 331 | resolver: &Resolver, |
316 | pred: &WherePredicate, | 332 | pred: &WherePredicate, |
317 | ) -> Option<TraitRef> { | 333 | ) -> Option<TraitRef> { |
318 | let self_ty = Ty::from_hir(db, resolver, &pred.type_ref); | 334 | let self_ty = Ty::from_hir(db, resolver, &pred.type_ref); |
319 | TraitRef::from_path(db, resolver, &pred.trait_ref, Some(self_ty)) | 335 | TraitRef::from_type_bound(db, resolver, &pred.bound, self_ty) |
336 | } | ||
337 | |||
338 | pub(crate) fn from_type_bound( | ||
339 | db: &impl HirDatabase, | ||
340 | resolver: &Resolver, | ||
341 | bound: &TypeBound, | ||
342 | self_ty: Ty, | ||
343 | ) -> Option<TraitRef> { | ||
344 | match bound { | ||
345 | TypeBound::Path(path) => TraitRef::from_path(db, resolver, path, Some(self_ty)), | ||
346 | TypeBound::Error => None, | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | impl GenericPredicate { | ||
352 | pub(crate) fn from_where_predicate( | ||
353 | db: &impl HirDatabase, | ||
354 | resolver: &Resolver, | ||
355 | where_predicate: &WherePredicate, | ||
356 | ) -> GenericPredicate { | ||
357 | TraitRef::from_where_predicate(db, &resolver, where_predicate) | ||
358 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) | ||
359 | } | ||
360 | |||
361 | pub(crate) fn from_type_bound( | ||
362 | db: &impl HirDatabase, | ||
363 | resolver: &Resolver, | ||
364 | bound: &TypeBound, | ||
365 | self_ty: Ty, | ||
366 | ) -> GenericPredicate { | ||
367 | TraitRef::from_type_bound(db, &resolver, bound, self_ty) | ||
368 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) | ||
320 | } | 369 | } |
321 | } | 370 | } |
322 | 371 | ||
@@ -376,10 +425,7 @@ pub(crate) fn trait_env( | |||
376 | ) -> Arc<super::TraitEnvironment> { | 425 | ) -> Arc<super::TraitEnvironment> { |
377 | let predicates = resolver | 426 | let predicates = resolver |
378 | .where_predicates_in_scope() | 427 | .where_predicates_in_scope() |
379 | .map(|pred| { | 428 | .map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) |
380 | TraitRef::for_where_predicate(db, &resolver, pred) | ||
381 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) | ||
382 | }) | ||
383 | .collect::<Vec<_>>(); | 429 | .collect::<Vec<_>>(); |
384 | 430 | ||
385 | Arc::new(super::TraitEnvironment { predicates }) | 431 | Arc::new(super::TraitEnvironment { predicates }) |
@@ -393,10 +439,7 @@ pub(crate) fn generic_predicates_query( | |||
393 | let resolver = def.resolver(db); | 439 | let resolver = def.resolver(db); |
394 | let predicates = resolver | 440 | let predicates = resolver |
395 | .where_predicates_in_scope() | 441 | .where_predicates_in_scope() |
396 | .map(|pred| { | 442 | .map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) |
397 | TraitRef::for_where_predicate(db, &resolver, pred) | ||
398 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) | ||
399 | }) | ||
400 | .collect::<Vec<_>>(); | 443 | .collect::<Vec<_>>(); |
401 | predicates.into() | 444 | predicates.into() |
402 | } | 445 | } |