Skip to content

Commit 6f77fd3

Browse files
committed
Got args kinda working
1 parent fd6d50f commit 6f77fd3

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

crates/hir-ty/src/infer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ pub enum InferenceDiagnostic {
229229
expr: ExprId,
230230
receiver: Ty,
231231
name: Name,
232+
arg_types: Vec<Ty>,
232233
/// Contains the type the field resolves to
233234
field_with_same_name: Option<Ty>,
234235
assoc_func_with_same_name: Option<FunctionId>,

crates/hir-ty/src/infer/expr.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,10 +1886,15 @@ impl InferenceContext<'_> {
18861886
},
18871887
);
18881888

1889+
let arg_types = args
1890+
.into_iter()
1891+
.map(|&arg| self.infer_expr_inner(arg, &Expectation::none(), ExprIsRead::Yes))
1892+
.collect();
18891893
self.push_diagnostic(InferenceDiagnostic::UnresolvedMethodCall {
18901894
expr: tgt_expr,
18911895
receiver: receiver_ty.clone(),
18921896
name: method_name.clone(),
1897+
arg_types,
18931898
field_with_same_name: field_with_same_name_exists.clone(),
18941899
assoc_func_with_same_name,
18951900
});

crates/hir/src/diagnostics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ pub struct UnresolvedMethodCall<'db> {
260260
pub expr: InFile<ExprOrPatPtr>,
261261
pub receiver: Type<'db>,
262262
pub name: Name,
263+
pub arg_types: Vec<Type<'db>>,
263264
pub field_with_same_name: Option<Type<'db>>,
264265
pub assoc_func_with_same_name: Option<Function>,
265266
}
@@ -688,13 +689,15 @@ impl<'db> AnyDiagnostic<'db> {
688689
expr,
689690
receiver,
690691
name,
692+
arg_types,
691693
field_with_same_name,
692694
assoc_func_with_same_name,
693695
} => {
694696
let expr = expr_syntax(*expr)?;
695697
UnresolvedMethodCall {
696698
expr,
697699
name: name.clone(),
700+
arg_types: arg_types.iter().map(|ty| Type::new(db, def, ty.clone())).collect(),
698701
receiver: Type::new(db, def, receiver.clone()),
699702
field_with_same_name: field_with_same_name
700703
.clone()

crates/ide-diagnostics/src/handlers/unresolved_method.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use ide_db::{
77
label::Label,
88
source_change::SourceChange,
99
};
10+
use itertools::Itertools;
1011
use syntax::{
1112
AstNode, SmolStr, TextRange, ToSmolStr,
1213
ast::{self, HasArgList, make},
@@ -87,22 +88,44 @@ fn add_method_fix(
8788
let db = ctx.sema.db;
8889
let ty = d.receiver.clone();
8990

90-
let impl_block =
91-
hir::Impl::all_for_type(db, ty).into_iter().find(|block| block.trait_(db).is_none())?;
91+
let mut all_impl_blocks = hir::Impl::all_for_type(db, ty.clone())
92+
.into_iter()
93+
.chain(hir::Impl::all_for_type(db, ty.strip_reference()));
94+
let impl_block = all_impl_blocks.find(|block| block.trait_(db).is_none())?;
95+
9296
let items = impl_block.items(db);
9397
let last_item = items.last()?;
9498
let source = last_item.source(db)?;
9599
let file_id = match source.file_id {
96100
hir::HirFileId::FileId(file_id) => file_id,
97101
hir::HirFileId::MacroFile(_) => return None,
98102
};
103+
let module_id = last_item.module(db);
99104
let end_of_last_item = source.node_file_range().file_range()?.range.end();
100105

101106
let method_body = match ctx.config.expr_fill_default {
102107
ExprFillDefaultMode::Default | ExprFillDefaultMode::Todo => "todo!()",
103108
ExprFillDefaultMode::Underscore => "_",
104109
};
105-
let text_to_insert = format!("\n fn {}(&self) {{ {method_body} }}", d.name.as_str());
110+
111+
let method_name = d.name.as_str();
112+
let params: Vec<String> = d
113+
.arg_types
114+
.iter()
115+
.enumerate()
116+
.map(|(i, ty)| {
117+
let name = format!("arg{}", i + 1);
118+
let ty = ty.display_source_code(db, module_id.into(), true).unwrap();
119+
format!("{name}: {ty}")
120+
})
121+
.collect();
122+
let param_list = if params.is_empty() {
123+
"&self".to_owned()
124+
} else {
125+
format!("&self, {}", params.into_iter().join(","))
126+
};
127+
128+
let text_to_insert = format!("\n fn {method_name}({param_list}) {{ {method_body} }}");
106129
Some(fix(
107130
"add-missing-method",
108131
"Add missing method",
@@ -424,7 +447,7 @@ struct Speaker;
424447
425448
impl Speaker {
426449
fn greet(&self) {
427-
self.say("hello");$0
450+
self.say("hello")$0;
428451
}
429452
}"#,
430453
r#"
@@ -434,8 +457,7 @@ impl Speaker {
434457
fn greet(&self) {
435458
self.say("hello");
436459
}
437-
438-
fn say(&self, arg1: &str) {}
460+
fn say(&self, arg1: &'static str) { todo!() }
439461
}"#,
440462
);
441463
}

0 commit comments

Comments
 (0)