ide/
signature_help.rs

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