Skip to content

Commit d89a4f0

Browse files
Merge #11173
11173: Allow adding partially resolved types r=Veykril a=SomeoneToIgnore Sometimes when writing something like `let foo = Arc::new(Mutex::new(CrazyGenerics::new(HashMap::new())))`, I want/have to specify an explicit type for the expression. Using turbofish isn't very readable and not always appreciated by guidelines, so `let foo: T` has to be filled. To ease that, the PR enables the `add_explicit_type` assist on types that contain unknown types and some generics. Fully unresolved types, arrays with unknown types and other known cases behave the same. `_` placeholder was chosen to replace an unknown type: ```rust let foo = HashMap::new(); // after assist usage, turns into let foo: HashMap<_, _> = HashMap::new(); ``` Co-authored-by: Kirill Bulatov <[email protected]>
2 parents df3d3d8 + 03291db commit d89a4f0

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

crates/hir_ty/src/display.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,27 @@ impl HirDisplay for Ty {
567567
};
568568
if !parameters_to_write.is_empty() {
569569
write!(f, "<")?;
570-
f.write_joined(parameters_to_write, ", ")?;
570+
571+
if f.display_target.is_source_code() {
572+
let mut first = true;
573+
for generic_arg in parameters_to_write {
574+
if !first {
575+
write!(f, ", ")?;
576+
}
577+
first = false;
578+
579+
if generic_arg.ty(Interner).map(|ty| ty.kind(Interner))
580+
== Some(&TyKind::Error)
581+
{
582+
write!(f, "_")?;
583+
} else {
584+
generic_arg.hir_fmt(f)?;
585+
}
586+
}
587+
} else {
588+
f.write_joined(parameters_to_write, ", ")?;
589+
}
590+
571591
write!(f, ">")?;
572592
}
573593
}

crates/ide_assists/src/handlers/add_explicit_type.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
6060
}
6161
.adjusted();
6262

63-
// Unresolved or unnameable types can't be annotated
64-
if ty.contains_unknown() || ty.is_closure() {
63+
// Fully unresolved or unnameable types can't be annotated
64+
if (ty.contains_unknown() && ty.type_arguments().count() == 0) || ty.is_closure() {
6565
cov_mark::hit!(add_explicit_type_not_applicable_if_ty_not_inferred);
6666
return None;
6767
}
@@ -139,11 +139,34 @@ fn f() {
139139
}
140140

141141
#[test]
142-
fn add_explicit_type_not_applicable_unresolved() {
142+
fn add_explicit_type_not_applicable_for_fully_unresolved() {
143143
cov_mark::check!(add_explicit_type_not_applicable_if_ty_not_inferred);
144144
check_assist_not_applicable(add_explicit_type, r#"fn f() { let a$0 = None; }"#);
145145
}
146146

147+
#[test]
148+
fn add_explicit_type_applicable_for_partially_unresolved() {
149+
check_assist(
150+
add_explicit_type,
151+
r#"
152+
struct Vec<T, V> { t: T, v: V }
153+
impl<T> Vec<T, Vec<ZZZ, i32>> {
154+
fn new() -> Self {
155+
panic!()
156+
}
157+
}
158+
fn f() { let a$0 = Vec::new(); }"#,
159+
r#"
160+
struct Vec<T, V> { t: T, v: V }
161+
impl<T> Vec<T, Vec<ZZZ, i32>> {
162+
fn new() -> Self {
163+
panic!()
164+
}
165+
}
166+
fn f() { let a: Vec<_, Vec<_, i32>> = Vec::new(); }"#,
167+
);
168+
}
169+
147170
#[test]
148171
fn add_explicit_type_not_applicable_closure_expr() {
149172
check_assist_not_applicable(add_explicit_type, r#"fn f() { let a$0 = || {}; }"#);

0 commit comments

Comments
 (0)