summaryrefslogtreecommitdiffstats
path: root/third_party/rust/paste/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/paste/tests
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/paste/tests')
-rw-r--r--third_party/rust/paste/tests/compiletest.rs7
-rw-r--r--third_party/rust/paste/tests/test_attr.rs60
-rw-r--r--third_party/rust/paste/tests/test_doc.rs77
-rw-r--r--third_party/rust/paste/tests/test_expr.rs283
-rw-r--r--third_party/rust/paste/tests/test_item.rs269
-rw-r--r--third_party/rust/paste/tests/ui/case-warning.rs15
-rw-r--r--third_party/rust/paste/tests/ui/case-warning.stderr16
-rw-r--r--third_party/rust/paste/tests/ui/env-empty.rs7
-rw-r--r--third_party/rust/paste/tests/ui/env-empty.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/env-non-string.rs7
-rw-r--r--third_party/rust/paste/tests/ui/env-non-string.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/env-suffix.rs7
-rw-r--r--third_party/rust/paste/tests/ui/env-suffix.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/env-unexpected.rs7
-rw-r--r--third_party/rust/paste/tests/ui/env-unexpected.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/invalid-ident.rs15
-rw-r--r--third_party/rust/paste/tests/ui/invalid-ident.stderr21
-rw-r--r--third_party/rust/paste/tests/ui/missing-paren-on-env.rs7
-rw-r--r--third_party/rust/paste/tests/ui/missing-paren-on-env.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/no-env-var.rs7
-rw-r--r--third_party/rust/paste/tests/ui/no-env-var.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/no-ident-after-colon.rs7
-rw-r--r--third_party/rust/paste/tests/ui/no-ident-after-colon.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/unexpected-group.rs7
-rw-r--r--third_party/rust/paste/tests/ui/unexpected-group.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/unexpected-modifier.rs7
-rw-r--r--third_party/rust/paste/tests/ui/unexpected-modifier.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/unexpected-punct.rs7
-rw-r--r--third_party/rust/paste/tests/ui/unexpected-punct.stderr5
-rw-r--r--third_party/rust/paste/tests/ui/unsupported-literal.rs21
-rw-r--r--third_party/rust/paste/tests/ui/unsupported-literal.stderr23
-rw-r--r--third_party/rust/paste/tests/ui/unsupported-modifier.rs7
-rw-r--r--third_party/rust/paste/tests/ui/unsupported-modifier.stderr5
33 files changed, 939 insertions, 0 deletions
diff --git a/third_party/rust/paste/tests/compiletest.rs b/third_party/rust/paste/tests/compiletest.rs
new file mode 100644
index 0000000000..7974a6249e
--- /dev/null
+++ b/third_party/rust/paste/tests/compiletest.rs
@@ -0,0 +1,7 @@
+#[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/*.rs");
+}
diff --git a/third_party/rust/paste/tests/test_attr.rs b/third_party/rust/paste/tests/test_attr.rs
new file mode 100644
index 0000000000..c880eac328
--- /dev/null
+++ b/third_party/rust/paste/tests/test_attr.rs
@@ -0,0 +1,60 @@
+use paste::paste;
+use paste_test_suite::paste_test;
+
+#[test]
+fn test_attr() {
+ paste! {
+ #[paste_test(k = "val" "ue")]
+ struct A;
+
+ #[paste_test_suite::paste_test(k = "val" "ue")]
+ struct B;
+
+ #[::paste_test_suite::paste_test(k = "val" "ue")]
+ struct C;
+
+ #[paste_test(k = "va" [<l u>] e)]
+ struct D;
+ }
+
+ let _ = A;
+ let _ = B;
+ let _ = C;
+ let _ = D;
+}
+
+#[test]
+fn test_paste_cfg() {
+ macro_rules! m {
+ ($ret:ident, $width:expr) => {
+ paste! {
+ #[cfg(any(feature = "protocol_feature_" $ret:snake, target_pointer_width = "" $width))]
+ fn new() -> $ret { todo!() }
+ }
+ };
+ }
+
+ struct Paste;
+
+ #[cfg(target_pointer_width = "64")]
+ m!(Paste, 64);
+ #[cfg(target_pointer_width = "32")]
+ m!(Paste, 32);
+
+ let _ = new;
+}
+
+#[test]
+fn test_path_in_attr() {
+ macro_rules! m {
+ (#[x = $x:ty]) => {
+ stringify!($x)
+ };
+ }
+
+ let ty = paste! {
+ m!(#[x = foo::Bar])
+ };
+
+ assert_eq!("foo::Bar", ty);
+}
diff --git a/third_party/rust/paste/tests/test_doc.rs b/third_party/rust/paste/tests/test_doc.rs
new file mode 100644
index 0000000000..2e2b14dc8a
--- /dev/null
+++ b/third_party/rust/paste/tests/test_doc.rs
@@ -0,0 +1,77 @@
+use paste::paste;
+
+#[test]
+fn test_paste_doc() {
+ macro_rules! m {
+ ($ret:ident) => {
+ paste! {
+ #[doc = "Create a new [`" $ret "`] object."]
+ fn new() -> $ret { todo!() }
+ }
+ };
+ }
+
+ struct Paste;
+ m!(Paste);
+
+ let _ = new;
+}
+
+macro_rules! get_doc {
+ (#[doc = $literal:tt]) => {
+ $literal
+ };
+}
+
+#[test]
+fn test_escaping() {
+ let doc = paste! {
+ get_doc!(#[doc = "s\"" r#"r#""#])
+ };
+
+ let expected = "s\"r#\"";
+ assert_eq!(doc, expected);
+}
+
+#[test]
+fn test_literals() {
+ let doc = paste! {
+ get_doc!(#[doc = "int=" 0x1 " bool=" true " float=" 0.01])
+ };
+
+ let expected = "int=0x1 bool=true float=0.01";
+ assert_eq!(doc, expected);
+}
+
+#[test]
+fn test_case() {
+ let doc = paste! {
+ get_doc!(#[doc = "HTTP " get:upper "!"])
+ };
+
+ let expected = "HTTP GET!";
+ assert_eq!(doc, expected);
+}
+
+// https://github.com/dtolnay/paste/issues/63
+#[test]
+fn test_stringify() {
+ macro_rules! create {
+ ($doc:expr) => {
+ paste! {
+ #[doc = $doc]
+ pub struct Struct;
+ }
+ };
+ }
+
+ macro_rules! forward {
+ ($name:ident) => {
+ create!(stringify!($name));
+ };
+ }
+
+ forward!(documentation);
+
+ let _ = Struct;
+}
diff --git a/third_party/rust/paste/tests/test_expr.rs b/third_party/rust/paste/tests/test_expr.rs
new file mode 100644
index 0000000000..5ce2549e6e
--- /dev/null
+++ b/third_party/rust/paste/tests/test_expr.rs
@@ -0,0 +1,283 @@
+use paste::paste;
+
+#[test]
+fn test_shared_hygiene() {
+ paste! {
+ let [<a a>] = 1;
+ assert_eq!([<a a>], 1);
+ }
+}
+
+#[test]
+fn test_repeat() {
+ const ROCKET_A: &str = "/a";
+ const ROCKET_B: &str = "/b";
+
+ macro_rules! routes {
+ ($($route:ident),*) => {{
+ paste! {
+ vec![$( [<ROCKET_ $route>] ),*]
+ }
+ }}
+ }
+
+ let routes = routes!(A, B);
+ assert_eq!(routes, vec!["/a", "/b"]);
+}
+
+#[test]
+fn test_literal_to_identifier() {
+ const CONST0: &str = "const0";
+
+ let pasted = paste!([<CONST 0>]);
+ assert_eq!(pasted, CONST0);
+
+ let pasted = paste!([<CONST '0'>]);
+ assert_eq!(pasted, CONST0);
+
+ let pasted = paste!([<CONST "0">]);
+ assert_eq!(pasted, CONST0);
+
+ let pasted = paste!([<CONST r"0">]);
+ assert_eq!(pasted, CONST0);
+
+ let pasted = paste!([<CONST '\u{30}'>]);
+ assert_eq!(pasted, CONST0);
+}
+
+#[test]
+fn test_literal_suffix() {
+ macro_rules! literal {
+ ($bit:tt) => {
+ paste!([<1_u $bit>])
+ };
+ }
+
+ assert_eq!(literal!(32), 1);
+}
+
+#[test]
+fn test_underscore() {
+ paste! {
+ const A_B: usize = 0;
+ assert_eq!([<A _ B>], 0);
+ }
+}
+
+#[test]
+fn test_lifetime() {
+ paste! {
+ #[allow(dead_code)]
+ struct S<[<'d e>]> {
+ q: &[<'d e>] str,
+ }
+ }
+}
+
+#[test]
+fn test_keyword() {
+ paste! {
+ struct [<F move>];
+
+ let _ = Fmove;
+ }
+}
+
+#[test]
+fn test_literal_str() {
+ paste! {
+ #[allow(non_camel_case_types)]
+ struct [<Foo "Bar-Baz">];
+
+ let _ = FooBar_Baz;
+ }
+}
+
+#[test]
+fn test_env_literal() {
+ paste! {
+ struct [<Lib env bar>];
+
+ let _ = Libenvbar;
+ }
+}
+
+#[test]
+fn test_env_present() {
+ paste! {
+ struct [<Lib env!("CARGO_PKG_NAME")>];
+
+ let _ = Libpaste;
+ }
+}
+
+#[test]
+fn test_raw_identifier() {
+ paste! {
+ struct [<F r#move>];
+
+ let _ = Fmove;
+ }
+}
+
+#[test]
+fn test_false_start() {
+ trait Trait {
+ fn f() -> usize;
+ }
+
+ struct S;
+
+ impl Trait for S {
+ fn f() -> usize {
+ 0
+ }
+ }
+
+ paste! {
+ let x = [<S as Trait>::f()];
+ assert_eq!(x[0], 0);
+ }
+}
+
+#[test]
+fn test_local_variable() {
+ let yy = 0;
+
+ paste! {
+ assert_eq!([<y y>], 0);
+ }
+}
+
+#[test]
+fn test_empty() {
+ paste! {
+ assert_eq!(stringify!([<y y>]), "yy");
+ assert_eq!(stringify!([<>]).replace(' ', ""), "[<>]");
+ }
+}
+
+#[test]
+fn test_env_to_lower() {
+ paste! {
+ struct [<Lib env!("CARGO_PKG_NAME"):lower>];
+
+ let _ = Libpaste;
+ }
+}
+
+#[test]
+fn test_env_to_upper() {
+ paste! {
+ const [<LIB env!("CARGO_PKG_NAME"):upper>]: &str = "libpaste";
+
+ let _ = LIBPASTE;
+ }
+}
+
+#[test]
+fn test_env_to_snake() {
+ paste! {
+ const [<LIB env!("CARGO_PKG_NAME"):snake:upper>]: &str = "libpaste";
+
+ let _ = LIBPASTE;
+ }
+}
+
+#[test]
+fn test_env_to_camel() {
+ paste! {
+ #[allow(non_upper_case_globals)]
+ const [<LIB env!("CARGO_PKG_NAME"):camel>]: &str = "libpaste";
+
+ let _ = LIBPaste;
+ }
+}
+
+mod test_x86_feature_literal {
+ // work around https://github.com/rust-lang/rust/issues/72726
+
+ use paste::paste;
+
+ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+ macro_rules! my_is_x86_feature_detected {
+ ($feat:literal) => {
+ paste! {
+ #[test]
+ fn test() {
+ let _ = is_x86_feature_detected!($feat);
+ }
+ }
+ };
+ }
+
+ #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+ macro_rules! my_is_x86_feature_detected {
+ ($feat:literal) => {
+ #[ignore]
+ #[test]
+ fn test() {}
+ };
+ }
+
+ my_is_x86_feature_detected!("mmx");
+}
+
+#[rustversion::since(1.46)]
+mod test_local_setter {
+ // https://github.com/dtolnay/paste/issues/7
+
+ use paste::paste;
+
+ #[derive(Default)]
+ struct Test {
+ val: i32,
+ }
+
+ impl Test {
+ fn set_val(&mut self, arg: i32) {
+ self.val = arg;
+ }
+ }
+
+ macro_rules! setter {
+ ($obj:expr, $field:ident, $value:expr) => {
+ paste! { $obj.[<set_ $field>]($value); }
+ };
+
+ ($field:ident, $value:expr) => {{
+ let mut new = Test::default();
+ setter!(new, val, $value);
+ new
+ }};
+ }
+
+ #[test]
+ fn test_local_setter() {
+ let a = setter!(val, 42);
+ assert_eq!(a.val, 42);
+ }
+}
+
+// https://github.com/dtolnay/paste/issues/85
+#[test]
+fn test_top_level_none_delimiter() {
+ macro_rules! clone {
+ ($val:expr) => {
+ paste! {
+ $val.clone()
+ }
+ };
+ }
+
+ #[derive(Clone)]
+ struct A;
+
+ impl A {
+ fn consume_self(self) {
+ let _ = self;
+ }
+ }
+
+ clone!(&A).consume_self();
+}
diff --git a/third_party/rust/paste/tests/test_item.rs b/third_party/rust/paste/tests/test_item.rs
new file mode 100644
index 0000000000..3821510a5d
--- /dev/null
+++ b/third_party/rust/paste/tests/test_item.rs
@@ -0,0 +1,269 @@
+mod test_basic {
+ use paste::paste;
+
+ struct Struct;
+
+ paste! {
+ impl Struct {
+ fn [<a b c>]() {}
+ }
+ }
+
+ #[test]
+ fn test() {
+ Struct::abc();
+ }
+}
+
+mod test_in_impl {
+ use paste::paste;
+
+ struct Struct;
+
+ impl Struct {
+ paste! {
+ fn [<a b c>]() {}
+ }
+ }
+
+ #[test]
+ fn test() {
+ Struct::abc();
+ }
+}
+
+mod test_none_delimited_single_ident {
+ use paste::paste;
+
+ macro_rules! m {
+ ($id:ident) => {
+ paste! {
+ fn f() -> &'static str {
+ stringify!($id)
+ }
+ }
+ };
+ }
+
+ m!(i32x4);
+
+ #[test]
+ fn test() {
+ assert_eq!(f(), "i32x4");
+ }
+}
+
+mod test_none_delimited_single_lifetime {
+ use paste::paste;
+
+ macro_rules! m {
+ ($life:lifetime) => {
+ paste! {
+ pub struct S<$life>(&$life ());
+ impl<$life> S<$life> {
+ fn f() {}
+ }
+ }
+ };
+ }
+
+ m!('a);
+
+ #[test]
+ fn test() {
+ S::f();
+ }
+}
+
+mod test_to_lower {
+ use paste::paste;
+
+ macro_rules! m {
+ ($id:ident) => {
+ paste! {
+ 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");
+ }
+}
+
+mod test_to_upper {
+ use paste::paste;
+
+ macro_rules! m {
+ ($id:ident) => {
+ paste! {
+ const [<MY_ $id:upper _HERE>]: &str = stringify!([<$id:upper>]);
+ }
+ };
+ }
+
+ m!(Test);
+
+ #[test]
+ fn test_to_upper() {
+ assert_eq!(MY_TEST_HERE, "TEST");
+ }
+}
+
+mod test_to_snake {
+ use paste::paste;
+
+ macro_rules! m {
+ ($id:ident) => {
+ paste! {
+ 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");
+ }
+}
+
+mod test_to_camel {
+ use paste::paste;
+
+ macro_rules! m {
+ ($id:ident) => {
+ paste! {
+ const DEFAULT_CAMEL: &str = stringify!([<$id:camel>]);
+ const LOWER_CAMEL: &str = stringify!([<$id:camel:lower>]);
+ const UPPER_CAMEL: &str = stringify!([<$id:camel:upper>]);
+ }
+ };
+ }
+
+ m!(this_is_but_a_test);
+
+ #[test]
+ fn test_to_camel() {
+ assert_eq!(DEFAULT_CAMEL, "ThisIsButATest");
+ assert_eq!(LOWER_CAMEL, "thisisbutatest");
+ assert_eq!(UPPER_CAMEL, "THISISBUTATEST");
+ }
+}
+
+mod test_doc_expr {
+ // https://github.com/dtolnay/paste/issues/29
+
+ use paste::paste;
+
+ macro_rules! doc_expr {
+ ($doc:expr) => {
+ paste! {
+ #[doc = $doc]
+ pub struct S;
+ }
+ };
+ }
+
+ doc_expr!(stringify!());
+
+ #[test]
+ fn test_doc_expr() {
+ let _: S;
+ }
+}
+
+mod test_type_in_path {
+ // https://github.com/dtolnay/paste/issues/31
+
+ use paste::paste;
+
+ mod keys {
+ #[derive(Default)]
+ pub struct Mib<T = ()>(std::marker::PhantomData<T>);
+ }
+
+ macro_rules! types {
+ ($mib:ty) => {
+ paste! {
+ #[derive(Default)]
+ pub struct S(pub keys::$mib);
+ }
+ };
+ }
+
+ macro_rules! write {
+ ($fn:ident, $field:ty) => {
+ paste! {
+ pub fn $fn() -> $field {
+ $field::default()
+ }
+ }
+ };
+ }
+
+ types! {Mib<[usize; 2]>}
+ write! {get_a, keys::Mib}
+ write! {get_b, usize}
+
+ #[test]
+ fn test_type_in_path() {
+ let _: S;
+ let _ = get_a;
+ let _ = get_b;
+ }
+}
+
+mod test_type_in_fn_arg {
+ // https://github.com/dtolnay/paste/issues/38
+
+ use paste::paste;
+
+ fn _jit_address(_node: ()) {}
+
+ macro_rules! jit_reexport {
+ ($fn:ident, $arg:ident : $typ:ty) => {
+ paste! {
+ pub fn $fn($arg: $typ) {
+ [<_jit_ $fn>]($arg);
+ }
+ }
+ };
+ }
+
+ jit_reexport!(address, node: ());
+
+ #[test]
+ fn test_type_in_fn_arg() {
+ let _ = address;
+ }
+}
+
+mod test_pat_in_expr_position {
+ // https://github.com/xiph/rav1e/pull/2324/files
+
+ use paste::paste;
+
+ macro_rules! rav1e_bad {
+ ($e:pat) => {
+ paste! {
+ #[test]
+ fn test() {
+ let _ = $e;
+ }
+ }
+ };
+ }
+
+ rav1e_bad!(std::fmt::Error);
+}
diff --git a/third_party/rust/paste/tests/ui/case-warning.rs b/third_party/rust/paste/tests/ui/case-warning.rs
new file mode 100644
index 0000000000..fdea4d619d
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/case-warning.rs
@@ -0,0 +1,15 @@
+#![deny(warnings)]
+
+use paste::paste;
+
+macro_rules! m {
+ ($i:ident) => {
+ paste! {
+ pub fn [<foo $i>]() {}
+ }
+ };
+}
+
+m!(Bar);
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/case-warning.stderr b/third_party/rust/paste/tests/ui/case-warning.stderr
new file mode 100644
index 0000000000..83099129df
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/case-warning.stderr
@@ -0,0 +1,16 @@
+error: function `fooBar` should have a snake case name
+ --> tests/ui/case-warning.rs:8:20
+ |
+8 | pub fn [<foo $i>]() {}
+ | ^^^^^^^^^^ help: convert the identifier to snake case: `foo_bar`
+...
+13 | m!(Bar);
+ | ------- in this macro invocation
+ |
+note: the lint level is defined here
+ --> tests/ui/case-warning.rs:1:9
+ |
+1 | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(non_snake_case)]` implied by `#[deny(warnings)]`
+ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/paste/tests/ui/env-empty.rs b/third_party/rust/paste/tests/ui/env-empty.rs
new file mode 100644
index 0000000000..1e9f2d0a24
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/env-empty.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<env!()>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/env-empty.stderr b/third_party/rust/paste/tests/ui/env-empty.stderr
new file mode 100644
index 0000000000..a1ef2e2f58
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/env-empty.stderr
@@ -0,0 +1,5 @@
+error: expected string literal as argument to env! macro
+ --> tests/ui/env-empty.rs:4:10
+ |
+4 | fn [<env!()>]() {}
+ | ^^^^^^
diff --git a/third_party/rust/paste/tests/ui/env-non-string.rs b/third_party/rust/paste/tests/ui/env-non-string.rs
new file mode 100644
index 0000000000..55255ef902
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/env-non-string.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<env!(1.31)>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/env-non-string.stderr b/third_party/rust/paste/tests/ui/env-non-string.stderr
new file mode 100644
index 0000000000..05b8deba83
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/env-non-string.stderr
@@ -0,0 +1,5 @@
+error: expected string literal
+ --> tests/ui/env-non-string.rs:4:15
+ |
+4 | fn [<env!(1.31)>]() {}
+ | ^^^^
diff --git a/third_party/rust/paste/tests/ui/env-suffix.rs b/third_party/rust/paste/tests/ui/env-suffix.rs
new file mode 100644
index 0000000000..b5c60af450
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/env-suffix.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<env!("VAR"suffix)>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/env-suffix.stderr b/third_party/rust/paste/tests/ui/env-suffix.stderr
new file mode 100644
index 0000000000..d723cbc7ed
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/env-suffix.stderr
@@ -0,0 +1,5 @@
+error: expected string literal
+ --> tests/ui/env-suffix.rs:4:15
+ |
+4 | fn [<env!("VAR"suffix)>]() {}
+ | ^^^^^^^^^^^
diff --git a/third_party/rust/paste/tests/ui/env-unexpected.rs b/third_party/rust/paste/tests/ui/env-unexpected.rs
new file mode 100644
index 0000000000..39cb770d98
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/env-unexpected.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<env!("VAR" "VAR")>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/env-unexpected.stderr b/third_party/rust/paste/tests/ui/env-unexpected.stderr
new file mode 100644
index 0000000000..25387b1140
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/env-unexpected.stderr
@@ -0,0 +1,5 @@
+error: unexpected token in env! macro
+ --> tests/ui/env-unexpected.rs:4:21
+ |
+4 | fn [<env!("VAR" "VAR")>]() {}
+ | ^^^^^
diff --git a/third_party/rust/paste/tests/ui/invalid-ident.rs b/third_party/rust/paste/tests/ui/invalid-ident.rs
new file mode 100644
index 0000000000..6a8cf3c44b
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/invalid-ident.rs
@@ -0,0 +1,15 @@
+use paste::paste;
+
+paste! {
+ fn [<0 f>]() {}
+}
+
+paste! {
+ fn [<f '"'>]() {}
+}
+
+paste! {
+ fn [<f "'">]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/invalid-ident.stderr b/third_party/rust/paste/tests/ui/invalid-ident.stderr
new file mode 100644
index 0000000000..28593fb1a6
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/invalid-ident.stderr
@@ -0,0 +1,21 @@
+error: expected identifier, found `0f`
+ --> tests/ui/invalid-ident.rs:3:1
+ |
+3 | / paste! {
+4 | | fn [<0 f>]() {}
+5 | | }
+ | |_^ expected identifier
+ |
+ = note: this error originates in the macro `paste` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `"f\""` is not a valid identifier
+ --> tests/ui/invalid-ident.rs:8:8
+ |
+8 | fn [<f '"'>]() {}
+ | ^^^^^^^^^
+
+error: `"f'"` is not a valid identifier
+ --> tests/ui/invalid-ident.rs:12:8
+ |
+12 | fn [<f "'">]() {}
+ | ^^^^^^^^^
diff --git a/third_party/rust/paste/tests/ui/missing-paren-on-env.rs b/third_party/rust/paste/tests/ui/missing-paren-on-env.rs
new file mode 100644
index 0000000000..44fefbd3e0
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/missing-paren-on-env.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<env! huh>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/missing-paren-on-env.stderr b/third_party/rust/paste/tests/ui/missing-paren-on-env.stderr
new file mode 100644
index 0000000000..7b4bc4604d
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/missing-paren-on-env.stderr
@@ -0,0 +1,5 @@
+error: expected `(`
+ --> tests/ui/missing-paren-on-env.rs:4:15
+ |
+4 | fn [<env! huh>]() {}
+ | ^^^
diff --git a/third_party/rust/paste/tests/ui/no-env-var.rs b/third_party/rust/paste/tests/ui/no-env-var.rs
new file mode 100644
index 0000000000..c6d8c3d59c
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/no-env-var.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<a env!("PASTE_UNKNOWN") b>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/no-env-var.stderr b/third_party/rust/paste/tests/ui/no-env-var.stderr
new file mode 100644
index 0000000000..60de9ede26
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/no-env-var.stderr
@@ -0,0 +1,5 @@
+error: no such env var: "PASTE_UNKNOWN"
+ --> tests/ui/no-env-var.rs:4:17
+ |
+4 | fn [<a env!("PASTE_UNKNOWN") b>]() {}
+ | ^^^^^^^^^^^^^^^
diff --git a/third_party/rust/paste/tests/ui/no-ident-after-colon.rs b/third_party/rust/paste/tests/ui/no-ident-after-colon.rs
new file mode 100644
index 0000000000..50b3b0dd01
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/no-ident-after-colon.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<name:0>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/no-ident-after-colon.stderr b/third_party/rust/paste/tests/ui/no-ident-after-colon.stderr
new file mode 100644
index 0000000000..9db91eb517
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/no-ident-after-colon.stderr
@@ -0,0 +1,5 @@
+error: expected identifier after `:`
+ --> tests/ui/no-ident-after-colon.rs:4:15
+ |
+4 | fn [<name:0>]() {}
+ | ^
diff --git a/third_party/rust/paste/tests/ui/unexpected-group.rs b/third_party/rust/paste/tests/ui/unexpected-group.rs
new file mode 100644
index 0000000000..63ee5161c7
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unexpected-group.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<a {} b>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/unexpected-group.stderr b/third_party/rust/paste/tests/ui/unexpected-group.stderr
new file mode 100644
index 0000000000..f66f5c15e0
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unexpected-group.stderr
@@ -0,0 +1,5 @@
+error: unexpected token
+ --> tests/ui/unexpected-group.rs:4:12
+ |
+4 | fn [<a {} b>]() {}
+ | ^^
diff --git a/third_party/rust/paste/tests/ui/unexpected-modifier.rs b/third_party/rust/paste/tests/ui/unexpected-modifier.rs
new file mode 100644
index 0000000000..99fe68f1ff
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unexpected-modifier.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<:lower x>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/unexpected-modifier.stderr b/third_party/rust/paste/tests/ui/unexpected-modifier.stderr
new file mode 100644
index 0000000000..1eaba3147a
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unexpected-modifier.stderr
@@ -0,0 +1,5 @@
+error: unexpected modifier
+ --> tests/ui/unexpected-modifier.rs:4:10
+ |
+4 | fn [<:lower x>]() {}
+ | ^^^^^^
diff --git a/third_party/rust/paste/tests/ui/unexpected-punct.rs b/third_party/rust/paste/tests/ui/unexpected-punct.rs
new file mode 100644
index 0000000000..d0edb9243a
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unexpected-punct.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<a + b>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/unexpected-punct.stderr b/third_party/rust/paste/tests/ui/unexpected-punct.stderr
new file mode 100644
index 0000000000..1a74a61d73
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unexpected-punct.stderr
@@ -0,0 +1,5 @@
+error: unexpected punct
+ --> tests/ui/unexpected-punct.rs:4:12
+ |
+4 | fn [<a + b>]() {}
+ | ^
diff --git a/third_party/rust/paste/tests/ui/unsupported-literal.rs b/third_party/rust/paste/tests/ui/unsupported-literal.rs
new file mode 100644
index 0000000000..7a9c490d8c
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unsupported-literal.rs
@@ -0,0 +1,21 @@
+use paste::paste;
+
+paste! {
+ fn [<x 1e+100 z>]() {}
+}
+
+paste! {
+ // `xyz` is not correct. `xbyz` is certainly not correct. Maybe `x121z`
+ // would be justifiable but for now don't accept this.
+ fn [<x b'y' z>]() {}
+}
+
+paste! {
+ fn [<x b"y" z>]() {}
+}
+
+paste! {
+ fn [<x br"y" z>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/unsupported-literal.stderr b/third_party/rust/paste/tests/ui/unsupported-literal.stderr
new file mode 100644
index 0000000000..a802b4580f
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unsupported-literal.stderr
@@ -0,0 +1,23 @@
+error: unsupported literal
+ --> tests/ui/unsupported-literal.rs:4:12
+ |
+4 | fn [<x 1e+100 z>]() {}
+ | ^^^^^^
+
+error: unsupported literal
+ --> tests/ui/unsupported-literal.rs:10:12
+ |
+10 | fn [<x b'y' z>]() {}
+ | ^^^^
+
+error: unsupported literal
+ --> tests/ui/unsupported-literal.rs:14:12
+ |
+14 | fn [<x b"y" z>]() {}
+ | ^^^^
+
+error: unsupported literal
+ --> tests/ui/unsupported-literal.rs:18:12
+ |
+18 | fn [<x br"y" z>]() {}
+ | ^^^^^
diff --git a/third_party/rust/paste/tests/ui/unsupported-modifier.rs b/third_party/rust/paste/tests/ui/unsupported-modifier.rs
new file mode 100644
index 0000000000..a65b36ae80
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unsupported-modifier.rs
@@ -0,0 +1,7 @@
+use paste::paste;
+
+paste! {
+ fn [<a:pillow>]() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/paste/tests/ui/unsupported-modifier.stderr b/third_party/rust/paste/tests/ui/unsupported-modifier.stderr
new file mode 100644
index 0000000000..3c7043541f
--- /dev/null
+++ b/third_party/rust/paste/tests/ui/unsupported-modifier.stderr
@@ -0,0 +1,5 @@
+error: unsupported modifier
+ --> tests/ui/unsupported-modifier.rs:4:11
+ |
+4 | fn [<a:pillow>]() {}
+ | ^^^^^^^