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