diff options
Diffstat (limited to 'crates/ra_hir/src/ty/tests.rs')
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 124 |
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] | ||
3556 | fn assoc_type_bindings() { | ||
3557 | assert_snapshot!( | ||
3558 | infer(r#" | ||
3559 | trait Trait { | ||
3560 | type Type; | ||
3561 | } | ||
3562 | |||
3563 | fn get<T: Trait>(t: T) -> <T as Trait>::Type {} | ||
3564 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} | ||
3565 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | ||
3566 | |||
3567 | struct S<T>; | ||
3568 | impl<T> Trait for S<T> { type Type = T; } | ||
3569 | |||
3570 | fn 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] | ||
3621 | fn projection_eq_within_chalk() { | ||
3622 | // std::env::set_var("CHALK_DEBUG", "1"); | ||
3623 | assert_snapshot!( | ||
3624 | infer(r#" | ||
3625 | trait Trait1 { | ||
3626 | type Type; | ||
3627 | } | ||
3628 | trait Trait2<T> { | ||
3629 | fn foo(self) -> T; | ||
3630 | } | ||
3631 | impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {} | ||
3632 | |||
3633 | fn 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 | } | ||
3551 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 3646 | fn 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 | ||