Mark ab/6881855 as merged

Bug: 172690556
Change-Id: I9bf368ee3a75fc8f67451808da49fba6e100a7cf
diff --git a/Android.bp b/Android.bp
index dec48b9..737bcea 100644
--- a/Android.bp
+++ b/Android.bp
@@ -17,4 +17,4 @@
 }
 
 // dependent_library ["feature_list"]
-//   futures-core-0.3.5 "alloc,std"
+//   futures-core-0.3.7 "alloc,std"
diff --git a/Cargo.toml b/Cargo.toml
index 5a3f79d..e5feaad 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,21 +13,22 @@
 [package]
 edition = "2018"
 name = "futures-channel"
-version = "0.3.5"
+version = "0.3.7"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "Channels for asynchronous communication using futures-rs.\n"
 homepage = "https://rust-lang.github.io/futures-rs"
-documentation = "https://docs.rs/futures-channel/0.3.5"
+documentation = "https://docs.rs/futures-channel/0.3.7"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/futures-rs"
 [package.metadata.docs.rs]
 all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
 [dependencies.futures-core]
-version = "0.3.5"
+version = "0.3.7"
 default-features = false
 
 [dependencies.futures-sink]
-version = "0.3.5"
+version = "0.3.7"
 optional = true
 default-features = false
 
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 9a8af2b..76aef73 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,12 +1,12 @@
 [package]
 name = "futures-channel"
 edition = "2018"
-version = "0.3.5"
+version = "0.3.7"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/futures-rs"
 homepage = "https://rust-lang.github.io/futures-rs"
-documentation = "https://docs.rs/futures-channel/0.3.5"
+documentation = "https://docs.rs/futures-channel/0.3.7"
 description = """
 Channels for asynchronous communication using futures-rs.
 """
@@ -24,8 +24,9 @@
 cfg-target-has-atomic = ["futures-core/cfg-target-has-atomic"]
 
 [dependencies]
-futures-core = { path = "../futures-core", version = "0.3.5", default-features = false }
-futures-sink = { path = "../futures-sink", version = "0.3.5", default-features = false, optional = true }
+futures-core = { path = "../futures-core", version = "0.3.7", default-features = false }
+futures-sink = { path = "../futures-sink", version = "0.3.7", default-features = false, optional = true }
 
 [package.metadata.docs.rs]
 all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
diff --git a/METADATA b/METADATA
index ab88381..ea8e204 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/futures-channel/futures-channel-0.3.5.crate"
+    value: "https://static.crates.io/crates/futures-channel/futures-channel-0.3.7.crate"
   }
-  version: "0.3.5"
+  version: "0.3.7"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 5
-    day: 8
+    month: 10
+    day: 25
   }
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..7d1919a
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,12 @@
+// Generated by cargo2android.py for tests in Android.bp
+{
+  "presubmit": [
+    {
+      "host": true,
+      "name": "futures-util_host_test_src_lib"
+    },
+    {
+      "name": "futures-util_device_test_src_lib"
+    }
+  ]
+}
diff --git a/src/lib.rs b/src/lib.rs
index f3d93d8..f8be701 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,9 +15,14 @@
 #![cfg_attr(test, warn(single_use_lifetimes))]
 #![warn(clippy::all)]
 
+// mem::take requires Rust 1.40, matches! requires Rust 1.42
+// Can be removed if the minimum supported version increased or if https://github.com/rust-lang/rust-clippy/issues/3941
+// get's implemented.
+#![allow(clippy::mem_replace_with_default, clippy::match_like_matches_macro)]
+
 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
 
-#![doc(html_root_url = "https://docs.rs/futures-channel/0.3.5")]
+#![doc(html_root_url = "https://docs.rs/futures-channel/0.3.7")]
 
 #[cfg(all(feature = "cfg-target-has-atomic", not(feature = "unstable")))]
 compile_error!("The `cfg-target-has-atomic` feature requires the `unstable` feature as an explicit opt-in to unstable features");
diff --git a/src/mpsc/mod.rs b/src/mpsc/mod.rs
index bce5e2e..64c551e 100644
--- a/src/mpsc/mod.rs
+++ b/src/mpsc/mod.rs
@@ -481,6 +481,11 @@
         Arc::ptr_eq(&self.inner, &other.inner)
     }
 
+    /// Returns whether the sender send to this receiver.
+    fn is_connected_to(&self, inner: &Arc<UnboundedInner<T>>) -> bool {
+        Arc::ptr_eq(&self.inner, &inner)
+    }
+
     /// Returns pointer to the Arc containing sender
     ///
     /// The returned pointer is not referenced and should be only used for hashing!
@@ -657,6 +662,11 @@
         Arc::ptr_eq(&self.inner, &other.inner)
     }
 
+    /// Returns whether the sender send to this receiver.
+    fn is_connected_to(&self, receiver: &Arc<BoundedInner<T>>) -> bool {
+        Arc::ptr_eq(&self.inner, &receiver)
+    } 
+
     /// Returns pointer to the Arc containing sender
     ///
     /// The returned pointer is not referenced and should be only used for hashing!
@@ -779,6 +789,14 @@
         }
     }
 
+    /// Returns whether the sender send to this receiver.
+    pub fn is_connected_to(&self, receiver: &Receiver<T>) -> bool {
+        match (&self.0, &receiver.inner) {
+            (Some(inner), Some(receiver)) => inner.is_connected_to(receiver),
+            _ => false,
+        }
+    }
+
     /// Hashes the receiver into the provided hasher
     pub fn hash_receiver<H>(&self, hasher: &mut H) where H: std::hash::Hasher {
         use std::hash::Hash;
@@ -860,6 +878,14 @@
         }
     }
 
+    /// Returns whether the sender send to this receiver.
+    pub fn is_connected_to(&self, receiver: &UnboundedReceiver<T>) -> bool {
+        match (&self.0, &receiver.inner) {
+            (Some(inner), Some(receiver)) => inner.is_connected_to(receiver),
+            _ => false,
+        }
+    }
+
     /// Hashes the receiver into the provided hasher
     pub fn hash_receiver<H>(&self, hasher: &mut H) where H: std::hash::Hasher {
         use std::hash::Hash;
diff --git a/src/oneshot.rs b/src/oneshot.rs
index 5f76cee..47d3ada 100644
--- a/src/oneshot.rs
+++ b/src/oneshot.rs
@@ -1,4 +1,6 @@
 //! A channel for sending a single message between asynchronous tasks.
+//!
+//! This is a single-producer, single-consumer channel.
 
 use alloc::sync::Arc;
 use core::fmt;
@@ -12,7 +14,7 @@
 
 /// A future for a value that will be provided by another asynchronous task.
 ///
-/// This is created by the [`channel`] function.
+/// This is created by the [`channel`](channel) function.
 #[must_use = "futures do nothing unless you `.await` or poll them"]
 #[derive(Debug)]
 pub struct Receiver<T> {
@@ -21,7 +23,7 @@
 
 /// A means of transmitting a single value to another task.
 ///
-/// This is created by the [`channel`] function.
+/// This is created by the [`channel`](channel) function.
 #[derive(Debug)]
 pub struct Sender<T> {
     inner: Arc<Inner<T>>,
@@ -68,7 +70,9 @@
     tx_task: Lock<Option<Waker>>,
 }
 
-/// Creates a new one-shot channel for sending values across asynchronous tasks.
+/// Creates a new one-shot channel for sending a single value across asynchronous tasks.
+///
+/// The channel works for a spsc (single-producer, single-consumer) scheme.
 ///
 /// This function is similar to Rust's channel constructor found in the standard
 /// library. Two halves are returned, the first of which is a `Sender` handle,
@@ -337,14 +341,13 @@
     ///
     /// If the value is successfully enqueued for the remote end to receive,
     /// then `Ok(())` is returned. If the receiving end was dropped before
-    /// this function was called, however, then `Err` is returned with the value
-    /// provided.
+    /// this function was called, however, then `Err(t)` is returned.
     pub fn send(self, t: T) -> Result<(), T> {
         self.inner.send(t)
     }
 
     /// Polls this `Sender` half to detect whether its associated
-    /// [`Receiver`](Receiver) with has been dropped.
+    /// [`Receiver`](Receiver) has been dropped.
     ///
     /// # Return values
     ///
@@ -377,6 +380,12 @@
     pub fn is_canceled(&self) -> bool {
         self.inner.is_canceled()
     }
+
+    /// Tests to see whether this `Sender` is connected to the given `Receiver`. That is, whether
+    /// they were created by the same call to `channel`.
+    pub fn is_connected_to(&self, receiver: &Receiver<T>) -> bool {
+        Arc::ptr_eq(&self.inner, &receiver.inner)
+    }
 }
 
 impl<T> Drop for Sender<T> {
diff --git a/tests/mpsc.rs b/tests/mpsc.rs
index 409fa6e..61c5a50 100644
--- a/tests/mpsc.rs
+++ b/tests/mpsc.rs
@@ -256,6 +256,7 @@
     t.join().unwrap();
 }
 
+#[allow(clippy::same_item_push)]
 #[test]
 fn stress_receiver_multi_task_bounded_hard() {
     const AMT: usize = 10_000;
@@ -394,6 +395,7 @@
 }
 
 /// Tests that after `poll_ready` indicates capacity a channel can always send without waiting.
+#[allow(clippy::same_item_push)]
 #[test]
 fn stress_poll_ready() {
     const AMT: u32 = 1000;
@@ -528,6 +530,17 @@
 }
 
 #[test]
+fn is_connected_to() {
+    let (txa, rxa) = mpsc::channel::<i32>(1);
+    let (txb, rxb) = mpsc::channel::<i32>(1);
+
+    assert!(txa.is_connected_to(&rxa));
+    assert!(txb.is_connected_to(&rxb));
+    assert!(!txa.is_connected_to(&rxb));
+    assert!(!txb.is_connected_to(&rxa));
+}
+
+#[test]
 fn hash_receiver() {
     use std::hash::Hasher;
     use std::collections::hash_map::DefaultHasher;