Skip to content

Commit 4171602

Browse files
authored
Merge pull request #22132 from Amit5601/feat-postfix-new
feat: add .new postfix completion based on expected type (rust-lang/r…
2 parents 2147146 + 71dcae2 commit 4171602

1 file changed

Lines changed: 60 additions & 1 deletion

File tree

crates/ide-completion/src/completions/postfix.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
mod format_like;
44

55
use base_db::SourceDatabase;
6-
use hir::{ItemInNs, Semantics};
6+
use hir::{HirDisplay, ItemInNs, Semantics};
77
use ide_db::{
88
RootDatabase, SnippetCap,
99
documentation::{Documentation, HasDocs},
@@ -117,6 +117,34 @@ pub(crate) fn complete_postfix(
117117
postfix_snippet("call", "function(expr)", &format!("${{1}}({receiver_text})"))
118118
.add_to(acc, ctx.db);
119119

120+
if let Some(expected_ty) = ctx.expected_type.as_ref() {
121+
let is_valid_new = expected_ty
122+
.iterate_assoc_items(ctx.db, |item| {
123+
if let hir::AssocItem::Function(func) = item
124+
&& func.name(ctx.db).as_str() == "new"
125+
&& !func.has_self_param(ctx.db)
126+
{
127+
let params = func.params_without_self(ctx.db);
128+
if params.len() == 1 {
129+
return Some(());
130+
}
131+
}
132+
None
133+
})
134+
.is_some();
135+
136+
if is_valid_new {
137+
let ty_name = expected_ty.display(ctx.db, ctx.display_target).to_string();
138+
139+
postfix_snippet(
140+
"new",
141+
&format!("{}::new(expr)", ty_name),
142+
&format!("{}::new({}$0)", ty_name, receiver_text),
143+
)
144+
.add_to(acc, ctx.db);
145+
}
146+
}
147+
120148
let try_enum = TryEnum::from_ty(&ctx.sema, receiver_ty);
121149
let is_in_cond = is_in_condition(&dot_receiver_including_refs);
122150
if let Some(parent) = dot_receiver_including_refs.syntax().parent() {
@@ -1560,6 +1588,37 @@ fn foo(x: Option<i32>, y: Option<i32>) {
15601588
.map(|it| it+2);
15611589
};
15621590
}
1591+
"#,
1592+
);
1593+
}
1594+
1595+
#[test]
1596+
fn postfix_new() {
1597+
check_edit(
1598+
"new",
1599+
r#"
1600+
struct OtherThing;
1601+
struct RefCell<T>(T);
1602+
impl<T> RefCell<T> {
1603+
fn new(t: T) -> Self { RefCell(t) }
1604+
}
1605+
1606+
fn main() {
1607+
let other_thing = OtherThing;
1608+
let thing: RefCell<OtherThing> = other_thing.$0;
1609+
}
1610+
"#,
1611+
r#"
1612+
struct OtherThing;
1613+
struct RefCell<T>(T);
1614+
impl<T> RefCell<T> {
1615+
fn new(t: T) -> Self { RefCell(t) }
1616+
}
1617+
1618+
fn main() {
1619+
let other_thing = OtherThing;
1620+
let thing: RefCell<OtherThing> = RefCell<OtherThing>::new(other_thing$0);
1621+
}
15631622
"#,
15641623
);
15651624
}

0 commit comments

Comments
 (0)