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.rs234
1 files changed, 234 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..a46f03b7f 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -1211,6 +1211,42 @@ fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
1211} 1211}
1212 1212
1213#[test] 1213#[test]
1214fn dyn_trait_in_impl() {
1215 assert_snapshot!(
1216 infer(r#"
1217trait Trait<T, U> {
1218 fn foo(&self) -> (T, U);
1219}
1220struct S<T, U> {}
1221impl<T, U> S<T, U> {
1222 fn bar(&self) -> &dyn Trait<T, U> { loop {} }
1223}
1224trait Trait2<T, U> {
1225 fn baz(&self) -> (T, U);
1226}
1227impl<T, U> Trait2<T, U> for dyn Trait<T, U> { }
1228
1229fn test(s: S<u32, i32>) {
1230 s.bar().baz();
1231}
1232"#),
1233 @r###"
1234 [33; 37) 'self': &Self
1235 [103; 107) 'self': &S<T, U>
1236 [129; 140) '{ loop {} }': &dyn Trait<T, U>
1237 [131; 138) 'loop {}': !
1238 [136; 138) '{}': ()
1239 [176; 180) 'self': &Self
1240 [252; 253) 's': S<u32, i32>
1241 [268; 290) '{ ...z(); }': ()
1242 [274; 275) 's': S<u32, i32>
1243 [274; 281) 's.bar()': &dyn Trait<u32, i32>
1244 [274; 287) 's.bar().baz()': (u32, i32)
1245 "###
1246 );
1247}
1248
1249#[test]
1214fn dyn_trait_bare() { 1250fn dyn_trait_bare() {
1215 assert_snapshot!( 1251 assert_snapshot!(
1216 infer(r#" 1252 infer(r#"
@@ -2204,3 +2240,201 @@ fn test(x: Box<dyn Trait>) {
2204 ); 2240 );
2205 assert_eq!(t, "()"); 2241 assert_eq!(t, "()");
2206} 2242}
2243
2244#[test]
2245fn string_to_owned() {
2246 let t = type_at(
2247 r#"
2248//- /main.rs
2249struct String {}
2250pub trait ToOwned {
2251 type Owned;
2252 fn to_owned(&self) -> Self::Owned;
2253}
2254impl ToOwned for str {
2255 type Owned = String;
2256}
2257fn test() {
2258 "foo".to_owned()<|>;
2259}
2260"#,
2261 );
2262 assert_eq!(t, "String");
2263}
2264
2265#[test]
2266fn iterator_chain() {
2267 assert_snapshot!(
2268 infer(r#"
2269//- /main.rs
2270#[lang = "fn_once"]
2271trait FnOnce<Args> {
2272 type Output;
2273}
2274#[lang = "fn_mut"]
2275trait FnMut<Args>: FnOnce<Args> { }
2276
2277enum Option<T> { Some(T), None }
2278use Option::*;
2279
2280pub trait Iterator {
2281 type Item;
2282
2283 fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
2284 where
2285 F: FnMut(Self::Item) -> Option<B>,
2286 { loop {} }
2287
2288 fn for_each<F>(self, f: F)
2289 where
2290 F: FnMut(Self::Item),
2291 { loop {} }
2292}
2293
2294pub trait IntoIterator {
2295 type Item;
2296 type IntoIter: Iterator<Item = Self::Item>;
2297 fn into_iter(self) -> Self::IntoIter;
2298}
2299
2300pub struct FilterMap<I, F> { }
2301impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
2302where
2303 F: FnMut(I::Item) -> Option<B>,
2304{
2305 type Item = B;
2306}
2307
2308#[stable(feature = "rust1", since = "1.0.0")]
2309impl<I: Iterator> IntoIterator for I {
2310 type Item = I::Item;
2311 type IntoIter = I;
2312
2313 fn into_iter(self) -> I {
2314 self
2315 }
2316}
2317
2318struct Vec<T> {}
2319impl<T> Vec<T> {
2320 fn new() -> Self { loop {} }
2321}
2322
2323impl<T> IntoIterator for Vec<T> {
2324 type Item = T;
2325 type IntoIter = IntoIter<T>;
2326}
2327
2328pub struct IntoIter<T> { }
2329impl<T> Iterator for IntoIter<T> {
2330 type Item = T;
2331}
2332
2333fn main() {
2334 Vec::<i32>::new().into_iter()
2335 .filter_map(|x| if x > 0 { Some(x as u32) } else { None })
2336 .for_each(|y| { y; });
2337}
2338"#),
2339 @r###"
2340 [240; 244) 'self': Self
2341 [246; 247) 'f': F
2342 [331; 342) '{ loop {} }': FilterMap<Self, F>
2343 [333; 340) 'loop {}': !
2344 [338; 340) '{}': ()
2345 [363; 367) 'self': Self
2346 [369; 370) 'f': F
2347 [419; 430) '{ loop {} }': ()
2348 [421; 428) 'loop {}': !
2349 [426; 428) '{}': ()
2350 [539; 543) 'self': Self
2351 [868; 872) 'self': I
2352 [879; 899) '{ ... }': I
2353 [889; 893) 'self': I
2354 [958; 969) '{ loop {} }': Vec<T>
2355 [960; 967) 'loop {}': !
2356 [965; 967) '{}': ()
2357 [1156; 1287) '{ ... }); }': ()
2358 [1162; 1177) 'Vec::<i32>::new': fn new<i32>() -> Vec<i32>
2359 [1162; 1179) 'Vec::<...:new()': Vec<i32>
2360 [1162; 1191) 'Vec::<...iter()': IntoIter<i32>
2361 [1162; 1256) 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>>
2362 [1162; 1284) 'Vec::<... y; })': ()
2363 [1210; 1255) '|x| if...None }': |i32| -> Option<u32>
2364 [1211; 1212) 'x': i32
2365 [1214; 1255) 'if x >...None }': Option<u32>
2366 [1217; 1218) 'x': i32
2367 [1217; 1222) 'x > 0': bool
2368 [1221; 1222) '0': i32
2369 [1223; 1241) '{ Some...u32) }': Option<u32>
2370 [1225; 1229) 'Some': Some<u32>(u32) -> Option<u32>
2371 [1225; 1239) 'Some(x as u32)': Option<u32>
2372 [1230; 1231) 'x': i32
2373 [1230; 1238) 'x as u32': u32
2374 [1247; 1255) '{ None }': Option<u32>
2375 [1249; 1253) 'None': Option<u32>
2376 [1273; 1283) '|y| { y; }': |u32| -> ()
2377 [1274; 1275) 'y': u32
2378 [1277; 1283) '{ y; }': ()
2379 [1279; 1280) 'y': u32
2380 "###
2381 );
2382}
2383
2384#[test]
2385fn nested_assoc() {
2386 let t = type_at(
2387 r#"
2388//- /main.rs
2389struct Bar;
2390struct Foo;
2391
2392trait A {
2393 type OutputA;
2394}
2395
2396impl A for Bar {
2397 type OutputA = Foo;
2398}
2399
2400trait B {
2401 type Output;
2402 fn foo() -> Self::Output;
2403}
2404
2405impl<T:A> B for T {
2406 type Output = T::OutputA;
2407 fn foo() -> Self::Output { loop {} }
2408}
2409
2410fn main() {
2411 Bar::foo()<|>;
2412}
2413"#,
2414 );
2415 assert_eq!(t, "Foo");
2416}
2417
2418#[test]
2419fn trait_object_no_coercion() {
2420 assert_snapshot!(
2421 infer_with_mismatches(r#"
2422trait Foo {}
2423
2424fn foo(x: &dyn Foo) {}
2425
2426fn test(x: &dyn Foo) {
2427 foo(x);
2428}
2429"#, true),
2430 @r###"
2431 [22; 23) 'x': &dyn Foo
2432 [35; 37) '{}': ()
2433 [47; 48) 'x': &dyn Foo
2434 [60; 75) '{ foo(x); }': ()
2435 [66; 69) 'foo': fn foo(&dyn Foo)
2436 [66; 72) 'foo(x)': ()
2437 [70; 71) 'x': &dyn Foo
2438 "###
2439 );
2440}