diff options
author | Florian Diebold <[email protected]> | 2020-03-04 22:00:44 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-06-05 16:08:27 +0100 |
commit | 02962b374ecefd6f2a75956f4fb18806531d1d51 (patch) | |
tree | 7c807d6a09db7e485ea39c3e67331b99829a364c /crates/ra_hir_ty/src/display.rs | |
parent | 9c52f527a1cef7d39c2b1c55b49dc5459d392a4d (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/display.rs')
-rw-r--r-- | crates/ra_hir_ty/src/display.rs | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs index b9c4d2e89..3e63a2415 100644 --- a/crates/ra_hir_ty/src/display.rs +++ b/crates/ra_hir_ty/src/display.rs | |||
@@ -359,6 +359,21 @@ impl HirDisplay for ApplicationTy { | |||
359 | write!(f, ">")?; | 359 | write!(f, ">")?; |
360 | } | 360 | } |
361 | } | 361 | } |
362 | TypeCtor::OpaqueType(opaque_ty_id) => { | ||
363 | let bounds = match opaque_ty_id { | ||
364 | crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | ||
365 | let datas = | ||
366 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | ||
367 | let data = (*datas) | ||
368 | .as_ref() | ||
369 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | ||
370 | data.clone().subst(&self.parameters) | ||
371 | } | ||
372 | }; | ||
373 | write!(f, "impl ")?; | ||
374 | write_bounds_like_dyn_trait(&bounds.value, f)?; | ||
375 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution | ||
376 | } | ||
362 | TypeCtor::Closure { .. } => { | 377 | TypeCtor::Closure { .. } => { |
363 | let sig = self.parameters[0].callable_sig(f.db); | 378 | let sig = self.parameters[0].callable_sig(f.db); |
364 | if let Some(sig) = sig { | 379 | if let Some(sig) = sig { |
@@ -427,14 +442,24 @@ impl HirDisplay for Ty { | |||
427 | } | 442 | } |
428 | } | 443 | } |
429 | Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, | 444 | Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, |
430 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | 445 | Ty::Dyn(predicates) => { |
431 | match self { | 446 | write!(f, "dyn ")?; |
432 | Ty::Dyn(_) => write!(f, "dyn ")?, | ||
433 | Ty::Opaque(_) => write!(f, "impl ")?, | ||
434 | _ => unreachable!(), | ||
435 | }; | ||
436 | write_bounds_like_dyn_trait(predicates, f)?; | 447 | write_bounds_like_dyn_trait(predicates, f)?; |
437 | } | 448 | } |
449 | Ty::Opaque(opaque_ty) => { | ||
450 | let bounds = match opaque_ty.opaque_ty_id { | ||
451 | crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | ||
452 | let datas = | ||
453 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | ||
454 | let data = (*datas) | ||
455 | .as_ref() | ||
456 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | ||
457 | data.clone().subst(&opaque_ty.parameters) | ||
458 | } | ||
459 | }; | ||
460 | write!(f, "impl ")?; | ||
461 | write_bounds_like_dyn_trait(&bounds.value, f)?; | ||
462 | } | ||
438 | Ty::Unknown => write!(f, "{{unknown}}")?, | 463 | Ty::Unknown => write!(f, "{{unknown}}")?, |
439 | Ty::Infer(..) => write!(f, "_")?, | 464 | Ty::Infer(..) => write!(f, "_")?, |
440 | } | 465 | } |