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.rs160
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]
2505fn method_resolution_trait_from_prelude() {
2506 let (mut db, pos) = MockDatabase::with_position(
2507 r#"
2508//- /main.rs
2509struct S;
2510impl Clone for S {}
2511
2512fn test() {
2513 S.clone()<|>;
2514}
2515
2516//- /lib.rs
2517#[prelude_import] use foo::*;
2518
2519mod 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]
2534fn 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
2539trait Trait { fn foo(self) -> u128; }
2540struct S;
2541impl<T> Trait for T where T: UnknownTrait {}
2542fn test() { (&S).foo()<|>; }
2543"#,
2544 );
2545 assert_eq!(t, "{unknown}");
2546}
2547
2548#[test]
2505fn method_resolution_where_clause_not_met() { 2549fn 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() {
2510trait Clone {} 2554trait Clone {}
2511trait Trait { fn foo(self) -> u128; } 2555trait Trait { fn foo(self) -> u128; }
2512struct S; 2556struct S;
2513impl S { fn foo(self) -> i8 { 0 } } 2557impl<T> Trait for T where T: Clone {}
2514impl<T> Trait for T where T: Clone { fn foo(self) -> u128 { 0 } }
2515fn test() { (&S).foo()<|>; } 2558fn 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]
2568fn 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
2573trait Clone {}
2574trait Trait { fn foo(self) -> u128; }
2575struct S;
2576impl<T: Clone> Trait for T {}
2577fn test() { (&S).foo()<|>; }
2578"#,
2579 );
2580 assert_eq!(t, "{unknown}");
2581}
2582
2583#[test]
2584fn method_resolution_where_clause_1() {
2585 let t = type_at(
2586 r#"
2587//- /main.rs
2588trait Clone {}
2589trait Trait { fn foo(self) -> u128; }
2590struct S;
2591impl Clone for S {};
2592impl<T> Trait for T where T: Clone {}
2593fn test() { S.foo()<|>; }
2594"#,
2595 );
2596 assert_eq!(t, "u128");
2597}
2598
2599#[test]
2600fn method_resolution_where_clause_2() {
2601 let t = type_at(
2602 r#"
2603//- /main.rs
2604trait Into<T> { fn into(self) -> T; }
2605trait From<T> { fn from(other: T) -> Self; }
2606struct S1;
2607struct S2;
2608impl From<S2> for S1 {};
2609impl<T, U> Into<U> for T where U: From<T> {}
2610fn test() { S2.into()<|>; }
2611"#,
2612 );
2613 assert_eq!(t, "S1");
2614}
2615
2616#[test]
2617fn method_resolution_where_clause_inline() {
2618 let t = type_at(
2619 r#"
2620//- /main.rs
2621trait Into<T> { fn into(self) -> T; }
2622trait From<T> { fn from(other: T) -> Self; }
2623struct S1;
2624struct S2;
2625impl From<S2> for S1 {};
2626impl<T, U: From<T>> Into<U> for T {}
2627fn test() { S2.into()<|>; }
2628"#,
2629 );
2630 assert_eq!(t, "S1");
2631}
2632
2633#[test]
2634fn method_resolution_encountering_fn_type() {
2635 covers!(trait_resolution_on_fn_type);
2636 type_at(
2637 r#"
2638//- /main.rs
2639fn foo() {}
2640trait FnOnce { fn call(self); }
2641fn test() { foo.call()<|>; }
2642"#,
2643 );
2644}
2645
2646#[test]
2647fn 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
2652trait SendX {}
2653
2654struct S1; impl SendX for S1;
2655struct S2; impl SendX for S2;
2656struct U1;
2657
2658trait Trait { fn method(self); }
2659
2660struct X1<A, B> {}
2661impl<A, B> SendX for X1<A, B> where A: SendX, B: SendX {}
2662
2663struct S<B, C> {}
2664
2665trait FnX {}
2666
2667impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {}
2668
2669fn test() { (S {}).method()<|>; }
2670"#,
2671 );
2672 assert_eq!(t, "{unknown}");
2519} 2673}
2520 2674
2521fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 2675fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {