@@ -2,6 +2,7 @@ use either::Either;
22use hir:: { known, Callable , HasVisibility , HirDisplay , Semantics , TypeInfo } ;
33use ide_db:: RootDatabase ;
44use ide_db:: { base_db:: FileRange , helpers:: FamousDefs } ;
5+ use itertools:: Itertools ;
56use stdx:: to_lower_snake_case;
67use syntax:: {
78 ast:: { self , AstNode , HasArgList , HasName } ,
@@ -211,11 +212,11 @@ fn get_bind_pat_hints(
211212 let label = match label {
212213 Some ( label) => label,
213214 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 ( ) {
215+ let ty_name = ty. display_truncated ( sema. db , config. max_length ) . to_string ( ) ;
216+ if is_named_constructor ( sema, pat, & ty_name ) . is_some ( ) {
216217 return None ;
217218 }
218- ty . into ( )
219+ ty_name . into ( )
219220 }
220221 } ;
221222
@@ -231,34 +232,60 @@ fn get_bind_pat_hints(
231232 Some ( ( ) )
232233}
233234
234- fn get_constructor_name ( sema : & Semantics < RootDatabase > , pat : & ast:: IdentPat ) -> Option < String > {
235- let it = pat. syntax ( ) . parent ( ) ?;
235+ fn is_named_constructor (
236+ sema : & Semantics < RootDatabase > ,
237+ pat : & ast:: IdentPat ,
238+ ty_name : & str ,
239+ ) -> Option < ( ) > {
240+ let let_node = pat. syntax ( ) . parent ( ) ?;
236241 let expr = match_ast ! {
237- match it {
242+ match let_node {
238243 ast:: LetStmt ( it) => it. initializer( ) ,
239244 ast:: Condition ( it) => it. expr( ) ,
240245 _ => None ,
241246 }
247+ } ?;
248+
249+ let expr = sema. descend_node_into_attributes ( expr. clone ( ) ) . pop ( ) . unwrap_or ( expr) ;
250+ // unwrap postfix expressions
251+ let expr = match expr {
252+ ast:: Expr :: TryExpr ( it) => it. expr ( ) ,
253+ ast:: Expr :: AwaitExpr ( it) => it. expr ( ) ,
254+ expr => Some ( expr) ,
255+ } ?;
256+ let expr = match expr {
257+ ast:: Expr :: CallExpr ( call) => match call. expr ( ) ? {
258+ ast:: Expr :: PathExpr ( p) => p,
259+ _ => return None ,
260+ } ,
261+ _ => return None ,
242262 } ;
263+ let path = expr. path ( ) ?;
243264
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 ( ) ) ;
265+ // Check for tuple-struct or tuple-variant in which case we can check the last segment
266+ let callable = sema. type_of_expr ( & ast:: Expr :: PathExpr ( expr) ) ?. original . as_callable ( sema. db ) ;
267+ let callable_kind = callable. map ( |it| it. kind ( ) ) ;
268+ if let Some ( hir:: CallableKind :: TupleStruct ( _) | hir:: CallableKind :: TupleEnumVariant ( _) ) =
269+ callable_kind
270+ {
271+ if let Some ( ctor) = path. segment ( ) {
272+ return ( & ctor. to_string ( ) == ty_name) . then ( || ( ) ) ;
273+ }
260274 }
261- None
275+
276+ // otherwise use the qualifying segment as the constructor name
277+ let qual_seg = path. qualifier ( ) ?. segment ( ) ?;
278+ let ctor_name = match qual_seg. kind ( ) ? {
279+ ast:: PathSegmentKind :: Name ( name_ref) => {
280+ match qual_seg. generic_arg_list ( ) . map ( |it| it. generic_args ( ) ) {
281+ Some ( generics) => format ! ( "{}<{}>" , name_ref, generics. format( ", " ) ) ,
282+ None => name_ref. to_string ( ) ,
283+ }
284+ }
285+ ast:: PathSegmentKind :: Type { type_ref : Some ( ty) , trait_ref : None } => ty. to_string ( ) ,
286+ _ => return None ,
287+ } ;
288+ ( & ctor_name == ty_name) . then ( || ( ) )
262289}
263290
264291/// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator<Item = Ty>`.
@@ -511,10 +538,12 @@ mod tests {
511538 max_length : None ,
512539 } ;
513540
541+ #[ track_caller]
514542 fn check ( ra_fixture : & str ) {
515543 check_with_config ( TEST_CONFIG , ra_fixture) ;
516544 }
517545
546+ #[ track_caller]
518547 fn check_params ( ra_fixture : & str ) {
519548 check_with_config (
520549 InlayHintsConfig {
@@ -527,6 +556,7 @@ mod tests {
527556 ) ;
528557 }
529558
559+ #[ track_caller]
530560 fn check_types ( ra_fixture : & str ) {
531561 check_with_config (
532562 InlayHintsConfig {
@@ -539,6 +569,7 @@ mod tests {
539569 ) ;
540570 }
541571
572+ #[ track_caller]
542573 fn check_chains ( ra_fixture : & str ) {
543574 check_with_config (
544575 InlayHintsConfig {
@@ -551,6 +582,7 @@ mod tests {
551582 ) ;
552583 }
553584
585+ #[ track_caller]
554586 fn check_with_config ( config : InlayHintsConfig , ra_fixture : & str ) {
555587 let ( analysis, file_id) = fixture:: file ( & ra_fixture) ;
556588 let expected = extract_annotations ( & * analysis. file_text ( file_id) . unwrap ( ) ) ;
@@ -560,6 +592,7 @@ mod tests {
560592 assert_eq ! ( expected, actual, "\n Expected:\n {:#?}\n \n Actual:\n {:#?}" , expected, actual) ;
561593 }
562594
595+ #[ track_caller]
563596 fn check_expect ( config : InlayHintsConfig , ra_fixture : & str , expect : Expect ) {
564597 let ( analysis, file_id) = fixture:: file ( & ra_fixture) ;
565598 let inlay_hints = analysis. inlay_hints ( & config, file_id) . unwrap ( ) ;
@@ -1232,11 +1265,12 @@ trait Display {}
12321265trait Sync {}
12331266
12341267fn main() {
1235- let _v = Vec::<Box<&(dyn Display + Sync)>>::new();
1268+ // The block expression wrapping disables the constructor hint hiding logic
1269+ let _v = { Vec::<Box<&(dyn Display + Sync)>>::new() };
12361270 //^^ Vec<Box<&(dyn Display + Sync)>>
1237- let _v = Vec::<Box<*const (dyn Display + Sync)>>::new();
1271+ let _v = { Vec::<Box<*const (dyn Display + Sync)>>::new() } ;
12381272 //^^ Vec<Box<*const (dyn Display + Sync)>>
1239- let _v = Vec::<Box<dyn Display + Sync>>::new();
1273+ let _v = { Vec::<Box<dyn Display + Sync>>::new() } ;
12401274 //^^ Vec<Box<dyn Display + Sync>>
12411275}
12421276"# ,
@@ -1304,13 +1338,10 @@ impl Generic<i32> {
13041338fn main() {
13051339 let strukt = Struct::new();
13061340 let tuple_struct = TupleStruct();
1307- // ^^^^^^^^^^^^ TupleStruct
13081341 let generic0 = Generic::new();
13091342 // ^^^^^^^^ Generic<i32>
13101343 let generic1 = Generic::<i32>::new();
1311- // ^^^^^^^^ Generic<i32>
13121344 let generic2 = <Generic<i32>>::new();
1313- // ^^^^^^^^ Generic<i32>
13141345}
13151346
13161347fn fallible() -> ControlFlow<()> {
0 commit comments