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