From fbd95785a6746a8bf100a0417b592f5fa35df882 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 17 Apr 2020 18:27:20 +0200 Subject: Add two more tests for associated types --- crates/ra_hir_ty/src/tests/traits.rs | 174 +++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 0a889f805..dc517fc4a 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -2204,3 +2204,177 @@ fn test(x: Box) { ); assert_eq!(t, "()"); } + +#[test] +fn string_to_owned() { + let t = type_at( + r#" +//- /main.rs +struct String {} +pub trait ToOwned { + type Owned; + fn to_owned(&self) -> Self::Owned; +} +impl ToOwned for str { + type Owned = String; +} +fn test() { + "foo".to_owned()<|>; +} +"#, + ); + assert_eq!(t, "String"); +} + +#[test] +fn iterator_chain() { + assert_snapshot!( + infer(r#" +//- /main.rs +#[lang = "fn_once"] +trait FnOnce { + type Output; +} +#[lang = "fn_mut"] +trait FnMut: FnOnce { } + +enum Option { Some(T), None } +use Option::*; + +pub trait Iterator { + type Item; + + fn filter_map(self, f: F) -> FilterMap + where + F: FnMut(Self::Item) -> Option, + { loop {} } + + fn for_each(self, f: F) + where + F: FnMut(Self::Item), + { loop {} } +} + +pub trait IntoIterator { + type Item; + type IntoIter: Iterator; + fn into_iter(self) -> Self::IntoIter; +} + +pub struct FilterMap { } +impl Iterator for FilterMap +where + F: FnMut(I::Item) -> Option, +{ + type Item = B; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl IntoIterator for I { + type Item = I::Item; + type IntoIter = I; + + fn into_iter(self) -> I { + self + } +} + +struct Vec {} +impl Vec { + fn new() -> Self { loop {} } +} + +impl IntoIterator for Vec { + type Item = T; + type IntoIter = IntoIter; +} + +pub struct IntoIter { } +impl Iterator for IntoIter { + type Item = T; +} + +fn main() { + Vec::::new().into_iter() + .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) + .for_each(|y| { y; }); +} +"#), + @r###" + [240; 244) 'self': Self + [246; 247) 'f': F + [331; 342) '{ loop {} }': FilterMap + [333; 340) 'loop {}': ! + [338; 340) '{}': () + [363; 367) 'self': Self + [369; 370) 'f': F + [419; 430) '{ loop {} }': () + [421; 428) 'loop {}': ! + [426; 428) '{}': () + [539; 543) 'self': Self + [868; 872) 'self': I + [879; 899) '{ ... }': I + [889; 893) 'self': I + [958; 969) '{ loop {} }': Vec + [960; 967) 'loop {}': ! + [965; 967) '{}': () + [1156; 1287) '{ ... }); }': () + [1162; 1177) 'Vec::::new': fn new() -> Vec + [1162; 1179) 'Vec::<...:new()': Vec + [1162; 1191) 'Vec::<...iter()': IntoIter + [1162; 1256) 'Vec::<...one })': FilterMap, |i32| -> Option> + [1162; 1284) 'Vec::<... y; })': () + [1210; 1255) '|x| if...None }': |i32| -> Option + [1211; 1212) 'x': i32 + [1214; 1255) 'if x >...None }': Option + [1217; 1218) 'x': i32 + [1217; 1222) 'x > 0': bool + [1221; 1222) '0': i32 + [1223; 1241) '{ Some...u32) }': Option + [1225; 1229) 'Some': Some(u32) -> Option + [1225; 1239) 'Some(x as u32)': Option + [1230; 1231) 'x': i32 + [1230; 1238) 'x as u32': u32 + [1247; 1255) '{ None }': Option + [1249; 1253) 'None': Option + [1273; 1283) '|y| { y; }': |u32| -> () + [1274; 1275) 'y': u32 + [1277; 1283) '{ y; }': () + [1279; 1280) 'y': u32 + "### + ); +} + +#[test] +fn nested_assoc() { + let t = type_at( + r#" +//- /main.rs +struct Bar; +struct Foo; + +trait A { + type OutputA; +} + +impl A for Bar { + type OutputA = Foo; +} + +trait B { + type Output; + fn foo() -> Self::Output; +} + +impl B for T { + type Output = T::OutputA; + fn foo() -> Self::Output { loop {} } +} + +fn main() { + Bar::foo()<|>; +} +"#, + ); + assert_eq!(t, "Foo"); +} -- cgit v1.2.3