]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/regression.rs
Merge #5733
[rust.git] / crates / hir_ty / src / tests / regression.rs
1 use expect_test::expect;
2 use test_utils::mark;
3
4 use super::{check_infer, check_types};
5
6 #[test]
7 fn 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]
25 fn 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]
44 fn 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]
69 fn 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]
89 fn 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]
112 fn 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]
141 fn 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]
168 fn 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]
190 fn 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]
214 fn 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]
238 fn 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]
287 fn 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]
312 fn 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]
329 fn 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]
354 fn 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]
387 fn 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]
404 fn issue_2683_chars_impl() {
405     check_types(
406         r#"
407 //- /main.rs crate:main deps:std
408 fn 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]
415 use prelude::*;
416
417 pub mod prelude {
418     pub use crate::iter::Iterator;
419     pub use crate::option::Option;
420 }
421
422 pub 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
437 pub mod option {
438     pub enum Option<T> {}
439 }
440
441 pub 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]
453 fn issue_3642_bad_macro_stackover() {
454     check_types(
455         r#"
456 #[macro_export]
457 macro_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
469 fn main() {
470     let anchor = match_ast! {
471        //^ ()
472         match parent {
473             as => {},
474             _ => return None
475         }
476     };
477 }"#,
478     );
479 }
480
481 #[test]
482 fn 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]
506 fn 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]
533 fn 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]
563 fn 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]
596 fn 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]
637 fn 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]
669 fn 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]
697 fn 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]
734 fn 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]
788 fn 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 }