@@ -16,42 +16,54 @@ fn function_implement_fn_traits() {
1616 trait Fn <Args > where Self : FnMut <Args > { }
1717 }
1818
19+ // Simple test: make sure a fully monomorphic type implements FnOnce
1920 goal {
2021 fn ( u8 ) : FnOnce <( u8 , ) >
2122 } yields {
2223 "Unique; substitution [], lifetime constraints []"
2324 }
2425
26+ // Same as above, but for FnMut
2527 goal {
2628 fn ( u8 ) : FnMut <( u8 , ) >
2729 } yields {
2830 "Unique; substitution [], lifetime constraints []"
2931 }
3032
33+ // Same as above, but for Fn
3134 goal {
3235 fn ( u8 ) : Fn <( u8 , ) >
3336 } yields {
3437 "Unique; substitution [], lifetime constraints []"
3538 }
3639
40+ // Function pointres implicity return `()` when no return
41+ // type is specified - make sure that normalization understands
42+ // this
3743 goal {
3844 Normalize ( <fn ( u8 ) as FnOnce <( u8 , ) >>:: Output -> ( ) )
3945 } yields {
4046 "Unique; substitution [], lifetime constraints []"
4147 }
4248
49+ // Tests normalizing when an explicit return type is used
4350 goal {
4451 Normalize ( <fn ( u8 ) -> bool as FnOnce <( u8 , ) >>:: Output -> bool )
4552 } yields {
4653 "Unique; substitution [], lifetime constraints []"
4754 }
4855
56+ // Tests that we fail to normalize when there's a mismatch with
57+ // fully monomorphic types.
4958 goal {
5059 Normalize ( <fn ( u8 ) -> bool as FnOnce <( u8 , ) >>:: Output -> u8 )
5160 } yields {
5261 "No possible solution"
5362 }
5463
64+ // Ensures that we don't find a solution when doing so would
65+ // require us to conclude that two different universally quantified
66+ // types (T and V) are equal.
5567 goal {
5668 forall<T , V > {
5769 Normalize ( <fn ( u8 , V ) -> T as FnOnce <( u8 , V ) >>:: Output -> V )
@@ -60,6 +72,7 @@ fn function_implement_fn_traits() {
6072 "No possible solution"
6173 }
6274
75+ // Tests that we can normalize a generic function pointer type
6376 goal {
6477 forall<T , V > {
6578 exists<U > {
@@ -70,18 +83,25 @@ fn function_implement_fn_traits() {
7083 "Unique; substitution [?0 := !1_0], lifetime constraints []"
7184 }
7285
86+ // Tests that we properly tuple function arguments when constrcting
87+ // the `FnOnce` impl
7388 goal {
7489 fn ( u8 , u32 ) : FnOnce <( u8 , u32 ) >
7590 } yields {
7691 "Unique; substitution [], lifetime constraints []"
7792 }
7893
94+ // Tests that we don't find a solution when fully monomorphic
95+ // types are mismatched
7996 goal {
8097 fn ( i32 ) : FnOnce <( bool , ) >
8198 } yields {
8299 "No possible solution"
83100 }
84101
102+ // Tests function pointer types that use the function's binder
103+ // Universally quantified lifetimes that differ only in their
104+ // name ('a vs 'b) should be considered equivalent here
85105 goal {
86106 forall<' a> {
87107 for <' b> fn ( & ' b u8 ) : FnOnce <( & ' a u8 , ) >
@@ -90,6 +110,10 @@ fn function_implement_fn_traits() {
90110 "Unique; substitution [], lifetime constraints []"
91111 }
92112
113+ // Tests that a 'stricter' function (requires lifetimes to be the same)
114+ // can implement `FnOnce` for a 'less strict' signature (dose not require
115+ // lifetimes to be the same), provided that the lifetimes are *actually*
116+ // the same.
93117 goal {
94118 forall<' a, ' b> {
95119 for <' c> fn ( & ' c u8 , & ' c i32 ) : FnOnce <( & ' a u8 , & ' b i32 ) >
@@ -98,6 +122,22 @@ fn function_implement_fn_traits() {
98122 "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"
99123 }
100124
125+ // Tests the opposite case as the previous test: a 'less strict' function
126+ // (does not require lifetimes to be the same) can implement `FnOnce` for
127+ // a 'stricter' signature (requires lifetimes to be the same) without
128+ // any additional requirements
129+ goal {
130+ forall<' a> {
131+ for <' b, ' c> fn ( & ' b u8 , & ' c i32 ) : FnOnce <( & ' a u8 , & ' a i32 ) >
132+ }
133+ } yields {
134+ "Unique; substitution [], lifetime constraints []"
135+ }
136+
137+ // Similiar to the above test, but for types instead of lifetimes:
138+ // a 'stricter' function (requires types to be the same) can never
139+ // implement `FnOnce` for a 'less strict' signature (does not require
140+ // types to be the same)
101141 goal {
102142 forall<T , U > {
103143 fn ( T , T ) : FnOnce <( T , U ) >
@@ -106,6 +146,9 @@ fn function_implement_fn_traits() {
106146 "No possible solution"
107147 }
108148
149+ // Tests the opposite case as a previous test: a 'less strict'
150+ // function can never implement 'FnOnce' for a 'more strict' signature
151+ // (does not require types to bthe same)
109152 goal {
110153 forall<T , U > {
111154 fn ( T , U ) : FnOnce <( T , T ) >
0 commit comments