use insta::assert_snapshot; use ra_db::fixture::WithFixture; use super::{infer, infer_with_mismatches, type_at, type_at_pos}; use crate::test_db::TestDB; #[test] fn infer_await() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std struct IntFuture; impl Future for IntFuture { type Output = u64; } fn test() { let r = IntFuture; let v = r.await; v<|>; } //- /std.rs crate:std #[prelude_import] use future::*; mod future { #[lang = "future_trait"] trait Future { type Output; } } "#, ); assert_eq!("u64", type_at_pos(&db, pos)); } #[test] fn infer_async() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std async fn foo() -> u64 { 128 } fn test() { let r = foo(); let v = r.await; v<|>; } //- /std.rs crate:std #[prelude_import] use future::*; mod future { #[lang = "future_trait"] trait Future { type Output; } } "#, ); assert_eq!("u64", type_at_pos(&db, pos)); } #[test] fn infer_desugar_async() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std async fn foo() -> u64 { 128 } fn test() { let r = foo(); r<|>; } //- /std.rs crate:std #[prelude_import] use future::*; mod future { trait Future { type Output; } } "#, ); assert_eq!("impl Future<Output = u64>", type_at_pos(&db, pos)); } #[test] fn infer_try() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std fn test() { let r: Result<i32, u64> = Result::Ok(1); let v = r?; v<|>; } //- /std.rs crate:std #[prelude_import] use ops::*; mod ops { trait Try { type Ok; type Error; } } #[prelude_import] use result::*; mod result { enum Result<O, E> { Ok(O), Err(E) } impl<O, E> crate::ops::Try for Result<O, E> { type Ok = O; type Error = E; } } "#, ); assert_eq!("i32", type_at_pos(&db, pos)); } #[test] fn infer_for_loop() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std use std::collections::Vec; fn test() { let v = Vec::new(); v.push("foo"); for x in v { x<|>; } } //- /std.rs crate:std #[prelude_import] use iter::*; mod iter { trait IntoIterator { type Item; } } mod collections { struct Vec<T> {} impl<T> Vec<T> { fn new() -> Self { Vec {} } fn push(&mut self, t: T) { } } impl<T> crate::iter::IntoIterator for Vec<T> { type Item=T; } } "#, ); assert_eq!("&str", type_at_pos(&db, pos)); } #[test] fn infer_ops_neg() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std struct Bar; struct Foo; impl std::ops::Neg for Bar { type Output = Foo; } fn test() { let a = Bar; let b = -a; b<|>; } //- /std.rs crate:std #[prelude_import] use ops::*; mod ops { #[lang = "neg"] pub trait Neg { type Output; } } "#, ); assert_eq!("Foo", type_at_pos(&db, pos)); } #[test] fn infer_ops_not() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std struct Bar; struct Foo; impl std::ops::Not for Bar { type Output = Foo; } fn test() { let a = Bar; let b = !a; b<|>; } //- /std.rs crate:std #[prelude_import] use ops::*; mod ops { #[lang = "not"] pub trait Not { type Output; } } "#, ); assert_eq!("Foo", type_at_pos(&db, pos)); } #[test] fn infer_from_bound_1() { assert_snapshot!( infer(r#" trait Trait<T> {} struct S<T>(T); impl<U> Trait<U> for S<U> {} fn foo<T: Trait<u32>>(t: T) {} fn test() { let s = S(unknown); foo(s); } "#), @r###" 86..87 't': T 92..94 '{}': () 105..144 '{ ...(s); }': () 115..116 's': S<u32> 119..120 'S': S<u32>(u32) -> S<u32> 119..129 'S(unknown)': S<u32> 121..128 'unknown': u32 135..138 'foo': fn foo<S<u32>>(S<u32>) 135..141 'foo(s)': () 139..140 's': S<u32> "### ); } #[test] fn infer_from_bound_2() { assert_snapshot!( infer(r#" trait Trait<T> {} struct S<T>(T); impl<U> Trait<U> for S<U> {} fn foo<U, T: Trait<U>>(t: T) -> U {} fn test() { let s = S(unknown); let x: u32 = foo(s); } "#), @r###" 87..88 't': T 98..100 '{}': () 111..163 '{ ...(s); }': () 121..122 's': S<u32> 125..126 'S': S<u32>(u32) -> S<u32> 125..135 'S(unknown)': S<u32> 127..134 'unknown': u32 145..146 'x': u32 154..157 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32 154..160 'foo(s)': u32 158..159 's': S<u32> "### ); } #[test] fn trait_default_method_self_bound_implements_trait() { test_utils::covers!(trait_self_implements_self); assert_snapshot!( infer(r#" trait Trait { fn foo(&self) -> i64; fn bar(&self) -> { let x = self.foo(); } } "#), @r###" 27..31 'self': &Self 53..57 'self': &Self 62..97 '{ ... }': () 76..77 'x': i64 80..84 'self': &Self 80..90 'self.foo()': i64 "### ); } #[test] fn trait_default_method_self_bound_implements_super_trait() { test_utils::covers!(trait_self_implements_self); assert_snapshot!( infer(r#" trait SuperTrait { fn foo(&self) -> i64; } trait Trait: SuperTrait { fn bar(&self) -> { let x = self.foo(); } } "#), @r###" 32..36 'self': &Self 86..90 'self': &Self 95..130 '{ ... }': () 109..110 'x': i64 113..117 'self': &Self 113..123 'self.foo()': i64 "### ); } #[test] fn infer_project_associated_type() { assert_snapshot!( infer(r#" trait Iterable { type Item; } struct S; impl Iterable for S { type Item = u32; } fn test<T: Iterable>() { let x: <S as Iterable>::Item = 1; let y: <T as Iterable>::Item = no_matter; let z: T::Item = no_matter; let a: <T>::Item = no_matter; } "#), @r###" 108..261 '{ ...ter; }': () 118..119 'x': u32 145..146 '1': u32 156..157 'y': Iterable::Item<T> 183..192 'no_matter': Iterable::Item<T> 202..203 'z': Iterable::Item<T> 215..224 'no_matter': Iterable::Item<T> 234..235 'a': Iterable::Item<T> 249..258 'no_matter': Iterable::Item<T> "### ); } #[test] fn infer_return_associated_type() { assert_snapshot!( infer(r#" trait Iterable { type Item; } struct S; impl Iterable for S { type Item = u32; } fn foo1<T: Iterable>(t: T) -> T::Item {} fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} fn foo3<T: Iterable>(t: T) -> <T>::Item {} fn test() { let x = foo1(S); let y = foo2(S); let z = foo3(S); } "#), @r###" 106..107 't': T 123..125 '{}': () 147..148 't': T 178..180 '{}': () 202..203 't': T 221..223 '{}': () 234..300 '{ ...(S); }': () 244..245 'x': u32 248..252 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item 248..255 'foo1(S)': u32 253..254 'S': S 265..266 'y': u32 269..273 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item 269..276 'foo2(S)': u32 274..275 'S': S 286..287 'z': u32 290..294 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item 290..297 'foo3(S)': u32 295..296 'S': S "### ); } #[test] fn infer_associated_type_bound() { assert_snapshot!( infer(r#" trait Iterable { type Item; } fn test<T: Iterable<Item=u32>>() { let y: T::Item = unknown; } "#), @r###" 67..100 '{ ...own; }': () 77..78 'y': u32 90..97 'unknown': u32 "### ); } #[test] fn infer_const_body() { assert_snapshot!( infer(r#" const A: u32 = 1 + 1; static B: u64 = { let x = 1; x }; "#), @r###" 16..17 '1': u32 16..21 '1 + 1': u32 20..21 '1': u32 39..55 '{ let ...1; x }': u64 45..46 'x': u64 49..50 '1': u64 52..53 'x': u64 "### ); } #[test] fn tuple_struct_fields() { assert_snapshot!( infer(r#" struct S(i32, u64); fn test() -> u64 { let a = S(4, 6); let b = a.0; a.1 } "#), @r###" 38..87 '{ ... a.1 }': u64 48..49 'a': S 52..53 'S': S(i32, u64) -> S 52..59 'S(4, 6)': S 54..55 '4': i32 57..58 '6': u64 69..70 'b': i32 73..74 'a': S 73..76 'a.0': i32 82..83 'a': S 82..85 'a.1': u64 "### ); } #[test] fn tuple_struct_with_fn() { assert_snapshot!( infer(r#" struct S(fn(u32) -> u64); fn test() -> u64 { let a = S(|i| 2*i); let b = a.0(4); a.0(2) } "#), @r###" 44..102 '{ ...0(2) }': u64 54..55 'a': S 58..59 'S': S(fn(u32) -> u64) -> S 58..68 'S(|i| 2*i)': S 60..67 '|i| 2*i': |u32| -> u64 61..62 'i': u32 64..65 '2': u32 64..67 '2*i': u32 66..67 'i': u32 78..79 'b': u64 82..83 'a': S 82..85 'a.0': fn(u32) -> u64 82..88 'a.0(4)': u64 86..87 '4': u32 94..95 'a': S 94..97 'a.0': fn(u32) -> u64 94..100 'a.0(2)': u64 98..99 '2': u32 "### ); } #[test] fn indexing_arrays() { assert_snapshot!( infer("fn main() { &mut [9][2]; }"), @r###" 10..26 '{ &mut...[2]; }': () 12..23 '&mut [9][2]': &mut {unknown} 17..20 '[9]': [i32; _] 17..23 '[9][2]': {unknown} 18..19 '9': i32 21..22 '2': i32 "### ) } #[test] fn infer_ops_index() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std struct Bar; struct Foo; impl std::ops::Index<u32> for Bar { type Output = Foo; } fn test() { let a = Bar; let b = a[1u32]; b<|>; } //- /std.rs crate:std #[prelude_import] use ops::*; mod ops { #[lang = "index"] pub trait Index<Idx> { type Output; } } "#, ); assert_eq!("Foo", type_at_pos(&db, pos)); } #[test] fn infer_ops_index_autoderef() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std fn test() { let a = &[1u32, 2, 3]; let b = a[1u32]; b<|>; } //- /std.rs crate:std impl<T> ops::Index<u32> for [T] { type Output = T; } #[prelude_import] use ops::*; mod ops { #[lang = "index"] pub trait Index<Idx> { type Output; } } "#, ); assert_eq!("u32", type_at_pos(&db, pos)); } #[test] fn deref_trait() { let t = type_at( r#" //- /main.rs #[lang = "deref"] trait Deref { type Target; fn deref(&self) -> &Self::Target; } struct Arc<T>; impl<T> Deref for Arc<T> { type Target = T; } struct S; impl S { fn foo(&self) -> u128 {} } fn test(s: Arc<S>) { (*s, s.foo())<|>; } "#, ); assert_eq!(t, "(S, u128)"); } #[test] fn deref_trait_with_inference_var() { let t = type_at( r#" //- /main.rs #[lang = "deref"] trait Deref { type Target; fn deref(&self) -> &Self::Target; } struct Arc<T>; fn new_arc<T>() -> Arc<T> {} impl<T> Deref for Arc<T> { type Target = T; } struct S; fn foo(a: Arc<S>) {} fn test() { let a = new_arc(); let b = (*a)<|>; foo(a); } "#, ); assert_eq!(t, "S"); } #[test] fn deref_trait_infinite_recursion() { let t = type_at( r#" //- /main.rs #[lang = "deref"] trait Deref { type Target; fn deref(&self) -> &Self::Target; } struct S; impl Deref for S { type Target = S; } fn test(s: S) { s.foo()<|>; } "#, ); assert_eq!(t, "{unknown}"); } #[test] fn deref_trait_with_question_mark_size() { let t = type_at( r#" //- /main.rs #[lang = "deref"] trait Deref { type Target; fn deref(&self) -> &Self::Target; } struct Arc<T>; impl<T> Deref for Arc<T> { type Target = T; } struct S; impl S { fn foo(&self) -> u128 {} } fn test(s: Arc<S>) { (*s, s.foo())<|>; } "#, ); assert_eq!(t, "(S, u128)"); } #[test] fn obligation_from_function_clause() { let t = type_at( r#" //- /main.rs struct S; trait Trait<T> {} impl Trait<u32> for S {} fn foo<T: Trait<U>, U>(t: T) -> U {} fn test(s: S) { foo(s)<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn obligation_from_method_clause() { let t = type_at( r#" //- /main.rs struct S; trait Trait<T> {} impl Trait<isize> for S {} struct O; impl O { fn foo<T: Trait<U>, U>(&self, t: T) -> U {} } fn test() { O.foo(S)<|>; } "#, ); assert_eq!(t, "isize"); } #[test] fn obligation_from_self_method_clause() { let t = type_at( r#" //- /main.rs struct S; trait Trait<T> {} impl Trait<i64> for S {} impl S { fn foo<U>(&self) -> U where Self: Trait<U> {} } fn test() { S.foo()<|>; } "#, ); assert_eq!(t, "i64"); } #[test] fn obligation_from_impl_clause() { let t = type_at( r#" //- /main.rs struct S; trait Trait<T> {} impl Trait<&str> for S {} struct O<T>; impl<U, T: Trait<U>> O<T> { fn foo(&self) -> U {} } fn test(o: O<S>) { o.foo()<|>; } "#, ); assert_eq!(t, "&str"); } #[test] fn generic_param_env_1() { let t = type_at( r#" //- /main.rs trait Clone {} trait Trait { fn foo(self) -> u128; } struct S; impl Clone for S {} impl<T> Trait for T where T: Clone {} fn test<T: Clone>(t: T) { t.foo()<|>; } "#, ); assert_eq!(t, "u128"); } #[test] fn generic_param_env_1_not_met() { let t = type_at( r#" //- /main.rs trait Clone {} trait Trait { fn foo(self) -> u128; } struct S; impl Clone for S {} impl<T> Trait for T where T: Clone {} fn test<T>(t: T) { t.foo()<|>; } "#, ); assert_eq!(t, "{unknown}"); } #[test] fn generic_param_env_2() { let t = type_at( r#" //- /main.rs trait Trait { fn foo(self) -> u128; } struct S; impl Trait for S {} fn test<T: Trait>(t: T) { t.foo()<|>; } "#, ); assert_eq!(t, "u128"); } #[test] fn generic_param_env_2_not_met() { let t = type_at( r#" //- /main.rs trait Trait { fn foo(self) -> u128; } struct S; impl Trait for S {} fn test<T>(t: T) { t.foo()<|>; } "#, ); assert_eq!(t, "{unknown}"); } #[test] fn generic_param_env_deref() { let t = type_at( r#" //- /main.rs #[lang = "deref"] trait Deref { type Target; } trait Trait {} impl<T> Deref for T where T: Trait { type Target = i128; } fn test<T: Trait>(t: T) { (*t)<|>; } "#, ); assert_eq!(t, "i128"); } #[test] fn associated_type_placeholder() { let t = type_at( r#" //- /main.rs pub trait ApplyL { type Out; } pub struct RefMutL<T>; impl<T> ApplyL for RefMutL<T> { type Out = <T as ApplyL>::Out; } fn test<T: ApplyL>() { let y: <RefMutL<T> as ApplyL>::Out = no_matter; y<|>; } "#, ); // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. assert_eq!(t, "ApplyL::Out<T>"); } #[test] fn associated_type_placeholder_2() { let t = type_at( r#" //- /main.rs pub trait ApplyL { type Out; } fn foo<T: ApplyL>(t: T) -> <T as ApplyL>::Out; fn test<T: ApplyL>(t: T) { let y = foo(t); y<|>; } "#, ); assert_eq!(t, "ApplyL::Out<T>"); } #[test] fn argument_impl_trait() { assert_snapshot!( infer_with_mismatches(r#" trait Trait<T> { fn foo(&self) -> T; fn foo2(&self) -> i64; } fn bar(x: impl Trait<u16>) {} struct S<T>(T); impl<T> Trait<T> for S<T> {} fn test(x: impl Trait<u64>, y: &impl Trait<u32>) { x; y; let z = S(1); bar(z); x.foo(); y.foo(); z.foo(); x.foo2(); y.foo2(); z.foo2(); } "#, true), @r###" 30..34 'self': &Self 55..59 'self': &Self 78..79 'x': impl Trait<u16> 98..100 '{}': () 155..156 'x': impl Trait<u64> 175..176 'y': &impl Trait<u32> 196..324 '{ ...2(); }': () 202..203 'x': impl Trait<u64> 209..210 'y': &impl Trait<u32> 220..221 'z': S<u16> 224..225 'S': S<u16>(u16) -> S<u16> 224..228 'S(1)': S<u16> 226..227 '1': u16 234..237 'bar': fn bar(S<u16>) 234..240 'bar(z)': () 238..239 'z': S<u16> 246..247 'x': impl Trait<u64> 246..253 'x.foo()': u64 259..260 'y': &impl Trait<u32> 259..266 'y.foo()': u32 272..273 'z': S<u16> 272..279 'z.foo()': u16 285..286 'x': impl Trait<u64> 285..293 'x.foo2()': i64 299..300 'y': &impl Trait<u32> 299..307 'y.foo2()': i64 313..314 'z': S<u16> 313..321 'z.foo2()': i64 "### ); } #[test] fn argument_impl_trait_type_args_1() { assert_snapshot!( infer_with_mismatches(r#" trait Trait {} trait Foo { // this function has an implicit Self param, an explicit type param, // and an implicit impl Trait param! fn bar<T>(x: impl Trait) -> T { loop {} } } fn foo<T>(x: impl Trait) -> T { loop {} } struct S; impl Trait for S {} struct F; impl Foo for F {} fn test() { Foo::bar(S); <F as Foo>::bar(S); F::bar(S); Foo::bar::<u32>(S); <F as Foo>::bar::<u32>(S); foo(S); foo::<u32>(S); foo::<u32, i32>(S); // we should ignore the extraneous i32 } "#, true), @r###" 156..157 'x': impl Trait 176..187 '{ loop {} }': T 178..185 'loop {}': ! 183..185 '{}': () 200..201 'x': impl Trait 220..231 '{ loop {} }': T 222..229 'loop {}': ! 227..229 '{}': () 301..510 '{ ... i32 }': () 307..315 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} 307..318 'Foo::bar(S)': {unknown} 316..317 'S': S 324..339 '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown} 324..342 '<F as ...bar(S)': {unknown} 340..341 'S': S 348..354 'F::bar': fn bar<F, {unknown}>(S) -> {unknown} 348..357 'F::bar(S)': {unknown} 355..356 'S': S 363..378 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32 363..381 'Foo::b...32>(S)': u32 379..380 'S': S 387..409 '<F as ...:<u32>': fn bar<F, u32>(S) -> u32 387..412 '<F as ...32>(S)': u32 410..411 'S': S 419..422 'foo': fn foo<{unknown}>(S) -> {unknown} 419..425 'foo(S)': {unknown} 423..424 'S': S 431..441 'foo::<u32>': fn foo<u32>(S) -> u32 431..444 'foo::<u32>(S)': u32 442..443 'S': S 450..465 'foo::<u32, i32>': fn foo<u32>(S) -> u32 450..468 'foo::<...32>(S)': u32 466..467 'S': S "### ); } #[test] fn argument_impl_trait_type_args_2() { assert_snapshot!( infer_with_mismatches(r#" trait Trait {} struct S; impl Trait for S {} struct F<T>; impl<T> F<T> { fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} } } fn test() { F.foo(S); F::<u32>.foo(S); F::<u32>.foo::<i32>(S); F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored } "#, true), @r###" 88..92 'self': F<T> 94..95 'x': impl Trait 119..130 '{ loop {} }': (T, U) 121..128 'loop {}': ! 126..128 '{}': () 144..284 '{ ...ored }': () 150..151 'F': F<{unknown}> 150..158 'F.foo(S)': ({unknown}, {unknown}) 156..157 'S': S 164..172 'F::<u32>': F<u32> 164..179 'F::<u32>.foo(S)': (u32, {unknown}) 177..178 'S': S 185..193 'F::<u32>': F<u32> 185..207 'F::<u3...32>(S)': (u32, i32) 205..206 'S': S 213..221 'F::<u32>': F<u32> 213..240 'F::<u3...32>(S)': (u32, i32) 238..239 'S': S "### ); } #[test] fn argument_impl_trait_to_fn_pointer() { assert_snapshot!( infer_with_mismatches(r#" trait Trait {} fn foo(x: impl Trait) { loop {} } struct S; impl Trait for S {} fn test() { let f: fn(S) -> () = foo; } "#, true), @r###" 23..24 'x': impl Trait 38..49 '{ loop {} }': () 40..47 'loop {}': ! 45..47 '{}': () 91..124 '{ ...foo; }': () 101..102 'f': fn(S) 118..121 'foo': fn foo(S) "### ); } #[test] #[ignore] fn impl_trait() { assert_snapshot!( infer(r#" trait Trait<T> { fn foo(&self) -> T; fn foo2(&self) -> i64; } fn bar() -> impl Trait<u64> {} fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { x; y; let z = bar(); x.foo(); y.foo(); z.foo(); x.foo2(); y.foo2(); z.foo2(); } "#), @r###" 30..34 'self': &Self 55..59 'self': &Self 99..101 '{}': () 111..112 'x': impl Trait<u64> 131..132 'y': &impl Trait<u64> 152..269 '{ ...2(); }': () 158..159 'x': impl Trait<u64> 165..166 'y': &impl Trait<u64> 176..177 'z': impl Trait<u64> 180..183 'bar': fn bar() -> impl Trait<u64> 180..185 'bar()': impl Trait<u64> 191..192 'x': impl Trait<u64> 191..198 'x.foo()': u64 204..205 'y': &impl Trait<u64> 204..211 'y.foo()': u64 217..218 'z': impl Trait<u64> 217..224 'z.foo()': u64 230..231 'x': impl Trait<u64> 230..238 'x.foo2()': i64 244..245 'y': &impl Trait<u64> 244..252 'y.foo2()': i64 258..259 'z': impl Trait<u64> 258..266 'z.foo2()': i64 "### ); } #[test] fn dyn_trait() { assert_snapshot!( infer(r#" trait Trait<T> { fn foo(&self) -> T; fn foo2(&self) -> i64; } fn bar() -> dyn Trait<u64> {} fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) { x; y; let z = bar(); x.foo(); y.foo(); z.foo(); x.foo2(); y.foo2(); z.foo2(); } "#), @r###" 30..34 'self': &Self 55..59 'self': &Self 98..100 '{}': () 110..111 'x': dyn Trait<u64> 129..130 'y': &dyn Trait<u64> 149..266 '{ ...2(); }': () 155..156 'x': dyn Trait<u64> 162..163 'y': &dyn Trait<u64> 173..174 'z': dyn Trait<u64> 177..180 'bar': fn bar() -> dyn Trait<u64> 177..182 'bar()': dyn Trait<u64> 188..189 'x': dyn Trait<u64> 188..195 'x.foo()': u64 201..202 'y': &dyn Trait<u64> 201..208 'y.foo()': u64 214..215 'z': dyn Trait<u64> 214..221 'z.foo()': u64 227..228 'x': dyn Trait<u64> 227..235 'x.foo2()': i64 241..242 'y': &dyn Trait<u64> 241..249 'y.foo2()': i64 255..256 'z': dyn Trait<u64> 255..263 'z.foo2()': i64 "### ); } #[test] fn dyn_trait_in_impl() { assert_snapshot!( infer(r#" trait Trait<T, U> { fn foo(&self) -> (T, U); } struct S<T, U> {} impl<T, U> S<T, U> { fn bar(&self) -> &dyn Trait<T, U> { loop {} } } trait Trait2<T, U> { fn baz(&self) -> (T, U); } impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } fn test(s: S<u32, i32>) { s.bar().baz(); } "#), @r###" 33..37 'self': &Self 103..107 'self': &S<T, U> 129..140 '{ loop {} }': &dyn Trait<T, U> 131..138 'loop {}': ! 136..138 '{}': () 176..180 'self': &Self 252..253 's': S<u32, i32> 268..290 '{ ...z(); }': () 274..275 's': S<u32, i32> 274..281 's.bar()': &dyn Trait<u32, i32> 274..287 's.bar().baz()': (u32, i32) "### ); } #[test] fn dyn_trait_bare() { assert_snapshot!( infer(r#" trait Trait { fn foo(&self) -> u64; } fn bar() -> Trait {} fn test(x: Trait, y: &Trait) -> u64 { x; y; let z = bar(); x.foo(); y.foo(); z.foo(); } "#), @r###" 27..31 'self': &Self 61..63 '{}': () 73..74 'x': dyn Trait 83..84 'y': &dyn Trait 101..176 '{ ...o(); }': () 107..108 'x': dyn Trait 114..115 'y': &dyn Trait 125..126 'z': dyn Trait 129..132 'bar': fn bar() -> dyn Trait 129..134 'bar()': dyn Trait 140..141 'x': dyn Trait 140..147 'x.foo()': u64 153..154 'y': &dyn Trait 153..160 'y.foo()': u64 166..167 'z': dyn Trait 166..173 'z.foo()': u64 "### ); } #[test] fn weird_bounds() { assert_snapshot!( infer(r#" trait Trait {} fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) { } "#), @r###" 24..25 'a': impl Trait + {error} 51..52 'b': impl {error} 70..71 'c': impl Trait 87..88 'd': impl {error} 108..109 'e': impl {error} 124..125 'f': impl Trait + {error} 148..151 '{ }': () "### ); } #[test] #[ignore] fn error_bound_chalk() { let t = type_at( r#" //- /main.rs trait Trait { fn foo(&self) -> u32 {} } fn test(x: (impl Trait + UnknownTrait)) { x.foo()<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn assoc_type_bindings() { assert_snapshot!( infer(r#" trait Trait { type Type; } fn get<T: Trait>(t: T) -> <T as Trait>::Type {} fn get2<U, T: Trait<Type = U>>(t: T) -> U {} fn set<T: Trait<Type = u64>>(t: T) -> T {t} struct S<T>; impl<T> Trait for S<T> { type Type = T; } fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { get(x); get2(x); get(y); get2(y); get(set(S)); get2(set(S)); get2(S::<str>); } "#), @r###" 50..51 't': T 78..80 '{}': () 112..113 't': T 123..125 '{}': () 155..156 't': T 166..169 '{t}': T 167..168 't': T 257..258 'x': T 263..264 'y': impl Trait<Type = i64> 290..398 '{ ...r>); }': () 296..299 'get': fn get<T>(T) -> <T as Trait>::Type 296..302 'get(x)': u32 300..301 'x': T 308..312 'get2': fn get2<u32, T>(T) -> u32 308..315 'get2(x)': u32 313..314 'x': T 321..324 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type 321..327 'get(y)': i64 325..326 'y': impl Trait<Type = i64> 333..337 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64 333..340 'get2(y)': i64 338..339 'y': impl Trait<Type = i64> 346..349 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type 346..357 'get(set(S))': u64 350..353 'set': fn set<S<u64>>(S<u64>) -> S<u64> 350..356 'set(S)': S<u64> 354..355 'S': S<u64> 363..367 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 363..375 'get2(set(S))': u64 368..371 'set': fn set<S<u64>>(S<u64>) -> S<u64> 368..374 'set(S)': S<u64> 372..373 'S': S<u64> 381..385 'get2': fn get2<str, S<str>>(S<str>) -> str 381..395 'get2(S::<str>)': str 386..394 'S::<str>': S<str> "### ); } #[test] fn impl_trait_assoc_binding_projection_bug() { let (db, pos) = TestDB::with_position( r#" //- /main.rs crate:main deps:std pub trait Language { type Kind; } pub enum RustLanguage {} impl Language for RustLanguage { type Kind = SyntaxKind; } struct SyntaxNode<L> {} fn foo() -> impl Iterator<Item = SyntaxNode<RustLanguage>> {} trait Clone { fn clone(&self) -> Self; } fn api_walkthrough() { for node in foo() { node.clone()<|>; } } //- /std.rs crate:std #[prelude_import] use iter::*; mod iter { trait IntoIterator { type Item; } trait Iterator { type Item; } impl<T: Iterator> IntoIterator for T { type Item = <T as Iterator>::Item; } } "#, ); assert_eq!("{unknown}", type_at_pos(&db, pos)); } #[test] fn projection_eq_within_chalk() { assert_snapshot!( infer(r#" trait Trait1 { type Type; } trait Trait2<T> { fn foo(self) -> T; } impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {} fn test<T: Trait1<Type = u32>>(x: T) { x.foo(); } "#), @r###" 62..66 'self': Self 164..165 'x': T 170..186 '{ ...o(); }': () 176..177 'x': T 176..183 'x.foo()': u32 "### ); } #[test] fn where_clause_trait_in_scope_for_method_resolution() { let t = type_at( r#" //- /main.rs mod foo { trait Trait { fn foo(&self) -> u32 {} } } fn test<T: foo::Trait>(x: T) { x.foo()<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn super_trait_method_resolution() { assert_snapshot!( infer(r#" mod foo { trait SuperTrait { fn foo(&self) -> u32 {} } } trait Trait1: foo::SuperTrait {} trait Trait2 where Self: foo::SuperTrait {} fn test<T: Trait1, U: Trait2>(x: T, y: U) { x.foo(); y.foo(); } "#), @r###" 50..54 'self': &Self 63..65 '{}': () 182..183 'x': T 188..189 'y': U 194..223 '{ ...o(); }': () 200..201 'x': T 200..207 'x.foo()': u32 213..214 'y': U 213..220 'y.foo()': u32 "### ); } #[test] fn super_trait_impl_trait_method_resolution() { assert_snapshot!( infer(r#" mod foo { trait SuperTrait { fn foo(&self) -> u32 {} } } trait Trait1: foo::SuperTrait {} fn test(x: &impl Trait1) { x.foo(); } "#), @r###" 50..54 'self': &Self 63..65 '{}': () 116..117 'x': &impl Trait1 133..149 '{ ...o(); }': () 139..140 'x': &impl Trait1 139..146 'x.foo()': u32 "### ); } #[test] fn super_trait_cycle() { // This just needs to not crash assert_snapshot!( infer(r#" trait A: B {} trait B: A {} fn test<T: A>(x: T) { x.foo(); } "#), @r###" 44..45 'x': T 50..66 '{ ...o(); }': () 56..57 'x': T 56..63 'x.foo()': {unknown} "### ); } #[test] fn super_trait_assoc_type_bounds() { assert_snapshot!( infer(r#" trait SuperTrait { type Type; } trait Trait where Self: SuperTrait {} fn get2<U, T: Trait<Type = U>>(t: T) -> U {} fn set<T: Trait<Type = u64>>(t: T) -> T {t} struct S<T>; impl<T> SuperTrait for S<T> { type Type = T; } impl<T> Trait for S<T> {} fn test() { get2(set(S)); } "#), @r###" 103..104 't': T 114..116 '{}': () 146..147 't': T 157..160 '{t}': T 158..159 't': T 259..280 '{ ...S)); }': () 265..269 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 265..277 'get2(set(S))': u64 270..273 'set': fn set<S<u64>>(S<u64>) -> S<u64> 270..276 'set(S)': S<u64> 274..275 'S': S<u64> "### ); } #[test] fn fn_trait() { assert_snapshot!( infer(r#" trait FnOnce<Args> { type Output; fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; } fn test<F: FnOnce(u32, u64) -> u128>(f: F) { f.call_once((1, 2)); } "#), @r###" 57..61 'self': Self 63..67 'args': Args 150..151 'f': F 156..184 '{ ...2)); }': () 162..163 'f': F 162..181 'f.call...1, 2))': u128 174..180 '(1, 2)': (u32, u64) 175..176 '1': u32 178..179 '2': u64 "### ); } #[test] fn closure_1() { assert_snapshot!( infer(r#" #[lang = "fn_once"] trait FnOnce<Args> { type Output; } enum Option<T> { Some(T), None } impl<T> Option<T> { fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} } fn test() { let x = Option::Some(1u32); x.map(|v| v + 1); x.map(|_v| 1u64); let y: Option<i64> = x.map(|_v| 1); } "#), @r###" 148..152 'self': Option<T> 154..155 'f': F 173..175 '{}': () 189..308 '{ ... 1); }': () 199..200 'x': Option<u32> 203..215 'Option::Some': Some<u32>(u32) -> Option<u32> 203..221 'Option...(1u32)': Option<u32> 216..220 '1u32': u32 227..228 'x': Option<u32> 227..243 'x.map(...v + 1)': Option<u32> 233..242 '|v| v + 1': |u32| -> u32 234..235 'v': u32 237..238 'v': u32 237..242 'v + 1': u32 241..242 '1': u32 249..250 'x': Option<u32> 249..265 'x.map(... 1u64)': Option<u64> 255..264 '|_v| 1u64': |u32| -> u64 256..258 '_v': u32 260..264 '1u64': u64 275..276 'y': Option<i64> 292..293 'x': Option<u32> 292..305 'x.map(|_v| 1)': Option<i64> 298..304 '|_v| 1': |u32| -> i64 299..301 '_v': u32 303..304 '1': i64 "### ); } #[test] fn closure_2() { assert_snapshot!( infer(r#" trait FnOnce<Args> { type Output; } fn test<F: FnOnce(u32) -> u64>(f: F) { f(1); let g = |v| v + 1; g(1u64); let h = |v| 1u128 + v; } "#), @r###" 73..74 'f': F 79..155 '{ ...+ v; }': () 85..86 'f': F 85..89 'f(1)': {unknown} 87..88 '1': i32 99..100 'g': |u64| -> i32 103..112 '|v| v + 1': |u64| -> i32 104..105 'v': u64 107..108 'v': u64 107..112 'v + 1': i32 111..112 '1': i32 118..119 'g': |u64| -> i32 118..125 'g(1u64)': i32 120..124 '1u64': u64 135..136 'h': |u128| -> u128 139..152 '|v| 1u128 + v': |u128| -> u128 140..141 'v': u128 143..148 '1u128': u128 143..152 '1u128 + v': u128 151..152 'v': u128 "### ); } #[test] fn closure_as_argument_inference_order() { assert_snapshot!( infer(r#" #[lang = "fn_once"] trait FnOnce<Args> { type Output; } fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} struct S; impl S { fn method(self) -> u64; fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} } fn test() { let x1 = foo1(S, |s| s.method()); let x2 = foo2(|s| s.method(), S); let x3 = S.foo1(S, |s| s.method()); let x4 = S.foo2(|s| s.method(), S); } "#), @r###" 95..96 'x': T 101..102 'f': F 112..114 '{}': () 148..149 'f': F 154..155 'x': T 165..167 '{}': () 202..206 'self': S 254..258 'self': S 260..261 'x': T 266..267 'f': F 277..279 '{}': () 317..321 'self': S 323..324 'f': F 329..330 'x': T 340..342 '{}': () 356..515 '{ ... S); }': () 366..368 'x1': u64 371..375 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 371..394 'foo1(S...hod())': u64 376..377 'S': S 379..393 '|s| s.method()': |S| -> u64 380..381 's': S 383..384 's': S 383..393 's.method()': u64 404..406 'x2': u64 409..413 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 409..432 'foo2(|...(), S)': u64 414..428 '|s| s.method()': |S| -> u64 415..416 's': S 418..419 's': S 418..428 's.method()': u64 430..431 'S': S 442..444 'x3': u64 447..448 'S': S 447..472 'S.foo1...hod())': u64 454..455 'S': S 457..471 '|s| s.method()': |S| -> u64 458..459 's': S 461..462 's': S 461..471 's.method()': u64 482..484 'x4': u64 487..488 'S': S 487..512 'S.foo2...(), S)': u64 494..508 '|s| s.method()': |S| -> u64 495..496 's': S 498..499 's': S 498..508 's.method()': u64 510..511 'S': S "### ); } #[test] fn unselected_projection_in_trait_env_1() { let t = type_at( r#" //- /main.rs trait Trait { type Item; } trait Trait2 { fn foo(&self) -> u32; } fn test<T: Trait>() where T::Item: Trait2 { let x: T::Item = no_matter; x.foo()<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn unselected_projection_in_trait_env_2() { let t = type_at( r#" //- /main.rs trait Trait<T> { type Item; } trait Trait2 { fn foo(&self) -> u32; } fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> { let x: T::Item = no_matter; x.foo()<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn unselected_projection_on_impl_self() { assert_snapshot!(infer( r#" //- /main.rs trait Trait { type Item; fn f(&self, x: Self::Item); } struct S; impl Trait for S { type Item = u32; fn f(&self, x: Self::Item) { let y = x; } } struct S2; impl Trait for S2 { type Item = i32; fn f(&self, x: <Self>::Item) { let y = x; } } "#, ), @r###" 54..58 'self': &Self 60..61 'x': Trait::Item<Self> 140..144 'self': &S 146..147 'x': u32 161..175 '{ let y = x; }': () 167..168 'y': u32 171..172 'x': u32 242..246 'self': &S2 248..249 'x': i32 265..279 '{ let y = x; }': () 271..272 'y': i32 275..276 'x': i32 "###); } #[test] fn unselected_projection_on_trait_self() { let t = type_at( r#" //- /main.rs trait Trait { type Item; fn f(&self) -> Self::Item { loop {} } } struct S; impl Trait for S { type Item = u32; } fn test() { S.f()<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn unselected_projection_chalk_fold() { let t = type_at( r#" //- /main.rs trait Interner {} trait Fold<I: Interner, TI = I> { type Result; } struct Ty<I: Interner> {} impl<I: Interner, TI: Interner> Fold<I, TI> for Ty<I> { type Result = Ty<TI>; } fn fold<I: Interner, T>(interner: &I, t: T) -> T::Result where T: Fold<I, I>, { loop {} } fn foo<I: Interner>(interner: &I, t: Ty<I>) { fold(interner, t)<|>; } "#, ); assert_eq!(t, "Ty<I>"); } #[test] fn trait_impl_self_ty() { let t = type_at( r#" //- /main.rs trait Trait<T> { fn foo(&self); } struct S; impl Trait<Self> for S {} fn test() { S.foo()<|>; } "#, ); assert_eq!(t, "()"); } #[test] fn trait_impl_self_ty_cycle() { let t = type_at( r#" //- /main.rs trait Trait { fn foo(&self); } struct S<T>; impl Trait for S<Self> {} fn test() { S.foo()<|>; } "#, ); assert_eq!(t, "{unknown}"); } #[test] fn unselected_projection_in_trait_env_cycle_1() { let t = type_at( r#" //- /main.rs trait Trait { type Item; } trait Trait2<T> {} fn test<T: Trait>() where T: Trait2<T::Item> { let x: T::Item = no_matter<|>; } "#, ); // this is a legitimate cycle assert_eq!(t, "{unknown}"); } #[test] fn unselected_projection_in_trait_env_cycle_2() { let t = type_at( r#" //- /main.rs trait Trait<T> { type Item; } fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> { let x: T::Item = no_matter<|>; } "#, ); // this is a legitimate cycle assert_eq!(t, "{unknown}"); } #[test] fn inline_assoc_type_bounds_1() { let t = type_at( r#" //- /main.rs trait Iterator { type Item; } trait OtherTrait<T> { fn foo(&self) -> T; } // workaround for Chalk assoc type normalization problems pub struct S<T>; impl<T: Iterator> Iterator for S<T> { type Item = <T as Iterator>::Item; } fn test<I: Iterator<Item: OtherTrait<u32>>>() { let x: <S<I> as Iterator>::Item; x.foo()<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn inline_assoc_type_bounds_2() { let t = type_at( r#" //- /main.rs trait Iterator { type Item; } fn test<I: Iterator<Item: Iterator<Item = u32>>>() { let x: <<I as Iterator>::Item as Iterator>::Item; x<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn proc_macro_server_types() { assert_snapshot!( infer(r#" macro_rules! with_api { ($S:ident, $self:ident, $m:ident) => { $m! { TokenStream { fn new() -> $S::TokenStream; }, Group { }, } }; } macro_rules! associated_item { (type TokenStream) => (type TokenStream: 'static;); (type Group) => (type Group: 'static;); ($($item:tt)*) => ($($item)*;) } macro_rules! declare_server_traits { ($($name:ident { $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* }),* $(,)?) => { pub trait Types { $(associated_item!(type $name);)* } $(pub trait $name: Types { $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* })* pub trait Server: Types $(+ $name)* {} impl<S: Types $(+ $name)*> Server for S {} } } with_api!(Self, self_, declare_server_traits); struct G {} struct T {} struct Rustc; impl Types for Rustc { type TokenStream = T; type Group = G; } fn make<T>() -> T { loop {} } impl TokenStream for Rustc { fn new() -> Self::TokenStream { let group: Self::Group = make(); make() } } "#), @r###" 1062..1073 '{ loop {} }': T 1064..1071 'loop {}': ! 1069..1071 '{}': () 1137..1200 '{ ... }': T 1151..1156 'group': G 1172..1176 'make': fn make<G>() -> G 1172..1178 'make()': G 1188..1192 'make': fn make<T>() -> T 1188..1194 'make()': T "### ); } #[test] fn unify_impl_trait() { assert_snapshot!( infer_with_mismatches(r#" trait Trait<T> {} fn foo(x: impl Trait<u32>) { loop {} } fn bar<T>(x: impl Trait<T>) -> T { loop {} } struct S<T>(T); impl<T> Trait<T> for S<T> {} fn default<T>() -> T { loop {} } fn test() -> impl Trait<i32> { let s1 = S(default()); foo(s1); let x: i32 = bar(S(default())); S(default()) } "#, true), @r###" 27..28 'x': impl Trait<u32> 47..58 '{ loop {} }': () 49..56 'loop {}': ! 54..56 '{}': () 69..70 'x': impl Trait<T> 92..103 '{ loop {} }': T 94..101 'loop {}': ! 99..101 '{}': () 172..183 '{ loop {} }': T 174..181 'loop {}': ! 179..181 '{}': () 214..310 '{ ...t()) }': S<{unknown}> 224..226 's1': S<u32> 229..230 'S': S<u32>(u32) -> S<u32> 229..241 'S(default())': S<u32> 231..238 'default': fn default<u32>() -> u32 231..240 'default()': u32 247..250 'foo': fn foo(S<u32>) 247..254 'foo(s1)': () 251..253 's1': S<u32> 264..265 'x': i32 273..276 'bar': fn bar<i32>(S<i32>) -> i32 273..290 'bar(S(...lt()))': i32 277..278 'S': S<i32>(i32) -> S<i32> 277..289 'S(default())': S<i32> 279..286 'default': fn default<i32>() -> i32 279..288 'default()': i32 296..297 'S': S<{unknown}>({unknown}) -> S<{unknown}> 296..308 'S(default())': S<{unknown}> 298..305 'default': fn default<{unknown}>() -> {unknown} 298..307 'default()': {unknown} "### ); } #[test] fn assoc_types_from_bounds() { assert_snapshot!( infer(r#" //- /main.rs #[lang = "fn_once"] trait FnOnce<Args> { type Output; } trait T { type O; } impl T for () { type O = (); } fn f<X, F>(_v: F) where X: T, F: FnOnce(&X::O), { } fn main() { f::<(), _>(|z| { z; }); } "#), @r###" 147..149 '_v': F 192..195 '{ }': () 207..238 '{ ... }); }': () 213..223 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) 213..235 'f::<()... z; })': () 224..234 '|z| { z; }': |&()| -> () 225..226 'z': &() 228..234 '{ z; }': () 230..231 'z': &() "### ); } #[test] fn associated_type_bound() { let t = type_at( r#" //- /main.rs pub trait Trait { type Item: OtherTrait<u32>; } pub trait OtherTrait<T> { fn foo(&self) -> T; } // this is just a workaround for chalk#234 pub struct S<T>; impl<T: Trait> Trait for S<T> { type Item = <T as Trait>::Item; } fn test<T: Trait>() { let y: <S<T> as Trait>::Item = no_matter; y.foo()<|>; } "#, ); assert_eq!(t, "u32"); } #[test] fn dyn_trait_through_chalk() { let t = type_at( r#" //- /main.rs struct Box<T> {} #[lang = "deref"] trait Deref { type Target; } impl<T> Deref for Box<T> { type Target = T; } trait Trait { fn foo(&self); } fn test(x: Box<dyn Trait>) { x.foo()<|>; } "#, ); 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<Args> { type Output; } #[lang = "fn_mut"] trait FnMut<Args>: FnOnce<Args> { } enum Option<T> { Some(T), None } use Option::*; pub trait Iterator { type Item; fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where F: FnMut(Self::Item) -> Option<B>, { loop {} } fn for_each<F>(self, f: F) where F: FnMut(Self::Item), { loop {} } } pub trait IntoIterator { type Item; type IntoIter: Iterator<Item = Self::Item>; fn into_iter(self) -> Self::IntoIter; } pub struct FilterMap<I, F> { } impl<B, I: Iterator, F> Iterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B>, { type Item = B; } #[stable(feature = "rust1", since = "1.0.0")] impl<I: Iterator> IntoIterator for I { type Item = I::Item; type IntoIter = I; fn into_iter(self) -> I { self } } struct Vec<T> {} impl<T> Vec<T> { fn new() -> Self { loop {} } } impl<T> IntoIterator for Vec<T> { type Item = T; type IntoIter = IntoIter<T>; } pub struct IntoIter<T> { } impl<T> Iterator for IntoIter<T> { type Item = T; } fn main() { Vec::<i32>::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<Self, F> 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<T> 960..967 'loop {}': ! 965..967 '{}': () 1156..1287 '{ ... }); }': () 1162..1177 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> 1162..1179 'Vec::<...:new()': Vec<i32> 1162..1191 'Vec::<...iter()': IntoIter<i32> 1162..1256 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> 1162..1284 'Vec::<... y; })': () 1210..1255 '|x| if...None }': |i32| -> Option<u32> 1211..1212 'x': i32 1214..1255 'if x >...None }': Option<u32> 1217..1218 'x': i32 1217..1222 'x > 0': bool 1221..1222 '0': i32 1223..1241 '{ Some...u32) }': Option<u32> 1225..1229 'Some': Some<u32>(u32) -> Option<u32> 1225..1239 'Some(x as u32)': Option<u32> 1230..1231 'x': i32 1230..1238 'x as u32': u32 1247..1255 '{ None }': Option<u32> 1249..1253 'None': Option<u32> 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<T:A> B for T { type Output = T::OutputA; fn foo() -> Self::Output { loop {} } } fn main() { Bar::foo()<|>; } "#, ); assert_eq!(t, "Foo"); } #[test] fn trait_object_no_coercion() { assert_snapshot!( infer_with_mismatches(r#" trait Foo {} fn foo(x: &dyn Foo) {} fn test(x: &dyn Foo) { foo(x); } "#, true), @r###" 22..23 'x': &dyn Foo 35..37 '{}': () 47..48 'x': &dyn Foo 60..75 '{ foo(x); }': () 66..69 'foo': fn foo(&dyn Foo) 66..72 'foo(x)': () 70..71 'x': &dyn Foo "### ); }