diff options
Diffstat (limited to 'crates/ra_hir_ty/src/tests.rs')
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 146 |
1 files changed, 134 insertions, 12 deletions
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index c8461b447..a3cc5cf95 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs | |||
@@ -8,7 +8,7 @@ use hir_def::{ | |||
8 | body::BodySourceMap, db::DefDatabase, nameres::CrateDefMap, AssocItemId, DefWithBodyId, | 8 | body::BodySourceMap, db::DefDatabase, nameres::CrateDefMap, AssocItemId, DefWithBodyId, |
9 | LocalModuleId, Lookup, ModuleDefId, | 9 | LocalModuleId, Lookup, ModuleDefId, |
10 | }; | 10 | }; |
11 | use hir_expand::Source; | 11 | use hir_expand::InFile; |
12 | use insta::assert_snapshot; | 12 | use insta::assert_snapshot; |
13 | use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; | 13 | use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; |
14 | use ra_syntax::{ | 14 | use ra_syntax::{ |
@@ -222,6 +222,56 @@ mod collections { | |||
222 | } | 222 | } |
223 | 223 | ||
224 | #[test] | 224 | #[test] |
225 | fn infer_ranges() { | ||
226 | let (db, pos) = TestDB::with_position( | ||
227 | r#" | ||
228 | //- /main.rs crate:main deps:std | ||
229 | fn test() { | ||
230 | let a = ..; | ||
231 | let b = 1..; | ||
232 | let c = ..2u32; | ||
233 | let d = 1..2usize; | ||
234 | let e = ..=10; | ||
235 | let f = 'a'..='z'; | ||
236 | |||
237 | let t = (a, b, c, d, e, f); | ||
238 | t<|>; | ||
239 | } | ||
240 | |||
241 | //- /std.rs crate:std | ||
242 | #[prelude_import] use prelude::*; | ||
243 | mod prelude {} | ||
244 | |||
245 | pub mod ops { | ||
246 | pub struct Range<Idx> { | ||
247 | pub start: Idx, | ||
248 | pub end: Idx, | ||
249 | } | ||
250 | pub struct RangeFrom<Idx> { | ||
251 | pub start: Idx, | ||
252 | } | ||
253 | struct RangeFull; | ||
254 | pub struct RangeInclusive<Idx> { | ||
255 | start: Idx, | ||
256 | end: Idx, | ||
257 | is_empty: u8, | ||
258 | } | ||
259 | pub struct RangeTo<Idx> { | ||
260 | pub end: Idx, | ||
261 | } | ||
262 | pub struct RangeToInclusive<Idx> { | ||
263 | pub end: Idx, | ||
264 | } | ||
265 | } | ||
266 | "#, | ||
267 | ); | ||
268 | assert_eq!( | ||
269 | "(RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)", | ||
270 | type_at_pos(&db, pos), | ||
271 | ); | ||
272 | } | ||
273 | |||
274 | #[test] | ||
225 | fn infer_while_let() { | 275 | fn infer_while_let() { |
226 | let (db, pos) = TestDB::with_position( | 276 | let (db, pos) = TestDB::with_position( |
227 | r#" | 277 | r#" |
@@ -2104,7 +2154,6 @@ fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) { | |||
2104 | } | 2154 | } |
2105 | 2155 | ||
2106 | #[test] | 2156 | #[test] |
2107 | #[should_panic] // we currently can't handle this | ||
2108 | fn recursive_type_alias() { | 2157 | fn recursive_type_alias() { |
2109 | assert_snapshot!( | 2158 | assert_snapshot!( |
2110 | infer(r#" | 2159 | infer(r#" |
@@ -2113,7 +2162,10 @@ type Foo = Foo; | |||
2113 | type Bar = A<Bar>; | 2162 | type Bar = A<Bar>; |
2114 | fn test(x: Foo) {} | 2163 | fn test(x: Foo) {} |
2115 | "#), | 2164 | "#), |
2116 | @"" | 2165 | @r###" |
2166 | [59; 60) 'x': {unknown} | ||
2167 | [67; 69) '{}': () | ||
2168 | "### | ||
2117 | ) | 2169 | ) |
2118 | } | 2170 | } |
2119 | 2171 | ||
@@ -3642,6 +3694,42 @@ fn main() { | |||
3642 | } | 3694 | } |
3643 | 3695 | ||
3644 | #[test] | 3696 | #[test] |
3697 | fn not_shadowing_primitive_by_module() { | ||
3698 | let t = type_at( | ||
3699 | r#" | ||
3700 | //- /str.rs | ||
3701 | fn foo() {} | ||
3702 | |||
3703 | //- /main.rs | ||
3704 | mod str; | ||
3705 | fn foo() -> &'static str { "" } | ||
3706 | |||
3707 | fn main() { | ||
3708 | foo()<|>; | ||
3709 | }"#, | ||
3710 | ); | ||
3711 | assert_eq!(t, "&str"); | ||
3712 | } | ||
3713 | |||
3714 | #[test] | ||
3715 | fn not_shadowing_module_by_primitive() { | ||
3716 | let t = type_at( | ||
3717 | r#" | ||
3718 | //- /str.rs | ||
3719 | fn foo() -> u32 {0} | ||
3720 | |||
3721 | //- /main.rs | ||
3722 | mod str; | ||
3723 | fn foo() -> &'static str { "" } | ||
3724 | |||
3725 | fn main() { | ||
3726 | str::foo()<|>; | ||
3727 | }"#, | ||
3728 | ); | ||
3729 | assert_eq!(t, "u32"); | ||
3730 | } | ||
3731 | |||
3732 | #[test] | ||
3645 | fn deref_trait() { | 3733 | fn deref_trait() { |
3646 | let t = type_at( | 3734 | let t = type_at( |
3647 | r#" | 3735 | r#" |
@@ -4626,10 +4714,48 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> { | |||
4626 | } | 4714 | } |
4627 | 4715 | ||
4628 | #[test] | 4716 | #[test] |
4629 | // FIXME this is currently a Salsa panic; it would be nicer if it just returned | 4717 | fn trait_impl_self_ty() { |
4630 | // in Unknown, and we should be able to do that once Salsa allows us to handle | 4718 | let t = type_at( |
4631 | // the cycle. But at least it doesn't overflow for now. | 4719 | r#" |
4632 | #[should_panic] | 4720 | //- /main.rs |
4721 | trait Trait<T> { | ||
4722 | fn foo(&self); | ||
4723 | } | ||
4724 | |||
4725 | struct S; | ||
4726 | |||
4727 | impl Trait<Self> for S {} | ||
4728 | |||
4729 | fn test() { | ||
4730 | S.foo()<|>; | ||
4731 | } | ||
4732 | "#, | ||
4733 | ); | ||
4734 | assert_eq!(t, "()"); | ||
4735 | } | ||
4736 | |||
4737 | #[test] | ||
4738 | fn trait_impl_self_ty_cycle() { | ||
4739 | let t = type_at( | ||
4740 | r#" | ||
4741 | //- /main.rs | ||
4742 | trait Trait { | ||
4743 | fn foo(&self); | ||
4744 | } | ||
4745 | |||
4746 | struct S<T>; | ||
4747 | |||
4748 | impl Trait for S<Self> {} | ||
4749 | |||
4750 | fn test() { | ||
4751 | S.foo()<|>; | ||
4752 | } | ||
4753 | "#, | ||
4754 | ); | ||
4755 | assert_eq!(t, "{unknown}"); | ||
4756 | } | ||
4757 | |||
4758 | #[test] | ||
4633 | fn unselected_projection_in_trait_env_cycle_1() { | 4759 | fn unselected_projection_in_trait_env_cycle_1() { |
4634 | let t = type_at( | 4760 | let t = type_at( |
4635 | r#" | 4761 | r#" |
@@ -4650,10 +4776,6 @@ fn test<T: Trait>() where T: Trait2<T::Item> { | |||
4650 | } | 4776 | } |
4651 | 4777 | ||
4652 | #[test] | 4778 | #[test] |
4653 | // FIXME this is currently a Salsa panic; it would be nicer if it just returned | ||
4654 | // in Unknown, and we should be able to do that once Salsa allows us to handle | ||
4655 | // the cycle. But at least it doesn't overflow for now. | ||
4656 | #[should_panic] | ||
4657 | fn unselected_projection_in_trait_env_cycle_2() { | 4779 | fn unselected_projection_in_trait_env_cycle_2() { |
4658 | let t = type_at( | 4780 | let t = type_at( |
4659 | r#" | 4781 | r#" |
@@ -4680,7 +4802,7 @@ fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { | |||
4680 | for decl in crate_def_map[module.local_id].scope.declarations() { | 4802 | for decl in crate_def_map[module.local_id].scope.declarations() { |
4681 | if let ModuleDefId::FunctionId(func) = decl { | 4803 | if let ModuleDefId::FunctionId(func) = decl { |
4682 | let (_body, source_map) = db.body_with_source_map(func.into()); | 4804 | let (_body, source_map) = db.body_with_source_map(func.into()); |
4683 | if let Some(expr_id) = source_map.node_expr(Source::new(pos.file_id.into(), &expr)) { | 4805 | if let Some(expr_id) = source_map.node_expr(InFile::new(pos.file_id.into(), &expr)) { |
4684 | let infer = db.infer(func.into()); | 4806 | let infer = db.infer(func.into()); |
4685 | let ty = &infer[expr_id]; | 4807 | let ty = &infer[expr_id]; |
4686 | return ty.display(db).to_string(); | 4808 | return ty.display(db).to_string(); |