@@ -151,6 +151,52 @@ fn downgrade() {
151151 assert ! ( shared2. downgrade( ) . is_none( ) ) ;
152152}
153153
154+ #[ test]
155+ fn ptr_eq ( ) {
156+ use future:: FusedFuture ;
157+ use std:: collections:: hash_map:: DefaultHasher ;
158+ use std:: hash:: Hasher ;
159+
160+ let ( tx, rx) = oneshot:: channel :: < i32 > ( ) ;
161+ let shared = rx. shared ( ) ;
162+ let mut shared2 = shared. clone ( ) ;
163+ let mut hasher = DefaultHasher :: new ( ) ;
164+ let mut hasher2 = DefaultHasher :: new ( ) ;
165+
166+ // Because these two futures share the same underlying future,
167+ // `ptr_eq` should return true.
168+ assert ! ( shared. ptr_eq( & shared2) ) ;
169+ // Equivalence relations are symmetric
170+ assert ! ( shared2. ptr_eq( & shared) ) ;
171+
172+ // If `ptr_eq` returns true, they should hash to the same value.
173+ shared. ptr_hash ( & mut hasher) ;
174+ shared2. ptr_hash ( & mut hasher2) ;
175+ assert_eq ! ( hasher. finish( ) , hasher2. finish( ) ) ;
176+
177+ tx. send ( 42 ) . unwrap ( ) ;
178+ assert_eq ! ( block_on( & mut shared2) . unwrap( ) , 42 ) ;
179+
180+ // Now that `shared2` has completed, `ptr_eq` should return false.
181+ assert ! ( shared2. is_terminated( ) ) ;
182+ assert ! ( !shared. ptr_eq( & shared2) ) ;
183+
184+ // `ptr_eq` should continue to work for the other `Shared`.
185+ let shared3 = shared. clone ( ) ;
186+ let mut hasher3 = DefaultHasher :: new ( ) ;
187+ assert ! ( shared. ptr_eq( & shared3) ) ;
188+
189+ shared3. ptr_hash ( & mut hasher3) ;
190+ assert_eq ! ( hasher. finish( ) , hasher3. finish( ) ) ;
191+
192+ let ( _tx, rx) = oneshot:: channel :: < i32 > ( ) ;
193+ let shared4 = rx. shared ( ) ;
194+
195+ // And `ptr_eq` should return false for two futures that don't share
196+ // the underlying future.
197+ assert ! ( !shared. ptr_eq( & shared4) ) ;
198+ }
199+
154200#[ test]
155201fn dont_clone_in_single_owner_shared_future ( ) {
156202 let counter = CountClone ( Rc :: new ( Cell :: new ( 0 ) ) ) ;
0 commit comments