diff options
Diffstat (limited to 'crates/hir_ty/src/tests')
-rw-r--r-- | crates/hir_ty/src/tests/macros.rs | 23 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/method_resolution.rs | 67 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/simple.rs | 155 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 60 |
4 files changed, 291 insertions, 14 deletions
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs index c64f0b5b5..fb3afaedc 100644 --- a/crates/hir_ty/src/tests/macros.rs +++ b/crates/hir_ty/src/tests/macros.rs | |||
@@ -1,7 +1,5 @@ | |||
1 | use std::fs; | ||
2 | |||
3 | use expect_test::expect; | 1 | use expect_test::expect; |
4 | use test_utils::project_dir; | 2 | use test_utils::{bench, bench_fixture, skip_slow_tests}; |
5 | 3 | ||
6 | use super::{check_infer, check_types}; | 4 | use super::{check_infer, check_types}; |
7 | 5 | ||
@@ -617,12 +615,11 @@ hello | |||
617 | } | 615 | } |
618 | 616 | ||
619 | #[test] | 617 | #[test] |
620 | #[ignore] | 618 | fn benchmark_include_macro() { |
621 | fn include_accidentally_quadratic() { | 619 | if skip_slow_tests() { |
622 | let file = project_dir().join("crates/syntax/test_data/accidentally_quadratic"); | 620 | return; |
623 | let big_file = fs::read_to_string(file).unwrap(); | 621 | } |
624 | let big_file = vec![big_file; 10].join("\n"); | 622 | let data = bench_fixture::big_struct(); |
625 | |||
626 | let fixture = r#" | 623 | let fixture = r#" |
627 | //- /main.rs | 624 | //- /main.rs |
628 | #[rustc_builtin_macro] | 625 | #[rustc_builtin_macro] |
@@ -635,8 +632,12 @@ fn main() { | |||
635 | //^ RegisterBlock | 632 | //^ RegisterBlock |
636 | } | 633 | } |
637 | "#; | 634 | "#; |
638 | let fixture = format!("{}\n//- /foo.rs\n{}", fixture, big_file); | 635 | let fixture = format!("{}\n//- /foo.rs\n{}", fixture, data); |
639 | check_types(&fixture); | 636 | |
637 | { | ||
638 | let _b = bench("include macro"); | ||
639 | check_types(&fixture); | ||
640 | } | ||
640 | } | 641 | } |
641 | 642 | ||
642 | #[test] | 643 | #[test] |
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs index a6a54e542..a9901d7b8 100644 --- a/crates/hir_ty/src/tests/method_resolution.rs +++ b/crates/hir_ty/src/tests/method_resolution.rs | |||
@@ -956,6 +956,51 @@ fn test() { foo.call(); } | |||
956 | } | 956 | } |
957 | 957 | ||
958 | #[test] | 958 | #[test] |
959 | fn super_trait_impl_return_trait_method_resolution() { | ||
960 | check_infer( | ||
961 | r#" | ||
962 | trait Base { | ||
963 | fn foo(self) -> usize; | ||
964 | } | ||
965 | |||
966 | trait Super : Base {} | ||
967 | |||
968 | fn base1() -> impl Base { loop {} } | ||
969 | fn super1() -> impl Super { loop {} } | ||
970 | |||
971 | fn test(base2: impl Base, super2: impl Super) { | ||
972 | base1().foo(); | ||
973 | super1().foo(); | ||
974 | base2.foo(); | ||
975 | super2.foo(); | ||
976 | } | ||
977 | "#, | ||
978 | expect![[r#" | ||
979 | 24..28 'self': Self | ||
980 | 90..101 '{ loop {} }': ! | ||
981 | 92..99 'loop {}': ! | ||
982 | 97..99 '{}': () | ||
983 | 128..139 '{ loop {} }': ! | ||
984 | 130..137 'loop {}': ! | ||
985 | 135..137 '{}': () | ||
986 | 149..154 'base2': impl Base | ||
987 | 167..173 'super2': impl Super | ||
988 | 187..264 '{ ...o(); }': () | ||
989 | 193..198 'base1': fn base1() -> impl Base | ||
990 | 193..200 'base1()': impl Base | ||
991 | 193..206 'base1().foo()': usize | ||
992 | 212..218 'super1': fn super1() -> impl Super | ||
993 | 212..220 'super1()': impl Super | ||
994 | 212..226 'super1().foo()': usize | ||
995 | 232..237 'base2': impl Base | ||
996 | 232..243 'base2.foo()': usize | ||
997 | 249..255 'super2': impl Super | ||
998 | 249..261 'super2.foo()': usize | ||
999 | "#]], | ||
1000 | ); | ||
1001 | } | ||
1002 | |||
1003 | #[test] | ||
959 | fn method_resolution_non_parameter_type() { | 1004 | fn method_resolution_non_parameter_type() { |
960 | check_types( | 1005 | check_types( |
961 | r#" | 1006 | r#" |
@@ -1106,3 +1151,25 @@ fn main() { | |||
1106 | "#, | 1151 | "#, |
1107 | ); | 1152 | ); |
1108 | } | 1153 | } |
1154 | |||
1155 | #[test] | ||
1156 | fn method_on_dyn_impl() { | ||
1157 | check_types( | ||
1158 | r#" | ||
1159 | trait Foo {} | ||
1160 | |||
1161 | impl Foo for u32 {} | ||
1162 | impl dyn Foo + '_ { | ||
1163 | pub fn dyn_foo(&self) -> u32 { | ||
1164 | 0 | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | fn main() { | ||
1169 | let f = &42u32 as &dyn Foo; | ||
1170 | f.dyn_foo(); | ||
1171 | // ^u32 | ||
1172 | } | ||
1173 | "#, | ||
1174 | ); | ||
1175 | } | ||
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 8d431b920..2947857a5 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs | |||
@@ -29,6 +29,30 @@ mod boxed { | |||
29 | } | 29 | } |
30 | 30 | ||
31 | #[test] | 31 | #[test] |
32 | fn infer_box_with_allocator() { | ||
33 | check_types( | ||
34 | r#" | ||
35 | //- /main.rs crate:main deps:std | ||
36 | fn test() { | ||
37 | let x = box 1; | ||
38 | let t = (x, box x, box &1, box [1]); | ||
39 | t; | ||
40 | } //^ (Box<i32, {unknown}>, Box<Box<i32, {unknown}>, {unknown}>, Box<&i32, {unknown}>, Box<[i32; _], {unknown}>) | ||
41 | |||
42 | //- /std.rs crate:std | ||
43 | #[prelude_import] use prelude::*; | ||
44 | mod boxed { | ||
45 | #[lang = "owned_box"] | ||
46 | pub struct Box<T: ?Sized, A: Allocator> { | ||
47 | inner: *mut T, | ||
48 | allocator: A, | ||
49 | } | ||
50 | } | ||
51 | "#, | ||
52 | ); | ||
53 | } | ||
54 | |||
55 | #[test] | ||
32 | fn infer_adt_self() { | 56 | fn infer_adt_self() { |
33 | check_types( | 57 | check_types( |
34 | r#" | 58 | r#" |
@@ -2391,3 +2415,134 @@ fn infer_const_params() { | |||
2391 | "#]], | 2415 | "#]], |
2392 | ); | 2416 | ); |
2393 | } | 2417 | } |
2418 | |||
2419 | #[test] | ||
2420 | fn infer_inner_type() { | ||
2421 | check_infer( | ||
2422 | r#" | ||
2423 | fn foo() { | ||
2424 | struct S { field: u32 } | ||
2425 | let s = S { field: 0 }; | ||
2426 | let f = s.field; | ||
2427 | } | ||
2428 | "#, | ||
2429 | expect![[r#" | ||
2430 | 9..89 '{ ...eld; }': () | ||
2431 | 47..48 's': S | ||
2432 | 51..65 'S { field: 0 }': S | ||
2433 | 62..63 '0': u32 | ||
2434 | 75..76 'f': u32 | ||
2435 | 79..80 's': S | ||
2436 | 79..86 's.field': u32 | ||
2437 | "#]], | ||
2438 | ); | ||
2439 | } | ||
2440 | |||
2441 | #[test] | ||
2442 | fn infer_nested_inner_type() { | ||
2443 | check_infer( | ||
2444 | r#" | ||
2445 | fn foo() { | ||
2446 | { | ||
2447 | let s = S { field: 0 }; | ||
2448 | let f = s.field; | ||
2449 | } | ||
2450 | struct S { field: u32 } | ||
2451 | } | ||
2452 | "#, | ||
2453 | expect![[r#" | ||
2454 | 9..109 '{ ...32 } }': () | ||
2455 | 15..79 '{ ... }': () | ||
2456 | 29..30 's': S | ||
2457 | 33..47 'S { field: 0 }': S | ||
2458 | 44..45 '0': u32 | ||
2459 | 61..62 'f': u32 | ||
2460 | 65..66 's': S | ||
2461 | 65..72 's.field': u32 | ||
2462 | "#]], | ||
2463 | ); | ||
2464 | } | ||
2465 | |||
2466 | #[test] | ||
2467 | fn inner_use_enum_rename() { | ||
2468 | check_infer( | ||
2469 | r#" | ||
2470 | enum Request { | ||
2471 | Info | ||
2472 | } | ||
2473 | |||
2474 | fn f() { | ||
2475 | use Request as R; | ||
2476 | |||
2477 | let r = R::Info; | ||
2478 | match r { | ||
2479 | R::Info => {} | ||
2480 | } | ||
2481 | } | ||
2482 | "#, | ||
2483 | expect![[r#" | ||
2484 | 34..123 '{ ... } }': () | ||
2485 | 67..68 'r': Request | ||
2486 | 71..78 'R::Info': Request | ||
2487 | 84..121 'match ... }': () | ||
2488 | 90..91 'r': Request | ||
2489 | 102..109 'R::Info': Request | ||
2490 | 113..115 '{}': () | ||
2491 | "#]], | ||
2492 | ) | ||
2493 | } | ||
2494 | |||
2495 | #[test] | ||
2496 | fn box_into_vec() { | ||
2497 | check_infer( | ||
2498 | r#" | ||
2499 | #[lang = "sized"] | ||
2500 | pub trait Sized {} | ||
2501 | |||
2502 | #[lang = "unsize"] | ||
2503 | pub trait Unsize<T: ?Sized> {} | ||
2504 | |||
2505 | #[lang = "coerce_unsized"] | ||
2506 | pub trait CoerceUnsized<T> {} | ||
2507 | |||
2508 | pub unsafe trait Allocator {} | ||
2509 | |||
2510 | pub struct Global; | ||
2511 | unsafe impl Allocator for Global {} | ||
2512 | |||
2513 | #[lang = "owned_box"] | ||
2514 | #[fundamental] | ||
2515 | pub struct Box<T: ?Sized, A: Allocator = Global>; | ||
2516 | |||
2517 | impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {} | ||
2518 | |||
2519 | pub struct Vec<T, A: Allocator = Global> {} | ||
2520 | |||
2521 | #[lang = "slice"] | ||
2522 | impl<T> [T] {} | ||
2523 | |||
2524 | #[lang = "slice_alloc"] | ||
2525 | impl<T> [T] { | ||
2526 | pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> { | ||
2527 | unimplemented!() | ||
2528 | } | ||
2529 | } | ||
2530 | |||
2531 | fn test() { | ||
2532 | let vec = <[_]>::into_vec(box [1i32]); | ||
2533 | } | ||
2534 | "#, | ||
2535 | expect![[r#" | ||
2536 | 569..573 'self': Box<[T], A> | ||
2537 | 602..634 '{ ... }': Vec<T, A> | ||
2538 | 612..628 'unimpl...ted!()': Vec<T, A> | ||
2539 | 648..694 '{ ...2]); }': () | ||
2540 | 658..661 'vec': Vec<i32, Global> | ||
2541 | 664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global> | ||
2542 | 664..691 '<[_]>:...1i32])': Vec<i32, Global> | ||
2543 | 680..690 'box [1i32]': Box<[i32; _], Global> | ||
2544 | 684..690 '[1i32]': [i32; _] | ||
2545 | 685..689 '1i32': i32 | ||
2546 | "#]], | ||
2547 | ) | ||
2548 | } | ||
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index e5a3f95a6..1298e5a88 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs | |||
@@ -1409,10 +1409,10 @@ fn weird_bounds() { | |||
1409 | fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} | 1409 | fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} |
1410 | "#, | 1410 | "#, |
1411 | expect![[r#" | 1411 | expect![[r#" |
1412 | 23..24 'a': impl Trait + {error} | 1412 | 23..24 'a': impl Trait |
1413 | 50..51 'b': impl {error} | 1413 | 50..51 'b': impl |
1414 | 69..70 'c': impl Trait | 1414 | 69..70 'c': impl Trait |
1415 | 86..87 'd': impl {error} | 1415 | 86..87 'd': impl |
1416 | 107..108 'e': impl {error} | 1416 | 107..108 'e': impl {error} |
1417 | 123..124 'f': impl Trait + {error} | 1417 | 123..124 'f': impl Trait + {error} |
1418 | 147..149 '{}': () | 1418 | 147..149 '{}': () |
@@ -3151,3 +3151,57 @@ fn test() { | |||
3151 | "#, | 3151 | "#, |
3152 | ); | 3152 | ); |
3153 | } | 3153 | } |
3154 | |||
3155 | #[test] | ||
3156 | fn inner_use() { | ||
3157 | check_types( | ||
3158 | r#" | ||
3159 | mod m { | ||
3160 | pub trait Tr { | ||
3161 | fn method(&self) -> u8 { 0 } | ||
3162 | } | ||
3163 | |||
3164 | impl Tr for () {} | ||
3165 | } | ||
3166 | |||
3167 | fn f() { | ||
3168 | use m::Tr; | ||
3169 | |||
3170 | ().method(); | ||
3171 | //^^^^^^^^^^^ u8 | ||
3172 | } | ||
3173 | "#, | ||
3174 | ); | ||
3175 | } | ||
3176 | |||
3177 | #[test] | ||
3178 | fn inner_use_in_block() { | ||
3179 | check_types( | ||
3180 | r#" | ||
3181 | mod m { | ||
3182 | pub trait Tr { | ||
3183 | fn method(&self) -> u8 { 0 } | ||
3184 | } | ||
3185 | |||
3186 | impl Tr for () {} | ||
3187 | } | ||
3188 | |||
3189 | fn f() { | ||
3190 | { | ||
3191 | use m::Tr; | ||
3192 | |||
3193 | ().method(); | ||
3194 | //^^^^^^^^^^^ u8 | ||
3195 | } | ||
3196 | |||
3197 | { | ||
3198 | ().method(); | ||
3199 | //^^^^^^^^^^^ {unknown} | ||
3200 | } | ||
3201 | |||
3202 | ().method(); | ||
3203 | //^^^^^^^^^^^ {unknown} | ||
3204 | } | ||
3205 | "#, | ||
3206 | ); | ||
3207 | } | ||