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