diff options
Diffstat (limited to 'crates/ra_hir/src/ty/tests.rs')
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 160 |
1 files changed, 157 insertions, 3 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index a38fe35c7..978cc2587 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2502,6 +2502,50 @@ fn test() { (&S).foo()<|>; } | |||
2502 | } | 2502 | } |
2503 | 2503 | ||
2504 | #[test] | 2504 | #[test] |
2505 | fn method_resolution_trait_from_prelude() { | ||
2506 | let (mut db, pos) = MockDatabase::with_position( | ||
2507 | r#" | ||
2508 | //- /main.rs | ||
2509 | struct S; | ||
2510 | impl Clone for S {} | ||
2511 | |||
2512 | fn test() { | ||
2513 | S.clone()<|>; | ||
2514 | } | ||
2515 | |||
2516 | //- /lib.rs | ||
2517 | #[prelude_import] use foo::*; | ||
2518 | |||
2519 | mod foo { | ||
2520 | trait Clone { | ||
2521 | fn clone(&self) -> Self; | ||
2522 | } | ||
2523 | } | ||
2524 | "#, | ||
2525 | ); | ||
2526 | db.set_crate_graph_from_fixture(crate_graph! { | ||
2527 | "main": ("/main.rs", ["other_crate"]), | ||
2528 | "other_crate": ("/lib.rs", []), | ||
2529 | }); | ||
2530 | assert_eq!("S", type_at_pos(&db, pos)); | ||
2531 | } | ||
2532 | |||
2533 | #[test] | ||
2534 | fn method_resolution_where_clause_for_unknown_trait() { | ||
2535 | // The blanket impl shouldn't apply because we can't even resolve UnknownTrait | ||
2536 | let t = type_at( | ||
2537 | r#" | ||
2538 | //- /main.rs | ||
2539 | trait Trait { fn foo(self) -> u128; } | ||
2540 | struct S; | ||
2541 | impl<T> Trait for T where T: UnknownTrait {} | ||
2542 | fn test() { (&S).foo()<|>; } | ||
2543 | "#, | ||
2544 | ); | ||
2545 | assert_eq!(t, "{unknown}"); | ||
2546 | } | ||
2547 | |||
2548 | #[test] | ||
2505 | fn method_resolution_where_clause_not_met() { | 2549 | fn method_resolution_where_clause_not_met() { |
2506 | // The blanket impl shouldn't apply because we can't prove S: Clone | 2550 | // The blanket impl shouldn't apply because we can't prove S: Clone |
2507 | let t = type_at( | 2551 | let t = type_at( |
@@ -2510,12 +2554,122 @@ fn method_resolution_where_clause_not_met() { | |||
2510 | trait Clone {} | 2554 | trait Clone {} |
2511 | trait Trait { fn foo(self) -> u128; } | 2555 | trait Trait { fn foo(self) -> u128; } |
2512 | struct S; | 2556 | struct S; |
2513 | impl S { fn foo(self) -> i8 { 0 } } | 2557 | impl<T> Trait for T where T: Clone {} |
2514 | impl<T> Trait for T where T: Clone { fn foo(self) -> u128 { 0 } } | ||
2515 | fn test() { (&S).foo()<|>; } | 2558 | fn test() { (&S).foo()<|>; } |
2516 | "#, | 2559 | "#, |
2517 | ); | 2560 | ); |
2518 | assert_eq!(t, "i8"); | 2561 | // This is also to make sure that we don't resolve to the foo method just |
2562 | // because that's the only method named foo we can find, which would make | ||
2563 | // the below tests not work | ||
2564 | assert_eq!(t, "{unknown}"); | ||
2565 | } | ||
2566 | |||
2567 | #[test] | ||
2568 | fn method_resolution_where_clause_inline_not_met() { | ||
2569 | // The blanket impl shouldn't apply because we can't prove S: Clone | ||
2570 | let t = type_at( | ||
2571 | r#" | ||
2572 | //- /main.rs | ||
2573 | trait Clone {} | ||
2574 | trait Trait { fn foo(self) -> u128; } | ||
2575 | struct S; | ||
2576 | impl<T: Clone> Trait for T {} | ||
2577 | fn test() { (&S).foo()<|>; } | ||
2578 | "#, | ||
2579 | ); | ||
2580 | assert_eq!(t, "{unknown}"); | ||
2581 | } | ||
2582 | |||
2583 | #[test] | ||
2584 | fn method_resolution_where_clause_1() { | ||
2585 | let t = type_at( | ||
2586 | r#" | ||
2587 | //- /main.rs | ||
2588 | trait Clone {} | ||
2589 | trait Trait { fn foo(self) -> u128; } | ||
2590 | struct S; | ||
2591 | impl Clone for S {}; | ||
2592 | impl<T> Trait for T where T: Clone {} | ||
2593 | fn test() { S.foo()<|>; } | ||
2594 | "#, | ||
2595 | ); | ||
2596 | assert_eq!(t, "u128"); | ||
2597 | } | ||
2598 | |||
2599 | #[test] | ||
2600 | fn method_resolution_where_clause_2() { | ||
2601 | let t = type_at( | ||
2602 | r#" | ||
2603 | //- /main.rs | ||
2604 | trait Into<T> { fn into(self) -> T; } | ||
2605 | trait From<T> { fn from(other: T) -> Self; } | ||
2606 | struct S1; | ||
2607 | struct S2; | ||
2608 | impl From<S2> for S1 {}; | ||
2609 | impl<T, U> Into<U> for T where U: From<T> {} | ||
2610 | fn test() { S2.into()<|>; } | ||
2611 | "#, | ||
2612 | ); | ||
2613 | assert_eq!(t, "S1"); | ||
2614 | } | ||
2615 | |||
2616 | #[test] | ||
2617 | fn method_resolution_where_clause_inline() { | ||
2618 | let t = type_at( | ||
2619 | r#" | ||
2620 | //- /main.rs | ||
2621 | trait Into<T> { fn into(self) -> T; } | ||
2622 | trait From<T> { fn from(other: T) -> Self; } | ||
2623 | struct S1; | ||
2624 | struct S2; | ||
2625 | impl From<S2> for S1 {}; | ||
2626 | impl<T, U: From<T>> Into<U> for T {} | ||
2627 | fn test() { S2.into()<|>; } | ||
2628 | "#, | ||
2629 | ); | ||
2630 | assert_eq!(t, "S1"); | ||
2631 | } | ||
2632 | |||
2633 | #[test] | ||
2634 | fn method_resolution_encountering_fn_type() { | ||
2635 | covers!(trait_resolution_on_fn_type); | ||
2636 | type_at( | ||
2637 | r#" | ||
2638 | //- /main.rs | ||
2639 | fn foo() {} | ||
2640 | trait FnOnce { fn call(self); } | ||
2641 | fn test() { foo.call()<|>; } | ||
2642 | "#, | ||
2643 | ); | ||
2644 | } | ||
2645 | |||
2646 | #[test] | ||
2647 | fn method_resolution_slow() { | ||
2648 | // this can get quite slow if we set the solver size limit too high | ||
2649 | let t = type_at( | ||
2650 | r#" | ||
2651 | //- /main.rs | ||
2652 | trait SendX {} | ||
2653 | |||
2654 | struct S1; impl SendX for S1; | ||
2655 | struct S2; impl SendX for S2; | ||
2656 | struct U1; | ||
2657 | |||
2658 | trait Trait { fn method(self); } | ||
2659 | |||
2660 | struct X1<A, B> {} | ||
2661 | impl<A, B> SendX for X1<A, B> where A: SendX, B: SendX {} | ||
2662 | |||
2663 | struct S<B, C> {} | ||
2664 | |||
2665 | trait FnX {} | ||
2666 | |||
2667 | impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {} | ||
2668 | |||
2669 | fn test() { (S {}).method()<|>; } | ||
2670 | "#, | ||
2671 | ); | ||
2672 | assert_eq!(t, "{unknown}"); | ||
2519 | } | 2673 | } |
2520 | 2674 | ||
2521 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 2675 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |