diff options
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 174 |
1 files changed, 174 insertions, 0 deletions
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<dyn Trait>) { | |||
2204 | ); | 2204 | ); |
2205 | assert_eq!(t, "()"); | 2205 | assert_eq!(t, "()"); |
2206 | } | 2206 | } |
2207 | |||
2208 | #[test] | ||
2209 | fn string_to_owned() { | ||
2210 | let t = type_at( | ||
2211 | r#" | ||
2212 | //- /main.rs | ||
2213 | struct String {} | ||
2214 | pub trait ToOwned { | ||
2215 | type Owned; | ||
2216 | fn to_owned(&self) -> Self::Owned; | ||
2217 | } | ||
2218 | impl ToOwned for str { | ||
2219 | type Owned = String; | ||
2220 | } | ||
2221 | fn test() { | ||
2222 | "foo".to_owned()<|>; | ||
2223 | } | ||
2224 | "#, | ||
2225 | ); | ||
2226 | assert_eq!(t, "String"); | ||
2227 | } | ||
2228 | |||
2229 | #[test] | ||
2230 | fn iterator_chain() { | ||
2231 | assert_snapshot!( | ||
2232 | infer(r#" | ||
2233 | //- /main.rs | ||
2234 | #[lang = "fn_once"] | ||
2235 | trait FnOnce<Args> { | ||
2236 | type Output; | ||
2237 | } | ||
2238 | #[lang = "fn_mut"] | ||
2239 | trait FnMut<Args>: FnOnce<Args> { } | ||
2240 | |||
2241 | enum Option<T> { Some(T), None } | ||
2242 | use Option::*; | ||
2243 | |||
2244 | pub trait Iterator { | ||
2245 | type Item; | ||
2246 | |||
2247 | fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> | ||
2248 | where | ||
2249 | F: FnMut(Self::Item) -> Option<B>, | ||
2250 | { loop {} } | ||
2251 | |||
2252 | fn for_each<F>(self, f: F) | ||
2253 | where | ||
2254 | F: FnMut(Self::Item), | ||
2255 | { loop {} } | ||
2256 | } | ||
2257 | |||
2258 | pub trait IntoIterator { | ||
2259 | type Item; | ||
2260 | type IntoIter: Iterator<Item = Self::Item>; | ||
2261 | fn into_iter(self) -> Self::IntoIter; | ||
2262 | } | ||
2263 | |||
2264 | pub struct FilterMap<I, F> { } | ||
2265 | impl<B, I: Iterator, F> Iterator for FilterMap<I, F> | ||
2266 | where | ||
2267 | F: FnMut(I::Item) -> Option<B>, | ||
2268 | { | ||
2269 | type Item = B; | ||
2270 | } | ||
2271 | |||
2272 | #[stable(feature = "rust1", since = "1.0.0")] | ||
2273 | impl<I: Iterator> IntoIterator for I { | ||
2274 | type Item = I::Item; | ||
2275 | type IntoIter = I; | ||
2276 | |||
2277 | fn into_iter(self) -> I { | ||
2278 | self | ||
2279 | } | ||
2280 | } | ||
2281 | |||
2282 | struct Vec<T> {} | ||
2283 | impl<T> Vec<T> { | ||
2284 | fn new() -> Self { loop {} } | ||
2285 | } | ||
2286 | |||
2287 | impl<T> IntoIterator for Vec<T> { | ||
2288 | type Item = T; | ||
2289 | type IntoIter = IntoIter<T>; | ||
2290 | } | ||
2291 | |||
2292 | pub struct IntoIter<T> { } | ||
2293 | impl<T> Iterator for IntoIter<T> { | ||
2294 | type Item = T; | ||
2295 | } | ||
2296 | |||
2297 | fn main() { | ||
2298 | Vec::<i32>::new().into_iter() | ||
2299 | .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) | ||
2300 | .for_each(|y| { y; }); | ||
2301 | } | ||
2302 | "#), | ||
2303 | @r###" | ||
2304 | [240; 244) 'self': Self | ||
2305 | [246; 247) 'f': F | ||
2306 | [331; 342) '{ loop {} }': FilterMap<Self, F> | ||
2307 | [333; 340) 'loop {}': ! | ||
2308 | [338; 340) '{}': () | ||
2309 | [363; 367) 'self': Self | ||
2310 | [369; 370) 'f': F | ||
2311 | [419; 430) '{ loop {} }': () | ||
2312 | [421; 428) 'loop {}': ! | ||
2313 | [426; 428) '{}': () | ||
2314 | [539; 543) 'self': Self | ||
2315 | [868; 872) 'self': I | ||
2316 | [879; 899) '{ ... }': I | ||
2317 | [889; 893) 'self': I | ||
2318 | [958; 969) '{ loop {} }': Vec<T> | ||
2319 | [960; 967) 'loop {}': ! | ||
2320 | [965; 967) '{}': () | ||
2321 | [1156; 1287) '{ ... }); }': () | ||
2322 | [1162; 1177) 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> | ||
2323 | [1162; 1179) 'Vec::<...:new()': Vec<i32> | ||
2324 | [1162; 1191) 'Vec::<...iter()': IntoIter<i32> | ||
2325 | [1162; 1256) 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> | ||
2326 | [1162; 1284) 'Vec::<... y; })': () | ||
2327 | [1210; 1255) '|x| if...None }': |i32| -> Option<u32> | ||
2328 | [1211; 1212) 'x': i32 | ||
2329 | [1214; 1255) 'if x >...None }': Option<u32> | ||
2330 | [1217; 1218) 'x': i32 | ||
2331 | [1217; 1222) 'x > 0': bool | ||
2332 | [1221; 1222) '0': i32 | ||
2333 | [1223; 1241) '{ Some...u32) }': Option<u32> | ||
2334 | [1225; 1229) 'Some': Some<u32>(u32) -> Option<u32> | ||
2335 | [1225; 1239) 'Some(x as u32)': Option<u32> | ||
2336 | [1230; 1231) 'x': i32 | ||
2337 | [1230; 1238) 'x as u32': u32 | ||
2338 | [1247; 1255) '{ None }': Option<u32> | ||
2339 | [1249; 1253) 'None': Option<u32> | ||
2340 | [1273; 1283) '|y| { y; }': |u32| -> () | ||
2341 | [1274; 1275) 'y': u32 | ||
2342 | [1277; 1283) '{ y; }': () | ||
2343 | [1279; 1280) 'y': u32 | ||
2344 | "### | ||
2345 | ); | ||
2346 | } | ||
2347 | |||
2348 | #[test] | ||
2349 | fn nested_assoc() { | ||
2350 | let t = type_at( | ||
2351 | r#" | ||
2352 | //- /main.rs | ||
2353 | struct Bar; | ||
2354 | struct Foo; | ||
2355 | |||
2356 | trait A { | ||
2357 | type OutputA; | ||
2358 | } | ||
2359 | |||
2360 | impl A for Bar { | ||
2361 | type OutputA = Foo; | ||
2362 | } | ||
2363 | |||
2364 | trait B { | ||
2365 | type Output; | ||
2366 | fn foo() -> Self::Output; | ||
2367 | } | ||
2368 | |||
2369 | impl<T:A> B for T { | ||
2370 | type Output = T::OutputA; | ||
2371 | fn foo() -> Self::Output { loop {} } | ||
2372 | } | ||
2373 | |||
2374 | fn main() { | ||
2375 | Bar::foo()<|>; | ||
2376 | } | ||
2377 | "#, | ||
2378 | ); | ||
2379 | assert_eq!(t, "Foo"); | ||
2380 | } | ||