aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/tests.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/tests.rs')
-rw-r--r--crates/ra_hir/src/ty/tests.rs124
1 files changed, 116 insertions, 8 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index d344ab12e..d92d4659b 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -2793,6 +2793,10 @@ fn main() {
2793} 2793}
2794"#), 2794"#),
2795 @r###" 2795 @r###"
2796 ![0; 17) '{Foo(v...,2,])}': Foo
2797 ![1; 4) 'Foo': Foo({unknown}) -> Foo
2798 ![1; 16) 'Foo(vec![1,2,])': Foo
2799 ![5; 15) 'vec![1,2,]': {unknown}
2796 [156; 182) '{ ...,2); }': () 2800 [156; 182) '{ ...,2); }': ()
2797 [166; 167) 'x': Foo 2801 [166; 167) 'x': Foo
2798 "### 2802 "###
@@ -3548,6 +3552,97 @@ fn test() {
3548 ); 3552 );
3549} 3553}
3550 3554
3555#[test]
3556fn assoc_type_bindings() {
3557 assert_snapshot!(
3558 infer(r#"
3559trait Trait {
3560 type Type;
3561}
3562
3563fn get<T: Trait>(t: T) -> <T as Trait>::Type {}
3564fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
3565fn set<T: Trait<Type = u64>>(t: T) -> T {t}
3566
3567struct S<T>;
3568impl<T> Trait for S<T> { type Type = T; }
3569
3570fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
3571 get(x);
3572 get2(x);
3573 get(y);
3574 get2(y);
3575 get(set(S));
3576 get2(set(S));
3577 get2(S::<str>);
3578}
3579"#),
3580 @r###"
3581 [50; 51) 't': T
3582 [78; 80) '{}': ()
3583 [112; 113) 't': T
3584 [123; 125) '{}': ()
3585 [155; 156) 't': T
3586 [166; 169) '{t}': T
3587 [167; 168) 't': T
3588 [257; 258) 'x': T
3589 [263; 264) 'y': impl Trait<Type = i64>
3590 [290; 398) '{ ...r>); }': ()
3591 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type
3592 [296; 302) 'get(x)': {unknown}
3593 [300; 301) 'x': T
3594 [308; 312) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U
3595 [308; 315) 'get2(x)': {unknown}
3596 [313; 314) 'x': T
3597 [321; 324) 'get': fn get<impl Trait<Type = i64>>(T) -> <T as Trait>::Type
3598 [321; 327) 'get(y)': {unknown}
3599 [325; 326) 'y': impl Trait<Type = i64>
3600 [333; 337) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U
3601 [333; 340) 'get2(y)': {unknown}
3602 [338; 339) 'y': impl Trait<Type = i64>
3603 [346; 349) 'get': fn get<S<u64>>(T) -> <T as Trait>::Type
3604 [346; 357) 'get(set(S))': u64
3605 [350; 353) 'set': fn set<S<u64>>(T) -> T
3606 [350; 356) 'set(S)': S<u64>
3607 [354; 355) 'S': S<u64>
3608 [363; 367) 'get2': fn get2<u64, S<u64>>(T) -> U
3609 [363; 375) 'get2(set(S))': u64
3610 [368; 371) 'set': fn set<S<u64>>(T) -> T
3611 [368; 374) 'set(S)': S<u64>
3612 [372; 373) 'S': S<u64>
3613 [381; 385) 'get2': fn get2<str, S<str>>(T) -> U
3614 [381; 395) 'get2(S::<str>)': str
3615 [386; 394) 'S::<str>': S<str>
3616 "###
3617 );
3618}
3619
3620#[test]
3621fn projection_eq_within_chalk() {
3622 // std::env::set_var("CHALK_DEBUG", "1");
3623 assert_snapshot!(
3624 infer(r#"
3625trait Trait1 {
3626 type Type;
3627}
3628trait Trait2<T> {
3629 fn foo(self) -> T;
3630}
3631impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
3632
3633fn test<T: Trait1<Type = u32>>(x: T) {
3634 x.foo();
3635}
3636"#),
3637 @r###"
3638 [62; 66) 'self': Self
3639 [164; 165) 'x': T
3640 [170; 186) '{ ...o(); }': ()
3641 [176; 177) 'x': T
3642 [176; 183) 'x.foo()': {unknown}
3643 "###
3644 );
3645}
3551fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 3646fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
3552 let file = db.parse(pos.file_id).ok().unwrap(); 3647 let file = db.parse(pos.file_id).ok().unwrap();
3553 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); 3648 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
@@ -3566,7 +3661,6 @@ fn infer(content: &str) -> String {
3566 let source_file = db.parse(file_id).ok().unwrap(); 3661 let source_file = db.parse(file_id).ok().unwrap();
3567 3662
3568 let mut acc = String::new(); 3663 let mut acc = String::new();
3569 // acc.push_str("\n");
3570 3664
3571 let mut infer_def = |inference_result: Arc<InferenceResult>, 3665 let mut infer_def = |inference_result: Arc<InferenceResult>,
3572 body_source_map: Arc<BodySourceMap>| { 3666 body_source_map: Arc<BodySourceMap>| {
@@ -3574,7 +3668,9 @@ fn infer(content: &str) -> String {
3574 3668
3575 for (pat, ty) in inference_result.type_of_pat.iter() { 3669 for (pat, ty) in inference_result.type_of_pat.iter() {
3576 let syntax_ptr = match body_source_map.pat_syntax(pat) { 3670 let syntax_ptr = match body_source_map.pat_syntax(pat) {
3577 Some(sp) => sp.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()), 3671 Some(sp) => {
3672 sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()))
3673 }
3578 None => continue, 3674 None => continue,
3579 }; 3675 };
3580 types.push((syntax_ptr, ty)); 3676 types.push((syntax_ptr, ty));
@@ -3582,22 +3678,34 @@ fn infer(content: &str) -> String {
3582 3678
3583 for (expr, ty) in inference_result.type_of_expr.iter() { 3679 for (expr, ty) in inference_result.type_of_expr.iter() {
3584 let syntax_ptr = match body_source_map.expr_syntax(expr) { 3680 let syntax_ptr = match body_source_map.expr_syntax(expr) {
3585 Some(sp) => sp.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()), 3681 Some(sp) => {
3682 sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()))
3683 }
3586 None => continue, 3684 None => continue,
3587 }; 3685 };
3588 types.push((syntax_ptr, ty)); 3686 types.push((syntax_ptr, ty));
3589 } 3687 }
3590 3688
3591 // sort ranges for consistency 3689 // sort ranges for consistency
3592 types.sort_by_key(|(ptr, _)| (ptr.range().start(), ptr.range().end())); 3690 types.sort_by_key(|(src_ptr, _)| (src_ptr.ast.range().start(), src_ptr.ast.range().end()));
3593 for (syntax_ptr, ty) in &types { 3691 for (src_ptr, ty) in &types {
3594 let node = syntax_ptr.to_node(source_file.syntax()); 3692 let node = src_ptr.ast.to_node(&src_ptr.file_syntax(&db));
3693
3595 let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) { 3694 let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) {
3596 (self_param.self_kw_token().text_range(), "self".to_string()) 3695 (self_param.self_kw_token().text_range(), "self".to_string())
3597 } else { 3696 } else {
3598 (syntax_ptr.range(), node.text().to_string().replace("\n", " ")) 3697 (src_ptr.ast.range(), node.text().to_string().replace("\n", " "))
3599 }; 3698 };
3600 write!(acc, "{} '{}': {}\n", range, ellipsize(text, 15), ty.display(&db)).unwrap(); 3699 let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" };
3700 write!(
3701 acc,
3702 "{}{} '{}': {}\n",
3703 macro_prefix,
3704 range,
3705 ellipsize(text, 15),
3706 ty.display(&db)
3707 )
3708 .unwrap();
3601 } 3709 }
3602 }; 3710 };
3603 3711