diff options
Diffstat (limited to 'crates/ra_hir_ty/src/tests/traits.rs')
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 178 |
1 files changed, 156 insertions, 22 deletions
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index e555c879a..34f4b9039 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1,10 +1,11 @@ | |||
1 | use insta::assert_snapshot; | 1 | use insta::assert_snapshot; |
2 | |||
3 | use ra_db::fixture::WithFixture; | 2 | use ra_db::fixture::WithFixture; |
3 | use test_utils::mark; | ||
4 | 4 | ||
5 | use super::{infer, infer_with_mismatches, type_at, type_at_pos}; | ||
6 | use crate::test_db::TestDB; | 5 | use crate::test_db::TestDB; |
7 | 6 | ||
7 | use super::{infer, infer_with_mismatches, type_at, type_at_pos}; | ||
8 | |||
8 | #[test] | 9 | #[test] |
9 | fn infer_await() { | 10 | fn infer_await() { |
10 | let (db, pos) = TestDB::with_position( | 11 | let (db, pos) = TestDB::with_position( |
@@ -301,7 +302,7 @@ fn test() { | |||
301 | 302 | ||
302 | #[test] | 303 | #[test] |
303 | fn trait_default_method_self_bound_implements_trait() { | 304 | fn trait_default_method_self_bound_implements_trait() { |
304 | test_utils::covers!(trait_self_implements_self); | 305 | mark::check!(trait_self_implements_self); |
305 | assert_snapshot!( | 306 | assert_snapshot!( |
306 | infer(r#" | 307 | infer(r#" |
307 | trait Trait { | 308 | trait Trait { |
@@ -324,7 +325,6 @@ trait Trait { | |||
324 | 325 | ||
325 | #[test] | 326 | #[test] |
326 | fn trait_default_method_self_bound_implements_super_trait() { | 327 | fn trait_default_method_self_bound_implements_super_trait() { |
327 | test_utils::covers!(trait_self_implements_self); | ||
328 | assert_snapshot!( | 328 | assert_snapshot!( |
329 | infer(r#" | 329 | infer(r#" |
330 | trait SuperTrait { | 330 | trait SuperTrait { |
@@ -1617,6 +1617,138 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) { | |||
1617 | } | 1617 | } |
1618 | 1618 | ||
1619 | #[test] | 1619 | #[test] |
1620 | fn fn_ptr_and_item() { | ||
1621 | assert_snapshot!( | ||
1622 | infer(r#" | ||
1623 | #[lang="fn_once"] | ||
1624 | trait FnOnce<Args> { | ||
1625 | type Output; | ||
1626 | |||
1627 | fn call_once(self, args: Args) -> Self::Output; | ||
1628 | } | ||
1629 | |||
1630 | trait Foo<T> { | ||
1631 | fn foo(&self) -> T; | ||
1632 | } | ||
1633 | |||
1634 | struct Bar<T>(T); | ||
1635 | |||
1636 | impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { | ||
1637 | fn foo(&self) -> (A1, R) {} | ||
1638 | } | ||
1639 | |||
1640 | enum Opt<T> { None, Some(T) } | ||
1641 | impl<T> Opt<T> { | ||
1642 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} | ||
1643 | } | ||
1644 | |||
1645 | fn test() { | ||
1646 | let bar: Bar<fn(u8) -> u32>; | ||
1647 | bar.foo(); | ||
1648 | |||
1649 | let opt: Opt<u8>; | ||
1650 | let f: fn(u8) -> u32; | ||
1651 | opt.map(f); | ||
1652 | } | ||
1653 | "#), | ||
1654 | @r###" | ||
1655 | 75..79 'self': Self | ||
1656 | 81..85 'args': Args | ||
1657 | 140..144 'self': &Self | ||
1658 | 244..248 'self': &Bar<F> | ||
1659 | 261..263 '{}': () | ||
1660 | 347..351 'self': Opt<T> | ||
1661 | 353..354 'f': F | ||
1662 | 369..371 '{}': () | ||
1663 | 385..501 '{ ...(f); }': () | ||
1664 | 395..398 'bar': Bar<fn(u8) -> u32> | ||
1665 | 424..427 'bar': Bar<fn(u8) -> u32> | ||
1666 | 424..433 'bar.foo()': {unknown} | ||
1667 | 444..447 'opt': Opt<u8> | ||
1668 | 466..467 'f': fn(u8) -> u32 | ||
1669 | 488..491 'opt': Opt<u8> | ||
1670 | 488..498 'opt.map(f)': Opt<FnOnce::Output<fn(u8) -> u32, (u8,)>> | ||
1671 | 496..497 'f': fn(u8) -> u32 | ||
1672 | "### | ||
1673 | ); | ||
1674 | } | ||
1675 | |||
1676 | #[test] | ||
1677 | fn fn_trait_deref_with_ty_default() { | ||
1678 | assert_snapshot!( | ||
1679 | infer(r#" | ||
1680 | #[lang = "deref"] | ||
1681 | trait Deref { | ||
1682 | type Target; | ||
1683 | |||
1684 | fn deref(&self) -> &Self::Target; | ||
1685 | } | ||
1686 | |||
1687 | #[lang="fn_once"] | ||
1688 | trait FnOnce<Args> { | ||
1689 | type Output; | ||
1690 | |||
1691 | fn call_once(self, args: Args) -> Self::Output; | ||
1692 | } | ||
1693 | |||
1694 | struct Foo; | ||
1695 | |||
1696 | impl Foo { | ||
1697 | fn foo(&self) -> usize {} | ||
1698 | } | ||
1699 | |||
1700 | struct Lazy<T, F = fn() -> T>(F); | ||
1701 | |||
1702 | impl<T, F> Lazy<T, F> { | ||
1703 | pub fn new(f: F) -> Lazy<T, F> {} | ||
1704 | } | ||
1705 | |||
1706 | impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { | ||
1707 | type Target = T; | ||
1708 | } | ||
1709 | |||
1710 | fn test() { | ||
1711 | let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); | ||
1712 | let r1 = lazy1.foo(); | ||
1713 | |||
1714 | fn make_foo_fn() -> Foo {} | ||
1715 | let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; | ||
1716 | let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); | ||
1717 | let r2 = lazy2.foo(); | ||
1718 | } | ||
1719 | "#), | ||
1720 | @r###" | ||
1721 | 65..69 'self': &Self | ||
1722 | 166..170 'self': Self | ||
1723 | 172..176 'args': Args | ||
1724 | 240..244 'self': &Foo | ||
1725 | 255..257 '{}': () | ||
1726 | 335..336 'f': F | ||
1727 | 355..357 '{}': () | ||
1728 | 444..690 '{ ...o(); }': () | ||
1729 | 454..459 'lazy1': Lazy<Foo, fn() -> T> | ||
1730 | 476..485 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T> | ||
1731 | 476..493 'Lazy::...| Foo)': Lazy<Foo, fn() -> T> | ||
1732 | 486..492 '|| Foo': || -> T | ||
1733 | 489..492 'Foo': Foo | ||
1734 | 503..505 'r1': {unknown} | ||
1735 | 508..513 'lazy1': Lazy<Foo, fn() -> T> | ||
1736 | 508..519 'lazy1.foo()': {unknown} | ||
1737 | 561..576 'make_foo_fn_ptr': fn() -> Foo | ||
1738 | 592..603 'make_foo_fn': fn make_foo_fn() -> Foo | ||
1739 | 613..618 'lazy2': Lazy<Foo, fn() -> T> | ||
1740 | 635..644 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T> | ||
1741 | 635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> T> | ||
1742 | 645..660 'make_foo_fn_ptr': fn() -> Foo | ||
1743 | 671..673 'r2': {unknown} | ||
1744 | 676..681 'lazy2': Lazy<Foo, fn() -> T> | ||
1745 | 676..687 'lazy2.foo()': {unknown} | ||
1746 | 550..552 '{}': () | ||
1747 | "### | ||
1748 | ); | ||
1749 | } | ||
1750 | |||
1751 | #[test] | ||
1620 | fn closure_1() { | 1752 | fn closure_1() { |
1621 | assert_snapshot!( | 1753 | assert_snapshot!( |
1622 | infer(r#" | 1754 | infer(r#" |
@@ -2055,7 +2187,7 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() { | |||
2055 | #[test] | 2187 | #[test] |
2056 | fn proc_macro_server_types() { | 2188 | fn proc_macro_server_types() { |
2057 | assert_snapshot!( | 2189 | assert_snapshot!( |
2058 | infer_with_mismatches(r#" | 2190 | infer(r#" |
2059 | macro_rules! with_api { | 2191 | macro_rules! with_api { |
2060 | ($S:ident, $self:ident, $m:ident) => { | 2192 | ($S:ident, $self:ident, $m:ident) => { |
2061 | $m! { | 2193 | $m! { |
@@ -2069,9 +2201,9 @@ macro_rules! with_api { | |||
2069 | } | 2201 | } |
2070 | macro_rules! associated_item { | 2202 | macro_rules! associated_item { |
2071 | (type TokenStream) => | 2203 | (type TokenStream) => |
2072 | (type TokenStream: 'static + Clone;); | 2204 | (type TokenStream: 'static;); |
2073 | (type Group) => | 2205 | (type Group) => |
2074 | (type Group: 'static + Clone;); | 2206 | (type Group: 'static;); |
2075 | ($($item:tt)*) => ($($item)*;) | 2207 | ($($item:tt)*) => ($($item)*;) |
2076 | } | 2208 | } |
2077 | macro_rules! declare_server_traits { | 2209 | macro_rules! declare_server_traits { |
@@ -2083,21 +2215,23 @@ macro_rules! declare_server_traits { | |||
2083 | } | 2215 | } |
2084 | 2216 | ||
2085 | $(pub trait $name: Types { | 2217 | $(pub trait $name: Types { |
2086 | $(associated_item!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)* | 2218 | $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* |
2087 | })* | 2219 | })* |
2088 | 2220 | ||
2089 | pub trait Server: Types $(+ $name)* {} | 2221 | pub trait Server: Types $(+ $name)* {} |
2090 | impl<S: Types $(+ $name)*> Server for S {} | 2222 | impl<S: Types $(+ $name)*> Server for S {} |
2091 | } | 2223 | } |
2092 | } | 2224 | } |
2225 | |||
2093 | with_api!(Self, self_, declare_server_traits); | 2226 | with_api!(Self, self_, declare_server_traits); |
2094 | struct Group {} | 2227 | struct G {} |
2095 | struct TokenStream {} | 2228 | struct T {} |
2096 | struct Rustc; | 2229 | struct Rustc; |
2097 | impl Types for Rustc { | 2230 | impl Types for Rustc { |
2098 | type TokenStream = TokenStream; | 2231 | type TokenStream = T; |
2099 | type Group = Group; | 2232 | type Group = G; |
2100 | } | 2233 | } |
2234 | |||
2101 | fn make<T>() -> T { loop {} } | 2235 | fn make<T>() -> T { loop {} } |
2102 | impl TokenStream for Rustc { | 2236 | impl TokenStream for Rustc { |
2103 | fn new() -> Self::TokenStream { | 2237 | fn new() -> Self::TokenStream { |
@@ -2105,17 +2239,17 @@ impl TokenStream for Rustc { | |||
2105 | make() | 2239 | make() |
2106 | } | 2240 | } |
2107 | } | 2241 | } |
2108 | "#, true), | 2242 | "#), |
2109 | @r###" | 2243 | @r###" |
2110 | 1115..1126 '{ loop {} }': T | 2244 | 1062..1073 '{ loop {} }': T |
2111 | 1117..1124 'loop {}': ! | 2245 | 1064..1071 'loop {}': ! |
2112 | 1122..1124 '{}': () | 2246 | 1069..1071 '{}': () |
2113 | 1190..1253 '{ ... }': {unknown} | 2247 | 1137..1200 '{ ... }': T |
2114 | 1204..1209 'group': {unknown} | 2248 | 1151..1156 'group': G |
2115 | 1225..1229 'make': fn make<{unknown}>() -> {unknown} | 2249 | 1172..1176 'make': fn make<G>() -> G |
2116 | 1225..1231 'make()': {unknown} | 2250 | 1172..1178 'make()': G |
2117 | 1241..1245 'make': fn make<{unknown}>() -> {unknown} | 2251 | 1188..1192 'make': fn make<T>() -> T |
2118 | 1241..1247 'make()': {unknown} | 2252 | 1188..1194 'make()': T |
2119 | "### | 2253 | "### |
2120 | ); | 2254 | ); |
2121 | } | 2255 | } |