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