*: make 0.7.x work with 0.9.x compiler (#530)

* *: make 0.7.x work with 0.9.x compiler

Signed-off-by: Jay Lee <BusyJayLee@gmail.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a6dfdb..ef93641 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.7.2 - 2021-05-28
+
+- Work with 0.9.x compiler
+
 # 0.7.1 - 2020-12-18
 
 - Allow CXX environment variable to override g++ for musl build (#500)
diff --git a/Cargo.toml b/Cargo.toml
index 7daa61e..ea94b84 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "grpcio"
-version = "0.7.1"
+version = "0.7.2"
 edition = "2018"
 authors = ["The TiKV Project Developers"]
 license = "Apache-2.0"
diff --git a/compiler/src/util.rs b/compiler/src/util.rs
index c46be2d..e6ff936 100644
--- a/compiler/src/util.rs
+++ b/compiler/src/util.rs
@@ -34,7 +34,7 @@
         let mut meet_lower = false;
         for i in self.pos..self.name.len() {
             let c = self.name[i];
-            if b'A' <= c && c <= b'Z' {
+            if (b'A'..=b'Z').contains(&c) {
                 if meet_lower {
                     // So it should be AaA or aaA
                     pos = i;
diff --git a/grpc-sys/build.rs b/grpc-sys/build.rs
index 44e1480..a5abf2b 100644
--- a/grpc-sys/build.rs
+++ b/grpc-sys/build.rs
@@ -267,7 +267,7 @@
 
 // Generate the bindings to grpc C-core.
 // Try to disable the generation of platform-related bindings.
-fn bindgen_grpc(mut config: bindgen::Builder, file_path: &PathBuf) {
+fn bindgen_grpc(mut config: bindgen::Builder, file_path: &Path) {
     // Search header files with API interface
     let mut headers = Vec::new();
     for result in WalkDir::new(Path::new("./grpc/include")) {
diff --git a/interop/src/server.rs b/interop/src/server.rs
index 4a06d7b..d27f47d 100644
--- a/interop/src/server.rs
+++ b/interop/src/server.rs
@@ -17,17 +17,6 @@
 use grpc_proto::testing::test_grpc::TestService;
 use grpc_proto::util;
 
-enum Error {
-    Grpc(grpc::Error),
-    Abort,
-}
-
-impl From<grpc::Error> for Error {
-    fn from(error: grpc::Error) -> Error {
-        Error::Grpc(error)
-    }
-}
-
 #[derive(Clone)]
 pub struct InteropTestService;
 
@@ -158,9 +147,10 @@
             sink.close().await?;
             Ok(())
         }
-        .map_err(|e: Error| match e {
-            Error::Grpc(grpc::Error::RemoteStopped) | Error::Abort => {}
-            Error::Grpc(e) => error!("failed to handle duplex call: {:?}", e),
+        .map_err(|e: grpc::Error| {
+            if !matches!(e, grpc::Error::RemoteStopped) {
+                error!("failed to handle duplex call: {:?}", e);
+            }
         })
         .map(|_| ());
         ctx.spawn(f)
diff --git a/src/call/client.rs b/src/call/client.rs
index 279e619..d1047bf 100644
--- a/src/call/client.rs
+++ b/src/call/client.rs
@@ -399,7 +399,7 @@
             t.close_f = Some(close_f);
         }
 
-        if let Poll::Pending = Pin::new(t.close_f.as_mut().unwrap()).poll(cx)? {
+        if Pin::new(t.close_f.as_mut().unwrap()).poll(cx)?.is_pending() {
             // if call is finished, can return early here.
             call.check_alive()?;
             return Poll::Pending;
diff --git a/src/call/mod.rs b/src/call/mod.rs
index a06e003..b8676f3 100644
--- a/src/call/mod.rs
+++ b/src/call/mod.rs
@@ -33,9 +33,9 @@
     }
 }
 
-impl Into<i32> for RpcStatusCode {
-    fn into(self) -> i32 {
-        self.0
+impl From<RpcStatusCode> for i32 {
+    fn from(c: RpcStatusCode) -> i32 {
+        c.0
     }
 }
 
@@ -533,7 +533,7 @@
         if !skip_finish_check {
             let mut finished = false;
             if let Some(close_f) = &mut self.close_f {
-                if let Poll::Ready(_) = Pin::new(close_f).poll(cx)? {
+                if Pin::new(close_f).poll(cx)?.is_ready() {
                     // Don't return immediately, there may be pending data.
                     finished = true;
                 }
diff --git a/src/cq.rs b/src/cq.rs
index 60b6bb3..58d6d6b 100644
--- a/src/cq.rs
+++ b/src/cq.rs
@@ -36,35 +36,39 @@
     }
 
     fn add_ref(&self) -> Result<()> {
+        let mut cnt = self.ref_cnt.load(Ordering::SeqCst);
         loop {
-            let cnt = self.ref_cnt.load(Ordering::SeqCst);
             if cnt <= 0 {
                 // `shutdown` has been called, reject any requests.
                 return Err(Error::QueueShutdown);
             }
             let new_cnt = cnt + 1;
-            if cnt
-                == self
-                    .ref_cnt
-                    .compare_and_swap(cnt, new_cnt, Ordering::SeqCst)
-            {
-                return Ok(());
+            match self.ref_cnt.compare_exchange_weak(
+                cnt,
+                new_cnt,
+                Ordering::SeqCst,
+                Ordering::SeqCst,
+            ) {
+                Ok(_) => return Ok(()),
+                Err(c) => cnt = c,
             }
         }
     }
 
     fn unref(&self) {
+        let mut cnt = self.ref_cnt.load(Ordering::SeqCst);
         let shutdown = loop {
-            let cnt = self.ref_cnt.load(Ordering::SeqCst);
             // If `shutdown` is not called, `cnt` > 0, so minus 1 to unref.
             // If `shutdown` is called, `cnt` < 0, so plus 1 to unref.
             let new_cnt = cnt - cnt.signum();
-            if cnt
-                == self
-                    .ref_cnt
-                    .compare_and_swap(cnt, new_cnt, Ordering::SeqCst)
-            {
-                break new_cnt == 0;
+            match self.ref_cnt.compare_exchange_weak(
+                cnt,
+                new_cnt,
+                Ordering::SeqCst,
+                Ordering::SeqCst,
+            ) {
+                Ok(_) => break new_cnt == 0,
+                Err(c) => cnt = c,
             }
         };
         if shutdown {
@@ -75,8 +79,8 @@
     }
 
     fn shutdown(&self) {
+        let mut cnt = self.ref_cnt.load(Ordering::SeqCst);
         let shutdown = loop {
-            let cnt = self.ref_cnt.load(Ordering::SeqCst);
             if cnt <= 0 {
                 // `shutdown` is called, skipped.
                 return;
@@ -85,12 +89,14 @@
             // Because `cnt` is initialized to 1, so minus 1 to make it reach
             // toward 0. That is `new_cnt = -(cnt - 1) = -cnt + 1`.
             let new_cnt = -cnt + 1;
-            if cnt
-                == self
-                    .ref_cnt
-                    .compare_and_swap(cnt, new_cnt, Ordering::SeqCst)
-            {
-                break new_cnt == 0;
+            match self.ref_cnt.compare_exchange_weak(
+                cnt,
+                new_cnt,
+                Ordering::SeqCst,
+                Ordering::SeqCst,
+            ) {
+                Ok(_) => break new_cnt == 0,
+                Err(c) => cnt = c,
             }
         };
         if shutdown {
diff --git a/src/lib.rs b/src/lib.rs
index 2bb0c11..9c4a60f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -80,3 +80,27 @@
 pub use crate::server::{
     CheckResult, Server, ServerBuilder, ServerChecker, Service, ServiceBuilder, ShutdownFuture,
 };
+
+/// A shortcut for implementing a service method by returning `UNIMPLEMENTED` status code.
+///
+/// Compiler will provide a default implementations for all methods to invoke this macro, so
+/// you usually won't call it directly. If you really need to, just call it like:
+/// ```ignored
+/// fn method(&self, ctx: grpcio::RpcContext, req: Request, resp: UnarySink<Response>) {
+///     unimplemented_call!(ctx, resp);
+/// }
+/// ```
+#[macro_export]
+macro_rules! unimplemented_call {
+    ($ctx:ident, $sink:ident) => {{
+        let f = async move {
+            let _ = $sink
+                .fail($crate::RpcStatus::new(
+                    $crate::RpcStatusCode::UNIMPLEMENTED,
+                    None,
+                ))
+                .await;
+        };
+        $ctx.spawn(f)
+    }};
+}
diff --git a/src/metadata.rs b/src/metadata.rs
index 746b593..893f6e2 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -16,11 +16,11 @@
     let mut is_upper_case = false;
     for b in key.as_bytes() {
         let b = *b;
-        if b >= b'A' && b <= b'Z' {
+        if (b'A'..=b'Z').contains(&b) {
             is_upper_case = true;
             continue;
-        } else if b >= b'a' && b <= b'z'
-            || b >= b'0' && b <= b'9'
+        } else if (b'a'..=b'z').contains(&b)
+            || (b'0'..=b'9').contains(&b)
             || b == b'_'
             || b == b'-'
             || b == b'.'
@@ -83,10 +83,10 @@
             }
         }
         let key = normalize_key(key, false)?;
-        self.add_metadata(&key, value.as_bytes())
+        Ok(self.add_metadata(&key, value.as_bytes()))
     }
 
-    fn add_metadata(&mut self, key: &str, value: &[u8]) -> Result<&mut MetadataBuilder> {
+    fn add_metadata(&mut self, key: &str, value: &[u8]) -> &mut MetadataBuilder {
         unsafe {
             grpc_sys::grpcwrap_metadata_array_add(
                 &mut self.arr.0,
@@ -96,7 +96,7 @@
                 value.len(),
             )
         }
-        Ok(self)
+        self
     }
 
     /// Add a metadata holding a binary value.
@@ -104,7 +104,7 @@
     /// `key` needs to have suffix (-bin) indicating a binary valued metadata entry.
     pub fn add_bytes(&mut self, key: &str, value: &[u8]) -> Result<&mut MetadataBuilder> {
         let key = normalize_key(key, true)?;
-        self.add_metadata(&key, value)
+        Ok(self.add_metadata(&key, value))
     }
 
     /// Create `Metadata` with configured entries.
@@ -221,7 +221,7 @@
         let mut builder = MetadataBuilder::with_capacity(self.len());
         for (k, v) in self.iter() {
             // use `add_metadata` to skip validation.
-            builder.add_metadata(k, v).unwrap();
+            builder.add_metadata(k, v);
         }
         builder.build()
     }