ide/
signature_help.rs

1//! This module provides primitives for showing type and function parameter information when editing
2//! a call or use-site.
3
4use std::collections::BTreeSet;
5
6use either::Either;
7use hir::{
8    AssocItem, DisplayTarget, GenericDef, GenericParam, HirDisplay, ModuleDef, PathResolution,
9    Semantics, Trait,
10};
11use ide_db::{
12    FilePosition, FxIndexMap,
13    active_parameter::{callable_for_arg_list, generic_def_for_node},
14    documentation::{Documentation, HasDocs},
15};
16use itertools::Itertools;
17use span::Edition;
18use stdx::format_to;
19use syntax::{
20    AstNode, Direction, NodeOrToken, SyntaxElementChildren, SyntaxNode, SyntaxToken, T, TextRange,
21    TextSize, ToSmolStr, algo,
22    ast::{self, AstChildren},
23    match_ast,
24};
25
26use crate::RootDatabase;
27
28/// Contains information about an item signature as seen from a use site.
29///
30/// This includes the "active parameter", which is the parameter whose value is currently being
31/// edited.
32#[derive(Debug)]
33pub struct SignatureHelp {
34    pub doc: Option<Documentation>,
35    pub signature: String,
36    pub active_parameter: Option<usize>,
37    parameters: Vec<TextRange>,
38}
39
40impl SignatureHelp {
41    pub fn parameter_labels(&self) -> impl Iterator<Item = &str> + '_ {
42        self.parameters.iter().map(move |&it| &self.signature[it])
43    }
44
45    pub fn parameter_ranges(&self) -> &[TextRange] {
46        &self.parameters
47    }
48
49    fn push_call_param(&mut self, param: &str) {
50        self.push_param("(", param);
51    }
52
53    fn push_generic_param(&mut self, param: &str) {
54        self.push_param("<", param);
55    }
56
57    fn push_record_field(&mut self, param: &str) {
58        self.push_param("{ ", param);
59    }
60
61    fn push_param(&mut self, opening_delim: &str, param: &str) {
62        if !self.signature.ends_with(opening_delim) {
63            self.signature.push_str(", ");
64        }
65        let start = TextSize::of(&self.signature);
66        self.signature.push_str(param);
67        let end = TextSize::of(&self.signature);
68        self.parameters.push(TextRange::new(start, end))
69    }
70}
71
72/// Computes parameter information for the given position.
73pub(crate) fn signature_help(
74    db: &RootDatabase,
75    FilePosition { file_id, offset }: FilePosition,
76) -> Option<SignatureHelp> {
77    let sema = Semantics::new(db);
78    let file = sema.parse_guess_edition(file_id);
79    let file = file.syntax();
80    let token = file
81        .token_at_offset(offset)
82        .left_biased()
83        // if the cursor is sandwiched between two space tokens and the call is unclosed
84        // this prevents us from leaving the CallExpression
85        .and_then(|tok| algo::skip_trivia_token(tok, Direction::Prev))?;
86    let token = sema.descend_into_macros_single_exact(token);
87    let edition =
88        sema.attach_first_edition(file_id).map(|it| it.edition(db)).unwrap_or(Edition::CURRENT);
89    let display_target = sema.first_crate(file_id)?.to_display_target(db);
90
91    for node in token.parent_ancestors() {
92        match_ast! {
93            match node {
94                ast::ArgList(arg_list) => {
95                    let cursor_outside = arg_list.r_paren_token().as_ref() == Some(&token);
96                    if cursor_outside {
97                        continue;
98                    }
99                    return signature_help_for_call(&sema, arg_list, token, edition, display_target);
100                },
101                ast::GenericArgList(garg_list) => {
102                    let cursor_outside = garg_list.r_angle_token().as_ref() == Some(&token);
103                    if cursor_outside {
104                        continue;
105                    }
106                    return signature_help_for_generics(&sema, garg_list, token, edition, display_target);
107                },
108                ast::RecordExpr(record) => {
109                    let cursor_outside = record.record_expr_field_list().and_then(|list| list.r_curly_token()).as_ref() == Some(&token);
110                    if cursor_outside {
111                        continue;
112                    }
113                    return signature_help_for_record_lit(&sema, record, token, edition, display_target);
114                },
115                ast::RecordPat(record) => {
116                    let cursor_outside = record.record_pat_field_list().and_then(|list| list.r_curly_token()).as_ref() == Some(&token);
117                    if cursor_outside {
118                        continue;
119                    }
120                    return signature_help_for_record_pat(&sema, record, token, edition, display_target);
121                },
122                ast::TupleStructPat(tuple_pat) => {
123                    let cursor_outside = tuple_pat.r_paren_token().as_ref() == Some(&token);
124                    if cursor_outside {
125                        continue;
126                    }
127                    return signature_help_for_tuple_struct_pat(&sema, tuple_pat, token, edition, display_target);
128                },
129                ast::TuplePat(tuple_pat) => {
130                    let cursor_outside = tuple_pat.r_paren_token().as_ref() == Some(&token);
131                    if cursor_outside {
132                        continue;
133                    }
134                    return signature_help_for_tuple_pat(&sema, tuple_pat, token, display_target);
135                },
136                ast::TupleExpr(tuple_expr) => {
137                    let cursor_outside = tuple_expr.r_paren_token().as_ref() == Some(&token);
138                    if cursor_outside {
139                        continue;
140                    }
141                    return signature_help_for_tuple_expr(&sema, tuple_expr, token, display_target);
142                },
143                _ => (),
144            }
145        }
146
147        // Stop at multi-line expressions, since the signature of the outer call is not very
148        // helpful inside them.
149        if let Some(expr) = ast::Expr::cast(node.clone())
150            && !matches!(expr, ast::Expr::RecordExpr(..))
151            && expr.syntax().text().contains_char('\n')
152        {
153            break;
154        }
155    }
156
157    None
158}
159
160fn signature_help_for_call(
161    sema: &Semantics<'_, RootDatabase>,
162    arg_list: ast::ArgList,
163    token: SyntaxToken,
164    edition: Edition,
165    display_target: DisplayTarget,
166) -> Option<SignatureHelp> {
167    let (callable, active_parameter) =
168        callable_for_arg_list(sema, arg_list, token.text_range().start())?;
169
170    let mut res =
171        SignatureHelp { doc: None, signature: String::new(), parameters: vec![], active_parameter };
172
173    let db = sema.db;
174    let mut fn_params = None;
175    match callable.kind() {
176        hir::CallableKind::Function(func) => {
177            res.doc = func.docs(db);
178            format_to!(res.signature, "fn {}", func.name(db).display(db, edition));
179
180            let generic_params = GenericDef::Function(func)
181                .params(db)
182                .iter()
183                .filter(|param| match param {
184                    GenericParam::TypeParam(type_param) => !type_param.is_implicit(db),
185                    GenericParam::ConstParam(_) | GenericParam::LifetimeParam(_) => true,
186                })
187                .map(|param| param.display(db, display_target))
188                .join(", ");
189            if !generic_params.is_empty() {
190                format_to!(res.signature, "<{}>", generic_params);
191            }
192
193            fn_params = Some(match callable.receiver_param(db) {
194                Some(_self) => func.params_without_self(db),
195                None => func.assoc_fn_params(db),
196            });
197        }
198        hir::CallableKind::TupleStruct(strukt) => {
199            res.doc = strukt.docs(db);
200            format_to!(res.signature, "struct {}", strukt.name(db).display(db, edition));
201
202            let generic_params = GenericDef::Adt(strukt.into())
203                .params(db)
204                .iter()
205                .map(|param| param.display(db, display_target))
206                .join(", ");
207            if !generic_params.is_empty() {
208                format_to!(res.signature, "<{}>", generic_params);
209            }
210        }
211        hir::CallableKind::TupleEnumVariant(variant) => {
212            res.doc = variant.docs(db);
213            format_to!(
214                res.signature,
215                "enum {}",
216                variant.parent_enum(db).name(db).display(db, edition),
217            );
218
219            let generic_params = GenericDef::Adt(variant.parent_enum(db).into())
220                .params(db)
221                .iter()
222                .map(|param| param.display(db, display_target))
223                .join(", ");
224            if !generic_params.is_empty() {
225                format_to!(res.signature, "<{}>", generic_params);
226            }
227
228            format_to!(res.signature, "::{}", variant.name(db).display(db, edition))
229        }
230        hir::CallableKind::Closure(closure) => {
231            let fn_trait = closure.fn_trait(db);
232            format_to!(res.signature, "impl {fn_trait}")
233        }
234        hir::CallableKind::FnPtr => format_to!(res.signature, "fn"),
235        hir::CallableKind::FnImpl(fn_trait) => match callable.ty().as_adt() {
236            // FIXME: Render docs of the concrete trait impl function
237            Some(adt) => format_to!(
238                res.signature,
239                "<{} as {fn_trait}>::{}",
240                adt.name(db).display(db, edition),
241                fn_trait.function_name()
242            ),
243            None => format_to!(res.signature, "impl {fn_trait}"),
244        },
245    }
246
247    res.signature.push('(');
248    {
249        if let Some((self_param, _)) = callable.receiver_param(db) {
250            format_to!(res.signature, "{}", self_param.display(db, display_target))
251        }
252        let mut buf = String::new();
253        for (idx, p) in callable.params().into_iter().enumerate() {
254            buf.clear();
255            if let Some(param) = sema.source(p.clone()) {
256                match param.value {
257                    Either::Right(param) => match param.pat() {
258                        Some(pat) => format_to!(buf, "{}: ", pat),
259                        None => format_to!(buf, "?: "),
260                    },
261                    Either::Left(_) => format_to!(buf, "self: "),
262                }
263            }
264            // APITs (argument position `impl Trait`s) are inferred as {unknown} as the user is
265            // in the middle of entering call arguments.
266            // In that case, fall back to render definitions of the respective parameters.
267            // This is overly conservative: we do not substitute known type vars
268            // (see FIXME in tests::impl_trait) and falling back on any unknowns.
269            hir::attach_db(db, || match (p.ty().contains_unknown(), fn_params.as_deref()) {
270                (true, Some(fn_params)) => {
271                    format_to!(buf, "{}", fn_params[idx].ty().display(db, display_target))
272                }
273                _ => format_to!(buf, "{}", p.ty().display(db, display_target)),
274            });
275            res.push_call_param(&buf);
276        }
277    }
278    res.signature.push(')');
279
280    let mut render = |ret_type: hir::Type<'_>| {
281        if !ret_type.is_unit() {
282            format_to!(res.signature, " -> {}", ret_type.display(db, display_target));
283        }
284    };
285    match callable.kind() {
286        hir::CallableKind::Function(func) if callable.return_type().contains_unknown() => {
287            render(func.ret_type(db))
288        }
289        hir::CallableKind::Function(_)
290        | hir::CallableKind::Closure(_)
291        | hir::CallableKind::FnPtr
292        | hir::CallableKind::FnImpl(_) => render(callable.return_type()),
293        hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => {}
294    }
295    Some(res)
296}
297
298fn signature_help_for_generics(
299    sema: &Semantics<'_, RootDatabase>,
300    arg_list: ast::GenericArgList,
301    token: SyntaxToken,
302    edition: Edition,
303    display_target: DisplayTarget,
304) -> Option<SignatureHelp> {
305    let (generics_def, mut active_parameter, first_arg_is_non_lifetime, variant) =
306        generic_def_for_node(sema, &arg_list, &token)?;
307    let mut res = SignatureHelp {
308        doc: None,
309        signature: String::new(),
310        parameters: vec![],
311        active_parameter: None,
312    };
313
314    let db = sema.db;
315    match generics_def {
316        hir::GenericDef::Function(it) => {
317            res.doc = it.docs(db);
318            format_to!(res.signature, "fn {}", it.name(db).display(db, edition));
319        }
320        hir::GenericDef::Adt(hir::Adt::Enum(it)) => {
321            res.doc = it.docs(db);
322            format_to!(res.signature, "enum {}", it.name(db).display(db, edition));
323            if let Some(variant) = variant {
324                // In paths, generics of an enum can be specified *after* one of its variants.
325                // eg. `None::<u8>`
326                // We'll use the signature of the enum, but include the docs of the variant.
327                res.doc = variant.docs(db);
328            }
329        }
330        hir::GenericDef::Adt(hir::Adt::Struct(it)) => {
331            res.doc = it.docs(db);
332            format_to!(res.signature, "struct {}", it.name(db).display(db, edition));
333        }
334        hir::GenericDef::Adt(hir::Adt::Union(it)) => {
335            res.doc = it.docs(db);
336            format_to!(res.signature, "union {}", it.name(db).display(db, edition));
337        }
338        hir::GenericDef::Trait(it) => {
339            res.doc = it.docs(db);
340            format_to!(res.signature, "trait {}", it.name(db).display(db, edition));
341        }
342        hir::GenericDef::TypeAlias(it) => {
343            res.doc = it.docs(db);
344            format_to!(res.signature, "type {}", it.name(db).display(db, edition));
345        }
346        // These don't have generic args that can be specified
347        hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) | hir::GenericDef::Static(_) => {
348            return None;
349        }
350    }
351
352    let params = generics_def.params(sema.db);
353    let num_lifetime_params =
354        params.iter().take_while(|param| matches!(param, GenericParam::LifetimeParam(_))).count();
355    if first_arg_is_non_lifetime {
356        // Lifetime parameters were omitted.
357        active_parameter += num_lifetime_params;
358    }
359    res.active_parameter = Some(active_parameter);
360
361    res.signature.push('<');
362    let mut buf = String::new();
363    for param in params {
364        if let hir::GenericParam::TypeParam(ty) = param
365            && ty.is_implicit(db)
366        {
367            continue;
368        }
369
370        buf.clear();
371        format_to!(buf, "{}", param.display(db, display_target));
372        match param {
373            GenericParam::TypeParam(param) => {
374                if let Some(ty) = param.default(db) {
375                    format_to!(buf, " = {}", ty.display(db, display_target));
376                }
377            }
378            GenericParam::ConstParam(param) => {
379                if let Some(expr) = param.default(db, display_target).and_then(|konst| konst.expr())
380                {
381                    format_to!(buf, " = {}", expr);
382                }
383            }
384            _ => {}
385        }
386        res.push_generic_param(&buf);
387    }
388    if let hir::GenericDef::Trait(tr) = generics_def {
389        add_assoc_type_bindings(db, &mut res, tr, arg_list, edition);
390    }
391    res.signature.push('>');
392
393    Some(res)
394}
395
396fn add_assoc_type_bindings(
397    db: &RootDatabase,
398    res: &mut SignatureHelp,
399    tr: Trait,
400    args: ast::GenericArgList,
401    edition: Edition,
402) {
403    if args.syntax().ancestors().find_map(ast::TypeBound::cast).is_none() {
404        // Assoc type bindings are only valid in type bound position.
405        return;
406    }
407
408    let present_bindings = args
409        .generic_args()
410        .filter_map(|arg| match arg {
411            ast::GenericArg::AssocTypeArg(arg) => arg.name_ref().map(|n| n.to_string()),
412            _ => None,
413        })
414        .collect::<BTreeSet<_>>();
415
416    let mut buf = String::new();
417    for binding in &present_bindings {
418        buf.clear();
419        format_to!(buf, "{} = …", binding);
420        res.push_generic_param(&buf);
421    }
422
423    for item in tr.items_with_supertraits(db) {
424        if let AssocItem::TypeAlias(ty) = item {
425            let name = ty.name(db).display_no_db(edition).to_smolstr();
426            if !present_bindings.contains(&*name) {
427                buf.clear();
428                format_to!(buf, "{} = …", name);
429                res.push_generic_param(&buf);
430            }
431        }
432    }
433}
434
435fn signature_help_for_record_lit(
436    sema: &Semantics<'_, RootDatabase>,
437    record: ast::RecordExpr,
438    token: SyntaxToken,
439    edition: Edition,
440    display_target: DisplayTarget,
441) -> Option<SignatureHelp> {
442    signature_help_for_record_(
443        sema,
444        record.record_expr_field_list()?.syntax().children_with_tokens(),
445        &record.path()?,
446        record
447            .record_expr_field_list()?
448            .fields()
449            .filter_map(|field| sema.resolve_record_field(&field))
450            .map(|(field, _, ty)| (field, ty)),
451        token,
452        edition,
453        display_target,
454    )
455}
456
457fn signature_help_for_record_pat(
458    sema: &Semantics<'_, RootDatabase>,
459    record: ast::RecordPat,
460    token: SyntaxToken,
461    edition: Edition,
462    display_target: DisplayTarget,
463) -> Option<SignatureHelp> {
464    signature_help_for_record_(
465        sema,
466        record.record_pat_field_list()?.syntax().children_with_tokens(),
467        &record.path()?,
468        record
469            .record_pat_field_list()?
470            .fields()
471            .filter_map(|field| sema.resolve_record_pat_field(&field)),
472        token,
473        edition,
474        display_target,
475    )
476}
477
478fn signature_help_for_tuple_struct_pat(
479    sema: &Semantics<'_, RootDatabase>,
480    pat: ast::TupleStructPat,
481    token: SyntaxToken,
482    edition: Edition,
483    display_target: DisplayTarget,
484) -> Option<SignatureHelp> {
485    let path = pat.path()?;
486    let path_res = sema.resolve_path(&path)?;
487    let mut res = SignatureHelp {
488        doc: None,
489        signature: String::new(),
490        parameters: vec![],
491        active_parameter: None,
492    };
493    let db = sema.db;
494
495    let fields: Vec<_> = if let PathResolution::Def(ModuleDef::Variant(variant)) = path_res {
496        let en = variant.parent_enum(db);
497
498        res.doc = en.docs(db);
499        format_to!(
500            res.signature,
501            "enum {}::{} (",
502            en.name(db).display(db, edition),
503            variant.name(db).display(db, edition)
504        );
505        variant.fields(db)
506    } else {
507        let adt = match path_res {
508            PathResolution::SelfType(imp) => imp.self_ty(db).as_adt()?,
509            PathResolution::Def(ModuleDef::Adt(adt)) => adt,
510            _ => return None,
511        };
512
513        match adt {
514            hir::Adt::Struct(it) => {
515                res.doc = it.docs(db);
516                format_to!(res.signature, "struct {} (", it.name(db).display(db, edition));
517                it.fields(db)
518            }
519            _ => return None,
520        }
521    };
522    Some(signature_help_for_tuple_pat_ish(
523        db,
524        res,
525        pat.syntax(),
526        token,
527        pat.fields(),
528        fields.into_iter().map(|it| it.ty(db).to_type(db)),
529        display_target,
530    ))
531}
532
533fn signature_help_for_tuple_pat(
534    sema: &Semantics<'_, RootDatabase>,
535    pat: ast::TuplePat,
536    token: SyntaxToken,
537    display_target: DisplayTarget,
538) -> Option<SignatureHelp> {
539    let db = sema.db;
540    let field_pats = pat.fields();
541    let pat = pat.into();
542    let ty = sema.type_of_pat(&pat)?;
543    let fields = ty.original.tuple_fields(db);
544
545    Some(signature_help_for_tuple_pat_ish(
546        db,
547        SignatureHelp {
548            doc: None,
549            signature: String::from('('),
550            parameters: vec![],
551            active_parameter: None,
552        },
553        pat.syntax(),
554        token,
555        field_pats,
556        fields.into_iter(),
557        display_target,
558    ))
559}
560
561fn signature_help_for_tuple_expr(
562    sema: &Semantics<'_, RootDatabase>,
563    expr: ast::TupleExpr,
564    token: SyntaxToken,
565    display_target: DisplayTarget,
566) -> Option<SignatureHelp> {
567    let active_parameter = Some(
568        expr.syntax()
569            .children_with_tokens()
570            .filter_map(NodeOrToken::into_token)
571            .filter(|t| t.kind() == T![,])
572            .take_while(|t| t.text_range().start() <= token.text_range().start())
573            .count(),
574    );
575
576    let db = sema.db;
577    let mut res = SignatureHelp {
578        doc: None,
579        signature: String::from('('),
580        parameters: vec![],
581        active_parameter,
582    };
583    let expr = sema.type_of_expr(&expr.into())?;
584    let fields = expr.original.tuple_fields(db);
585    let mut buf = String::new();
586    for ty in fields {
587        format_to!(buf, "{}", ty.display_truncated(db, Some(20), display_target));
588        res.push_call_param(&buf);
589        buf.clear();
590    }
591    res.signature.push(')');
592    Some(res)
593}
594
595fn signature_help_for_record_<'db>(
596    sema: &Semantics<'db, RootDatabase>,
597    field_list_children: SyntaxElementChildren,
598    path: &ast::Path,
599    fields2: impl Iterator<Item = (hir::Field, hir::Type<'db>)>,
600    token: SyntaxToken,
601    edition: Edition,
602    display_target: DisplayTarget,
603) -> Option<SignatureHelp> {
604    let active_parameter = field_list_children
605        .filter_map(NodeOrToken::into_token)
606        .filter(|t| t.kind() == T![,])
607        .take_while(|t| t.text_range().start() <= token.text_range().start())
608        .count();
609
610    let mut res = SignatureHelp {
611        doc: None,
612        signature: String::new(),
613        parameters: vec![],
614        active_parameter: Some(active_parameter),
615    };
616
617    let fields;
618
619    let db = sema.db;
620    let path_res = sema.resolve_path(path)?;
621    if let PathResolution::Def(ModuleDef::Variant(variant)) = path_res {
622        fields = variant.fields(db);
623        let en = variant.parent_enum(db);
624
625        res.doc = en.docs(db);
626        format_to!(
627            res.signature,
628            "enum {}::{} {{ ",
629            en.name(db).display(db, edition),
630            variant.name(db).display(db, edition)
631        );
632    } else {
633        let adt = match path_res {
634            PathResolution::SelfType(imp) => imp.self_ty(db).as_adt()?,
635            PathResolution::Def(ModuleDef::Adt(adt)) => adt,
636            _ => return None,
637        };
638
639        match adt {
640            hir::Adt::Struct(it) => {
641                fields = it.fields(db);
642                res.doc = it.docs(db);
643                format_to!(res.signature, "struct {} {{ ", it.name(db).display(db, edition));
644            }
645            hir::Adt::Union(it) => {
646                fields = it.fields(db);
647                res.doc = it.docs(db);
648                format_to!(res.signature, "union {} {{ ", it.name(db).display(db, edition));
649            }
650            _ => return None,
651        }
652    }
653
654    let mut fields =
655        fields.into_iter().map(|field| (field.name(db), Some(field))).collect::<FxIndexMap<_, _>>();
656    let mut buf = String::new();
657    for (field, ty) in fields2 {
658        let name = field.name(db);
659        format_to!(
660            buf,
661            "{}: {}",
662            name.display(db, edition),
663            ty.display_truncated(db, Some(20), display_target)
664        );
665        res.push_record_field(&buf);
666        buf.clear();
667
668        if let Some(field) = fields.get_mut(&name) {
669            *field = None;
670        }
671    }
672    for (name, field) in fields {
673        let Some(field) = field else { continue };
674        format_to!(
675            buf,
676            "{}: {}",
677            name.display(db, edition),
678            field.ty(db).display_truncated(db, Some(20), display_target)
679        );
680        res.push_record_field(&buf);
681        buf.clear();
682    }
683    res.signature.push_str(" }");
684    Some(res)
685}
686
687fn signature_help_for_tuple_pat_ish<'db>(
688    db: &'db RootDatabase,
689    mut res: SignatureHelp,
690    pat: &SyntaxNode,
691    token: SyntaxToken,
692    mut field_pats: AstChildren<ast::Pat>,
693    fields: impl ExactSizeIterator<Item = hir::Type<'db>>,
694    display_target: DisplayTarget,
695) -> SignatureHelp {
696    let rest_pat = field_pats.find(|it| matches!(it, ast::Pat::RestPat(_)));
697    let is_left_of_rest_pat =
698        rest_pat.is_none_or(|it| token.text_range().start() < it.syntax().text_range().end());
699
700    let commas = pat
701        .children_with_tokens()
702        .filter_map(NodeOrToken::into_token)
703        .filter(|t| t.kind() == T![,]);
704
705    res.active_parameter = {
706        Some(if is_left_of_rest_pat {
707            commas.take_while(|t| t.text_range().start() <= token.text_range().start()).count()
708        } else {
709            let n_commas = commas
710                .collect::<Vec<_>>()
711                .into_iter()
712                .rev()
713                .take_while(|t| t.text_range().start() > token.text_range().start())
714                .count();
715            fields.len().saturating_sub(1).saturating_sub(n_commas)
716        })
717    };
718
719    let mut buf = String::new();
720    for ty in fields {
721        format_to!(buf, "{}", ty.display_truncated(db, Some(20), display_target));
722        res.push_call_param(&buf);
723        buf.clear();
724    }
725    res.signature.push(')');
726    res
727}
728#[cfg(test)]
729mod tests {
730
731    use expect_test::{Expect, expect};
732    use ide_db::FilePosition;
733    use stdx::format_to;
734    use test_fixture::ChangeFixture;
735
736    use crate::RootDatabase;
737
738    /// Creates analysis from a multi-file fixture, returns positions marked with $0.
739    pub(crate) fn position(
740        #[rust_analyzer::rust_fixture] ra_fixture: &str,
741    ) -> (RootDatabase, FilePosition) {
742        let mut database = RootDatabase::default();
743        let change_fixture = ChangeFixture::parse(&database, ra_fixture);
744        database.apply_change(change_fixture.change);
745        let (file_id, range_or_offset) =
746            change_fixture.file_position.expect("expected a marker ($0)");
747        let offset = range_or_offset.expect_offset();
748        let position = FilePosition { file_id: file_id.file_id(&database), offset };
749        (database, position)
750    }
751
752    #[track_caller]
753    fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
754        let fixture = format!(
755            r#"
756//- minicore: sized, fn
757{ra_fixture}
758            "#
759        );
760        let (db, position) = position(&fixture);
761        let sig_help = hir::attach_db(&db, || crate::signature_help::signature_help(&db, position));
762        let actual = match sig_help {
763            Some(sig_help) => {
764                let mut rendered = String::new();
765                if let Some(docs) = &sig_help.doc {
766                    format_to!(rendered, "{}\n------\n", docs.as_str());
767                }
768                format_to!(rendered, "{}\n", sig_help.signature);
769                let mut offset = 0;
770                for (i, range) in sig_help.parameter_ranges().iter().enumerate() {
771                    let is_active = sig_help.active_parameter == Some(i);
772
773                    let start = u32::from(range.start());
774                    let gap = start.checked_sub(offset).unwrap_or_else(|| {
775                        panic!("parameter ranges out of order: {:?}", sig_help.parameter_ranges())
776                    });
777                    rendered.extend(std::iter::repeat_n(' ', gap as usize));
778                    let param_text = &sig_help.signature[*range];
779                    let width = param_text.chars().count(); // …
780                    let marker = if is_active { '^' } else { '-' };
781                    rendered.extend(std::iter::repeat_n(marker, width));
782                    offset += gap + u32::from(range.len());
783                }
784                if !sig_help.parameter_ranges().is_empty() {
785                    format_to!(rendered, "\n");
786                }
787                rendered
788            }
789            None => String::new(),
790        };
791        expect.assert_eq(&actual);
792    }
793
794    #[test]
795    fn test_fn_signature_two_args() {
796        check(
797            r#"
798fn foo(x: u32, y: u32) -> u32 {x + y}
799fn bar() { foo($03, ); }
800"#,
801            expect![[r#"
802                fn foo(x: u32, y: u32) -> u32
803                       ^^^^^^  ------
804            "#]],
805        );
806        check(
807            r#"
808fn foo(x: u32, y: u32) -> u32 {x + y}
809fn bar() { foo(3$0, ); }
810"#,
811            expect![[r#"
812                fn foo(x: u32, y: u32) -> u32
813                       ^^^^^^  ------
814            "#]],
815        );
816        check(
817            r#"
818fn foo(x: u32, y: u32) -> u32 {x + y}
819fn bar() { foo(3,$0 ); }
820"#,
821            expect![[r#"
822                fn foo(x: u32, y: u32) -> u32
823                       ------  ^^^^^^
824            "#]],
825        );
826        check(
827            r#"
828fn foo(x: u32, y: u32) -> u32 {x + y}
829fn bar() { foo(3, $0); }
830"#,
831            expect![[r#"
832                fn foo(x: u32, y: u32) -> u32
833                       ------  ^^^^^^
834            "#]],
835        );
836    }
837
838    #[test]
839    fn test_fn_signature_two_args_empty() {
840        check(
841            r#"
842fn foo(x: u32, y: u32) -> u32 {x + y}
843fn bar() { foo($0); }
844"#,
845            expect![[r#"
846                fn foo(x: u32, y: u32) -> u32
847                       ^^^^^^  ------
848            "#]],
849        );
850    }
851
852    #[test]
853    fn test_fn_signature_two_args_first_generics() {
854        check(
855            r#"
856fn foo<T, U: Copy + Display>(x: T, y: U) -> u32
857    where T: Copy + Display, U: Debug
858{ x + y }
859
860fn bar() { foo($03, ); }
861"#,
862            expect![[r#"
863                fn foo<T, U>(x: i32, y: U) -> u32
864                             ^^^^^^  ----
865            "#]],
866        );
867    }
868
869    #[test]
870    fn test_fn_signature_no_params() {
871        check(
872            r#"
873fn foo<T>() -> T where T: Copy + Display {}
874fn bar() { foo($0); }
875"#,
876            expect![[r#"
877                fn foo<T>() -> T
878            "#]],
879        );
880    }
881
882    #[test]
883    fn test_fn_signature_for_impl() {
884        check(
885            r#"
886struct F;
887impl F { pub fn new() { } }
888fn bar() {
889    let _ : F = F::new($0);
890}
891"#,
892            expect![[r#"
893                fn new()
894            "#]],
895        );
896    }
897
898    #[test]
899    fn test_fn_signature_for_method_self() {
900        check(
901            r#"
902struct S;
903impl S { pub fn do_it(&self) {} }
904
905fn bar() {
906    let s: S = S;
907    s.do_it($0);
908}
909"#,
910            expect![[r#"
911                fn do_it(&self)
912            "#]],
913        );
914    }
915
916    #[test]
917    fn test_fn_signature_for_method_with_arg() {
918        check(
919            r#"
920struct S;
921impl S {
922    fn foo(&self, x: i32) {}
923}
924
925fn main() { S.foo($0); }
926"#,
927            expect![[r#"
928                fn foo(&self, x: i32)
929                              ^^^^^^
930            "#]],
931        );
932    }
933
934    #[test]
935    fn test_fn_signature_for_generic_method() {
936        check(
937            r#"
938struct S<T>(T);
939impl<T> S<T> {
940    fn foo(&self, x: T) {}
941}
942
943fn main() { S(1u32).foo($0); }
944"#,
945            expect![[r#"
946                fn foo(&self, x: u32)
947                              ^^^^^^
948            "#]],
949        );
950    }
951
952    #[test]
953    fn test_fn_signature_for_method_with_arg_as_assoc_fn() {
954        check(
955            r#"
956struct S;
957impl S {
958    fn foo(&self, x: i32) {}
959}
960
961fn main() { S::foo($0); }
962"#,
963            expect![[r#"
964                fn foo(self: &S, x: i32)
965                       ^^^^^^^^  ------
966            "#]],
967        );
968    }
969
970    #[test]
971    fn test_fn_signature_with_docs_simple() {
972        check(
973            r#"
974/// test
975// non-doc-comment
976fn foo(j: u32) -> u32 {
977    j
978}
979
980fn bar() {
981    let _ = foo($0);
982}
983"#,
984            expect![[r#"
985                test
986                ------
987                fn foo(j: u32) -> u32
988                       ^^^^^^
989            "#]],
990        );
991    }
992
993    #[test]
994    fn test_fn_signature_with_docs() {
995        check(
996            r#"
997/// Adds one to the number given.
998///
999/// # Examples
1000///
1001/// ```
1002/// let five = 5;
1003///
1004/// assert_eq!(6, my_crate::add_one(5));
1005/// ```
1006pub fn add_one(x: i32) -> i32 {
1007    x + 1
1008}
1009
1010pub fn r#do() {
1011    add_one($0
1012}"#,
1013            expect![[r##"
1014                Adds one to the number given.
1015
1016                # Examples
1017
1018                ```
1019                let five = 5;
1020
1021                assert_eq!(6, my_crate::add_one(5));
1022                ```
1023                ------
1024                fn add_one(x: i32) -> i32
1025                           ^^^^^^
1026            "##]],
1027        );
1028    }
1029
1030    #[test]
1031    fn test_fn_signature_with_docs_impl() {
1032        check(
1033            r#"
1034struct addr;
1035impl addr {
1036    /// Adds one to the number given.
1037    ///
1038    /// # Examples
1039    ///
1040    /// ```
1041    /// let five = 5;
1042    ///
1043    /// assert_eq!(6, my_crate::add_one(5));
1044    /// ```
1045    pub fn add_one(x: i32) -> i32 {
1046        x + 1
1047    }
1048}
1049
1050pub fn do_it() {
1051    addr {};
1052    addr::add_one($0);
1053}
1054"#,
1055            expect![[r##"
1056                Adds one to the number given.
1057
1058                # Examples
1059
1060                ```
1061                let five = 5;
1062
1063                assert_eq!(6, my_crate::add_one(5));
1064                ```
1065                ------
1066                fn add_one(x: i32) -> i32
1067                           ^^^^^^
1068            "##]],
1069        );
1070    }
1071
1072    #[test]
1073    fn test_fn_signature_with_docs_from_actix() {
1074        check(
1075            r#"
1076trait Actor {
1077    /// Actor execution context type
1078    type Context;
1079}
1080trait WriteHandler<E>
1081where
1082    Self: Actor
1083{
1084    /// Method is called when writer finishes.
1085    ///
1086    /// By default this method stops actor's `Context`.
1087    fn finished(&mut self, ctx: &mut Self::Context) {}
1088}
1089
1090fn foo(mut r: impl WriteHandler<()>) {
1091    r.finished($0);
1092}
1093"#,
1094            expect![[r#"
1095                Method is called when writer finishes.
1096
1097                By default this method stops actor's `Context`.
1098                ------
1099                fn finished(&mut self, ctx: &mut <impl WriteHandler<()> as Actor>::Context)
1100                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1101            "#]],
1102        );
1103    }
1104
1105    #[test]
1106    fn call_info_bad_offset() {
1107        check(
1108            r#"
1109fn foo(x: u32, y: u32) -> u32 {x + y}
1110fn bar() { foo $0 (3, ); }
1111"#,
1112            expect![[""]],
1113        );
1114    }
1115
1116    #[test]
1117    fn outside_of_arg_list() {
1118        check(
1119            r#"
1120fn foo(a: u8) {}
1121fn f() {
1122    foo(123)$0
1123}
1124"#,
1125            expect![[]],
1126        );
1127        check(
1128            r#"
1129fn foo<T>(a: u8) {}
1130fn f() {
1131    foo::<u32>$0()
1132}
1133"#,
1134            expect![[]],
1135        );
1136        check(
1137            r#"
1138fn foo(a: u8) -> u8 {a}
1139fn bar(a: u8) -> u8 {a}
1140fn f() {
1141    foo(bar(123)$0)
1142}
1143"#,
1144            expect![[r#"
1145                fn foo(a: u8) -> u8
1146                       ^^^^^
1147            "#]],
1148        );
1149        check(
1150            r#"
1151struct Vec<T>(T);
1152struct Vec2<T>(T);
1153fn f() {
1154    let _: Vec2<Vec<u8>$0>
1155}
1156"#,
1157            expect![[r#"
1158                struct Vec2<T>
1159                            ^
1160            "#]],
1161        );
1162    }
1163
1164    #[test]
1165    fn test_nested_method_in_lambda() {
1166        check(
1167            r#"
1168struct Foo;
1169impl Foo { fn bar(&self, _: u32) { } }
1170
1171fn bar(_: u32) { }
1172
1173fn main() {
1174    let foo = Foo;
1175    std::thread::spawn(move || foo.bar($0));
1176}
1177"#,
1178            expect![[r#"
1179                fn bar(&self, _: u32)
1180                              ^^^^^^
1181            "#]],
1182        );
1183    }
1184
1185    #[test]
1186    fn works_for_tuple_structs() {
1187        check(
1188            r#"
1189/// A cool tuple struct
1190struct S(u32, i32);
1191fn main() {
1192    let s = S(0, $0);
1193}
1194"#,
1195            expect![[r#"
1196                A cool tuple struct
1197                ------
1198                struct S(u32, i32)
1199                         ---  ^^^
1200            "#]],
1201        );
1202    }
1203
1204    #[test]
1205    fn tuple_struct_pat() {
1206        check(
1207            r#"
1208/// A cool tuple struct
1209struct S(u32, i32);
1210fn main() {
1211    let S(0, $0);
1212}
1213"#,
1214            expect![[r#"
1215                A cool tuple struct
1216                ------
1217                struct S (u32, i32)
1218                          ---  ^^^
1219            "#]],
1220        );
1221    }
1222
1223    #[test]
1224    fn tuple_struct_pat_rest() {
1225        check(
1226            r#"
1227/// A cool tuple struct
1228struct S(u32, i32, f32, u16);
1229fn main() {
1230    let S(0, .., $0);
1231}
1232"#,
1233            expect![[r#"
1234                A cool tuple struct
1235                ------
1236                struct S (u32, i32, f32, u16)
1237                          ---  ---  ---  ^^^
1238            "#]],
1239        );
1240        check(
1241            r#"
1242/// A cool tuple struct
1243struct S(u32, i32, f32, u16, u8);
1244fn main() {
1245    let S(0, .., $0, 0);
1246}
1247"#,
1248            expect![[r#"
1249                A cool tuple struct
1250                ------
1251                struct S (u32, i32, f32, u16, u8)
1252                          ---  ---  ---  ^^^  --
1253            "#]],
1254        );
1255        check(
1256            r#"
1257/// A cool tuple struct
1258struct S(u32, i32, f32, u16);
1259fn main() {
1260    let S($0, .., 1);
1261}
1262"#,
1263            expect![[r#"
1264                A cool tuple struct
1265                ------
1266                struct S (u32, i32, f32, u16)
1267                          ^^^  ---  ---  ---
1268            "#]],
1269        );
1270        check(
1271            r#"
1272/// A cool tuple struct
1273struct S(u32, i32, f32, u16, u8);
1274fn main() {
1275    let S(1, .., 1, $0, 2);
1276}
1277"#,
1278            expect![[r#"
1279                A cool tuple struct
1280                ------
1281                struct S (u32, i32, f32, u16, u8)
1282                          ---  ---  ---  ^^^  --
1283            "#]],
1284        );
1285        check(
1286            r#"
1287/// A cool tuple struct
1288struct S(u32, i32, f32, u16);
1289fn main() {
1290    let S(1, $0.., 1);
1291}
1292"#,
1293            expect![[r#"
1294                A cool tuple struct
1295                ------
1296                struct S (u32, i32, f32, u16)
1297                          ---  ^^^  ---  ---
1298            "#]],
1299        );
1300        check(
1301            r#"
1302/// A cool tuple struct
1303struct S(u32, i32, f32, u16);
1304fn main() {
1305    let S(1, ..$0, 1);
1306}
1307"#,
1308            expect![[r#"
1309                A cool tuple struct
1310                ------
1311                struct S (u32, i32, f32, u16)
1312                          ---  ^^^  ---  ---
1313            "#]],
1314        );
1315    }
1316
1317    #[test]
1318    fn generic_struct() {
1319        check(
1320            r#"
1321struct S<T>(T);
1322fn main() {
1323    let s = S($0);
1324}
1325"#,
1326            expect![[r#"
1327                struct S<T>({unknown})
1328                            ^^^^^^^^^
1329            "#]],
1330        );
1331    }
1332
1333    #[test]
1334    fn works_for_enum_variants() {
1335        check(
1336            r#"
1337enum E {
1338    /// A Variant
1339    A(i32),
1340    /// Another
1341    B,
1342    /// And C
1343    C { a: i32, b: i32 }
1344}
1345
1346fn main() {
1347    let a = E::A($0);
1348}
1349"#,
1350            expect![[r#"
1351                A Variant
1352                ------
1353                enum E::A(i32)
1354                          ^^^
1355            "#]],
1356        );
1357    }
1358
1359    #[test]
1360    fn cant_call_struct_record() {
1361        check(
1362            r#"
1363struct S { x: u32, y: i32 }
1364fn main() {
1365    let s = S($0);
1366}
1367"#,
1368            expect![[""]],
1369        );
1370    }
1371
1372    #[test]
1373    fn cant_call_enum_record() {
1374        check(
1375            r#"
1376enum E {
1377    /// A Variant
1378    A(i32),
1379    /// Another
1380    B,
1381    /// And C
1382    C { a: i32, b: i32 }
1383}
1384
1385fn main() {
1386    let a = E::C($0);
1387}
1388"#,
1389            expect![[""]],
1390        );
1391    }
1392
1393    #[test]
1394    fn fn_signature_for_call_in_macro() {
1395        check(
1396            r#"
1397macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
1398fn foo() { }
1399id! {
1400    fn bar() { foo($0); }
1401}
1402"#,
1403            expect![[r#"
1404                fn foo()
1405            "#]],
1406        );
1407    }
1408
1409    #[test]
1410    fn fn_signature_for_method_call_defined_in_macro() {
1411        check(
1412            r#"
1413macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
1414struct S;
1415id! {
1416    impl S {
1417        fn foo<'a>(&'a mut self) {}
1418    }
1419}
1420fn test() { S.foo($0); }
1421"#,
1422            expect![[r#"
1423                fn foo<'a>(&'a mut self)
1424            "#]],
1425        );
1426    }
1427
1428    #[test]
1429    fn call_info_for_lambdas() {
1430        check(
1431            r#"
1432struct S;
1433fn foo(s: S) -> i32 { 92 }
1434fn main() {
1435    let _move = S;
1436    (|s| {{_move}; foo(s)})($0)
1437}
1438        "#,
1439            expect![[r#"
1440                impl FnOnce(s: S) -> i32
1441                            ^^^^
1442            "#]],
1443        );
1444        check(
1445            r#"
1446struct S;
1447fn foo(s: S) -> i32 { 92 }
1448fn main() {
1449    (|s| foo(s))($0)
1450}
1451        "#,
1452            expect![[r#"
1453                impl Fn(s: S) -> i32
1454                        ^^^^
1455            "#]],
1456        );
1457        check(
1458            r#"
1459struct S;
1460fn foo(s: S) -> i32 { 92 }
1461fn main() {
1462    let mut mutate = 0;
1463    (|s| { mutate = 1; foo(s) })($0)
1464}
1465        "#,
1466            expect![[r#"
1467                impl FnMut(s: S) -> i32
1468                           ^^^^
1469            "#]],
1470        );
1471    }
1472
1473    #[test]
1474    fn call_info_for_fn_def_over_reference() {
1475        check(
1476            r#"
1477struct S;
1478fn foo(s: S) -> i32 { 92 }
1479fn main() {
1480    let bar = &&&&&foo;
1481    bar($0);
1482}
1483        "#,
1484            expect![[r#"
1485                fn foo(s: S) -> i32
1486                       ^^^^
1487            "#]],
1488        )
1489    }
1490
1491    #[test]
1492    fn call_info_for_fn_ptr() {
1493        check(
1494            r#"
1495fn main(f: fn(i32, f64) -> char) {
1496    f(0, $0)
1497}
1498        "#,
1499            expect![[r#"
1500                fn(i32, f64) -> char
1501                   ---  ^^^
1502            "#]],
1503        )
1504    }
1505
1506    #[test]
1507    fn call_info_for_fn_impl() {
1508        check(
1509            r#"
1510struct S;
1511impl core::ops::FnOnce<(i32, f64)> for S {
1512    type Output = char;
1513}
1514impl core::ops::FnMut<(i32, f64)> for S {}
1515impl core::ops::Fn<(i32, f64)> for S {}
1516fn main() {
1517    S($0);
1518}
1519        "#,
1520            expect![[r#"
1521                <S as Fn>::call(i32, f64) -> char
1522                                ^^^  ---
1523            "#]],
1524        );
1525        check(
1526            r#"
1527struct S;
1528impl core::ops::FnOnce<(i32, f64)> for S {
1529    type Output = char;
1530}
1531impl core::ops::FnMut<(i32, f64)> for S {}
1532impl core::ops::Fn<(i32, f64)> for S {}
1533fn main() {
1534    S(1, $0);
1535}
1536        "#,
1537            expect![[r#"
1538                <S as Fn>::call(i32, f64) -> char
1539                                ---  ^^^
1540            "#]],
1541        );
1542        check(
1543            r#"
1544struct S;
1545impl core::ops::FnOnce<(i32, f64)> for S {
1546    type Output = char;
1547}
1548impl core::ops::FnOnce<(char, char)> for S {
1549    type Output = f64;
1550}
1551fn main() {
1552    S($0);
1553}
1554        "#,
1555            expect![""],
1556        );
1557        check(
1558            r#"
1559struct S;
1560impl core::ops::FnOnce<(i32, f64)> for S {
1561    type Output = char;
1562}
1563impl core::ops::FnOnce<(char, char)> for S {
1564    type Output = f64;
1565}
1566fn main() {
1567    // FIXME: The ide layer loses the calling info here so we get an ambiguous trait solve result
1568    S(0i32, $0);
1569}
1570        "#,
1571            expect![""],
1572        );
1573    }
1574
1575    #[test]
1576    fn call_info_for_unclosed_call() {
1577        check(
1578            r#"
1579fn foo(foo: u32, bar: u32) {}
1580fn main() {
1581    foo($0
1582}"#,
1583            expect![[r#"
1584                fn foo(foo: u32, bar: u32)
1585                       ^^^^^^^^  --------
1586            "#]],
1587        );
1588        // check with surrounding space
1589        check(
1590            r#"
1591fn foo(foo: u32, bar: u32) {}
1592fn main() {
1593    foo( $0
1594}"#,
1595            expect![[r#"
1596                fn foo(foo: u32, bar: u32)
1597                       ^^^^^^^^  --------
1598            "#]],
1599        )
1600    }
1601
1602    #[test]
1603    fn test_multiline_argument() {
1604        check(
1605            r#"
1606fn callee(a: u8, b: u8) {}
1607fn main() {
1608    callee(match 0 {
1609        0 => 1,$0
1610    })
1611}"#,
1612            expect![[r#""#]],
1613        );
1614        check(
1615            r#"
1616fn callee(a: u8, b: u8) {}
1617fn main() {
1618    callee(match 0 {
1619        0 => 1,
1620    },$0)
1621}"#,
1622            expect![[r#"
1623                fn callee(a: u8, b: u8)
1624                          -----  ^^^^^
1625            "#]],
1626        );
1627        check(
1628            r#"
1629fn callee(a: u8, b: u8) {}
1630fn main() {
1631    callee($0match 0 {
1632        0 => 1,
1633    })
1634}"#,
1635            expect![[r#"
1636                fn callee(a: u8, b: u8)
1637                          ^^^^^  -----
1638            "#]],
1639        );
1640    }
1641
1642    #[test]
1643    fn test_generics_simple() {
1644        check(
1645            r#"
1646/// Option docs.
1647enum Option<T> {
1648    Some(T),
1649    None,
1650}
1651
1652fn f() {
1653    let opt: Option<$0
1654}
1655        "#,
1656            expect![[r#"
1657                Option docs.
1658                ------
1659                enum Option<T>
1660                            ^
1661            "#]],
1662        );
1663    }
1664
1665    #[test]
1666    fn test_generics_on_variant() {
1667        check(
1668            r#"
1669/// Option docs.
1670enum Option<T> {
1671    /// Some docs.
1672    Some(T),
1673    /// None docs.
1674    None,
1675}
1676
1677use Option::*;
1678
1679fn f() {
1680    None::<$0
1681}
1682        "#,
1683            expect![[r#"
1684                None docs.
1685                ------
1686                enum Option<T>
1687                            ^
1688            "#]],
1689        );
1690    }
1691
1692    #[test]
1693    fn test_lots_of_generics() {
1694        check(
1695            r#"
1696trait Tr<T> {}
1697
1698struct S<T>(T);
1699
1700impl<T> S<T> {
1701    fn f<G, H>(g: G, h: impl Tr<G>) where G: Tr<()> {}
1702}
1703
1704fn f() {
1705    S::<u8>::f::<(), $0
1706}
1707        "#,
1708            expect![[r#"
1709                fn f<G: Tr<()>, H>
1710                     ---------  ^
1711            "#]],
1712        );
1713    }
1714
1715    #[test]
1716    fn test_generics_in_trait_ufcs() {
1717        check(
1718            r#"
1719trait Tr {
1720    fn f<T: Tr, U>() {}
1721}
1722
1723struct S;
1724
1725impl Tr for S {}
1726
1727fn f() {
1728    <S as Tr>::f::<$0
1729}
1730        "#,
1731            expect![[r#"
1732                fn f<T: Tr, U>
1733                     ^^^^^  -
1734            "#]],
1735        );
1736    }
1737
1738    #[test]
1739    fn test_generics_in_method_call() {
1740        check(
1741            r#"
1742struct S;
1743
1744impl S {
1745    fn f<T>(&self) {}
1746}
1747
1748fn f() {
1749    S.f::<$0
1750}
1751        "#,
1752            expect![[r#"
1753                fn f<T>
1754                     ^
1755            "#]],
1756        );
1757    }
1758
1759    #[test]
1760    fn test_generic_param_in_method_call() {
1761        check(
1762            r#"
1763struct Foo;
1764impl Foo {
1765    fn test<V>(&mut self, val: V) {}
1766}
1767fn sup() {
1768    Foo.test($0)
1769}
1770"#,
1771            expect![[r#"
1772                fn test<V>(&mut self, val: V)
1773                                      ^^^^^^
1774            "#]],
1775        );
1776    }
1777
1778    #[test]
1779    fn test_generic_kinds() {
1780        check(
1781            r#"
1782fn callee<'a, const A: u8, T, const C: u8>() {}
1783
1784fn f() {
1785    callee::<'static, $0
1786}
1787        "#,
1788            expect![[r#"
1789                fn callee<'a, const A: u8, T, const C: u8>
1790                          --  ^^^^^^^^^^^  -  -----------
1791            "#]],
1792        );
1793        check(
1794            r#"
1795fn callee<'a, const A: u8, T, const C: u8>() {}
1796
1797fn f() {
1798    callee::<NON_LIFETIME$0
1799}
1800        "#,
1801            expect![[r#"
1802                fn callee<'a, const A: u8, T, const C: u8>
1803                          --  ^^^^^^^^^^^  -  -----------
1804            "#]],
1805        );
1806    }
1807
1808    #[test]
1809    fn test_trait_assoc_types() {
1810        check(
1811            r#"
1812trait Trait<'a, T> {
1813    type Assoc;
1814}
1815fn f() -> impl Trait<(), $0
1816            "#,
1817            expect![[r#"
1818                trait Trait<'a, T, Assoc = …>
1819                            --  -  ^^^^^^^^^
1820            "#]],
1821        );
1822        check(
1823            r#"
1824trait Iterator {
1825    type Item;
1826}
1827fn f() -> impl Iterator<$0
1828            "#,
1829            expect![[r#"
1830                trait Iterator<Item = …>
1831                               ^^^^^^^^
1832            "#]],
1833        );
1834        check(
1835            r#"
1836trait Iterator {
1837    type Item;
1838}
1839fn f() -> impl Iterator<Item = $0
1840            "#,
1841            expect![[r#"
1842                trait Iterator<Item = …>
1843                               ^^^^^^^^
1844            "#]],
1845        );
1846        check(
1847            r#"
1848trait Tr {
1849    type A;
1850    type B;
1851}
1852fn f() -> impl Tr<$0
1853            "#,
1854            expect![[r#"
1855                trait Tr<A = …, B = …>
1856                         ^^^^^  -----
1857            "#]],
1858        );
1859        check(
1860            r#"
1861trait Tr {
1862    type A;
1863    type B;
1864}
1865fn f() -> impl Tr<B$0
1866            "#,
1867            expect![[r#"
1868                trait Tr<A = …, B = …>
1869                         ^^^^^  -----
1870            "#]],
1871        );
1872        check(
1873            r#"
1874trait Tr {
1875    type A;
1876    type B;
1877}
1878fn f() -> impl Tr<B = $0
1879            "#,
1880            expect![[r#"
1881                trait Tr<B = …, A = …>
1882                         ^^^^^  -----
1883            "#]],
1884        );
1885        check(
1886            r#"
1887trait Tr {
1888    type A;
1889    type B;
1890}
1891fn f() -> impl Tr<B = (), $0
1892            "#,
1893            expect![[r#"
1894                trait Tr<B = …, A = …>
1895                         -----  ^^^^^
1896            "#]],
1897        );
1898    }
1899
1900    #[test]
1901    fn test_supertrait_assoc() {
1902        check(
1903            r#"
1904trait Super {
1905    type SuperTy;
1906}
1907trait Sub: Super + Super {
1908    type SubTy;
1909}
1910fn f() -> impl Sub<$0
1911            "#,
1912            expect![[r#"
1913                trait Sub<SubTy = …, SuperTy = …>
1914                          ^^^^^^^^^  -----------
1915            "#]],
1916        );
1917    }
1918
1919    #[test]
1920    fn no_assoc_types_outside_type_bounds() {
1921        check(
1922            r#"
1923trait Tr<T> {
1924    type Assoc;
1925}
1926
1927impl Tr<$0
1928        "#,
1929            expect![[r#"
1930            trait Tr<T>
1931                     ^
1932        "#]],
1933        );
1934    }
1935
1936    #[test]
1937    fn impl_trait() {
1938        // FIXME: Substitute type vars in impl trait (`U` -> `i8`)
1939        check(
1940            r#"
1941trait Trait<T> {}
1942struct Wrap<T>(T);
1943fn foo<U>(x: Wrap<impl Trait<U>>) {}
1944fn f() {
1945    foo::<i8>($0)
1946}
1947"#,
1948            expect![[r#"
1949                fn foo<U>(x: Wrap<impl Trait<U>>)
1950                          ^^^^^^^^^^^^^^^^^^^^^^
1951            "#]],
1952        );
1953    }
1954
1955    #[test]
1956    fn fully_qualified_syntax() {
1957        check(
1958            r#"
1959fn f() {
1960    trait A { fn foo(&self, other: Self); }
1961    A::foo(&self$0, other);
1962}
1963"#,
1964            expect![[r#"
1965                fn foo(self: &Self, other: Self)
1966                       ^^^^^^^^^^^  -----------
1967            "#]],
1968        );
1969    }
1970
1971    #[test]
1972    fn help_for_generic_call() {
1973        check(
1974            r#"
1975fn f<F: FnOnce(u8, u16) -> i32>(f: F) {
1976    f($0)
1977}
1978"#,
1979            expect![[r#"
1980                impl FnOnce(u8, u16) -> i32
1981                            ^^  ---
1982            "#]],
1983        );
1984        check(
1985            r#"
1986fn f<T, F: FnMut(&T, u16) -> &T>(f: F) {
1987    f($0)
1988}
1989"#,
1990            expect![[r#"
1991                impl FnMut(&T, u16) -> &T
1992                           ^^  ---
1993            "#]],
1994        );
1995    }
1996
1997    #[test]
1998    fn regression_13579() {
1999        check(
2000            r#"
2001fn f() {
2002    take(2)($0);
2003}
2004
2005fn take<C, Error>(
2006    count: C
2007) -> impl Fn() -> C  {
2008    move || count
2009}
2010"#,
2011            expect![[r#"
2012                impl Fn() -> i32
2013            "#]],
2014        );
2015    }
2016
2017    #[test]
2018    fn record_literal() {
2019        check(
2020            r#"
2021struct Strukt<T, U = ()> {
2022    t: T,
2023    u: U,
2024    unit: (),
2025}
2026fn f() {
2027    Strukt {
2028        u: 0,
2029        $0
2030    }
2031}
2032"#,
2033            expect![[r#"
2034                struct Strukt { u: i32, t: T, unit: () }
2035                                ------  ^^^^  --------
2036            "#]],
2037        );
2038    }
2039
2040    #[test]
2041    fn record_literal_nonexistent_field() {
2042        check(
2043            r#"
2044struct Strukt {
2045    a: u8,
2046}
2047fn f() {
2048    Strukt {
2049        b: 8,
2050        $0
2051    }
2052}
2053"#,
2054            expect![[r#"
2055                struct Strukt { a: u8 }
2056                                -----
2057            "#]],
2058        );
2059    }
2060
2061    #[test]
2062    fn tuple_variant_record_literal() {
2063        check(
2064            r#"
2065enum Opt {
2066    Some(u8),
2067}
2068fn f() {
2069    Opt::Some {$0}
2070}
2071"#,
2072            expect![[r#"
2073                enum Opt::Some { 0: u8 }
2074                                 ^^^^^
2075            "#]],
2076        );
2077        check(
2078            r#"
2079enum Opt {
2080    Some(u8),
2081}
2082fn f() {
2083    Opt::Some {0:0,$0}
2084}
2085"#,
2086            expect![[r#"
2087                enum Opt::Some { 0: u8 }
2088                                 -----
2089            "#]],
2090        );
2091    }
2092
2093    #[test]
2094    fn record_literal_self() {
2095        check(
2096            r#"
2097struct S { t: u8 }
2098impl S {
2099    fn new() -> Self {
2100        Self { $0 }
2101    }
2102}
2103        "#,
2104            expect![[r#"
2105                struct S { t: u8 }
2106                           ^^^^^
2107            "#]],
2108        );
2109    }
2110
2111    #[test]
2112    fn record_pat() {
2113        check(
2114            r#"
2115struct Strukt<T, U = ()> {
2116    t: T,
2117    u: U,
2118    unit: (),
2119}
2120fn f() {
2121    let Strukt {
2122        u: 0,
2123        $0
2124    }
2125}
2126"#,
2127            expect![[r#"
2128                struct Strukt { u: i32, t: T, unit: () }
2129                                ------  ^^^^  --------
2130            "#]],
2131        );
2132    }
2133
2134    #[test]
2135    fn test_enum_in_nested_method_in_lambda() {
2136        check(
2137            r#"
2138enum A {
2139    A,
2140    B
2141}
2142
2143fn bar(_: A) { }
2144
2145fn main() {
2146    let foo = Foo;
2147    std::thread::spawn(move || { bar(A:$0) } );
2148}
2149"#,
2150            expect![[r#"
2151                fn bar(_: A)
2152                       ^^^^
2153            "#]],
2154        );
2155    }
2156
2157    #[test]
2158    fn test_tuple_expr_free() {
2159        check(
2160            r#"
2161fn main() {
2162    (0$0, 1, 3);
2163}
2164"#,
2165            expect![[r#"
2166                (i32, i32, i32)
2167                 ^^^  ---  ---
2168            "#]],
2169        );
2170        check(
2171            r#"
2172fn main() {
2173    ($0 1, 3);
2174}
2175"#,
2176            expect![[r#"
2177                (i32, i32)
2178                 ^^^  ---
2179            "#]],
2180        );
2181        check(
2182            r#"
2183fn main() {
2184    (1, 3 $0);
2185}
2186"#,
2187            expect![[r#"
2188                (i32, i32)
2189                 ---  ^^^
2190            "#]],
2191        );
2192        check(
2193            r#"
2194fn main() {
2195    (1, 3 $0,);
2196}
2197"#,
2198            expect![[r#"
2199                (i32, i32)
2200                 ---  ^^^
2201            "#]],
2202        );
2203    }
2204
2205    #[test]
2206    fn test_tuple_expr_expected() {
2207        check(
2208            r#"
2209fn main() {
2210    let _: (&str, u32, u32)= ($0, 1, 3);
2211}
2212"#,
2213            expect![[r#"
2214                (&str, u32, u32)
2215                 ^^^^  ---  ---
2216            "#]],
2217        );
2218        // FIXME: Should typeck report a 4-ary tuple for the expression here?
2219        check(
2220            r#"
2221fn main() {
2222    let _: (&str, u32, u32, u32) = ($0, 1, 3);
2223}
2224"#,
2225            expect![[r#"
2226                (&str, u32, u32)
2227                 ^^^^  ---  ---
2228            "#]],
2229        );
2230        check(
2231            r#"
2232fn main() {
2233    let _: (&str, u32, u32)= ($0, 1, 3, 5);
2234}
2235"#,
2236            expect![[r#"
2237                (&str, u32, u32, i32)
2238                 ^^^^  ---  ---  ---
2239            "#]],
2240        );
2241    }
2242
2243    #[test]
2244    fn test_tuple_pat_free() {
2245        check(
2246            r#"
2247fn main() {
2248    let ($0, 1, 3);
2249}
2250"#,
2251            expect![[r#"
2252                ({unknown}, i32, i32)
2253                 ^^^^^^^^^  ---  ---
2254            "#]],
2255        );
2256        check(
2257            r#"
2258fn main() {
2259    let (0$0, 1, 3);
2260}
2261"#,
2262            expect![[r#"
2263                (i32, i32, i32)
2264                 ^^^  ---  ---
2265            "#]],
2266        );
2267        check(
2268            r#"
2269fn main() {
2270    let ($0 1, 3);
2271}
2272"#,
2273            expect![[r#"
2274                (i32, i32)
2275                 ^^^  ---
2276            "#]],
2277        );
2278        check(
2279            r#"
2280fn main() {
2281    let (1, 3 $0);
2282}
2283"#,
2284            expect![[r#"
2285                (i32, i32)
2286                 ---  ^^^
2287            "#]],
2288        );
2289        check(
2290            r#"
2291fn main() {
2292    let (1, 3 $0,);
2293}
2294"#,
2295            expect![[r#"
2296                (i32, i32)
2297                 ---  ^^^
2298            "#]],
2299        );
2300        check(
2301            r#"
2302fn main() {
2303    let (1, 3 $0, ..);
2304}
2305"#,
2306            expect![[r#"
2307                (i32, i32)
2308                 ---  ^^^
2309            "#]],
2310        );
2311        check(
2312            r#"
2313fn main() {
2314    let (1, 3, .., $0);
2315}
2316"#,
2317            // FIXME: This is wrong, this should not mark the last as active
2318            expect![[r#"
2319                (i32, i32)
2320                 ---  ^^^
2321            "#]],
2322        );
2323    }
2324
2325    #[test]
2326    fn test_tuple_pat_expected() {
2327        check(
2328            r#"
2329fn main() {
2330    let (0$0, 1, 3): (i32, i32, i32);
2331}
2332"#,
2333            expect![[r#"
2334                (i32, i32, i32)
2335                 ^^^  ---  ---
2336            "#]],
2337        );
2338        check(
2339            r#"
2340fn main() {
2341    let ($0, 1, 3): (i32, i32, i32);
2342}
2343"#,
2344            expect![[r#"
2345                (i32, i32, i32)
2346                 ^^^  ---  ---
2347            "#]],
2348        );
2349        check(
2350            r#"
2351fn main() {
2352    let (1, 3 $0): (i32,);
2353}
2354"#,
2355            expect![[r#"
2356                (i32, i32)
2357                 ---  ^^^
2358            "#]],
2359        );
2360        check(
2361            r#"
2362fn main() {
2363    let (1, 3 $0, ..): (i32, i32, i32, i32);
2364}
2365"#,
2366            expect![[r#"
2367                (i32, i32, i32, i32)
2368                 ---  ^^^  ---  ---
2369            "#]],
2370        );
2371        check(
2372            r#"
2373fn main() {
2374    let (1, 3, .., $0): (i32, i32, i32);
2375}
2376"#,
2377            expect![[r#"
2378                (i32, i32, i32)
2379                 ---  ---  ^^^
2380            "#]],
2381        );
2382    }
2383    #[test]
2384    fn test_tuple_pat_expected_inferred() {
2385        check(
2386            r#"
2387fn main() {
2388    let (0$0, 1, 3) = (1, 2 ,3);
2389}
2390"#,
2391            expect![[r#"
2392                (i32, i32, i32)
2393                 ^^^  ---  ---
2394            "#]],
2395        );
2396        check(
2397            r#"
2398fn main() {
2399    let ($0 1, 3) = (1, 2, 3);
2400}
2401"#,
2402            // FIXME: Should typeck report a 3-ary tuple for the pattern here?
2403            expect![[r#"
2404                (i32, i32)
2405                 ^^^  ---
2406            "#]],
2407        );
2408        check(
2409            r#"
2410fn main() {
2411    let (1, 3 $0) = (1,);
2412}
2413"#,
2414            expect![[r#"
2415                (i32, i32)
2416                 ---  ^^^
2417            "#]],
2418        );
2419        check(
2420            r#"
2421fn main() {
2422    let (1, 3 $0, ..) = (1, 2, 3, 4);
2423}
2424"#,
2425            expect![[r#"
2426                (i32, i32, i32, i32)
2427                 ---  ^^^  ---  ---
2428            "#]],
2429        );
2430        check(
2431            r#"
2432fn main() {
2433    let (1, 3, .., $0) = (1, 2, 3);
2434}
2435"#,
2436            expect![[r#"
2437                (i32, i32, i32)
2438                 ---  ---  ^^^
2439            "#]],
2440        );
2441    }
2442
2443    #[test]
2444    fn test_tuple_generic_param() {
2445        check(
2446            r#"
2447struct S<T>(T);
2448
2449fn main() {
2450    let s: S<$0
2451}
2452            "#,
2453            expect![[r#"
2454                struct S<T>
2455                         ^
2456            "#]],
2457        );
2458    }
2459
2460    #[test]
2461    fn test_enum_generic_param() {
2462        check(
2463            r#"
2464enum Option<T> {
2465    Some(T),
2466    None,
2467}
2468
2469fn main() {
2470    let opt: Option<$0
2471}
2472            "#,
2473            expect![[r#"
2474                enum Option<T>
2475                            ^
2476            "#]],
2477        );
2478    }
2479
2480    #[test]
2481    fn test_enum_variant_generic_param() {
2482        check(
2483            r#"
2484enum Option<T> {
2485    Some(T),
2486    None,
2487}
2488
2489fn main() {
2490    let opt = Option::Some($0);
2491}
2492            "#,
2493            expect![[r#"
2494                enum Option<T>::Some({unknown})
2495                                     ^^^^^^^^^
2496            "#]],
2497        );
2498    }
2499
2500    #[test]
2501    fn test_generic_arg_with_default() {
2502        check(
2503            r#"
2504struct S<T = u8> {
2505    field: T,
2506}
2507
2508fn main() {
2509    let s: S<$0
2510}
2511            "#,
2512            expect![[r#"
2513                struct S<T = u8>
2514                         ^^^^^^
2515            "#]],
2516        );
2517
2518        check(
2519            r#"
2520struct S<const C: u8 = 5> {
2521    field: C,
2522}
2523
2524fn main() {
2525    let s: S<$0
2526}
2527            "#,
2528            expect![[r#"
2529                struct S<const C: u8 = 5>
2530                         ^^^^^^^^^^^^^^^
2531            "#]],
2532        );
2533    }
2534}