From 02962b374ecefd6f2a75956f4fb18806531d1d51 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Wed, 4 Mar 2020 23:00:44 +0100 Subject: 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. --- crates/ra_hir_ty/src/display.rs | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_ty/src/display.rs') 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 { write!(f, ">")?; } } + TypeCtor::OpaqueType(opaque_ty_id) => { + let bounds = match opaque_ty_id { + crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { + let datas = + f.db.return_type_impl_traits(func).expect("impl trait id without data"); + let data = (*datas) + .as_ref() + .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); + data.clone().subst(&self.parameters) + } + }; + write!(f, "impl ")?; + write_bounds_like_dyn_trait(&bounds.value, f)?; + // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution + } TypeCtor::Closure { .. } => { let sig = self.parameters[0].callable_sig(f.db); if let Some(sig) = sig { @@ -427,14 +442,24 @@ impl HirDisplay for Ty { } } Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, - Ty::Dyn(predicates) | Ty::Opaque(predicates) => { - match self { - Ty::Dyn(_) => write!(f, "dyn ")?, - Ty::Opaque(_) => write!(f, "impl ")?, - _ => unreachable!(), - }; + Ty::Dyn(predicates) => { + write!(f, "dyn ")?; write_bounds_like_dyn_trait(predicates, f)?; } + Ty::Opaque(opaque_ty) => { + let bounds = match opaque_ty.opaque_ty_id { + crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { + let datas = + f.db.return_type_impl_traits(func).expect("impl trait id without data"); + let data = (*datas) + .as_ref() + .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); + data.clone().subst(&opaque_ty.parameters) + } + }; + write!(f, "impl ")?; + write_bounds_like_dyn_trait(&bounds.value, f)?; + } Ty::Unknown => write!(f, "{{unknown}}")?, Ty::Infer(..) => write!(f, "_")?, } -- cgit v1.2.3 From 0d2328f3eaf69c6a50fe6c1e946257bd3503d751 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 5 Jun 2020 17:41:58 +0200 Subject: Review fixes --- crates/ra_hir_ty/src/display.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src/display.rs') diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs index 3e63a2415..3c97e1354 100644 --- a/crates/ra_hir_ty/src/display.rs +++ b/crates/ra_hir_ty/src/display.rs @@ -4,7 +4,7 @@ use std::fmt; use crate::{ db::HirDatabase, utils::generics, ApplicationTy, CallableDef, FnSig, GenericPredicate, - Obligation, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, + Obligation, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, }; use hir_def::{ find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, AssocContainerId, @@ -361,7 +361,7 @@ impl HirDisplay for ApplicationTy { } TypeCtor::OpaqueType(opaque_ty_id) => { let bounds = match opaque_ty_id { - crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { + OpaqueTyId::ReturnTypeImplTrait(func, idx) => { let datas = f.db.return_type_impl_traits(func).expect("impl trait id without data"); let data = (*datas) @@ -448,7 +448,7 @@ impl HirDisplay for Ty { } Ty::Opaque(opaque_ty) => { let bounds = match opaque_ty.opaque_ty_id { - crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { + OpaqueTyId::ReturnTypeImplTrait(func, idx) => { let datas = f.db.return_type_impl_traits(func).expect("impl trait id without data"); let data = (*datas) -- cgit v1.2.3