diff options
Diffstat (limited to 'crates/completion/src/completions/qualified_path.rs')
-rw-r--r-- | crates/completion/src/completions/qualified_path.rs | 783 |
1 files changed, 0 insertions, 783 deletions
diff --git a/crates/completion/src/completions/qualified_path.rs b/crates/completion/src/completions/qualified_path.rs deleted file mode 100644 index 33df26761..000000000 --- a/crates/completion/src/completions/qualified_path.rs +++ /dev/null | |||
@@ -1,783 +0,0 @@ | |||
1 | //! Completion of paths, i.e. `some::prefix::$0`. | ||
2 | |||
3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; | ||
4 | use rustc_hash::FxHashSet; | ||
5 | use syntax::AstNode; | ||
6 | use test_utils::mark; | ||
7 | |||
8 | use crate::{CompletionContext, Completions}; | ||
9 | |||
10 | pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { | ||
11 | let path = match &ctx.path_qual { | ||
12 | Some(path) => path.clone(), | ||
13 | None => return, | ||
14 | }; | ||
15 | |||
16 | if ctx.attribute_under_caret.is_some() || ctx.mod_declaration_under_caret.is_some() { | ||
17 | return; | ||
18 | } | ||
19 | |||
20 | let context_module = ctx.scope.module(); | ||
21 | |||
22 | let resolution = match ctx.sema.resolve_path(&path) { | ||
23 | Some(res) => res, | ||
24 | None => return, | ||
25 | }; | ||
26 | |||
27 | // Add associated types on type parameters and `Self`. | ||
28 | resolution.assoc_type_shorthand_candidates(ctx.db, |alias| { | ||
29 | acc.add_type_alias(ctx, alias); | ||
30 | None::<()> | ||
31 | }); | ||
32 | |||
33 | match resolution { | ||
34 | PathResolution::Def(hir::ModuleDef::Module(module)) => { | ||
35 | let module_scope = module.scope(ctx.db, context_module); | ||
36 | for (name, def) in module_scope { | ||
37 | if ctx.use_item_syntax.is_some() { | ||
38 | if let ScopeDef::Unknown = def { | ||
39 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { | ||
40 | if name_ref.syntax().text() == name.to_string().as_str() { | ||
41 | // for `use self::foo$0`, don't suggest `foo` as a completion | ||
42 | mark::hit!(dont_complete_current_use); | ||
43 | continue; | ||
44 | } | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | acc.add_resolution(ctx, name.to_string(), &def); | ||
50 | } | ||
51 | } | ||
52 | PathResolution::Def(def @ hir::ModuleDef::Adt(_)) | ||
53 | | PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_)) => { | ||
54 | if let hir::ModuleDef::Adt(Adt::Enum(e)) = def { | ||
55 | for variant in e.variants(ctx.db) { | ||
56 | acc.add_enum_variant(ctx, variant, None); | ||
57 | } | ||
58 | } | ||
59 | let ty = match def { | ||
60 | hir::ModuleDef::Adt(adt) => adt.ty(ctx.db), | ||
61 | hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), | ||
62 | _ => unreachable!(), | ||
63 | }; | ||
64 | |||
65 | // XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType. | ||
66 | // (where AssocType is defined on a trait, not an inherent impl) | ||
67 | |||
68 | let krate = ctx.krate; | ||
69 | if let Some(krate) = krate { | ||
70 | let traits_in_scope = ctx.scope.traits_in_scope(); | ||
71 | ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { | ||
72 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { | ||
73 | return None; | ||
74 | } | ||
75 | match item { | ||
76 | hir::AssocItem::Function(func) => { | ||
77 | acc.add_function(ctx, func, None); | ||
78 | } | ||
79 | hir::AssocItem::Const(ct) => acc.add_const(ctx, ct), | ||
80 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), | ||
81 | } | ||
82 | None::<()> | ||
83 | }); | ||
84 | |||
85 | // Iterate assoc types separately | ||
86 | ty.iterate_assoc_items(ctx.db, krate, |item| { | ||
87 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { | ||
88 | return None; | ||
89 | } | ||
90 | match item { | ||
91 | hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {} | ||
92 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), | ||
93 | } | ||
94 | None::<()> | ||
95 | }); | ||
96 | } | ||
97 | } | ||
98 | PathResolution::Def(hir::ModuleDef::Trait(t)) => { | ||
99 | // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`. | ||
100 | for item in t.items(ctx.db) { | ||
101 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { | ||
102 | continue; | ||
103 | } | ||
104 | match item { | ||
105 | hir::AssocItem::Function(func) => { | ||
106 | acc.add_function(ctx, func, None); | ||
107 | } | ||
108 | hir::AssocItem::Const(ct) => acc.add_const(ctx, ct), | ||
109 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | PathResolution::TypeParam(_) | PathResolution::SelfType(_) => { | ||
114 | if let Some(krate) = ctx.krate { | ||
115 | let ty = match resolution { | ||
116 | PathResolution::TypeParam(param) => param.ty(ctx.db), | ||
117 | PathResolution::SelfType(impl_def) => impl_def.target_ty(ctx.db), | ||
118 | _ => return, | ||
119 | }; | ||
120 | |||
121 | if let Some(Adt::Enum(e)) = ty.as_adt() { | ||
122 | for variant in e.variants(ctx.db) { | ||
123 | acc.add_enum_variant(ctx, variant, None); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | let traits_in_scope = ctx.scope.traits_in_scope(); | ||
128 | let mut seen = FxHashSet::default(); | ||
129 | ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { | ||
130 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { | ||
131 | return None; | ||
132 | } | ||
133 | |||
134 | // We might iterate candidates of a trait multiple times here, so deduplicate | ||
135 | // them. | ||
136 | if seen.insert(item) { | ||
137 | match item { | ||
138 | hir::AssocItem::Function(func) => { | ||
139 | acc.add_function(ctx, func, None); | ||
140 | } | ||
141 | hir::AssocItem::Const(ct) => acc.add_const(ctx, ct), | ||
142 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), | ||
143 | } | ||
144 | } | ||
145 | None::<()> | ||
146 | }); | ||
147 | } | ||
148 | } | ||
149 | _ => {} | ||
150 | } | ||
151 | } | ||
152 | |||
153 | #[cfg(test)] | ||
154 | mod tests { | ||
155 | use expect_test::{expect, Expect}; | ||
156 | use test_utils::mark; | ||
157 | |||
158 | use crate::{ | ||
159 | test_utils::{check_edit, completion_list}, | ||
160 | CompletionKind, | ||
161 | }; | ||
162 | |||
163 | fn check(ra_fixture: &str, expect: Expect) { | ||
164 | let actual = completion_list(ra_fixture, CompletionKind::Reference); | ||
165 | expect.assert_eq(&actual); | ||
166 | } | ||
167 | |||
168 | fn check_builtin(ra_fixture: &str, expect: Expect) { | ||
169 | let actual = completion_list(ra_fixture, CompletionKind::BuiltinType); | ||
170 | expect.assert_eq(&actual); | ||
171 | } | ||
172 | |||
173 | #[test] | ||
174 | fn dont_complete_current_use() { | ||
175 | mark::check!(dont_complete_current_use); | ||
176 | check(r#"use self::foo$0;"#, expect![[""]]); | ||
177 | } | ||
178 | |||
179 | #[test] | ||
180 | fn dont_complete_current_use_in_braces_with_glob() { | ||
181 | check( | ||
182 | r#" | ||
183 | mod foo { pub struct S; } | ||
184 | use self::{foo::*, bar$0}; | ||
185 | "#, | ||
186 | expect![[r#" | ||
187 | st S | ||
188 | md foo | ||
189 | "#]], | ||
190 | ); | ||
191 | } | ||
192 | |||
193 | #[test] | ||
194 | fn dont_complete_primitive_in_use() { | ||
195 | check_builtin(r#"use self::$0;"#, expect![[""]]); | ||
196 | } | ||
197 | |||
198 | #[test] | ||
199 | fn dont_complete_primitive_in_module_scope() { | ||
200 | check_builtin(r#"fn foo() { self::$0 }"#, expect![[""]]); | ||
201 | } | ||
202 | |||
203 | #[test] | ||
204 | fn completes_primitives() { | ||
205 | check_builtin( | ||
206 | r#"fn main() { let _: $0 = 92; }"#, | ||
207 | expect![[r#" | ||
208 | bt u32 | ||
209 | bt bool | ||
210 | bt u8 | ||
211 | bt isize | ||
212 | bt u16 | ||
213 | bt u64 | ||
214 | bt u128 | ||
215 | bt f32 | ||
216 | bt i128 | ||
217 | bt i16 | ||
218 | bt str | ||
219 | bt i64 | ||
220 | bt char | ||
221 | bt f64 | ||
222 | bt i32 | ||
223 | bt i8 | ||
224 | bt usize | ||
225 | "#]], | ||
226 | ); | ||
227 | } | ||
228 | |||
229 | #[test] | ||
230 | fn completes_mod_with_same_name_as_function() { | ||
231 | check( | ||
232 | r#" | ||
233 | use self::my::$0; | ||
234 | |||
235 | mod my { pub struct Bar; } | ||
236 | fn my() {} | ||
237 | "#, | ||
238 | expect![[r#" | ||
239 | st Bar | ||
240 | "#]], | ||
241 | ); | ||
242 | } | ||
243 | |||
244 | #[test] | ||
245 | fn filters_visibility() { | ||
246 | check( | ||
247 | r#" | ||
248 | use self::my::$0; | ||
249 | |||
250 | mod my { | ||
251 | struct Bar; | ||
252 | pub struct Foo; | ||
253 | pub use Bar as PublicBar; | ||
254 | } | ||
255 | "#, | ||
256 | expect![[r#" | ||
257 | st Foo | ||
258 | st PublicBar | ||
259 | "#]], | ||
260 | ); | ||
261 | } | ||
262 | |||
263 | #[test] | ||
264 | fn completes_use_item_starting_with_self() { | ||
265 | check( | ||
266 | r#" | ||
267 | use self::m::$0; | ||
268 | |||
269 | mod m { pub struct Bar; } | ||
270 | "#, | ||
271 | expect![[r#" | ||
272 | st Bar | ||
273 | "#]], | ||
274 | ); | ||
275 | } | ||
276 | |||
277 | #[test] | ||
278 | fn completes_use_item_starting_with_crate() { | ||
279 | check( | ||
280 | r#" | ||
281 | //- /lib.rs | ||
282 | mod foo; | ||
283 | struct Spam; | ||
284 | //- /foo.rs | ||
285 | use crate::Sp$0 | ||
286 | "#, | ||
287 | expect![[r#" | ||
288 | md foo | ||
289 | st Spam | ||
290 | "#]], | ||
291 | ); | ||
292 | } | ||
293 | |||
294 | #[test] | ||
295 | fn completes_nested_use_tree() { | ||
296 | check( | ||
297 | r#" | ||
298 | //- /lib.rs | ||
299 | mod foo; | ||
300 | struct Spam; | ||
301 | //- /foo.rs | ||
302 | use crate::{Sp$0}; | ||
303 | "#, | ||
304 | expect![[r#" | ||
305 | md foo | ||
306 | st Spam | ||
307 | "#]], | ||
308 | ); | ||
309 | } | ||
310 | |||
311 | #[test] | ||
312 | fn completes_deeply_nested_use_tree() { | ||
313 | check( | ||
314 | r#" | ||
315 | //- /lib.rs | ||
316 | mod foo; | ||
317 | pub mod bar { | ||
318 | pub mod baz { | ||
319 | pub struct Spam; | ||
320 | } | ||
321 | } | ||
322 | //- /foo.rs | ||
323 | use crate::{bar::{baz::Sp$0}}; | ||
324 | "#, | ||
325 | expect![[r#" | ||
326 | st Spam | ||
327 | "#]], | ||
328 | ); | ||
329 | } | ||
330 | |||
331 | #[test] | ||
332 | fn completes_enum_variant() { | ||
333 | check( | ||
334 | r#" | ||
335 | enum E { Foo, Bar(i32) } | ||
336 | fn foo() { let _ = E::$0 } | ||
337 | "#, | ||
338 | expect![[r#" | ||
339 | ev Foo () | ||
340 | ev Bar(…) (i32) | ||
341 | "#]], | ||
342 | ); | ||
343 | } | ||
344 | |||
345 | #[test] | ||
346 | fn completes_struct_associated_items() { | ||
347 | check( | ||
348 | r#" | ||
349 | //- /lib.rs | ||
350 | struct S; | ||
351 | |||
352 | impl S { | ||
353 | fn a() {} | ||
354 | fn b(&self) {} | ||
355 | const C: i32 = 42; | ||
356 | type T = i32; | ||
357 | } | ||
358 | |||
359 | fn foo() { let _ = S::$0 } | ||
360 | "#, | ||
361 | expect![[r#" | ||
362 | fn a() fn a() | ||
363 | me b(…) fn b(&self) | ||
364 | ct C const C: i32 = 42; | ||
365 | ta T type T = i32; | ||
366 | "#]], | ||
367 | ); | ||
368 | } | ||
369 | |||
370 | #[test] | ||
371 | fn associated_item_visibility() { | ||
372 | check( | ||
373 | r#" | ||
374 | struct S; | ||
375 | |||
376 | mod m { | ||
377 | impl super::S { | ||
378 | pub(crate) fn public_method() { } | ||
379 | fn private_method() { } | ||
380 | pub(crate) type PublicType = u32; | ||
381 | type PrivateType = u32; | ||
382 | pub(crate) const PUBLIC_CONST: u32 = 1; | ||
383 | const PRIVATE_CONST: u32 = 1; | ||
384 | } | ||
385 | } | ||
386 | |||
387 | fn foo() { let _ = S::$0 } | ||
388 | "#, | ||
389 | expect![[r#" | ||
390 | fn public_method() pub(crate) fn public_method() | ||
391 | ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1; | ||
392 | ta PublicType pub(crate) type PublicType = u32; | ||
393 | "#]], | ||
394 | ); | ||
395 | } | ||
396 | |||
397 | #[test] | ||
398 | fn completes_enum_associated_method() { | ||
399 | check( | ||
400 | r#" | ||
401 | enum E {}; | ||
402 | impl E { fn m() { } } | ||
403 | |||
404 | fn foo() { let _ = E::$0 } | ||
405 | "#, | ||
406 | expect![[r#" | ||
407 | fn m() fn m() | ||
408 | "#]], | ||
409 | ); | ||
410 | } | ||
411 | |||
412 | #[test] | ||
413 | fn completes_union_associated_method() { | ||
414 | check( | ||
415 | r#" | ||
416 | union U {}; | ||
417 | impl U { fn m() { } } | ||
418 | |||
419 | fn foo() { let _ = U::$0 } | ||
420 | "#, | ||
421 | expect![[r#" | ||
422 | fn m() fn m() | ||
423 | "#]], | ||
424 | ); | ||
425 | } | ||
426 | |||
427 | #[test] | ||
428 | fn completes_use_paths_across_crates() { | ||
429 | check( | ||
430 | r#" | ||
431 | //- /main.rs crate:main deps:foo | ||
432 | use foo::$0; | ||
433 | |||
434 | //- /foo/lib.rs crate:foo | ||
435 | pub mod bar { pub struct S; } | ||
436 | "#, | ||
437 | expect![[r#" | ||
438 | md bar | ||
439 | "#]], | ||
440 | ); | ||
441 | } | ||
442 | |||
443 | #[test] | ||
444 | fn completes_trait_associated_method_1() { | ||
445 | check( | ||
446 | r#" | ||
447 | trait Trait { fn m(); } | ||
448 | |||
449 | fn foo() { let _ = Trait::$0 } | ||
450 | "#, | ||
451 | expect![[r#" | ||
452 | fn m() fn m() | ||
453 | "#]], | ||
454 | ); | ||
455 | } | ||
456 | |||
457 | #[test] | ||
458 | fn completes_trait_associated_method_2() { | ||
459 | check( | ||
460 | r#" | ||
461 | trait Trait { fn m(); } | ||
462 | |||
463 | struct S; | ||
464 | impl Trait for S {} | ||
465 | |||
466 | fn foo() { let _ = S::$0 } | ||
467 | "#, | ||
468 | expect![[r#" | ||
469 | fn m() fn m() | ||
470 | "#]], | ||
471 | ); | ||
472 | } | ||
473 | |||
474 | #[test] | ||
475 | fn completes_trait_associated_method_3() { | ||
476 | check( | ||
477 | r#" | ||
478 | trait Trait { fn m(); } | ||
479 | |||
480 | struct S; | ||
481 | impl Trait for S {} | ||
482 | |||
483 | fn foo() { let _ = <S as Trait>::$0 } | ||
484 | "#, | ||
485 | expect![[r#" | ||
486 | fn m() fn m() | ||
487 | "#]], | ||
488 | ); | ||
489 | } | ||
490 | |||
491 | #[test] | ||
492 | fn completes_ty_param_assoc_ty() { | ||
493 | check( | ||
494 | r#" | ||
495 | trait Super { | ||
496 | type Ty; | ||
497 | const CONST: u8; | ||
498 | fn func() {} | ||
499 | fn method(&self) {} | ||
500 | } | ||
501 | |||
502 | trait Sub: Super { | ||
503 | type SubTy; | ||
504 | const C2: (); | ||
505 | fn subfunc() {} | ||
506 | fn submethod(&self) {} | ||
507 | } | ||
508 | |||
509 | fn foo<T: Sub>() { T::$0 } | ||
510 | "#, | ||
511 | expect![[r#" | ||
512 | ta SubTy type SubTy; | ||
513 | ta Ty type Ty; | ||
514 | ct C2 const C2: (); | ||
515 | fn subfunc() fn subfunc() | ||
516 | me submethod(…) fn submethod(&self) | ||
517 | ct CONST const CONST: u8; | ||
518 | fn func() fn func() | ||
519 | me method(…) fn method(&self) | ||
520 | "#]], | ||
521 | ); | ||
522 | } | ||
523 | |||
524 | #[test] | ||
525 | fn completes_self_param_assoc_ty() { | ||
526 | check( | ||
527 | r#" | ||
528 | trait Super { | ||
529 | type Ty; | ||
530 | const CONST: u8 = 0; | ||
531 | fn func() {} | ||
532 | fn method(&self) {} | ||
533 | } | ||
534 | |||
535 | trait Sub: Super { | ||
536 | type SubTy; | ||
537 | const C2: () = (); | ||
538 | fn subfunc() {} | ||
539 | fn submethod(&self) {} | ||
540 | } | ||
541 | |||
542 | struct Wrap<T>(T); | ||
543 | impl<T> Super for Wrap<T> {} | ||
544 | impl<T> Sub for Wrap<T> { | ||
545 | fn subfunc() { | ||
546 | // Should be able to assume `Self: Sub + Super` | ||
547 | Self::$0 | ||
548 | } | ||
549 | } | ||
550 | "#, | ||
551 | expect![[r#" | ||
552 | ta SubTy type SubTy; | ||
553 | ta Ty type Ty; | ||
554 | ct CONST const CONST: u8 = 0; | ||
555 | fn func() fn func() | ||
556 | me method(…) fn method(&self) | ||
557 | ct C2 const C2: () = (); | ||
558 | fn subfunc() fn subfunc() | ||
559 | me submethod(…) fn submethod(&self) | ||
560 | "#]], | ||
561 | ); | ||
562 | } | ||
563 | |||
564 | #[test] | ||
565 | fn completes_type_alias() { | ||
566 | check( | ||
567 | r#" | ||
568 | struct S; | ||
569 | impl S { fn foo() {} } | ||
570 | type T = S; | ||
571 | impl T { fn bar() {} } | ||
572 | |||
573 | fn main() { T::$0; } | ||
574 | "#, | ||
575 | expect![[r#" | ||
576 | fn foo() fn foo() | ||
577 | fn bar() fn bar() | ||
578 | "#]], | ||
579 | ); | ||
580 | } | ||
581 | |||
582 | #[test] | ||
583 | fn completes_qualified_macros() { | ||
584 | check( | ||
585 | r#" | ||
586 | #[macro_export] | ||
587 | macro_rules! foo { () => {} } | ||
588 | |||
589 | fn main() { let _ = crate::$0 } | ||
590 | "#, | ||
591 | expect![[r##" | ||
592 | fn main() fn main() | ||
593 | ma foo!(…) #[macro_export] macro_rules! foo | ||
594 | "##]], | ||
595 | ); | ||
596 | } | ||
597 | |||
598 | #[test] | ||
599 | fn test_super_super_completion() { | ||
600 | check( | ||
601 | r#" | ||
602 | mod a { | ||
603 | const A: usize = 0; | ||
604 | mod b { | ||
605 | const B: usize = 0; | ||
606 | mod c { use super::super::$0 } | ||
607 | } | ||
608 | } | ||
609 | "#, | ||
610 | expect![[r#" | ||
611 | md b | ||
612 | ct A | ||
613 | "#]], | ||
614 | ); | ||
615 | } | ||
616 | |||
617 | #[test] | ||
618 | fn completes_reexported_items_under_correct_name() { | ||
619 | check( | ||
620 | r#" | ||
621 | fn foo() { self::m::$0 } | ||
622 | |||
623 | mod m { | ||
624 | pub use super::p::wrong_fn as right_fn; | ||
625 | pub use super::p::WRONG_CONST as RIGHT_CONST; | ||
626 | pub use super::p::WrongType as RightType; | ||
627 | } | ||
628 | mod p { | ||
629 | fn wrong_fn() {} | ||
630 | const WRONG_CONST: u32 = 1; | ||
631 | struct WrongType {}; | ||
632 | } | ||
633 | "#, | ||
634 | expect![[r#" | ||
635 | ct RIGHT_CONST | ||
636 | fn right_fn() fn wrong_fn() | ||
637 | st RightType | ||
638 | "#]], | ||
639 | ); | ||
640 | |||
641 | check_edit( | ||
642 | "RightType", | ||
643 | r#" | ||
644 | fn foo() { self::m::$0 } | ||
645 | |||
646 | mod m { | ||
647 | pub use super::p::wrong_fn as right_fn; | ||
648 | pub use super::p::WRONG_CONST as RIGHT_CONST; | ||
649 | pub use super::p::WrongType as RightType; | ||
650 | } | ||
651 | mod p { | ||
652 | fn wrong_fn() {} | ||
653 | const WRONG_CONST: u32 = 1; | ||
654 | struct WrongType {}; | ||
655 | } | ||
656 | "#, | ||
657 | r#" | ||
658 | fn foo() { self::m::RightType } | ||
659 | |||
660 | mod m { | ||
661 | pub use super::p::wrong_fn as right_fn; | ||
662 | pub use super::p::WRONG_CONST as RIGHT_CONST; | ||
663 | pub use super::p::WrongType as RightType; | ||
664 | } | ||
665 | mod p { | ||
666 | fn wrong_fn() {} | ||
667 | const WRONG_CONST: u32 = 1; | ||
668 | struct WrongType {}; | ||
669 | } | ||
670 | "#, | ||
671 | ); | ||
672 | } | ||
673 | |||
674 | #[test] | ||
675 | fn completes_in_simple_macro_call() { | ||
676 | check( | ||
677 | r#" | ||
678 | macro_rules! m { ($e:expr) => { $e } } | ||
679 | fn main() { m!(self::f$0); } | ||
680 | fn foo() {} | ||
681 | "#, | ||
682 | expect![[r#" | ||
683 | fn main() fn main() | ||
684 | fn foo() fn foo() | ||
685 | "#]], | ||
686 | ); | ||
687 | } | ||
688 | |||
689 | #[test] | ||
690 | fn function_mod_share_name() { | ||
691 | check( | ||
692 | r#" | ||
693 | fn foo() { self::m::$0 } | ||
694 | |||
695 | mod m { | ||
696 | pub mod z {} | ||
697 | pub fn z() {} | ||
698 | } | ||
699 | "#, | ||
700 | expect![[r#" | ||
701 | md z | ||
702 | fn z() pub fn z() | ||
703 | "#]], | ||
704 | ); | ||
705 | } | ||
706 | |||
707 | #[test] | ||
708 | fn completes_hashmap_new() { | ||
709 | check( | ||
710 | r#" | ||
711 | struct RandomState; | ||
712 | struct HashMap<K, V, S = RandomState> {} | ||
713 | |||
714 | impl<K, V> HashMap<K, V, RandomState> { | ||
715 | pub fn new() -> HashMap<K, V, RandomState> { } | ||
716 | } | ||
717 | fn foo() { | ||
718 | HashMap::$0 | ||
719 | } | ||
720 | "#, | ||
721 | expect![[r#" | ||
722 | fn new() pub fn new() -> HashMap<K, V, RandomState> | ||
723 | "#]], | ||
724 | ); | ||
725 | } | ||
726 | |||
727 | #[test] | ||
728 | fn dont_complete_attr() { | ||
729 | check( | ||
730 | r#" | ||
731 | mod foo { pub struct Foo; } | ||
732 | #[foo::$0] | ||
733 | fn f() {} | ||
734 | "#, | ||
735 | expect![[""]], | ||
736 | ); | ||
737 | } | ||
738 | |||
739 | #[test] | ||
740 | fn completes_function() { | ||
741 | check( | ||
742 | r#" | ||
743 | fn foo( | ||
744 | a: i32, | ||
745 | b: i32 | ||
746 | ) { | ||
747 | |||
748 | } | ||
749 | |||
750 | fn main() { | ||
751 | fo$0 | ||
752 | } | ||
753 | "#, | ||
754 | expect![[r#" | ||
755 | fn main() fn main() | ||
756 | fn foo(…) fn foo(a: i32, b: i32) | ||
757 | "#]], | ||
758 | ); | ||
759 | } | ||
760 | |||
761 | #[test] | ||
762 | fn completes_self_enum() { | ||
763 | check( | ||
764 | r#" | ||
765 | enum Foo { | ||
766 | Bar, | ||
767 | Baz, | ||
768 | } | ||
769 | |||
770 | impl Foo { | ||
771 | fn foo(self) { | ||
772 | Self::$0 | ||
773 | } | ||
774 | } | ||
775 | "#, | ||
776 | expect![[r#" | ||
777 | ev Bar () | ||
778 | ev Baz () | ||
779 | me foo(…) fn foo(self) | ||
780 | "#]], | ||
781 | ); | ||
782 | } | ||
783 | } | ||