1use 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#[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
72pub(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 .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 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 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 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 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 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 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 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 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(); 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(
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 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 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 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 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 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}