diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index d2f9c2b8b1e..71763430ea3 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> = 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 e6ff0762caa..b42c5fe7fc4 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 - 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 297..298 'y': i64