diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index cd898a45d21..95d1550afc3 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -567,7 +567,27 @@ impl HirDisplay for Ty { }; if !parameters_to_write.is_empty() { write!(f, "<")?; - f.write_joined(parameters_to_write, ", ")?; + + if f.display_target.is_source_code() { + let mut first = true; + for generic_arg in parameters_to_write { + if !first { + write!(f, ", ")?; + } + first = false; + + if generic_arg.ty(Interner).map(|ty| ty.kind(Interner)) + == Some(&TyKind::Error) + { + write!(f, "_")?; + } else { + generic_arg.hir_fmt(f)?; + } + } + } else { + f.write_joined(parameters_to_write, ", ")?; + } + write!(f, ">")?; } } diff --git a/crates/ide_assists/src/handlers/add_explicit_type.rs b/crates/ide_assists/src/handlers/add_explicit_type.rs index 169bb0cbf4f..d7e1be900ff 100644 --- a/crates/ide_assists/src/handlers/add_explicit_type.rs +++ b/crates/ide_assists/src/handlers/add_explicit_type.rs @@ -60,8 +60,8 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio } .adjusted(); - // Unresolved or unnameable types can't be annotated - if ty.contains_unknown() || ty.is_closure() { + // Fully unresolved or unnameable types can't be annotated + if (ty.contains_unknown() && ty.type_arguments().count() == 0) || ty.is_closure() { cov_mark::hit!(add_explicit_type_not_applicable_if_ty_not_inferred); return None; } @@ -139,11 +139,34 @@ fn f() { } #[test] - fn add_explicit_type_not_applicable_unresolved() { + fn add_explicit_type_not_applicable_for_fully_unresolved() { cov_mark::check!(add_explicit_type_not_applicable_if_ty_not_inferred); check_assist_not_applicable(add_explicit_type, r#"fn f() { let a$0 = None; }"#); } + #[test] + fn add_explicit_type_applicable_for_partially_unresolved() { + check_assist( + add_explicit_type, + r#" + struct Vec { t: T, v: V } + impl Vec> { + fn new() -> Self { + panic!() + } + } + fn f() { let a$0 = Vec::new(); }"#, + r#" + struct Vec { t: T, v: V } + impl Vec> { + fn new() -> Self { + panic!() + } + } + fn f() { let a: Vec<_, Vec<_, i32>> = Vec::new(); }"#, + ); + } + #[test] fn add_explicit_type_not_applicable_closure_expr() { check_assist_not_applicable(add_explicit_type, r#"fn f() { let a$0 = || {}; }"#);