Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/display.rs31
-rw-r--r--crates/hir-ty/src/tests/simple.rs12
2 files changed, 36 insertions, 7 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index d2f9c2b8b1..71763430ea 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -20,6 +20,7 @@ use hir_def::{
};
use hir_expand::{hygiene::Hygiene, name::Name};
use itertools::Itertools;
+use smallvec::SmallVec;
use syntax::SmolStr;
use crate::{
@@ -221,6 +222,7 @@ pub enum DisplaySourceCodeError {
PathNotFound,
UnknownType,
Closure,
+ Generator,
}
pub enum HirDisplayError {
@@ -782,7 +784,34 @@ impl HirDisplay for Ty {
write!(f, "{{unknown}}")?;
}
TyKind::InferenceVar(..) => write!(f, "_")?,
- TyKind::Generator(..) => write!(f, "{{generator}}")?,
+ TyKind::Generator(_, subst) => {
+ if f.display_target.is_source_code() {
+ return Err(HirDisplayError::DisplaySourceCodeError(
+ DisplaySourceCodeError::Generator,
+ ));
+ }
+
+ let subst = subst.as_slice(Interner);
+ let a: Option<SmallVec<[&Ty; 3]>> = subst
+ .get(subst.len() - 3..)
+ .map(|args| args.iter().map(|arg| arg.ty(Interner)).collect())
+ .flatten();
+
+ if let Some([resume_ty, yield_ty, ret_ty]) = a.as_deref() {
+ write!(f, "|")?;
+ resume_ty.hir_fmt(f)?;
+ write!(f, "|")?;
+
+ write!(f, " yields ")?;
+ yield_ty.hir_fmt(f)?;
+
+ write!(f, " -> ")?;
+ ret_ty.hir_fmt(f)?;
+ } else {
+ // This *should* be unreachable, but fallback just in case.
+ write!(f, "{{generator}}")?;
+ }
+ }
TyKind::GeneratorWitness(..) => write!(f, "{{generator witness}}")?,
}
Ok(())
diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs
index e6ff0762ca..b42c5fe7fc 100644
--- a/crates/hir-ty/src/tests/simple.rs
+++ b/crates/hir-ty/src/tests/simple.rs
@@ -1944,8 +1944,8 @@ fn test() {
70..71 'v': i64
78..80 '{}': ()
91..362 '{ ... } }': ()
- 101..106 'mut g': {generator}
- 109..218 '|r| { ... }': {generator}
+ 101..106 'mut g': |usize| yields i64 -> &str
+ 109..218 '|r| { ... }': |usize| yields i64 -> &str
110..111 'r': usize
113..218 '{ ... }': &str
127..128 'a': usize
@@ -1959,11 +1959,11 @@ fn test() {
187..188 '2': i64
198..212 '"return value"': &str
225..360 'match ... }': ()
- 231..239 'Pin::new': fn new<&mut {generator}>(&mut {generator}) -> Pin<&mut {generator}>
- 231..247 'Pin::n...mut g)': Pin<&mut {generator}>
+ 231..239 'Pin::new': fn new<&mut |usize| yields i64 -> &str>(&mut |usize| yields i64 -> &str) -> Pin<&mut |usize| yields i64 -> &str>
+ 231..247 'Pin::n...mut g)': Pin<&mut |usize| yields i64 -> &str>
231..262 'Pin::n...usize)': GeneratorState<i64, &str>
- 240..246 '&mut g': &mut {generator}
- 245..246 'g': {generator}
+ 240..246 '&mut g': &mut |usize| yields i64 -> &str
+ 245..246 'g': |usize| yields i64 -> &str
255..261 '0usize': usize
273..299 'Genera...ded(y)': GeneratorState<i64, &str>
297..298 'y': i64