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