mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
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.
This commit is contained in:
parent
9c52f527a1
commit
02962b374e
10 changed files with 403 additions and 85 deletions
|
@ -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, "_")?,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue