aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/tests/regression.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-08-13 15:35:29 +0100
committerAleksey Kladov <[email protected]>2020-08-13 15:35:29 +0100
commit6a77ec7bbe6ddbf663dce9529d11d1bb56c5489a (patch)
treeb6e3d7e0109eb82bca75b5ebc35a7d723542b8dd /crates/hir_ty/src/tests/regression.rs
parent50f8c1ebf23f634b68529603a917e3feeda457fa (diff)
Rename ra_hir_ty -> hir_ty
Diffstat (limited to 'crates/hir_ty/src/tests/regression.rs')
-rw-r--r--crates/hir_ty/src/tests/regression.rs842
1 files changed, 842 insertions, 0 deletions
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
new file mode 100644
index 000000000..b9ab0f357
--- /dev/null
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -0,0 +1,842 @@
1use expect::expect;
2use test_utils::mark;
3
4use super::{check_infer, check_types};
5
6#[test]
7fn bug_484() {
8 check_infer(
9 r#"
10 fn test() {
11 let x = if true {};
12 }
13 "#,
14 expect![[r#"
15 10..37 '{ ... {}; }': ()
16 20..21 'x': ()
17 24..34 'if true {}': ()
18 27..31 'true': bool
19 32..34 '{}': ()
20 "#]],
21 );
22}
23
24#[test]
25fn no_panic_on_field_of_enum() {
26 check_infer(
27 r#"
28 enum X {}
29
30 fn test(x: X) {
31 x.some_field;
32 }
33 "#,
34 expect![[r#"
35 19..20 'x': X
36 25..46 '{ ...eld; }': ()
37 31..32 'x': X
38 31..43 'x.some_field': {unknown}
39 "#]],
40 );
41}
42
43#[test]
44fn bug_585() {
45 check_infer(
46 r#"
47 fn test() {
48 X {};
49 match x {
50 A::B {} => (),
51 A::Y() => (),
52 }
53 }
54 "#,
55 expect![[r#"
56 10..88 '{ ... } }': ()
57 16..20 'X {}': {unknown}
58 26..86 'match ... }': ()
59 32..33 'x': {unknown}
60 44..51 'A::B {}': {unknown}
61 55..57 '()': ()
62 67..73 'A::Y()': {unknown}
63 77..79 '()': ()
64 "#]],
65 );
66}
67
68#[test]
69fn bug_651() {
70 check_infer(
71 r#"
72 fn quux() {
73 let y = 92;
74 1 + y;
75 }
76 "#,
77 expect![[r#"
78 10..40 '{ ...+ y; }': ()
79 20..21 'y': i32
80 24..26 '92': i32
81 32..33 '1': i32
82 32..37 '1 + y': i32
83 36..37 'y': i32
84 "#]],
85 );
86}
87
88#[test]
89fn recursive_vars() {
90 mark::check!(type_var_cycles_resolve_completely);
91 mark::check!(type_var_cycles_resolve_as_possible);
92 check_infer(
93 r#"
94 fn test() {
95 let y = unknown;
96 [y, &y];
97 }
98 "#,
99 expect![[r#"
100 10..47 '{ ...&y]; }': ()
101 20..21 'y': &{unknown}
102 24..31 'unknown': &{unknown}
103 37..44 '[y, &y]': [&&{unknown}; _]
104 38..39 'y': &{unknown}
105 41..43 '&y': &&{unknown}
106 42..43 'y': &{unknown}
107 "#]],
108 );
109}
110
111#[test]
112fn recursive_vars_2() {
113 check_infer(
114 r#"
115 fn test() {
116 let x = unknown;
117 let y = unknown;
118 [(x, y), (&y, &x)];
119 }
120 "#,
121 expect![[r#"
122 10..79 '{ ...x)]; }': ()
123 20..21 'x': &&{unknown}
124 24..31 'unknown': &&{unknown}
125 41..42 'y': &&{unknown}
126 45..52 'unknown': &&{unknown}
127 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _]
128 59..65 '(x, y)': (&&&{unknown}, &&&{unknown})
129 60..61 'x': &&{unknown}
130 63..64 'y': &&{unknown}
131 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown})
132 68..70 '&y': &&&{unknown}
133 69..70 'y': &&{unknown}
134 72..74 '&x': &&&{unknown}
135 73..74 'x': &&{unknown}
136 "#]],
137 );
138}
139
140#[test]
141fn infer_std_crash_1() {
142 // caused stack overflow, taken from std
143 check_infer(
144 r#"
145 enum Maybe<T> {
146 Real(T),
147 Fake,
148 }
149
150 fn write() {
151 match something_unknown {
152 Maybe::Real(ref mut something) => (),
153 }
154 }
155 "#,
156 expect![[r#"
157 53..138 '{ ... } }': ()
158 59..136 'match ... }': ()
159 65..82 'someth...nknown': Maybe<{unknown}>
160 93..123 'Maybe:...thing)': Maybe<{unknown}>
161 105..122 'ref mu...ething': &mut {unknown}
162 127..129 '()': ()
163 "#]],
164 );
165}
166
167#[test]
168fn infer_std_crash_2() {
169 mark::check!(type_var_resolves_to_int_var);
170 // caused "equating two type variables, ...", taken from std
171 check_infer(
172 r#"
173 fn test_line_buffer() {
174 &[0, b'\n', 1, b'\n'];
175 }
176 "#,
177 expect![[r#"
178 22..52 '{ ...n']; }': ()
179 28..49 '&[0, b...b'\n']': &[u8; _]
180 29..49 '[0, b'...b'\n']': [u8; _]
181 30..31 '0': u8
182 33..38 'b'\n'': u8
183 40..41 '1': u8
184 43..48 'b'\n'': u8
185 "#]],
186 );
187}
188
189#[test]
190fn infer_std_crash_3() {
191 // taken from rustc
192 check_infer(
193 r#"
194 pub fn compute() {
195 match nope!() {
196 SizeSkeleton::Pointer { non_zero: true, tail } => {}
197 }
198 }
199 "#,
200 expect![[r#"
201 17..107 '{ ... } }': ()
202 23..105 'match ... }': ()
203 29..36 'nope!()': {unknown}
204 47..93 'SizeSk...tail }': {unknown}
205 81..85 'true': bool
206 81..85 'true': bool
207 87..91 'tail': {unknown}
208 97..99 '{}': ()
209 "#]],
210 );
211}
212
213#[test]
214fn infer_std_crash_4() {
215 // taken from rustc
216 check_infer(
217 r#"
218 pub fn primitive_type() {
219 match *self {
220 BorrowedRef { type_: Primitive(p), ..} => {},
221 }
222 }
223 "#,
224 expect![[r#"
225 24..105 '{ ... } }': ()
226 30..103 'match ... }': ()
227 36..41 '*self': {unknown}
228 37..41 'self': {unknown}
229 52..90 'Borrow...), ..}': {unknown}
230 73..85 'Primitive(p)': {unknown}
231 83..84 'p': {unknown}
232 94..96 '{}': ()
233 "#]],
234 );
235}
236
237#[test]
238fn infer_std_crash_5() {
239 // taken from rustc
240 check_infer(
241 r#"
242 fn extra_compiler_flags() {
243 for content in doesnt_matter {
244 let name = if doesnt_matter {
245 first
246 } else {
247 &content
248 };
249
250 let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) {
251 name
252 } else {
253 content
254 };
255 }
256 }
257 "#,
258 expect![[r#"
259 26..322 '{ ... } }': ()
260 32..320 'for co... }': ()
261 36..43 'content': &{unknown}
262 47..60 'doesnt_matter': {unknown}
263 61..320 '{ ... }': ()
264 75..79 'name': &&{unknown}
265 82..166 'if doe... }': &&{unknown}
266 85..98 'doesnt_matter': bool
267 99..128 '{ ... }': &&{unknown}
268 113..118 'first': &&{unknown}
269 134..166 '{ ... }': &&{unknown}
270 148..156 '&content': &&{unknown}
271 149..156 'content': &{unknown}
272 181..188 'content': &{unknown}
273 191..313 'if ICE... }': &{unknown}
274 194..231 'ICE_RE..._VALUE': {unknown}
275 194..247 'ICE_RE...&name)': bool
276 241..246 '&name': &&&{unknown}
277 242..246 'name': &&{unknown}
278 248..276 '{ ... }': &&{unknown}
279 262..266 'name': &&{unknown}
280 282..313 '{ ... }': &{unknown}
281 296..303 'content': &{unknown}
282 "#]],
283 );
284}
285
286#[test]
287fn infer_nested_generics_crash() {
288 // another crash found typechecking rustc
289 check_infer(
290 r#"
291 struct Canonical<V> {
292 value: V,
293 }
294 struct QueryResponse<V> {
295 value: V,
296 }
297 fn test<R>(query_response: Canonical<QueryResponse<R>>) {
298 &query_response.value;
299 }
300 "#,
301 expect![[r#"
302 91..105 'query_response': Canonical<QueryResponse<R>>
303 136..166 '{ ...lue; }': ()
304 142..163 '&query....value': &QueryResponse<R>
305 143..157 'query_response': Canonical<QueryResponse<R>>
306 143..163 'query_....value': QueryResponse<R>
307 "#]],
308 );
309}
310
311#[test]
312fn infer_paren_macro_call() {
313 check_infer(
314 r#"
315 macro_rules! bar { () => {0u32} }
316 fn test() {
317 let a = (bar!());
318 }
319 "#,
320 expect![[r#"
321 !0..4 '0u32': u32
322 44..69 '{ ...()); }': ()
323 54..55 'a': u32
324 "#]],
325 );
326}
327
328#[test]
329fn bug_1030() {
330 check_infer(
331 r#"
332 struct HashSet<T, H>;
333 struct FxHasher;
334 type FxHashSet<T> = HashSet<T, FxHasher>;
335
336 impl<T, H> HashSet<T, H> {
337 fn default() -> HashSet<T, H> {}
338 }
339
340 pub fn main_loop() {
341 FxHashSet::default();
342 }
343 "#,
344 expect![[r#"
345 143..145 '{}': ()
346 168..197 '{ ...t(); }': ()
347 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher>
348 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher>
349 "#]],
350 );
351}
352
353#[test]
354fn issue_2669() {
355 check_infer(
356 r#"
357 trait A {}
358 trait Write {}
359 struct Response<T> {}
360
361 trait D {
362 fn foo();
363 }
364
365 impl<T:A> D for Response<T> {
366 fn foo() {
367 end();
368 fn end<W: Write>() {
369 let _x: T = loop {};
370 }
371 }
372 }
373 "#,
374 expect![[r#"
375 119..214 '{ ... }': ()
376 129..132 'end': fn end<{unknown}>()
377 129..134 'end()': ()
378 163..208 '{ ... }': ()
379 181..183 '_x': !
380 190..197 'loop {}': !
381 195..197 '{}': ()
382 "#]],
383 )
384}
385
386#[test]
387fn issue_2705() {
388 check_infer(
389 r#"
390 trait Trait {}
391 fn test() {
392 <Trait<u32>>::foo()
393 }
394 "#,
395 expect![[r#"
396 25..52 '{ ...oo() }': ()
397 31..48 '<Trait...>::foo': {unknown}
398 31..50 '<Trait...:foo()': ()
399 "#]],
400 );
401}
402
403#[test]
404fn issue_2683_chars_impl() {
405 check_types(
406 r#"
407//- /main.rs crate:main deps:std
408fn test() {
409 let chars: std::str::Chars<'_>;
410 (chars.next(), chars.nth(1));
411} //^ (Option<char>, Option<char>)
412
413//- /std.rs crate:std
414#[prelude_import]
415use prelude::*;
416
417pub mod prelude {
418 pub use crate::iter::Iterator;
419 pub use crate::option::Option;
420}
421
422pub mod iter {
423 pub use self::traits::Iterator;
424 pub mod traits {
425 pub use self::iterator::Iterator;
426
427 pub mod iterator {
428 pub trait Iterator {
429 type Item;
430 fn next(&mut self) -> Option<Self::Item>;
431 fn nth(&mut self, n: usize) -> Option<Self::Item> {}
432 }
433 }
434 }
435}
436
437pub mod option {
438 pub enum Option<T> {}
439}
440
441pub mod str {
442 pub struct Chars<'a> {}
443 impl<'a> Iterator for Chars<'a> {
444 type Item = char;
445 fn next(&mut self) -> Option<char> {}
446 }
447}
448"#,
449 );
450}
451
452#[test]
453fn issue_3642_bad_macro_stackover() {
454 check_types(
455 r#"
456#[macro_export]
457macro_rules! match_ast {
458 (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) };
459
460 (match ($node:expr) {
461 $( ast::$ast:ident($it:ident) => $res:expr, )*
462 _ => $catch_all:expr $(,)?
463 }) => {{
464 $( if let Some($it) = ast::$ast::cast($node.clone()) { $res } else )*
465 { $catch_all }
466 }};
467}
468
469fn main() {
470 let anchor = match_ast! {
471 //^ ()
472 match parent {
473 as => {},
474 _ => return None
475 }
476 };
477}"#,
478 );
479}
480
481#[test]
482fn issue_3999_slice() {
483 check_infer(
484 r#"
485 fn foo(params: &[usize]) {
486 match params {
487 [ps @ .., _] => {}
488 }
489 }
490 "#,
491 expect![[r#"
492 7..13 'params': &[usize]
493 25..80 '{ ... } }': ()
494 31..78 'match ... }': ()
495 37..43 'params': &[usize]
496 54..66 '[ps @ .., _]': [usize]
497 55..62 'ps @ ..': &[usize]
498 60..62 '..': [usize]
499 64..65 '_': usize
500 70..72 '{}': ()
501 "#]],
502 );
503}
504
505#[test]
506fn issue_3999_struct() {
507 // rust-analyzer should not panic on seeing this malformed
508 // record pattern.
509 check_infer(
510 r#"
511 struct Bar {
512 a: bool,
513 }
514 fn foo(b: Bar) {
515 match b {
516 Bar { a: .. } => {},
517 }
518 }
519 "#,
520 expect![[r#"
521 35..36 'b': Bar
522 43..95 '{ ... } }': ()
523 49..93 'match ... }': ()
524 55..56 'b': Bar
525 67..80 'Bar { a: .. }': Bar
526 76..78 '..': bool
527 84..86 '{}': ()
528 "#]],
529 );
530}
531
532#[test]
533fn issue_4235_name_conflicts() {
534 check_infer(
535 r#"
536 struct FOO {}
537 static FOO:FOO = FOO {};
538
539 impl FOO {
540 fn foo(&self) {}
541 }
542
543 fn main() {
544 let a = &FOO;
545 a.foo();
546 }
547 "#,
548 expect![[r#"
549 31..37 'FOO {}': FOO
550 63..67 'self': &FOO
551 69..71 '{}': ()
552 85..119 '{ ...o(); }': ()
553 95..96 'a': &FOO
554 99..103 '&FOO': &FOO
555 100..103 'FOO': FOO
556 109..110 'a': &FOO
557 109..116 'a.foo()': ()
558 "#]],
559 );
560}
561
562#[test]
563fn issue_4465_dollar_crate_at_type() {
564 check_infer(
565 r#"
566 pub struct Foo {}
567 pub fn anything<T>() -> T {
568 loop {}
569 }
570 macro_rules! foo {
571 () => {{
572 let r: $crate::Foo = anything();
573 r
574 }};
575 }
576 fn main() {
577 let _a = foo!();
578 }
579 "#,
580 expect![[r#"
581 44..59 '{ loop {} }': T
582 50..57 'loop {}': !
583 55..57 '{}': ()
584 !0..31 '{letr:...g();r}': Foo
585 !4..5 'r': Foo
586 !18..26 'anything': fn anything<Foo>() -> Foo
587 !18..28 'anything()': Foo
588 !29..30 'r': Foo
589 163..187 '{ ...!(); }': ()
590 173..175 '_a': Foo
591 "#]],
592 );
593}
594
595#[test]
596fn issue_4053_diesel_where_clauses() {
597 check_infer(
598 r#"
599 trait BoxedDsl<DB> {
600 type Output;
601 fn internal_into_boxed(self) -> Self::Output;
602 }
603
604 struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> {
605 order: Order,
606 }
607
608 trait QueryFragment<DB: Backend> {}
609
610 trait Into<T> { fn into(self) -> T; }
611
612 impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB>
613 for SelectStatement<F, S, D, W, O, LOf, G>
614 where
615 O: Into<dyn QueryFragment<DB>>,
616 {
617 type Output = XXX;
618
619 fn internal_into_boxed(self) -> Self::Output {
620 self.order.into();
621 }
622 }
623 "#,
624 expect![[r#"
625 65..69 'self': Self
626 267..271 'self': Self
627 466..470 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
628 488..522 '{ ... }': ()
629 498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
630 498..508 'self.order': O
631 498..515 'self.o...into()': dyn QueryFragment<DB>
632 "#]],
633 );
634}
635
636#[test]
637fn issue_4953() {
638 check_infer(
639 r#"
640 pub struct Foo(pub i64);
641 impl Foo {
642 fn test() -> Self { Self(0i64) }
643 }
644 "#,
645 expect![[r#"
646 58..72 '{ Self(0i64) }': Foo
647 60..64 'Self': Foo(i64) -> Foo
648 60..70 'Self(0i64)': Foo
649 65..69 '0i64': i64
650 "#]],
651 );
652 check_infer(
653 r#"
654 pub struct Foo<T>(pub T);
655 impl Foo<i64> {
656 fn test() -> Self { Self(0i64) }
657 }
658 "#,
659 expect![[r#"
660 64..78 '{ Self(0i64) }': Foo<i64>
661 66..70 'Self': Foo<i64>(i64) -> Foo<i64>
662 66..76 'Self(0i64)': Foo<i64>
663 71..75 '0i64': i64
664 "#]],
665 );
666}
667
668#[test]
669fn issue_4931() {
670 check_infer(
671 r#"
672 trait Div<T> {
673 type Output;
674 }
675
676 trait CheckedDiv: Div<()> {}
677
678 trait PrimInt: CheckedDiv<Output = ()> {
679 fn pow(self);
680 }
681
682 fn check<T: PrimInt>(i: T) {
683 i.pow();
684 }
685 "#,
686 expect![[r#"
687 117..121 'self': Self
688 148..149 'i': T
689 154..170 '{ ...w(); }': ()
690 160..161 'i': T
691 160..167 'i.pow()': ()
692 "#]],
693 );
694}
695
696#[test]
697fn issue_4885() {
698 check_infer(
699 r#"
700 #[lang = "coerce_unsized"]
701 pub trait CoerceUnsized<T> {}
702
703 trait Future {
704 type Output;
705 }
706 trait Foo<R> {
707 type Bar;
708 }
709 fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar>
710 where
711 K: Foo<R>,
712 {
713 bar(key)
714 }
715 fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar>
716 where
717 K: Foo<R>,
718 {
719 }
720 "#,
721 expect![[r#"
722 136..139 'key': &K
723 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
724 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
725 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
726 208..211 'key': &K
727 228..231 'key': &K
728 290..293 '{ }': ()
729 "#]],
730 );
731}
732
733#[test]
734fn issue_4800() {
735 check_infer(
736 r#"
737 trait Debug {}
738
739 struct Foo<T>;
740
741 type E1<T> = (T, T, T);
742 type E2<T> = E1<E1<E1<(T, T, T)>>>;
743
744 impl Debug for Foo<E2<()>> {}
745
746 struct Request;
747
748 pub trait Future {
749 type Output;
750 }
751
752 pub struct PeerSet<D>;
753
754 impl<D> Service<Request> for PeerSet<D>
755 where
756 D: Discover,
757 D::Key: Debug,
758 {
759 type Error = ();
760 type Future = dyn Future<Output = Self::Error>;
761
762 fn call(&mut self) -> Self::Future {
763 loop {}
764 }
765 }
766
767 pub trait Discover {
768 type Key;
769 }
770
771 pub trait Service<Request> {
772 type Error;
773 type Future: Future<Output = Self::Error>;
774 fn call(&mut self) -> Self::Future;
775 }
776 "#,
777 expect![[r#"
778 379..383 'self': &mut PeerSet<D>
779 401..424 '{ ... }': dyn Future<Output = ()>
780 411..418 'loop {}': !
781 416..418 '{}': ()
782 575..579 'self': &mut Self
783 "#]],
784 );
785}
786
787#[test]
788fn issue_4966() {
789 check_infer(
790 r#"
791 pub trait IntoIterator {
792 type Item;
793 }
794
795 struct Repeat<A> { element: A }
796
797 struct Map<F> { f: F }
798
799 struct Vec<T> {}
800
801 #[lang = "deref"]
802 pub trait Deref {
803 type Target;
804 }
805
806 impl<T> Deref for Vec<T> {
807 type Target = [T];
808 }
809
810 fn from_iter<A, T: IntoIterator<Item = A>>(iter: T) -> Vec<A> {}
811
812 fn main() {
813 let inner = Map { f: |_: &f64| 0.0 };
814
815 let repeat = Repeat { element: inner };
816
817 let vec = from_iter(repeat);
818
819 vec.foo_bar();
820 }
821 "#,
822 expect![[r#"
823 270..274 'iter': T
824 289..291 '{}': ()
825 303..447 '{ ...r(); }': ()
826 313..318 'inner': Map<|&f64| -> f64>
827 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64>
828 330..343 '|_: &f64| 0.0': |&f64| -> f64
829 331..332 '_': &f64
830 340..343 '0.0': f64
831 356..362 'repeat': Repeat<Map<|&f64| -> f64>>
832 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
833 383..388 'inner': Map<|&f64| -> f64>
834 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
835 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
836 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
837 417..423 'repeat': Repeat<Map<|&f64| -> f64>>
838 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
839 431..444 'vec.foo_bar()': {unknown}
840 "#]],
841 );
842}