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