aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/tests/traits.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/tests/traits.rs')
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs212
1 files changed, 185 insertions, 27 deletions
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 22ae6ca90..0a889f805 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -349,7 +349,6 @@ trait Trait: SuperTrait {
349 349
350#[test] 350#[test]
351fn infer_project_associated_type() { 351fn infer_project_associated_type() {
352 // y, z, a don't yet work because of https://github.com/rust-lang/chalk/issues/234
353 assert_snapshot!( 352 assert_snapshot!(
354 infer(r#" 353 infer(r#"
355trait Iterable { 354trait Iterable {
@@ -368,12 +367,12 @@ fn test<T: Iterable>() {
368 [108; 261) '{ ...ter; }': () 367 [108; 261) '{ ...ter; }': ()
369 [118; 119) 'x': u32 368 [118; 119) 'x': u32
370 [145; 146) '1': u32 369 [145; 146) '1': u32
371 [156; 157) 'y': {unknown} 370 [156; 157) 'y': Iterable::Item<T>
372 [183; 192) 'no_matter': {unknown} 371 [183; 192) 'no_matter': Iterable::Item<T>
373 [202; 203) 'z': {unknown} 372 [202; 203) 'z': Iterable::Item<T>
374 [215; 224) 'no_matter': {unknown} 373 [215; 224) 'no_matter': Iterable::Item<T>
375 [234; 235) 'a': {unknown} 374 [234; 235) 'a': Iterable::Item<T>
376 [249; 258) 'no_matter': {unknown} 375 [249; 258) 'no_matter': Iterable::Item<T>
377 "### 376 "###
378 ); 377 );
379} 378}
@@ -433,8 +432,8 @@ fn test<T: Iterable<Item=u32>>() {
433"#), 432"#),
434 @r###" 433 @r###"
435 [67; 100) '{ ...own; }': () 434 [67; 100) '{ ...own; }': ()
436 [77; 78) 'y': {unknown} 435 [77; 78) 'y': u32
437 [90; 97) 'unknown': {unknown} 436 [90; 97) 'unknown': u32
438 "### 437 "###
439 ); 438 );
440} 439}
@@ -549,7 +548,7 @@ impl std::ops::Index<u32> for Bar {
549 548
550fn test() { 549fn test() {
551 let a = Bar; 550 let a = Bar;
552 let b = a[1]; 551 let b = a[1u32];
553 b<|>; 552 b<|>;
554} 553}
555 554
@@ -574,7 +573,7 @@ fn infer_ops_index_autoderef() {
574//- /main.rs crate:main deps:std 573//- /main.rs crate:main deps:std
575fn test() { 574fn test() {
576 let a = &[1u32, 2, 3]; 575 let a = &[1u32, 2, 3];
577 let b = a[1]; 576 let b = a[1u32];
578 b<|>; 577 b<|>;
579} 578}
580 579
@@ -916,11 +915,7 @@ fn test<T: ApplyL>(t: T) {
916} 915}
917"#, 916"#,
918 ); 917 );
919 // FIXME here Chalk doesn't normalize the type to a placeholder. I think we 918 assert_eq!(t, "ApplyL::Out<T>");
920 // need to add a rule like Normalize(<T as ApplyL>::Out -> ApplyL::Out<T>)
921 // to the trait env ourselves here; probably Chalk can't do this by itself.
922 // assert_eq!(t, "ApplyL::Out<[missing name]>");
923 assert_eq!(t, "{unknown}");
924} 919}
925 920
926#[test] 921#[test]
@@ -1329,16 +1324,16 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
1329 [263; 264) 'y': impl Trait<Type = i64> 1324 [263; 264) 'y': impl Trait<Type = i64>
1330 [290; 398) '{ ...r>); }': () 1325 [290; 398) '{ ...r>); }': ()
1331 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type 1326 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type
1332 [296; 302) 'get(x)': {unknown} 1327 [296; 302) 'get(x)': u32
1333 [300; 301) 'x': T 1328 [300; 301) 'x': T
1334 [308; 312) 'get2': fn get2<{unknown}, T>(T) -> {unknown} 1329 [308; 312) 'get2': fn get2<u32, T>(T) -> u32
1335 [308; 315) 'get2(x)': {unknown} 1330 [308; 315) 'get2(x)': u32
1336 [313; 314) 'x': T 1331 [313; 314) 'x': T
1337 [321; 324) 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type 1332 [321; 324) 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type
1338 [321; 327) 'get(y)': {unknown} 1333 [321; 327) 'get(y)': i64
1339 [325; 326) 'y': impl Trait<Type = i64> 1334 [325; 326) 'y': impl Trait<Type = i64>
1340 [333; 337) 'get2': fn get2<{unknown}, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> {unknown} 1335 [333; 337) 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64
1341 [333; 340) 'get2(y)': {unknown} 1336 [333; 340) 'get2(y)': i64
1342 [338; 339) 'y': impl Trait<Type = i64> 1337 [338; 339) 'y': impl Trait<Type = i64>
1343 [346; 349) 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type 1338 [346; 349) 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type
1344 [346; 357) 'get(set(S))': u64 1339 [346; 357) 'get(set(S))': u64
@@ -1402,7 +1397,6 @@ mod iter {
1402 1397
1403#[test] 1398#[test]
1404fn projection_eq_within_chalk() { 1399fn projection_eq_within_chalk() {
1405 // std::env::set_var("CHALK_DEBUG", "1");
1406 assert_snapshot!( 1400 assert_snapshot!(
1407 infer(r#" 1401 infer(r#"
1408trait Trait1 { 1402trait Trait1 {
@@ -1422,7 +1416,7 @@ fn test<T: Trait1<Type = u32>>(x: T) {
1422 [164; 165) 'x': T 1416 [164; 165) 'x': T
1423 [170; 186) '{ ...o(); }': () 1417 [170; 186) '{ ...o(); }': ()
1424 [176; 177) 'x': T 1418 [176; 177) 'x': T
1425 [176; 183) 'x.foo()': {unknown} 1419 [176; 183) 'x.foo()': u32
1426 "### 1420 "###
1427 ); 1421 );
1428} 1422}
@@ -1578,7 +1572,7 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
1578 [150; 151) 'f': F 1572 [150; 151) 'f': F
1579 [156; 184) '{ ...2)); }': () 1573 [156; 184) '{ ...2)); }': ()
1580 [162; 163) 'f': F 1574 [162; 163) 'f': F
1581 [162; 181) 'f.call...1, 2))': {unknown} 1575 [162; 181) 'f.call...1, 2))': u128
1582 [174; 180) '(1, 2)': (u32, u64) 1576 [174; 180) '(1, 2)': (u32, u64)
1583 [175; 176) '1': u32 1577 [175; 176) '1': u32
1584 [178; 179) '2': u64 1578 [178; 179) '2': u64
@@ -1803,7 +1797,7 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
1803} 1797}
1804 1798
1805#[test] 1799#[test]
1806fn unselected_projection_on_trait_self() { 1800fn unselected_projection_on_impl_self() {
1807 assert_snapshot!(infer( 1801 assert_snapshot!(infer(
1808 r#" 1802 r#"
1809//- /main.rs 1803//- /main.rs
@@ -1829,7 +1823,7 @@ impl Trait for S2 {
1829"#, 1823"#,
1830 ), @r###" 1824 ), @r###"
1831 [54; 58) 'self': &Self 1825 [54; 58) 'self': &Self
1832 [60; 61) 'x': {unknown} 1826 [60; 61) 'x': Trait::Item<Self>
1833 [140; 144) 'self': &S 1827 [140; 144) 'self': &S
1834 [146; 147) 'x': u32 1828 [146; 147) 'x': u32
1835 [161; 175) '{ let y = x; }': () 1829 [161; 175) '{ let y = x; }': ()
@@ -1844,6 +1838,30 @@ impl Trait for S2 {
1844} 1838}
1845 1839
1846#[test] 1840#[test]
1841fn unselected_projection_on_trait_self() {
1842 let t = type_at(
1843 r#"
1844//- /main.rs
1845trait Trait {
1846 type Item;
1847
1848 fn f(&self) -> Self::Item { loop {} }
1849}
1850
1851struct S;
1852impl Trait for S {
1853 type Item = u32;
1854}
1855
1856fn test() {
1857 S.f()<|>;
1858}
1859"#,
1860 );
1861 assert_eq!(t, "u32");
1862}
1863
1864#[test]
1847fn trait_impl_self_ty() { 1865fn trait_impl_self_ty() {
1848 let t = type_at( 1866 let t = type_at(
1849 r#" 1867 r#"
@@ -1924,6 +1942,119 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
1924} 1942}
1925 1943
1926#[test] 1944#[test]
1945fn inline_assoc_type_bounds_1() {
1946 let t = type_at(
1947 r#"
1948//- /main.rs
1949trait Iterator {
1950 type Item;
1951}
1952trait OtherTrait<T> {
1953 fn foo(&self) -> T;
1954}
1955
1956// workaround for Chalk assoc type normalization problems
1957pub struct S<T>;
1958impl<T: Iterator> Iterator for S<T> {
1959 type Item = <T as Iterator>::Item;
1960}
1961
1962fn test<I: Iterator<Item: OtherTrait<u32>>>() {
1963 let x: <S<I> as Iterator>::Item;
1964 x.foo()<|>;
1965}
1966"#,
1967 );
1968 assert_eq!(t, "u32");
1969}
1970
1971#[test]
1972fn inline_assoc_type_bounds_2() {
1973 let t = type_at(
1974 r#"
1975//- /main.rs
1976trait Iterator {
1977 type Item;
1978}
1979
1980fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
1981 let x: <<I as Iterator>::Item as Iterator>::Item;
1982 x<|>;
1983}
1984"#,
1985 );
1986 assert_eq!(t, "u32");
1987}
1988
1989#[test]
1990fn proc_macro_server_types() {
1991 assert_snapshot!(
1992 infer_with_mismatches(r#"
1993macro_rules! with_api {
1994 ($S:ident, $self:ident, $m:ident) => {
1995 $m! {
1996 TokenStream {
1997 fn new() -> $S::TokenStream;
1998 },
1999 Group {
2000 },
2001 }
2002 };
2003}
2004macro_rules! associated_item {
2005 (type TokenStream) =>
2006 (type TokenStream: 'static + Clone;);
2007 (type Group) =>
2008 (type Group: 'static + Clone;);
2009 ($($item:tt)*) => ($($item)*;)
2010}
2011macro_rules! declare_server_traits {
2012 ($($name:ident {
2013 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
2014 }),* $(,)?) => {
2015 pub trait Types {
2016 $(associated_item!(type $name);)*
2017 }
2018
2019 $(pub trait $name: Types {
2020 $(associated_item!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2021 })*
2022
2023 pub trait Server: Types $(+ $name)* {}
2024 impl<S: Types $(+ $name)*> Server for S {}
2025 }
2026}
2027with_api!(Self, self_, declare_server_traits);
2028struct Group {}
2029struct TokenStream {}
2030struct Rustc;
2031impl Types for Rustc {
2032 type TokenStream = TokenStream;
2033 type Group = Group;
2034}
2035fn make<T>() -> T { loop {} }
2036impl TokenStream for Rustc {
2037 fn new() -> Self::TokenStream {
2038 let group: Self::Group = make();
2039 make()
2040 }
2041}
2042"#, true),
2043 @r###"
2044 [1115; 1126) '{ loop {} }': T
2045 [1117; 1124) 'loop {}': !
2046 [1122; 1124) '{}': ()
2047 [1190; 1253) '{ ... }': {unknown}
2048 [1204; 1209) 'group': {unknown}
2049 [1225; 1229) 'make': fn make<{unknown}>() -> {unknown}
2050 [1225; 1231) 'make()': {unknown}
2051 [1241; 1245) 'make': fn make<{unknown}>() -> {unknown}
2052 [1241; 1247) 'make()': {unknown}
2053 "###
2054 );
2055}
2056
2057#[test]
1927fn unify_impl_trait() { 2058fn unify_impl_trait() {
1928 assert_snapshot!( 2059 assert_snapshot!(
1929 infer_with_mismatches(r#" 2060 infer_with_mismatches(r#"
@@ -2023,6 +2154,33 @@ fn main() {
2023} 2154}
2024 2155
2025#[test] 2156#[test]
2157fn associated_type_bound() {
2158 let t = type_at(
2159 r#"
2160//- /main.rs
2161pub trait Trait {
2162 type Item: OtherTrait<u32>;
2163}
2164pub trait OtherTrait<T> {
2165 fn foo(&self) -> T;
2166}
2167
2168// this is just a workaround for chalk#234
2169pub struct S<T>;
2170impl<T: Trait> Trait for S<T> {
2171 type Item = <T as Trait>::Item;
2172}
2173
2174fn test<T: Trait>() {
2175 let y: <S<T> as Trait>::Item = no_matter;
2176 y.foo()<|>;
2177}
2178"#,
2179 );
2180 assert_eq!(t, "u32");
2181}
2182
2183#[test]
2026fn dyn_trait_through_chalk() { 2184fn dyn_trait_through_chalk() {
2027 let t = type_at( 2185 let t = type_at(
2028 r#" 2186 r#"