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