Add OWNERS; upgrade to 0.1.10 am: 443b81192a am: f113e370ad am: a6c944f184 am: 1cbdc38ed3

Change-Id: Iccc98df442223a03c06841988250a5013ff47180
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index bcbbaac..28d7b30 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "1638f7a113f03e6bf10df488c2347acecb83e1d7"
+    "sha1": "5feb37605c9ec2d237651dbd669e3527566a839e"
   }
 }
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..da4d076
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+language: rust
+
+rust:
+  - 1.31.0
+  - stable
+  - beta
+  - nightly
+
+script: cargo test
+
+matrix:
+  include:
+    - rust: nightly
+      name: Minimal versions
+      before_script:
+        - cargo -Z minimal-versions generate-lockfile
+      script:
+        - cargo check --locked
diff --git a/Cargo.toml b/Cargo.toml
index ad8c6df..f9d3ead 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,16 +13,23 @@
 [package]
 edition = "2018"
 name = "paste"
-version = "0.1.7"
+version = "0.1.10"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 description = "Macros for all your token pasting needs"
 readme = "README.md"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/dtolnay/paste"
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
 [dependencies.paste-impl]
-version = "=0.1.7"
+version = "=0.1.10"
 
 [dependencies.proc-macro-hack]
 version = "0.5.9"
+[dev-dependencies.rustversion]
+version = "1.0"
+
+[dev-dependencies.trybuild]
+version = "1.0"
 [badges.travis-ci]
 repository = "dtolnay/paste"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 1758544..6f0d704 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "paste"
-version = "0.1.7"
+version = "0.1.10"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -12,8 +12,15 @@
 travis-ci = { repository = "dtolnay/paste" }
 
 [dependencies]
-paste-impl = { version = "=0.1.7", path = "impl" }
+paste-impl = { version = "=0.1.10", path = "impl" }
 proc-macro-hack = "0.5.9"
 
+[dev-dependencies]
+rustversion = "1.0"
+trybuild = "1.0"
+
 [workspace]
 members = ["impl"]
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
diff --git a/METADATA b/METADATA
index 4cdc4e4..bf81f11 100644
--- a/METADATA
+++ b/METADATA
@@ -1,7 +1,5 @@
 name: "paste"
-description:
-    "Macros for all your token pasting needs"
-
+description: "Macros for all your token pasting needs"
 third_party {
   url {
     type: HOMEPAGE
@@ -11,7 +9,11 @@
     type: GIT
     value: "https://github.com/dtolnay/paste"
   }
-  version: "0.1.7"
-  last_upgrade_date { year: 2020 month: 3 day: 17 }
+  version: "0.1.10"
   license_type: NOTICE
+  last_upgrade_date {
+    year: 2020
+    month: 4
+    day: 17
+  }
 }
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..46fc303
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1 @@
+include platform/prebuilts/rust:/OWNERS
diff --git a/README.md b/README.md
index b33c810..4204dbe 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,8 @@
 
 This approach works with any stable or nightly Rust compiler 1.30+.
 
+<br>
+
 ## Pasting identifiers
 
 There are two entry points, `paste::expr!` for macros in expression position and
@@ -45,6 +47,8 @@
 }
 ```
 
+<br>
+
 ## More elaborate examples
 
 This program demonstrates how you may want to bundle a paste invocation inside
@@ -116,6 +120,23 @@
 
 <br>
 
+## Case conversion
+
+Use `$var:lower` or `$var:upper` in the segment list to convert an interpolated
+segment to lower- or uppercase as part of the paste. For example, `[<ld_
+$reg:lower _expr>]` would paste to `ld_bc_expr` if invoked with $reg=`Bc`.
+
+Use `$var:snake` to convert CamelCase input to snake\_case. These compose, so
+for example `$var:snake:upper` would give you SCREAMING\_CASE.
+
+The precise Unicode conversions are as defined by [`str::to_lowercase`] and
+[`str::to_uppercase`].
+
+[`str::to_lowercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_lowercase
+[`str::to_uppercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_uppercase
+
+<br>
+
 #### License
 
 <sup>
diff --git a/src/lib.rs b/src/lib.rs
index 34663c5..8125222 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,6 +9,8 @@
 //!
 //! This approach works with any stable or nightly Rust compiler 1.30+.
 //!
+//! <br>
+//!
 //! # Pasting identifiers
 //!
 //! There are two entry points, `paste::expr!` for macros in expression position and
@@ -33,6 +35,8 @@
 //! }
 //! ```
 //!
+//! <br><br>
+//!
 //! # More elaborate examples
 //!
 //! This program demonstrates how you may want to bundle a paste invocation inside
@@ -103,6 +107,24 @@
 //! #
 //! # fn main() {}
 //! ```
+//!
+//! <br><br>
+//!
+//! # Case conversion
+//!
+//! Use `$var:lower` or `$var:upper` in the segment list to convert an
+//! interpolated segment to lower- or uppercase as part of the paste. For
+//! example, `[<ld_ $reg:lower _expr>]` would paste to `ld_bc_expr` if invoked
+//! with $reg=`Bc`.
+//!
+//! Use `$var:snake` to convert CamelCase input to snake\_case. These compose,
+//! so for example `$var:snake:upper` would give you SCREAMING\_CASE.
+//!
+//! The precise Unicode conversions are as defined by [`str::to_lowercase`] and
+//! [`str::to_uppercase`].
+//!
+//! [`str::to_lowercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_lowercase
+//! [`str::to_uppercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_uppercase
 
 #![no_std]
 
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
new file mode 100644
index 0000000..f9aea23
--- /dev/null
+++ b/tests/compiletest.rs
@@ -0,0 +1,6 @@
+#[rustversion::attr(not(nightly), ignore)]
+#[test]
+fn ui() {
+    let t = trybuild::TestCases::new();
+    t.compile_fail("tests/ui/*.rs");
+}
diff --git a/tests/test.rs b/tests/test.rs
index e96a2d2..435eb71 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -171,3 +171,87 @@
         assert_eq!(f(), "i32x4");
     }
 }
+
+mod test_to_lower {
+    macro_rules! m {
+        ($id:ident) => {
+            paste::item! {
+                fn [<my_ $id:lower _here>](_arg: u8) -> &'static str {
+                    stringify!([<$id:lower>])
+                }
+            }
+        };
+    }
+
+    m!(Test);
+
+    #[test]
+    fn test_to_lower() {
+        assert_eq!(my_test_here(0), "test");
+    }
+}
+
+#[test]
+fn test_env_to_lower() {
+    paste::expr! {
+        struct [<Lib env!("CARGO_PKG_NAME"):lower>];
+
+        let _ = Libpaste;
+    }
+}
+
+mod test_to_upper {
+    macro_rules! m {
+        ($id:ident) => {
+            paste::item! {
+                const [<MY_ $id:upper _HERE>]: &str = stringify!([<$id:upper>]);
+            }
+        };
+    }
+
+    m!(Test);
+
+    #[test]
+    fn test_to_upper() {
+        assert_eq!(MY_TEST_HERE, "TEST");
+    }
+}
+
+#[test]
+fn test_env_to_upper() {
+    paste::expr! {
+        const [<LIB env!("CARGO_PKG_NAME"):upper>]: &str = "libpaste";
+
+        let _ = LIBPASTE;
+    }
+}
+
+mod test_to_snake {
+    macro_rules! m {
+        ($id:ident) => {
+            paste::item! {
+                const DEFAULT_SNAKE: &str = stringify!([<$id:snake>]);
+                const LOWER_SNAKE: &str = stringify!([<$id:snake:lower>]);
+                const UPPER_SNAKE: &str = stringify!([<$id:snake:upper>]);
+            }
+        };
+    }
+
+    m!(ThisIsButATest);
+
+    #[test]
+    fn test_to_snake() {
+        assert_eq!(DEFAULT_SNAKE, "this_is_but_a_test");
+        assert_eq!(LOWER_SNAKE, "this_is_but_a_test");
+        assert_eq!(UPPER_SNAKE, "THIS_IS_BUT_A_TEST");
+    }
+}
+
+#[test]
+fn test_env_to_snake() {
+    paste::expr! {
+        const [<LIB env!("CARGO_PKG_NAME"):snake:upper>]: &str = "libpaste";
+
+        let _ = LIBPASTE;
+    }
+}
diff --git a/tests/ui/case-warning.rs b/tests/ui/case-warning.rs
new file mode 100644
index 0000000..4b41ab6
--- /dev/null
+++ b/tests/ui/case-warning.rs
@@ -0,0 +1,13 @@
+#![deny(warnings)]
+
+macro_rules! m {
+    ($i:ident) => {
+        paste::item! {
+            pub fn [<foo $i>]() {}
+        }
+    };
+}
+
+m!(Bar);
+
+fn main() {}
diff --git a/tests/ui/case-warning.stderr b/tests/ui/case-warning.stderr
new file mode 100644
index 0000000..5bf37a0
--- /dev/null
+++ b/tests/ui/case-warning.stderr
@@ -0,0 +1,16 @@
+error: function `fooBar` should have a snake case name
+  --> $DIR/case-warning.rs:6:20
+   |
+6  |             pub fn [<foo $i>]() {}
+   |                    ^^^^^^^^^^ help: convert the identifier to snake case: `foo_bar`
+...
+11 | m!(Bar);
+   | -------- in this macro invocation
+   |
+note: the lint level is defined here
+  --> $DIR/case-warning.rs:1:9
+   |
+1  | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(non_snake_case)]` implied by `#[deny(warnings)]`
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/no-env-var.rs b/tests/ui/no-env-var.rs
new file mode 100644
index 0000000..87aad35
--- /dev/null
+++ b/tests/ui/no-env-var.rs
@@ -0,0 +1,5 @@
+paste::item! {
+    fn [<a env!("PASTE_UNKNOWN") b>]() {}
+}
+
+fn main() {}
diff --git a/tests/ui/no-env-var.stderr b/tests/ui/no-env-var.stderr
new file mode 100644
index 0000000..2ec206d
--- /dev/null
+++ b/tests/ui/no-env-var.stderr
@@ -0,0 +1,5 @@
+error: no such env var
+ --> $DIR/no-env-var.rs:2:17
+  |
+2 |     fn [<a env!("PASTE_UNKNOWN") b>]() {}
+  |                 ^^^^^^^^^^^^^^^
diff --git a/tests/ui/unexpected-modifier.rs b/tests/ui/unexpected-modifier.rs
new file mode 100644
index 0000000..00a1e99
--- /dev/null
+++ b/tests/ui/unexpected-modifier.rs
@@ -0,0 +1,5 @@
+paste::item! {
+    fn [<:lower x>]() {}
+}
+
+fn main() {}
diff --git a/tests/ui/unexpected-modifier.stderr b/tests/ui/unexpected-modifier.stderr
new file mode 100644
index 0000000..4a518b8
--- /dev/null
+++ b/tests/ui/unexpected-modifier.stderr
@@ -0,0 +1,5 @@
+error: unexpected modifier
+ --> $DIR/unexpected-modifier.rs:2:10
+  |
+2 |     fn [<:lower x>]() {}
+  |          ^^^^^^
diff --git a/tests/ui/unsupported-modifier.rs b/tests/ui/unsupported-modifier.rs
new file mode 100644
index 0000000..5ab049f
--- /dev/null
+++ b/tests/ui/unsupported-modifier.rs
@@ -0,0 +1,5 @@
+paste::item! {
+    fn [<a:pillow>]() {}
+}
+
+fn main() {}
diff --git a/tests/ui/unsupported-modifier.stderr b/tests/ui/unsupported-modifier.stderr
new file mode 100644
index 0000000..ffbc742
--- /dev/null
+++ b/tests/ui/unsupported-modifier.stderr
@@ -0,0 +1,5 @@
+error: unsupported modifier
+ --> $DIR/unsupported-modifier.rs:2:11
+  |
+2 |     fn [<a:pillow>]() {}
+  |           ^^^^^^^