Skip to content

Commit 992b464

Browse files
committed
feat: Hide type inlay hints for constructors
1 parent 5b0c91d commit 992b464

File tree

2 files changed

+102
-5
lines changed

2 files changed

+102
-5
lines changed

crates/ide/src/inlay_hints.rs

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,28 +198,69 @@ fn get_bind_pat_hints(
198198

199199
let descended = sema.descend_node_into_attributes(pat.clone()).pop();
200200
let desc_pat = descended.as_ref().unwrap_or(pat);
201-
let krate = sema.scope(desc_pat.syntax()).module().map(|it| it.krate());
202-
let famous_defs = FamousDefs(sema, krate);
203-
204201
let ty = sema.type_of_pat(&desc_pat.clone().into())?.original;
205202

206203
if should_not_display_type_hint(sema, &pat, &ty) {
207204
return None;
208205
}
209206

207+
let krate = sema.scope(desc_pat.syntax()).module().map(|it| it.krate());
208+
let famous_defs = FamousDefs(sema, krate);
209+
let label = hint_iterator(sema, &famous_defs, config, &ty);
210+
211+
let label = match label {
212+
Some(label) => label,
213+
None => {
214+
let ty = ty.display_truncated(sema.db, config.max_length).to_string();
215+
if Some(&*ty) == get_constructor_name(sema, pat).as_deref() {
216+
return None;
217+
}
218+
ty.into()
219+
}
220+
};
221+
210222
acc.push(InlayHint {
211223
range: match pat.name() {
212224
Some(name) => name.syntax().text_range(),
213225
None => pat.syntax().text_range(),
214226
},
215227
kind: InlayKind::TypeHint,
216-
label: hint_iterator(sema, &famous_defs, config, &ty)
217-
.unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string().into()),
228+
label,
218229
});
219230

220231
Some(())
221232
}
222233

234+
fn get_constructor_name(sema: &Semantics<RootDatabase>, pat: &ast::IdentPat) -> Option<String> {
235+
let it = pat.syntax().parent()?;
236+
let expr = match_ast! {
237+
match it {
238+
ast::LetStmt(it) => it.initializer(),
239+
ast::Condition(it) => it.expr(),
240+
_ => None,
241+
}
242+
};
243+
244+
if let Some(expr) = expr {
245+
let expr = sema.descend_node_into_attributes(expr.clone()).pop().unwrap_or(expr);
246+
let expr = match expr {
247+
ast::Expr::TryExpr(it) => it.expr(),
248+
ast::Expr::AwaitExpr(it) => it.expr(),
249+
expr => Some(expr),
250+
}?;
251+
let path = match expr {
252+
ast::Expr::CallExpr(call) => match call.expr()? {
253+
ast::Expr::PathExpr(p) => p.path(),
254+
_ => None,
255+
},
256+
_ => None,
257+
}?;
258+
let seg = path.qualifier()?.segment()?;
259+
return Some(seg.to_string());
260+
}
261+
None
262+
}
263+
223264
/// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator<Item = Ty>`.
224265
fn hint_iterator(
225266
sema: &Semantics<RootDatabase>,
@@ -1234,6 +1275,51 @@ fn main() {
12341275
);
12351276
}
12361277

1278+
#[test]
1279+
fn skip_constructor_type_hints() {
1280+
check_types(
1281+
r#"
1282+
//- minicore: try
1283+
use core::ops::ControlFlow;
1284+
1285+
struct Struct;
1286+
struct TupleStruct();
1287+
1288+
impl Struct {
1289+
fn new() -> Self {
1290+
Struct
1291+
}
1292+
fn try_new() -> ControlFlow<(), Self> {
1293+
ControlFlow::Continue(Struct)
1294+
}
1295+
}
1296+
1297+
struct Generic<T>(T);
1298+
impl Generic<i32> {
1299+
fn new() -> Self {
1300+
Generic(0)
1301+
}
1302+
}
1303+
1304+
fn main() {
1305+
let strukt = Struct::new();
1306+
let tuple_struct = TupleStruct();
1307+
// ^^^^^^^^^^^^ TupleStruct
1308+
let generic0 = Generic::new();
1309+
// ^^^^^^^^ Generic<i32>
1310+
let generic1 = Generic::<i32>::new();
1311+
// ^^^^^^^^ Generic<i32>
1312+
let generic2 = <Generic<i32>>::new();
1313+
// ^^^^^^^^ Generic<i32>
1314+
}
1315+
1316+
fn fallible() -> ControlFlow<()> {
1317+
let strukt = Struct::try_new()?;
1318+
}
1319+
"#,
1320+
);
1321+
}
1322+
12371323
#[test]
12381324
fn closures() {
12391325
check(

crates/test_utils/src/minicore.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,17 @@ pub mod ops {
300300
#[lang = "branch"]
301301
fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
302302
}
303+
304+
impl<B, C> Try for ControlFlow<B, C> {
305+
type Output = C;
306+
type Residual = ControlFlow<B, convert::Infallible>;
307+
fn from_output(output: Self::Output) -> Self {}
308+
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {}
309+
}
310+
311+
impl<B, C> FromResidual for ControlFlow<B, C> {
312+
fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self {}
313+
}
303314
}
304315
pub use self::try_::{ControlFlow, FromResidual, Try};
305316
// endregion:try

0 commit comments

Comments
 (0)