2019-12-03 12:38:54 +00:00
use insta ::assert_snapshot ;
2019-12-15 20:06:08 +00:00
2019-12-03 12:38:54 +00:00
use ra_db ::fixture ::WithFixture ;
2019-12-15 20:06:08 +00:00
use super ::{ infer , infer_with_mismatches , type_at , type_at_pos } ;
use crate ::test_db ::TestDB ;
2019-12-03 12:38:54 +00:00
#[ 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 {
2019-12-29 16:39:31 +00:00
#[ lang = " future_trait " ]
2019-12-03 12:38:54 +00:00
trait Future {
type Output ;
}
}
" #,
) ;
assert_eq! ( " u64 " , type_at_pos ( & db , pos ) ) ;
}
2019-12-24 11:45:28 +00:00
#[ 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 {
2019-12-29 16:39:31 +00:00
#[ lang = " future_trait " ]
2019-12-24 11:45:28 +00:00
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 ) ) ;
}
2019-12-03 12:38:54 +00:00
#[ 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 ) ) ;
}
2019-12-13 11:44:42 +00:00
#[ 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 {
2019-12-29 16:39:31 +00:00
#[ lang = " neg " ]
2019-12-13 11:44:42 +00:00
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 {
2019-12-29 16:39:31 +00:00
#[ lang = " not " ]
2019-12-13 11:44:42 +00:00
pub trait Not {
type Output ;
}
}
" #,
) ;
assert_eq! ( " Foo " , type_at_pos ( & db , pos ) ) ;
}
2019-12-03 12:38:54 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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 >
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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 >
2019-12-03 12:38:54 +00:00
" ###
) ;
2020-02-14 18:16:42 +00:00
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
27 .. 31 ' self ' : & Self
53 .. 57 ' self ' : & Self
62 .. 97 ' { .. . } ' : ( )
76 .. 77 'x' : i64
80 .. 84 ' self ' : & Self
80 .. 90 ' self . foo ( ) ' : i64
2020-02-14 18:16:42 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
32 .. 36 ' self ' : & Self
86 .. 90 ' self ' : & Self
95 .. 130 ' { .. . } ' : ( )
109 .. 110 'x' : i64
113 .. 117 ' self ' : & Self
113 .. 123 ' self . foo ( ) ' : i64
2020-02-14 18:16:42 +00:00
" ###
) ;
2019-12-03 12:38:54 +00:00
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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 >
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
67 .. 100 ' { .. . own ; } ' : ( )
77 .. 78 'y' : u32
90 .. 97 ' unknown ' : u32
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ test ]
fn infer_const_body ( ) {
assert_snapshot! (
infer ( r #"
const A : u32 = 1 + 1 ;
static B : u64 = { let x = 1 ; x } ;
" #),
@ r ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ test ]
fn indexing_arrays ( ) {
assert_snapshot! (
infer ( " fn main() { &mut [9][2]; } " ) ,
@ r ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
)
}
2019-12-19 04:45:07 +00:00
#[ 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 ;
2020-04-10 15:44:43 +00:00
let b = a [ 1 u32 ] ;
2019-12-19 04:45:07 +00:00
b < | > ;
}
//- /std.rs crate:std
#[ prelude_import ] use ops ::* ;
mod ops {
2019-12-29 16:39:31 +00:00
#[ lang = " index " ]
2019-12-19 04:45:07 +00:00
pub trait Index < Idx > {
type Output ;
}
}
" #,
) ;
assert_eq! ( " Foo " , type_at_pos ( & db , pos ) ) ;
}
2020-02-29 21:48:23 +00:00
#[ test ]
fn infer_ops_index_autoderef ( ) {
let ( db , pos ) = TestDB ::with_position (
r #"
//- /main.rs crate:main deps:std
fn test ( ) {
let a = & [ 1 u32 , 2 , 3 ] ;
2020-04-10 15:44:43 +00:00
let b = a [ 1 u32 ] ;
2020-02-29 21:48:23 +00:00
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 ) ) ;
}
2019-12-03 12:38:54 +00:00
#[ 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].
2020-01-31 15:52:43 +00:00
assert_eq! ( t , " ApplyL::Out<T> " ) ;
2019-12-03 12:38:54 +00:00
}
#[ 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 < | > ;
}
" #,
) ;
2020-04-10 15:44:43 +00:00
assert_eq! ( t , " ApplyL::Out<T> " ) ;
2019-12-03 12:38:54 +00:00
}
2020-01-31 15:05:58 +00:00
#[ test ]
fn argument_impl_trait ( ) {
assert_snapshot! (
infer_with_mismatches ( r #"
trait Trait < T > {
fn foo ( & self ) -> T ;
fn foo2 ( & self ) -> i64 ;
}
2020-02-02 12:04:22 +00:00
fn bar ( x : impl Trait < u16 > ) { }
2020-01-31 15:05:58 +00:00
struct S < T > ( T ) ;
impl < T > Trait < T > for S < T > { }
2020-02-02 12:04:22 +00:00
fn test ( x : impl Trait < u64 > , y : & impl Trait < u32 > ) {
2020-01-31 15:05:58 +00:00
x ;
y ;
let z = S ( 1 ) ;
bar ( z ) ;
x . foo ( ) ;
y . foo ( ) ;
z . foo ( ) ;
x . foo2 ( ) ;
y . foo2 ( ) ;
z . foo2 ( ) ;
}
" #, true),
@ r ###"
2020-04-24 21:51:02 +00:00
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
2020-01-31 15:05:58 +00:00
" ###
) ;
}
2020-02-07 15:24:09 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2020-02-07 15:24:09 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2020-02-07 15:24:09 +00:00
" ###
) ;
}
2020-02-07 17:27:54 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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 )
2020-02-07 17:27:54 +00:00
" ###
) ;
}
2019-12-03 12:38:54 +00:00
#[ test ]
2020-01-27 20:38:10 +00:00
#[ ignore ]
2019-12-03 12:38:54 +00:00
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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
2020-04-17 20:48:29 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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 )
2020-04-17 20:48:29 +00:00
" ###
) ;
}
2019-12-03 12:38:54 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ test ]
fn weird_bounds ( ) {
assert_snapshot! (
infer ( r #"
trait Trait { }
2020-01-24 15:46:43 +00:00
fn test ( a : impl Trait + ' lifetime , b : impl ' lifetime , c : impl ( Trait ) , d : impl ( ' lifetime ) , e : impl ? Sized , f : impl Trait + ? Sized ) {
2019-12-03 12:38:54 +00:00
}
" #),
@ r ###"
2020-04-24 21:51:02 +00:00
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 ' { } ' : ( )
2019-12-03 12:38:54 +00:00
" ###
) ;
}
2019-12-21 18:15:06 +00:00
#[ test ]
2020-01-27 20:38:10 +00:00
#[ ignore ]
2019-12-21 18:15:06 +00:00
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 " ) ;
}
2019-12-03 12:38:54 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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 >
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
62 .. 66 ' self ' : Self
164 .. 165 'x' : T
170 .. 186 ' { .. . o ( ) ; } ' : ( )
176 .. 177 'x' : T
176 .. 183 ' x . foo ( ) ' : u32
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
2020-02-07 17:27:54 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
50 .. 54 ' self ' : & Self
63 .. 65 ' { } ' : ( )
116 .. 117 'x' : & impl Trait1
133 .. 149 ' { .. . o ( ) ; } ' : ( )
139 .. 140 'x' : & impl Trait1
139 .. 146 ' x . foo ( ) ' : u32
2020-02-07 17:27:54 +00:00
" ###
) ;
}
2019-12-03 12:38:54 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
44 .. 45 'x' : T
50 .. 66 ' { .. . o ( ) ; } ' : ( )
56 .. 57 'x' : T
56 .. 63 ' x . foo ( ) ' : { unknown }
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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 >
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ( 1 u32 ) ;
x . map ( | v | v + 1 ) ;
x . map ( | _v | 1 u64 ) ;
let y : Option < i64 > = x . map ( | _v | 1 ) ;
}
" #),
@ r ###"
2020-04-24 21:51:02 +00:00
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 .. . ( 1 u32 ) ' : Option < u32 >
216 .. 220 ' 1 u32 ' : 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 ( .. . 1 u64 ) ' : Option < u64 >
255 .. 264 ' | _v | 1 u64 ' : | u32 | -> u64
256 .. 258 '_ v ' : u32
260 .. 264 ' 1 u64 ' : 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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ( 1 u64 ) ;
let h = | v | 1 u128 + v ;
}
" #),
@ r ###"
2020-04-24 21:51:02 +00:00
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 ( 1 u64 ) ' : i32
120 .. 124 ' 1 u64 ' : u64
135 .. 136 'h' : | u128 | -> u128
139 .. 152 ' | v | 1 u128 + v ' : | u128 | -> u128
140 .. 141 'v' : u128
143 .. 148 ' 1 u128 ' : u128
143 .. 152 ' 1 u128 + v ' : u128
151 .. 152 'v' : u128
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2019-12-03 12:38:54 +00:00
" ###
) ;
}
#[ 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 " ) ;
}
2020-03-06 17:08:10 +00:00
#[ test ]
2020-04-12 10:29:03 +00:00
fn unselected_projection_on_impl_self ( ) {
2020-03-06 17:08:10 +00:00
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 ###"
2020-04-24 21:51:02 +00:00
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
2020-03-06 17:08:10 +00:00
" ###);
}
2020-04-12 10:29:03 +00:00
#[ 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 " ) ;
}
2019-12-03 12:38:54 +00:00
#[ 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} " ) ;
}
2019-12-06 11:45:00 +00:00
2020-04-10 20:05:46 +00:00
#[ 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 < | > ;
}
" #,
) ;
2020-04-10 15:44:43 +00:00
assert_eq! ( t , " u32 " ) ;
2020-04-10 20:05:46 +00:00
}
2020-04-13 09:55:34 +00:00
#[ test ]
fn proc_macro_server_types ( ) {
assert_snapshot! (
infer_with_mismatches ( 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 + Clone ; ) ;
( type Group ) = >
( type Group : 'static + Clone ; ) ;
( $( $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 ( & mut self , $( $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 Group { }
struct TokenStream { }
struct Rustc ;
impl Types for Rustc {
type TokenStream = TokenStream ;
type Group = Group ;
}
fn make < T > ( ) -> T { loop { } }
impl TokenStream for Rustc {
fn new ( ) -> Self ::TokenStream {
let group : Self ::Group = make ( ) ;
make ( )
}
}
" #, true),
@ r ###"
2020-04-24 21:51:02 +00:00
1115 .. 1126 ' { loop { } } ' : T
1117 .. 1124 ' loop { } ' : !
1122 .. 1124 ' { } ' : ( )
1190 .. 1253 ' { .. . } ' : { unknown }
1204 .. 1209 ' group ' : { unknown }
1225 .. 1229 ' make ' : fn make < { unknown } > ( ) -> { unknown }
1225 .. 1231 ' make ( ) ' : { unknown }
1241 .. 1245 ' make ' : fn make < { unknown } > ( ) -> { unknown }
1241 .. 1247 ' make ( ) ' : { unknown }
2020-04-13 09:55:34 +00:00
" ###
) ;
}
2019-12-06 11:45:00 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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 }
2019-12-06 11:45:00 +00:00
" ###
) ;
}
2020-02-21 12:47:49 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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' : & ( )
2020-02-21 12:47:49 +00:00
" ###
) ;
}
2020-04-06 15:24:08 +00:00
2020-04-12 10:28:24 +00:00
#[ 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 " ) ;
}
2020-04-06 15:24:08 +00:00
#[ 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 , " () " ) ;
}
2020-04-17 16:27:20 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2020-04-17 16:27:20 +00:00
" ###
) ;
}
#[ 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 " ) ;
}
2020-04-17 17:41:37 +00:00
#[ 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 ###"
2020-04-24 21:51:02 +00:00
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
2020-04-17 17:41:37 +00:00
" ###
) ;
}