]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/crates/ide/src/signature_help.rs
Rollup merge of #99714 - ouz-a:issue_57961, r=oli-obk
[rust.git] / src / tools / rust-analyzer / crates / ide / src / signature_help.rs
1 //! This module provides primitives for showing type and function parameter information when editing
2 //! a call or use-site.
3
4 use std::collections::BTreeSet;
5
6 use either::Either;
7 use hir::{AssocItem, GenericParam, HasAttrs, HirDisplay, Semantics, Trait};
8 use ide_db::{active_parameter::callable_for_node, base_db::FilePosition};
9 use stdx::format_to;
10 use syntax::{
11     algo,
12     ast::{self, HasArgList},
13     match_ast, AstNode, Direction, SyntaxToken, TextRange, TextSize,
14 };
15
16 use crate::RootDatabase;
17
18 /// Contains information about an item signature as seen from a use site.
19 ///
20 /// This includes the "active parameter", which is the parameter whose value is currently being
21 /// edited.
22 #[derive(Debug)]
23 pub struct SignatureHelp {
24     pub doc: Option<String>,
25     pub signature: String,
26     pub active_parameter: Option<usize>,
27     parameters: Vec<TextRange>,
28 }
29
30 impl SignatureHelp {
31     pub fn parameter_labels(&self) -> impl Iterator<Item = &str> + '_ {
32         self.parameters.iter().map(move |&it| &self.signature[it])
33     }
34
35     pub fn parameter_ranges(&self) -> &[TextRange] {
36         &self.parameters
37     }
38
39     fn push_call_param(&mut self, param: &str) {
40         self.push_param('(', param);
41     }
42
43     fn push_generic_param(&mut self, param: &str) {
44         self.push_param('<', param);
45     }
46
47     fn push_param(&mut self, opening_delim: char, param: &str) {
48         if !self.signature.ends_with(opening_delim) {
49             self.signature.push_str(", ");
50         }
51         let start = TextSize::of(&self.signature);
52         self.signature.push_str(param);
53         let end = TextSize::of(&self.signature);
54         self.parameters.push(TextRange::new(start, end))
55     }
56 }
57
58 /// Computes parameter information for the given position.
59 pub(crate) fn signature_help(db: &RootDatabase, position: FilePosition) -> Option<SignatureHelp> {
60     let sema = Semantics::new(db);
61     let file = sema.parse(position.file_id);
62     let file = file.syntax();
63     let token = file
64         .token_at_offset(position.offset)
65         .left_biased()
66         // if the cursor is sandwiched between two space tokens and the call is unclosed
67         // this prevents us from leaving the CallExpression
68         .and_then(|tok| algo::skip_trivia_token(tok, Direction::Prev))?;
69     let token = sema.descend_into_macros_single(token);
70
71     for node in token.parent_ancestors() {
72         match_ast! {
73             match node {
74                 ast::ArgList(arg_list) => {
75                     let cursor_outside = arg_list.r_paren_token().as_ref() == Some(&token);
76                     if cursor_outside {
77                         return None;
78                     }
79                     return signature_help_for_call(&sema, token);
80                 },
81                 ast::GenericArgList(garg_list) => {
82                     let cursor_outside = garg_list.r_angle_token().as_ref() == Some(&token);
83                     if cursor_outside {
84                         return None;
85                     }
86                     return signature_help_for_generics(&sema, token);
87                 },
88                 _ => (),
89             }
90         }
91     }
92
93     None
94 }
95
96 fn signature_help_for_call(
97     sema: &Semantics<'_, RootDatabase>,
98     token: SyntaxToken,
99 ) -> Option<SignatureHelp> {
100     // Find the calling expression and its NameRef
101     let mut node = token.parent()?;
102     let calling_node = loop {
103         if let Some(callable) = ast::CallableExpr::cast(node.clone()) {
104             if callable
105                 .arg_list()
106                 .map_or(false, |it| it.syntax().text_range().contains(token.text_range().start()))
107             {
108                 break callable;
109             }
110         }
111
112         // Stop at multi-line expressions, since the signature of the outer call is not very
113         // helpful inside them.
114         if let Some(expr) = ast::Expr::cast(node.clone()) {
115             if expr.syntax().text().contains_char('\n') {
116                 return None;
117             }
118         }
119
120         node = node.parent()?;
121     };
122
123     let (callable, active_parameter) = callable_for_node(sema, &calling_node, &token)?;
124
125     let mut res =
126         SignatureHelp { doc: None, signature: String::new(), parameters: vec![], active_parameter };
127
128     let db = sema.db;
129     let mut fn_params = None;
130     match callable.kind() {
131         hir::CallableKind::Function(func) => {
132             res.doc = func.docs(db).map(|it| it.into());
133             format_to!(res.signature, "fn {}", func.name(db));
134             fn_params = Some(match callable.receiver_param(db) {
135                 Some(_self) => func.params_without_self(db),
136                 None => func.assoc_fn_params(db),
137             });
138         }
139         hir::CallableKind::TupleStruct(strukt) => {
140             res.doc = strukt.docs(db).map(|it| it.into());
141             format_to!(res.signature, "struct {}", strukt.name(db));
142         }
143         hir::CallableKind::TupleEnumVariant(variant) => {
144             res.doc = variant.docs(db).map(|it| it.into());
145             format_to!(
146                 res.signature,
147                 "enum {}::{}",
148                 variant.parent_enum(db).name(db),
149                 variant.name(db)
150             );
151         }
152         hir::CallableKind::Closure | hir::CallableKind::FnPtr => (),
153     }
154
155     res.signature.push('(');
156     {
157         if let Some(self_param) = callable.receiver_param(db) {
158             format_to!(res.signature, "{}", self_param)
159         }
160         let mut buf = String::new();
161         for (idx, (pat, ty)) in callable.params(db).into_iter().enumerate() {
162             buf.clear();
163             if let Some(pat) = pat {
164                 match pat {
165                     Either::Left(_self) => format_to!(buf, "self: "),
166                     Either::Right(pat) => format_to!(buf, "{}: ", pat),
167                 }
168             }
169             // APITs (argument position `impl Trait`s) are inferred as {unknown} as the user is
170             // in the middle of entering call arguments.
171             // In that case, fall back to render definitions of the respective parameters.
172             // This is overly conservative: we do not substitute known type vars
173             // (see FIXME in tests::impl_trait) and falling back on any unknowns.
174             match (ty.contains_unknown(), fn_params.as_deref()) {
175                 (true, Some(fn_params)) => format_to!(buf, "{}", fn_params[idx].ty().display(db)),
176                 _ => format_to!(buf, "{}", ty.display(db)),
177             }
178             res.push_call_param(&buf);
179         }
180     }
181     res.signature.push(')');
182
183     let mut render = |ret_type: hir::Type| {
184         if !ret_type.is_unit() {
185             format_to!(res.signature, " -> {}", ret_type.display(db));
186         }
187     };
188     match callable.kind() {
189         hir::CallableKind::Function(func) if callable.return_type().contains_unknown() => {
190             render(func.ret_type(db))
191         }
192         hir::CallableKind::Function(_) | hir::CallableKind::Closure | hir::CallableKind::FnPtr => {
193             render(callable.return_type())
194         }
195         hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => {}
196     }
197     Some(res)
198 }
199
200 fn signature_help_for_generics(
201     sema: &Semantics<'_, RootDatabase>,
202     token: SyntaxToken,
203 ) -> Option<SignatureHelp> {
204     let parent = token.parent()?;
205     let arg_list = parent
206         .ancestors()
207         .filter_map(ast::GenericArgList::cast)
208         .find(|list| list.syntax().text_range().contains(token.text_range().start()))?;
209
210     let mut active_parameter = arg_list
211         .generic_args()
212         .take_while(|arg| arg.syntax().text_range().end() <= token.text_range().start())
213         .count();
214
215     let first_arg_is_non_lifetime = arg_list
216         .generic_args()
217         .next()
218         .map_or(false, |arg| !matches!(arg, ast::GenericArg::LifetimeArg(_)));
219
220     let mut generics_def = if let Some(path) =
221         arg_list.syntax().ancestors().find_map(ast::Path::cast)
222     {
223         let res = sema.resolve_path(&path)?;
224         let generic_def: hir::GenericDef = match res {
225             hir::PathResolution::Def(hir::ModuleDef::Adt(it)) => it.into(),
226             hir::PathResolution::Def(hir::ModuleDef::Function(it)) => it.into(),
227             hir::PathResolution::Def(hir::ModuleDef::Trait(it)) => it.into(),
228             hir::PathResolution::Def(hir::ModuleDef::TypeAlias(it)) => it.into(),
229             hir::PathResolution::Def(hir::ModuleDef::Variant(it)) => it.into(),
230             hir::PathResolution::Def(hir::ModuleDef::BuiltinType(_))
231             | hir::PathResolution::Def(hir::ModuleDef::Const(_))
232             | hir::PathResolution::Def(hir::ModuleDef::Macro(_))
233             | hir::PathResolution::Def(hir::ModuleDef::Module(_))
234             | hir::PathResolution::Def(hir::ModuleDef::Static(_)) => return None,
235             hir::PathResolution::BuiltinAttr(_)
236             | hir::PathResolution::ToolModule(_)
237             | hir::PathResolution::Local(_)
238             | hir::PathResolution::TypeParam(_)
239             | hir::PathResolution::ConstParam(_)
240             | hir::PathResolution::SelfType(_) => return None,
241         };
242
243         generic_def
244     } else if let Some(method_call) = arg_list.syntax().parent().and_then(ast::MethodCallExpr::cast)
245     {
246         // recv.method::<$0>()
247         let method = sema.resolve_method_call(&method_call)?;
248         method.into()
249     } else {
250         return None;
251     };
252
253     let mut res = SignatureHelp {
254         doc: None,
255         signature: String::new(),
256         parameters: vec![],
257         active_parameter: None,
258     };
259
260     let db = sema.db;
261     match generics_def {
262         hir::GenericDef::Function(it) => {
263             res.doc = it.docs(db).map(|it| it.into());
264             format_to!(res.signature, "fn {}", it.name(db));
265         }
266         hir::GenericDef::Adt(hir::Adt::Enum(it)) => {
267             res.doc = it.docs(db).map(|it| it.into());
268             format_to!(res.signature, "enum {}", it.name(db));
269         }
270         hir::GenericDef::Adt(hir::Adt::Struct(it)) => {
271             res.doc = it.docs(db).map(|it| it.into());
272             format_to!(res.signature, "struct {}", it.name(db));
273         }
274         hir::GenericDef::Adt(hir::Adt::Union(it)) => {
275             res.doc = it.docs(db).map(|it| it.into());
276             format_to!(res.signature, "union {}", it.name(db));
277         }
278         hir::GenericDef::Trait(it) => {
279             res.doc = it.docs(db).map(|it| it.into());
280             format_to!(res.signature, "trait {}", it.name(db));
281         }
282         hir::GenericDef::TypeAlias(it) => {
283             res.doc = it.docs(db).map(|it| it.into());
284             format_to!(res.signature, "type {}", it.name(db));
285         }
286         hir::GenericDef::Variant(it) => {
287             // In paths, generics of an enum can be specified *after* one of its variants.
288             // eg. `None::<u8>`
289             // We'll use the signature of the enum, but include the docs of the variant.
290             res.doc = it.docs(db).map(|it| it.into());
291             let it = it.parent_enum(db);
292             format_to!(res.signature, "enum {}", it.name(db));
293             generics_def = it.into();
294         }
295         // These don't have generic args that can be specified
296         hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) => return None,
297     }
298
299     let params = generics_def.params(sema.db);
300     let num_lifetime_params =
301         params.iter().take_while(|param| matches!(param, GenericParam::LifetimeParam(_))).count();
302     if first_arg_is_non_lifetime {
303         // Lifetime parameters were omitted.
304         active_parameter += num_lifetime_params;
305     }
306     res.active_parameter = Some(active_parameter);
307
308     res.signature.push('<');
309     let mut buf = String::new();
310     for param in params {
311         if let hir::GenericParam::TypeParam(ty) = param {
312             if ty.is_implicit(db) {
313                 continue;
314             }
315         }
316
317         buf.clear();
318         format_to!(buf, "{}", param.display(db));
319         res.push_generic_param(&buf);
320     }
321     if let hir::GenericDef::Trait(tr) = generics_def {
322         add_assoc_type_bindings(db, &mut res, tr, arg_list);
323     }
324     res.signature.push('>');
325
326     Some(res)
327 }
328
329 fn add_assoc_type_bindings(
330     db: &RootDatabase,
331     res: &mut SignatureHelp,
332     tr: Trait,
333     args: ast::GenericArgList,
334 ) {
335     if args.syntax().ancestors().find_map(ast::TypeBound::cast).is_none() {
336         // Assoc type bindings are only valid in type bound position.
337         return;
338     }
339
340     let present_bindings = args
341         .generic_args()
342         .filter_map(|arg| match arg {
343             ast::GenericArg::AssocTypeArg(arg) => arg.name_ref().map(|n| n.to_string()),
344             _ => None,
345         })
346         .collect::<BTreeSet<_>>();
347
348     let mut buf = String::new();
349     for binding in &present_bindings {
350         buf.clear();
351         format_to!(buf, "{} = …", binding);
352         res.push_generic_param(&buf);
353     }
354
355     for item in tr.items_with_supertraits(db) {
356         if let AssocItem::TypeAlias(ty) = item {
357             let name = ty.name(db).to_smol_str();
358             if !present_bindings.contains(&*name) {
359                 buf.clear();
360                 format_to!(buf, "{} = …", name);
361                 res.push_generic_param(&buf);
362             }
363         }
364     }
365 }
366
367 #[cfg(test)]
368 mod tests {
369     use std::iter;
370
371     use expect_test::{expect, Expect};
372     use ide_db::base_db::{fixture::ChangeFixture, FilePosition};
373     use stdx::format_to;
374
375     use crate::RootDatabase;
376
377     /// Creates analysis from a multi-file fixture, returns positions marked with $0.
378     pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
379         let change_fixture = ChangeFixture::parse(ra_fixture);
380         let mut database = RootDatabase::default();
381         database.apply_change(change_fixture.change);
382         let (file_id, range_or_offset) =
383             change_fixture.file_position.expect("expected a marker ($0)");
384         let offset = range_or_offset.expect_offset();
385         (database, FilePosition { file_id, offset })
386     }
387
388     fn check(ra_fixture: &str, expect: Expect) {
389         // Implicitly add `Sized` to avoid noisy `T: ?Sized` in the results.
390         let fixture = format!(
391             r#"
392 #[lang = "sized"] trait Sized {{}}
393 {ra_fixture}
394             "#
395         );
396         let (db, position) = position(&fixture);
397         let sig_help = crate::signature_help::signature_help(&db, position);
398         let actual = match sig_help {
399             Some(sig_help) => {
400                 let mut rendered = String::new();
401                 if let Some(docs) = &sig_help.doc {
402                     format_to!(rendered, "{}\n------\n", docs.as_str());
403                 }
404                 format_to!(rendered, "{}\n", sig_help.signature);
405                 let mut offset = 0;
406                 for (i, range) in sig_help.parameter_ranges().iter().enumerate() {
407                     let is_active = sig_help.active_parameter == Some(i);
408
409                     let start = u32::from(range.start());
410                     let gap = start.checked_sub(offset).unwrap_or_else(|| {
411                         panic!("parameter ranges out of order: {:?}", sig_help.parameter_ranges())
412                     });
413                     rendered.extend(iter::repeat(' ').take(gap as usize));
414                     let param_text = &sig_help.signature[*range];
415                     let width = param_text.chars().count(); // …
416                     let marker = if is_active { '^' } else { '-' };
417                     rendered.extend(iter::repeat(marker).take(width));
418                     offset += gap + u32::from(range.len());
419                 }
420                 if !sig_help.parameter_ranges().is_empty() {
421                     format_to!(rendered, "\n");
422                 }
423                 rendered
424             }
425             None => String::new(),
426         };
427         expect.assert_eq(&actual);
428     }
429
430     #[test]
431     fn test_fn_signature_two_args() {
432         check(
433             r#"
434 fn foo(x: u32, y: u32) -> u32 {x + y}
435 fn bar() { foo($03, ); }
436 "#,
437             expect![[r#"
438                 fn foo(x: u32, y: u32) -> u32
439                        ^^^^^^  ------
440             "#]],
441         );
442         check(
443             r#"
444 fn foo(x: u32, y: u32) -> u32 {x + y}
445 fn bar() { foo(3$0, ); }
446 "#,
447             expect![[r#"
448                 fn foo(x: u32, y: u32) -> u32
449                        ^^^^^^  ------
450             "#]],
451         );
452         check(
453             r#"
454 fn foo(x: u32, y: u32) -> u32 {x + y}
455 fn bar() { foo(3,$0 ); }
456 "#,
457             expect![[r#"
458                 fn foo(x: u32, y: u32) -> u32
459                        ------  ^^^^^^
460             "#]],
461         );
462         check(
463             r#"
464 fn foo(x: u32, y: u32) -> u32 {x + y}
465 fn bar() { foo(3, $0); }
466 "#,
467             expect![[r#"
468                 fn foo(x: u32, y: u32) -> u32
469                        ------  ^^^^^^
470             "#]],
471         );
472     }
473
474     #[test]
475     fn test_fn_signature_two_args_empty() {
476         check(
477             r#"
478 fn foo(x: u32, y: u32) -> u32 {x + y}
479 fn bar() { foo($0); }
480 "#,
481             expect![[r#"
482                 fn foo(x: u32, y: u32) -> u32
483                        ^^^^^^  ------
484             "#]],
485         );
486     }
487
488     #[test]
489     fn test_fn_signature_two_args_first_generics() {
490         check(
491             r#"
492 fn foo<T, U: Copy + Display>(x: T, y: U) -> u32
493     where T: Copy + Display, U: Debug
494 { x + y }
495
496 fn bar() { foo($03, ); }
497 "#,
498             expect![[r#"
499                 fn foo(x: i32, y: U) -> u32
500                        ^^^^^^  ----
501             "#]],
502         );
503     }
504
505     #[test]
506     fn test_fn_signature_no_params() {
507         check(
508             r#"
509 fn foo<T>() -> T where T: Copy + Display {}
510 fn bar() { foo($0); }
511 "#,
512             expect![[r#"
513                 fn foo() -> T
514             "#]],
515         );
516     }
517
518     #[test]
519     fn test_fn_signature_for_impl() {
520         check(
521             r#"
522 struct F;
523 impl F { pub fn new() { } }
524 fn bar() {
525     let _ : F = F::new($0);
526 }
527 "#,
528             expect![[r#"
529                 fn new()
530             "#]],
531         );
532     }
533
534     #[test]
535     fn test_fn_signature_for_method_self() {
536         check(
537             r#"
538 struct S;
539 impl S { pub fn do_it(&self) {} }
540
541 fn bar() {
542     let s: S = S;
543     s.do_it($0);
544 }
545 "#,
546             expect![[r#"
547                 fn do_it(&self)
548             "#]],
549         );
550     }
551
552     #[test]
553     fn test_fn_signature_for_method_with_arg() {
554         check(
555             r#"
556 struct S;
557 impl S {
558     fn foo(&self, x: i32) {}
559 }
560
561 fn main() { S.foo($0); }
562 "#,
563             expect![[r#"
564                 fn foo(&self, x: i32)
565                               ^^^^^^
566             "#]],
567         );
568     }
569
570     #[test]
571     fn test_fn_signature_for_generic_method() {
572         check(
573             r#"
574 struct S<T>(T);
575 impl<T> S<T> {
576     fn foo(&self, x: T) {}
577 }
578
579 fn main() { S(1u32).foo($0); }
580 "#,
581             expect![[r#"
582                 fn foo(&self, x: u32)
583                               ^^^^^^
584             "#]],
585         );
586     }
587
588     #[test]
589     fn test_fn_signature_for_method_with_arg_as_assoc_fn() {
590         check(
591             r#"
592 struct S;
593 impl S {
594     fn foo(&self, x: i32) {}
595 }
596
597 fn main() { S::foo($0); }
598 "#,
599             expect![[r#"
600                 fn foo(self: &S, x: i32)
601                        ^^^^^^^^  ------
602             "#]],
603         );
604     }
605
606     #[test]
607     fn test_fn_signature_with_docs_simple() {
608         check(
609             r#"
610 /// test
611 // non-doc-comment
612 fn foo(j: u32) -> u32 {
613     j
614 }
615
616 fn bar() {
617     let _ = foo($0);
618 }
619 "#,
620             expect![[r#"
621                 test
622                 ------
623                 fn foo(j: u32) -> u32
624                        ^^^^^^
625             "#]],
626         );
627     }
628
629     #[test]
630     fn test_fn_signature_with_docs() {
631         check(
632             r#"
633 /// Adds one to the number given.
634 ///
635 /// # Examples
636 ///
637 /// ```
638 /// let five = 5;
639 ///
640 /// assert_eq!(6, my_crate::add_one(5));
641 /// ```
642 pub fn add_one(x: i32) -> i32 {
643     x + 1
644 }
645
646 pub fn do() {
647     add_one($0
648 }"#,
649             expect![[r##"
650                 Adds one to the number given.
651
652                 # Examples
653
654                 ```
655                 let five = 5;
656
657                 assert_eq!(6, my_crate::add_one(5));
658                 ```
659                 ------
660                 fn add_one(x: i32) -> i32
661                            ^^^^^^
662             "##]],
663         );
664     }
665
666     #[test]
667     fn test_fn_signature_with_docs_impl() {
668         check(
669             r#"
670 struct addr;
671 impl addr {
672     /// Adds one to the number given.
673     ///
674     /// # Examples
675     ///
676     /// ```
677     /// let five = 5;
678     ///
679     /// assert_eq!(6, my_crate::add_one(5));
680     /// ```
681     pub fn add_one(x: i32) -> i32 {
682         x + 1
683     }
684 }
685
686 pub fn do_it() {
687     addr {};
688     addr::add_one($0);
689 }
690 "#,
691             expect![[r##"
692                 Adds one to the number given.
693
694                 # Examples
695
696                 ```
697                 let five = 5;
698
699                 assert_eq!(6, my_crate::add_one(5));
700                 ```
701                 ------
702                 fn add_one(x: i32) -> i32
703                            ^^^^^^
704             "##]],
705         );
706     }
707
708     #[test]
709     fn test_fn_signature_with_docs_from_actix() {
710         check(
711             r#"
712 trait Actor {
713     /// Actor execution context type
714     type Context;
715 }
716 trait WriteHandler<E>
717 where
718     Self: Actor
719 {
720     /// Method is called when writer finishes.
721     ///
722     /// By default this method stops actor's `Context`.
723     fn finished(&mut self, ctx: &mut Self::Context) {}
724 }
725
726 fn foo(mut r: impl WriteHandler<()>) {
727     r.finished($0);
728 }
729 "#,
730             expect![[r#"
731                 Method is called when writer finishes.
732
733                 By default this method stops actor's `Context`.
734                 ------
735                 fn finished(&mut self, ctx: &mut <impl WriteHandler<()> as Actor>::Context)
736                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
737             "#]],
738         );
739     }
740
741     #[test]
742     fn call_info_bad_offset() {
743         check(
744             r#"
745 fn foo(x: u32, y: u32) -> u32 {x + y}
746 fn bar() { foo $0 (3, ); }
747 "#,
748             expect![[""]],
749         );
750     }
751
752     #[test]
753     fn outside_of_arg_list() {
754         check(
755             r#"
756 fn foo(a: u8) {}
757 fn f() {
758     foo(123)$0
759 }
760 "#,
761             expect![[]],
762         );
763         check(
764             r#"
765 fn foo<T>(a: u8) {}
766 fn f() {
767     foo::<u32>$0()
768 }
769 "#,
770             expect![[]],
771         );
772     }
773
774     #[test]
775     fn test_nested_method_in_lambda() {
776         check(
777             r#"
778 struct Foo;
779 impl Foo { fn bar(&self, _: u32) { } }
780
781 fn bar(_: u32) { }
782
783 fn main() {
784     let foo = Foo;
785     std::thread::spawn(move || foo.bar($0));
786 }
787 "#,
788             expect![[r#"
789                 fn bar(&self, _: u32)
790                               ^^^^^^
791             "#]],
792         );
793     }
794
795     #[test]
796     fn works_for_tuple_structs() {
797         check(
798             r#"
799 /// A cool tuple struct
800 struct S(u32, i32);
801 fn main() {
802     let s = S(0, $0);
803 }
804 "#,
805             expect![[r#"
806                 A cool tuple struct
807                 ------
808                 struct S(u32, i32)
809                          ---  ^^^
810             "#]],
811         );
812     }
813
814     #[test]
815     fn generic_struct() {
816         check(
817             r#"
818 struct S<T>(T);
819 fn main() {
820     let s = S($0);
821 }
822 "#,
823             expect![[r#"
824                 struct S({unknown})
825                          ^^^^^^^^^
826             "#]],
827         );
828     }
829
830     #[test]
831     fn works_for_enum_variants() {
832         check(
833             r#"
834 enum E {
835     /// A Variant
836     A(i32),
837     /// Another
838     B,
839     /// And C
840     C { a: i32, b: i32 }
841 }
842
843 fn main() {
844     let a = E::A($0);
845 }
846 "#,
847             expect![[r#"
848                 A Variant
849                 ------
850                 enum E::A(i32)
851                           ^^^
852             "#]],
853         );
854     }
855
856     #[test]
857     fn cant_call_struct_record() {
858         check(
859             r#"
860 struct S { x: u32, y: i32 }
861 fn main() {
862     let s = S($0);
863 }
864 "#,
865             expect![[""]],
866         );
867     }
868
869     #[test]
870     fn cant_call_enum_record() {
871         check(
872             r#"
873 enum E {
874     /// A Variant
875     A(i32),
876     /// Another
877     B,
878     /// And C
879     C { a: i32, b: i32 }
880 }
881
882 fn main() {
883     let a = E::C($0);
884 }
885 "#,
886             expect![[""]],
887         );
888     }
889
890     #[test]
891     fn fn_signature_for_call_in_macro() {
892         check(
893             r#"
894 macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
895 fn foo() { }
896 id! {
897     fn bar() { foo($0); }
898 }
899 "#,
900             expect![[r#"
901                 fn foo()
902             "#]],
903         );
904     }
905
906     #[test]
907     fn call_info_for_lambdas() {
908         check(
909             r#"
910 struct S;
911 fn foo(s: S) -> i32 { 92 }
912 fn main() {
913     (|s| foo(s))($0)
914 }
915         "#,
916             expect![[r#"
917                 (s: S) -> i32
918                  ^^^^
919             "#]],
920         )
921     }
922
923     #[test]
924     fn call_info_for_fn_ptr() {
925         check(
926             r#"
927 fn main(f: fn(i32, f64) -> char) {
928     f(0, $0)
929 }
930         "#,
931             expect![[r#"
932                 (i32, f64) -> char
933                  ---  ^^^
934             "#]],
935         )
936     }
937
938     #[test]
939     fn call_info_for_unclosed_call() {
940         check(
941             r#"
942 fn foo(foo: u32, bar: u32) {}
943 fn main() {
944     foo($0
945 }"#,
946             expect![[r#"
947                 fn foo(foo: u32, bar: u32)
948                        ^^^^^^^^  --------
949             "#]],
950         );
951         // check with surrounding space
952         check(
953             r#"
954 fn foo(foo: u32, bar: u32) {}
955 fn main() {
956     foo( $0
957 }"#,
958             expect![[r#"
959                 fn foo(foo: u32, bar: u32)
960                        ^^^^^^^^  --------
961             "#]],
962         )
963     }
964
965     #[test]
966     fn test_multiline_argument() {
967         check(
968             r#"
969 fn callee(a: u8, b: u8) {}
970 fn main() {
971     callee(match 0 {
972         0 => 1,$0
973     })
974 }"#,
975             expect![[r#""#]],
976         );
977         check(
978             r#"
979 fn callee(a: u8, b: u8) {}
980 fn main() {
981     callee(match 0 {
982         0 => 1,
983     },$0)
984 }"#,
985             expect![[r#"
986                 fn callee(a: u8, b: u8)
987                           -----  ^^^^^
988             "#]],
989         );
990         check(
991             r#"
992 fn callee(a: u8, b: u8) {}
993 fn main() {
994     callee($0match 0 {
995         0 => 1,
996     })
997 }"#,
998             expect![[r#"
999                 fn callee(a: u8, b: u8)
1000                           ^^^^^  -----
1001             "#]],
1002         );
1003     }
1004
1005     #[test]
1006     fn test_generics_simple() {
1007         check(
1008             r#"
1009 /// Option docs.
1010 enum Option<T> {
1011     Some(T),
1012     None,
1013 }
1014
1015 fn f() {
1016     let opt: Option<$0
1017 }
1018         "#,
1019             expect![[r#"
1020                 Option docs.
1021                 ------
1022                 enum Option<T>
1023                             ^
1024             "#]],
1025         );
1026     }
1027
1028     #[test]
1029     fn test_generics_on_variant() {
1030         check(
1031             r#"
1032 /// Option docs.
1033 enum Option<T> {
1034     /// Some docs.
1035     Some(T),
1036     /// None docs.
1037     None,
1038 }
1039
1040 use Option::*;
1041
1042 fn f() {
1043     None::<$0
1044 }
1045         "#,
1046             expect![[r#"
1047                 None docs.
1048                 ------
1049                 enum Option<T>
1050                             ^
1051             "#]],
1052         );
1053     }
1054
1055     #[test]
1056     fn test_lots_of_generics() {
1057         check(
1058             r#"
1059 trait Tr<T> {}
1060
1061 struct S<T>(T);
1062
1063 impl<T> S<T> {
1064     fn f<G, H>(g: G, h: impl Tr<G>) where G: Tr<()> {}
1065 }
1066
1067 fn f() {
1068     S::<u8>::f::<(), $0
1069 }
1070         "#,
1071             expect![[r#"
1072                 fn f<G: Tr<()>, H>
1073                      ---------  ^
1074             "#]],
1075         );
1076     }
1077
1078     #[test]
1079     fn test_generics_in_trait_ufcs() {
1080         check(
1081             r#"
1082 trait Tr {
1083     fn f<T: Tr, U>() {}
1084 }
1085
1086 struct S;
1087
1088 impl Tr for S {}
1089
1090 fn f() {
1091     <S as Tr>::f::<$0
1092 }
1093         "#,
1094             expect![[r#"
1095                 fn f<T: Tr, U>
1096                      ^^^^^  -
1097             "#]],
1098         );
1099     }
1100
1101     #[test]
1102     fn test_generics_in_method_call() {
1103         check(
1104             r#"
1105 struct S;
1106
1107 impl S {
1108     fn f<T>(&self) {}
1109 }
1110
1111 fn f() {
1112     S.f::<$0
1113 }
1114         "#,
1115             expect![[r#"
1116                 fn f<T>
1117                      ^
1118             "#]],
1119         );
1120     }
1121
1122     #[test]
1123     fn test_generic_param_in_method_call() {
1124         check(
1125             r#"
1126 struct Foo;
1127 impl Foo {
1128     fn test<V>(&mut self, val: V) {}
1129 }
1130 fn sup() {
1131     Foo.test($0)
1132 }
1133 "#,
1134             expect![[r#"
1135                 fn test(&mut self, val: V)
1136                                    ^^^^^^
1137             "#]],
1138         );
1139     }
1140
1141     #[test]
1142     fn test_generic_kinds() {
1143         check(
1144             r#"
1145 fn callee<'a, const A: u8, T, const C: u8>() {}
1146
1147 fn f() {
1148     callee::<'static, $0
1149 }
1150         "#,
1151             expect![[r#"
1152                 fn callee<'a, const A: u8, T, const C: u8>
1153                           --  ^^^^^^^^^^^  -  -----------
1154             "#]],
1155         );
1156         check(
1157             r#"
1158 fn callee<'a, const A: u8, T, const C: u8>() {}
1159
1160 fn f() {
1161     callee::<NON_LIFETIME$0
1162 }
1163         "#,
1164             expect![[r#"
1165                 fn callee<'a, const A: u8, T, const C: u8>
1166                           --  ^^^^^^^^^^^  -  -----------
1167             "#]],
1168         );
1169     }
1170
1171     #[test]
1172     fn test_trait_assoc_types() {
1173         check(
1174             r#"
1175 trait Trait<'a, T> {
1176     type Assoc;
1177 }
1178 fn f() -> impl Trait<(), $0
1179             "#,
1180             expect![[r#"
1181                 trait Trait<'a, T, Assoc = …>
1182                             --  -  ^^^^^^^^^
1183             "#]],
1184         );
1185         check(
1186             r#"
1187 trait Iterator {
1188     type Item;
1189 }
1190 fn f() -> impl Iterator<$0
1191             "#,
1192             expect![[r#"
1193                 trait Iterator<Item = …>
1194                                ^^^^^^^^
1195             "#]],
1196         );
1197         check(
1198             r#"
1199 trait Iterator {
1200     type Item;
1201 }
1202 fn f() -> impl Iterator<Item = $0
1203             "#,
1204             expect![[r#"
1205                 trait Iterator<Item = …>
1206                                ^^^^^^^^
1207             "#]],
1208         );
1209         check(
1210             r#"
1211 trait Tr {
1212     type A;
1213     type B;
1214 }
1215 fn f() -> impl Tr<$0
1216             "#,
1217             expect![[r#"
1218                 trait Tr<A = …, B = …>
1219                          ^^^^^  -----
1220             "#]],
1221         );
1222         check(
1223             r#"
1224 trait Tr {
1225     type A;
1226     type B;
1227 }
1228 fn f() -> impl Tr<B$0
1229             "#,
1230             expect![[r#"
1231                 trait Tr<A = …, B = …>
1232                          ^^^^^  -----
1233             "#]],
1234         );
1235         check(
1236             r#"
1237 trait Tr {
1238     type A;
1239     type B;
1240 }
1241 fn f() -> impl Tr<B = $0
1242             "#,
1243             expect![[r#"
1244                 trait Tr<B = …, A = …>
1245                          ^^^^^  -----
1246             "#]],
1247         );
1248         check(
1249             r#"
1250 trait Tr {
1251     type A;
1252     type B;
1253 }
1254 fn f() -> impl Tr<B = (), $0
1255             "#,
1256             expect![[r#"
1257                 trait Tr<B = …, A = …>
1258                          -----  ^^^^^
1259             "#]],
1260         );
1261     }
1262
1263     #[test]
1264     fn test_supertrait_assoc() {
1265         check(
1266             r#"
1267 trait Super {
1268     type SuperTy;
1269 }
1270 trait Sub: Super + Super {
1271     type SubTy;
1272 }
1273 fn f() -> impl Sub<$0
1274             "#,
1275             expect![[r#"
1276                 trait Sub<SubTy = …, SuperTy = …>
1277                           ^^^^^^^^^  -----------
1278             "#]],
1279         );
1280     }
1281
1282     #[test]
1283     fn no_assoc_types_outside_type_bounds() {
1284         check(
1285             r#"
1286 trait Tr<T> {
1287     type Assoc;
1288 }
1289
1290 impl Tr<$0
1291         "#,
1292             expect![[r#"
1293             trait Tr<T>
1294                      ^
1295         "#]],
1296         );
1297     }
1298
1299     #[test]
1300     fn impl_trait() {
1301         // FIXME: Substitute type vars in impl trait (`U` -> `i8`)
1302         check(
1303             r#"
1304 trait Trait<T> {}
1305 struct Wrap<T>(T);
1306 fn foo<U>(x: Wrap<impl Trait<U>>) {}
1307 fn f() {
1308     foo::<i8>($0)
1309 }
1310 "#,
1311             expect![[r#"
1312                 fn foo(x: Wrap<impl Trait<U>>)
1313                        ^^^^^^^^^^^^^^^^^^^^^^
1314             "#]],
1315         );
1316     }
1317
1318     #[test]
1319     fn fully_qualified_syntax() {
1320         check(
1321             r#"
1322 fn f() {
1323     trait A { fn foo(&self, other: Self); }
1324     A::foo(&self$0, other);
1325 }
1326 "#,
1327             expect![[r#"
1328                 fn foo(self: &Self, other: Self)
1329                        ^^^^^^^^^^^  -----------
1330             "#]],
1331         );
1332     }
1333 }