aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/tests.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/tests.rs')
-rw-r--r--crates/ra_hir_ty/src/tests.rs146
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};
11use hir_expand::Source; 11use hir_expand::InFile;
12use insta::assert_snapshot; 12use insta::assert_snapshot;
13use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; 13use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase};
14use ra_syntax::{ 14use ra_syntax::{
@@ -222,6 +222,56 @@ mod collections {
222} 222}
223 223
224#[test] 224#[test]
225fn infer_ranges() {
226 let (db, pos) = TestDB::with_position(
227 r#"
228//- /main.rs crate:main deps:std
229fn 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::*;
243mod prelude {}
244
245pub 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]
225fn infer_while_let() { 275fn 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
2108fn recursive_type_alias() { 2157fn recursive_type_alias() {
2109 assert_snapshot!( 2158 assert_snapshot!(
2110 infer(r#" 2159 infer(r#"
@@ -2113,7 +2162,10 @@ type Foo = Foo;
2113type Bar = A<Bar>; 2162type Bar = A<Bar>;
2114fn test(x: Foo) {} 2163fn 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]
3697fn not_shadowing_primitive_by_module() {
3698 let t = type_at(
3699 r#"
3700//- /str.rs
3701fn foo() {}
3702
3703//- /main.rs
3704mod str;
3705fn foo() -> &'static str { "" }
3706
3707fn main() {
3708 foo()<|>;
3709}"#,
3710 );
3711 assert_eq!(t, "&str");
3712}
3713
3714#[test]
3715fn not_shadowing_module_by_primitive() {
3716 let t = type_at(
3717 r#"
3718//- /str.rs
3719fn foo() -> u32 {0}
3720
3721//- /main.rs
3722mod str;
3723fn foo() -> &'static str { "" }
3724
3725fn main() {
3726 str::foo()<|>;
3727}"#,
3728 );
3729 assert_eq!(t, "u32");
3730}
3731
3732#[test]
3645fn deref_trait() { 3733fn 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 4717fn 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
4721trait Trait<T> {
4722 fn foo(&self);
4723}
4724
4725struct S;
4726
4727impl Trait<Self> for S {}
4728
4729fn test() {
4730 S.foo()<|>;
4731}
4732"#,
4733 );
4734 assert_eq!(t, "()");
4735}
4736
4737#[test]
4738fn trait_impl_self_ty_cycle() {
4739 let t = type_at(
4740 r#"
4741//- /main.rs
4742trait Trait {
4743 fn foo(&self);
4744}
4745
4746struct S<T>;
4747
4748impl Trait for S<Self> {}
4749
4750fn test() {
4751 S.foo()<|>;
4752}
4753"#,
4754 );
4755 assert_eq!(t, "{unknown}");
4756}
4757
4758#[test]
4633fn unselected_projection_in_trait_env_cycle_1() { 4759fn 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]
4657fn unselected_projection_in_trait_env_cycle_2() { 4779fn 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();