summaryrefslogtreecommitdiffstats
path: root/third_party/rust/quote/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/quote/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/quote/tests')
-rw-r--r--third_party/rust/quote/tests/compiletest.rs7
-rw-r--r--third_party/rust/quote/tests/test.rs519
-rw-r--r--third_party/rust/quote/tests/ui/does-not-have-iter-interpolated-dup.rs9
-rw-r--r--third_party/rust/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr10
-rw-r--r--third_party/rust/quote/tests/ui/does-not-have-iter-interpolated.rs9
-rw-r--r--third_party/rust/quote/tests/ui/does-not-have-iter-interpolated.stderr10
-rw-r--r--third_party/rust/quote/tests/ui/does-not-have-iter-separated.rs5
-rw-r--r--third_party/rust/quote/tests/ui/does-not-have-iter-separated.stderr10
-rw-r--r--third_party/rust/quote/tests/ui/does-not-have-iter.rs5
-rw-r--r--third_party/rust/quote/tests/ui/does-not-have-iter.stderr10
-rw-r--r--third_party/rust/quote/tests/ui/not-quotable.rs7
-rw-r--r--third_party/rust/quote/tests/ui/not-quotable.stderr20
-rw-r--r--third_party/rust/quote/tests/ui/not-repeatable.rs8
-rw-r--r--third_party/rust/quote/tests/ui/not-repeatable.stderr35
-rw-r--r--third_party/rust/quote/tests/ui/wrong-type-span.rs7
-rw-r--r--third_party/rust/quote/tests/ui/wrong-type-span.stderr8
16 files changed, 679 insertions, 0 deletions
diff --git a/third_party/rust/quote/tests/compiletest.rs b/third_party/rust/quote/tests/compiletest.rs
new file mode 100644
index 0000000000..7974a6249e
--- /dev/null
+++ b/third_party/rust/quote/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/quote/tests/test.rs b/third_party/rust/quote/tests/test.rs
new file mode 100644
index 0000000000..52ec7bcfb3
--- /dev/null
+++ b/third_party/rust/quote/tests/test.rs
@@ -0,0 +1,519 @@
+#![allow(
+ clippy::disallowed_names,
+ clippy::shadow_unrelated,
+ clippy::unseparated_literal_suffix,
+ clippy::used_underscore_binding
+)]
+
+use std::borrow::Cow;
+use std::collections::BTreeSet;
+
+use proc_macro2::{Ident, Span, TokenStream};
+use quote::{format_ident, quote, quote_spanned, TokenStreamExt};
+
+struct X;
+
+impl quote::ToTokens for X {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(Ident::new("X", Span::call_site()));
+ }
+}
+
+#[test]
+fn test_quote_impl() {
+ let tokens = quote! {
+ impl<'a, T: ToTokens> ToTokens for &'a T {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens)
+ }
+ }
+ };
+
+ let expected = concat!(
+ "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
+ "fn to_tokens (& self , tokens : & mut TokenStream) { ",
+ "(* * self) . to_tokens (tokens) ",
+ "} ",
+ "}"
+ );
+
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_quote_spanned_impl() {
+ let span = Span::call_site();
+ let tokens = quote_spanned! {span=>
+ impl<'a, T: ToTokens> ToTokens for &'a T {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens)
+ }
+ }
+ };
+
+ let expected = concat!(
+ "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
+ "fn to_tokens (& self , tokens : & mut TokenStream) { ",
+ "(* * self) . to_tokens (tokens) ",
+ "} ",
+ "}"
+ );
+
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_substitution() {
+ let x = X;
+ let tokens = quote!(#x <#x> (#x) [#x] {#x});
+
+ let expected = "X < X > (X) [X] { X }";
+
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_iter() {
+ let primes = &[X, X, X, X];
+
+ assert_eq!("X X X X", quote!(#(#primes)*).to_string());
+
+ assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string());
+
+ assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string());
+}
+
+#[test]
+fn test_array() {
+ let array: [u8; 40] = [0; 40];
+ let _ = quote!(#(#array #array)*);
+
+ let ref_array: &[u8; 40] = &[0; 40];
+ let _ = quote!(#(#ref_array #ref_array)*);
+
+ let ref_slice: &[u8] = &[0; 40];
+ let _ = quote!(#(#ref_slice #ref_slice)*);
+
+ let array: [X; 2] = [X, X]; // !Copy
+ let _ = quote!(#(#array #array)*);
+
+ let ref_array: &[X; 2] = &[X, X];
+ let _ = quote!(#(#ref_array #ref_array)*);
+
+ let ref_slice: &[X] = &[X, X];
+ let _ = quote!(#(#ref_slice #ref_slice)*);
+}
+
+#[test]
+fn test_advanced() {
+ let generics = quote!( <'a, T> );
+
+ let where_clause = quote!( where T: Serialize );
+
+ let field_ty = quote!(String);
+
+ let item_ty = quote!(Cow<'a, str>);
+
+ let path = quote!(SomeTrait::serialize_with);
+
+ let value = quote!(self.x);
+
+ let tokens = quote! {
+ struct SerializeWith #generics #where_clause {
+ value: &'a #field_ty,
+ phantom: ::std::marker::PhantomData<#item_ty>,
+ }
+
+ impl #generics ::serde::Serialize for SerializeWith #generics #where_clause {
+ fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
+ where S: ::serde::Serializer
+ {
+ #path(self.value, s)
+ }
+ }
+
+ SerializeWith {
+ value: #value,
+ phantom: ::std::marker::PhantomData::<#item_ty>,
+ }
+ };
+
+ let expected = concat!(
+ "struct SerializeWith < 'a , T > where T : Serialize { ",
+ "value : & 'a String , ",
+ "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ",
+ "} ",
+ "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ",
+ "fn serialize < S > (& self , s : & mut S) -> Result < () , S :: Error > ",
+ "where S : :: serde :: Serializer ",
+ "{ ",
+ "SomeTrait :: serialize_with (self . value , s) ",
+ "} ",
+ "} ",
+ "SerializeWith { ",
+ "value : self . x , ",
+ "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ",
+ "}"
+ );
+
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_integer() {
+ let ii8 = -1i8;
+ let ii16 = -1i16;
+ let ii32 = -1i32;
+ let ii64 = -1i64;
+ let ii128 = -1i128;
+ let iisize = -1isize;
+ let uu8 = 1u8;
+ let uu16 = 1u16;
+ let uu32 = 1u32;
+ let uu64 = 1u64;
+ let uu128 = 1u128;
+ let uusize = 1usize;
+
+ let tokens = quote! {
+ 1 1i32 1u256
+ #ii8 #ii16 #ii32 #ii64 #ii128 #iisize
+ #uu8 #uu16 #uu32 #uu64 #uu128 #uusize
+ };
+ let expected =
+ "1 1i32 1u256 - 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_floating() {
+ let e32 = 2.345f32;
+
+ let e64 = 2.345f64;
+
+ let tokens = quote! {
+ #e32
+ #e64
+ };
+ let expected = concat!("2.345f32 2.345f64");
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_char() {
+ let zero = '\u{1}';
+ let pound = '#';
+ let quote = '"';
+ let apost = '\'';
+ let newline = '\n';
+ let heart = '\u{2764}';
+
+ let tokens = quote! {
+ #zero #pound #quote #apost #newline #heart
+ };
+ let expected = "'\\u{1}' '#' '\"' '\\'' '\\n' '\u{2764}'";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_str() {
+ let s = "\u{1} a 'b \" c";
+ let tokens = quote!(#s);
+ let expected = "\"\\u{1} a 'b \\\" c\"";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_string() {
+ let s = "\u{1} a 'b \" c".to_string();
+ let tokens = quote!(#s);
+ let expected = "\"\\u{1} a 'b \\\" c\"";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_interpolated_literal() {
+ macro_rules! m {
+ ($literal:literal) => {
+ quote!($literal)
+ };
+ }
+
+ let tokens = m!(1);
+ let expected = "1";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(-1);
+ let expected = "- 1";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(true);
+ let expected = "true";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(-true);
+ let expected = "- true";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_ident() {
+ let foo = Ident::new("Foo", Span::call_site());
+ let bar = Ident::new(&format!("Bar{}", 7), Span::call_site());
+ let tokens = quote!(struct #foo; enum #bar {});
+ let expected = "struct Foo ; enum Bar7 { }";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_underscore() {
+ let tokens = quote!(let _;);
+ let expected = "let _ ;";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_duplicate() {
+ let ch = 'x';
+
+ let tokens = quote!(#ch #ch);
+
+ let expected = "'x' 'x'";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_fancy_repetition() {
+ let foo = vec!["a", "b"];
+ let bar = vec![true, false];
+
+ let tokens = quote! {
+ #(#foo: #bar),*
+ };
+
+ let expected = r#""a" : true , "b" : false"#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_nested_fancy_repetition() {
+ let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']];
+
+ let tokens = quote! {
+ #(
+ #(#nested)*
+ ),*
+ };
+
+ let expected = "'a' 'b' 'c' , 'x' 'y' 'z'";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_duplicate_name_repetition() {
+ let foo = &["a", "b"];
+
+ let tokens = quote! {
+ #(#foo: #foo),*
+ #(#foo: #foo),*
+ };
+
+ let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_duplicate_name_repetition_no_copy() {
+ let foo = vec!["a".to_owned(), "b".to_owned()];
+
+ let tokens = quote! {
+ #(#foo: #foo),*
+ };
+
+ let expected = r#""a" : "a" , "b" : "b""#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_btreeset_repetition() {
+ let mut set = BTreeSet::new();
+ set.insert("a".to_owned());
+ set.insert("b".to_owned());
+
+ let tokens = quote! {
+ #(#set: #set),*
+ };
+
+ let expected = r#""a" : "a" , "b" : "b""#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_variable_name_conflict() {
+ // The implementation of `#(...),*` uses the variable `_i` but it should be
+ // fine, if a little confusing when debugging.
+ let _i = vec!['a', 'b'];
+ let tokens = quote! { #(#_i),* };
+ let expected = "'a' , 'b'";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_nonrep_in_repetition() {
+ let rep = vec!["a", "b"];
+ let nonrep = "c";
+
+ let tokens = quote! {
+ #(#rep #rep : #nonrep #nonrep),*
+ };
+
+ let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_empty_quote() {
+ let tokens = quote!();
+ assert_eq!("", tokens.to_string());
+}
+
+#[test]
+fn test_box_str() {
+ let b = "str".to_owned().into_boxed_str();
+ let tokens = quote! { #b };
+ assert_eq!("\"str\"", tokens.to_string());
+}
+
+#[test]
+fn test_cow() {
+ let owned: Cow<Ident> = Cow::Owned(Ident::new("owned", Span::call_site()));
+
+ let ident = Ident::new("borrowed", Span::call_site());
+ let borrowed = Cow::Borrowed(&ident);
+
+ let tokens = quote! { #owned #borrowed };
+ assert_eq!("owned borrowed", tokens.to_string());
+}
+
+#[test]
+fn test_closure() {
+ fn field_i(i: usize) -> Ident {
+ format_ident!("__field{}", i)
+ }
+
+ let fields = (0usize..3)
+ .map(field_i as fn(_) -> _)
+ .map(|var| quote! { #var });
+
+ let tokens = quote! { #(#fields)* };
+ assert_eq!("__field0 __field1 __field2", tokens.to_string());
+}
+
+#[test]
+fn test_append_tokens() {
+ let mut a = quote!(a);
+ let b = quote!(b);
+ a.append_all(b);
+ assert_eq!("a b", a.to_string());
+}
+
+#[test]
+fn test_format_ident() {
+ let id0 = format_ident!("Aa");
+ let id1 = format_ident!("Hello{x}", x = id0);
+ let id2 = format_ident!("Hello{x}", x = 5usize);
+ let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize);
+ let id4 = format_ident!("Aa", span = Span::call_site());
+ let id5 = format_ident!("Hello{}", Cow::Borrowed("World"));
+
+ assert_eq!(id0, "Aa");
+ assert_eq!(id1, "HelloAa");
+ assert_eq!(id2, "Hello5");
+ assert_eq!(id3, "HelloAa_10");
+ assert_eq!(id4, "Aa");
+ assert_eq!(id5, "HelloWorld");
+}
+
+#[test]
+fn test_format_ident_strip_raw() {
+ let id = format_ident!("r#struct");
+ let my_id = format_ident!("MyId{}", id);
+ let raw_my_id = format_ident!("r#MyId{}", id);
+
+ assert_eq!(id, "r#struct");
+ assert_eq!(my_id, "MyIdstruct");
+ assert_eq!(raw_my_id, "r#MyIdstruct");
+}
+
+#[test]
+fn test_outer_line_comment() {
+ let tokens = quote! {
+ /// doc
+ };
+ let expected = "# [doc = r\" doc\"]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_inner_line_comment() {
+ let tokens = quote! {
+ //! doc
+ };
+ let expected = "# ! [doc = r\" doc\"]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_outer_block_comment() {
+ let tokens = quote! {
+ /** doc */
+ };
+ let expected = "# [doc = r\" doc \"]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_inner_block_comment() {
+ let tokens = quote! {
+ /*! doc */
+ };
+ let expected = "# ! [doc = r\" doc \"]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_outer_attr() {
+ let tokens = quote! {
+ #[inline]
+ };
+ let expected = "# [inline]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_inner_attr() {
+ let tokens = quote! {
+ #![no_std]
+ };
+ let expected = "# ! [no_std]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+// https://github.com/dtolnay/quote/issues/130
+#[test]
+fn test_star_after_repetition() {
+ let c = vec!['0', '1'];
+ let tokens = quote! {
+ #(
+ f(#c);
+ )*
+ *out = None;
+ };
+ let expected = "f ('0') ; f ('1') ; * out = None ;";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_quote_raw_id() {
+ let id = quote!(r#raw_id);
+ assert_eq!(id.to_string(), "r#raw_id");
+}
diff --git a/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated-dup.rs b/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
new file mode 100644
index 0000000000..0a39f41507
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
@@ -0,0 +1,9 @@
+use quote::quote;
+
+fn main() {
+ let nonrep = "";
+
+ // Without some protection against repetitions with no iterator somewhere
+ // inside, this would loop infinitely.
+ quote!(#(#nonrep #nonrep)*);
+}
diff --git a/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr b/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
new file mode 100644
index 0000000000..8087879af7
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-interpolated-dup.rs:8:5
+ |
+8 | quote!(#(#nonrep #nonrep)*);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated.rs b/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated.rs
new file mode 100644
index 0000000000..2c740cc083
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated.rs
@@ -0,0 +1,9 @@
+use quote::quote;
+
+fn main() {
+ let nonrep = "";
+
+ // Without some protection against repetitions with no iterator somewhere
+ // inside, this would loop infinitely.
+ quote!(#(#nonrep)*);
+}
diff --git a/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated.stderr b/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated.stderr
new file mode 100644
index 0000000000..2dcf206dd4
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/does-not-have-iter-interpolated.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-interpolated.rs:8:5
+ |
+8 | quote!(#(#nonrep)*);
+ | ^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/quote/tests/ui/does-not-have-iter-separated.rs b/third_party/rust/quote/tests/ui/does-not-have-iter-separated.rs
new file mode 100644
index 0000000000..c027243dda
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/does-not-have-iter-separated.rs
@@ -0,0 +1,5 @@
+use quote::quote;
+
+fn main() {
+ quote!(#(a b),*);
+}
diff --git a/third_party/rust/quote/tests/ui/does-not-have-iter-separated.stderr b/third_party/rust/quote/tests/ui/does-not-have-iter-separated.stderr
new file mode 100644
index 0000000000..87a19fe073
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/does-not-have-iter-separated.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-separated.rs:4:5
+ |
+4 | quote!(#(a b),*);
+ | ^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/quote/tests/ui/does-not-have-iter.rs b/third_party/rust/quote/tests/ui/does-not-have-iter.rs
new file mode 100644
index 0000000000..8908353b57
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/does-not-have-iter.rs
@@ -0,0 +1,5 @@
+use quote::quote;
+
+fn main() {
+ quote!(#(a b)*);
+}
diff --git a/third_party/rust/quote/tests/ui/does-not-have-iter.stderr b/third_party/rust/quote/tests/ui/does-not-have-iter.stderr
new file mode 100644
index 0000000000..32aa62d9bb
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/does-not-have-iter.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter.rs:4:5
+ |
+4 | quote!(#(a b)*);
+ | ^^^^^^^^^^^^^^^
+ | |
+ | expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/quote/tests/ui/not-quotable.rs b/third_party/rust/quote/tests/ui/not-quotable.rs
new file mode 100644
index 0000000000..220542d841
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/not-quotable.rs
@@ -0,0 +1,7 @@
+use quote::quote;
+use std::net::Ipv4Addr;
+
+fn main() {
+ let ip = Ipv4Addr::LOCALHOST;
+ _ = quote! { #ip };
+}
diff --git a/third_party/rust/quote/tests/ui/not-quotable.stderr b/third_party/rust/quote/tests/ui/not-quotable.stderr
new file mode 100644
index 0000000000..c323d99b76
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/not-quotable.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied
+ --> tests/ui/not-quotable.rs:6:9
+ |
+6 | _ = quote! { #ip };
+ | ^^^^^^^^^^^^^^
+ | |
+ | the trait `ToTokens` is not implemented for `Ipv4Addr`
+ | required by a bound introduced by this call
+ |
+ = help: the following other types implement trait `ToTokens`:
+ &'a T
+ &'a mut T
+ Box<T>
+ Cow<'a, T>
+ Option<T>
+ Rc<T>
+ RepInterp<T>
+ String
+ and 23 others
+ = note: this error originates in the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/quote/tests/ui/not-repeatable.rs b/third_party/rust/quote/tests/ui/not-repeatable.rs
new file mode 100644
index 0000000000..c1debf5f80
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/not-repeatable.rs
@@ -0,0 +1,8 @@
+use quote::quote;
+
+struct Ipv4Addr;
+
+fn main() {
+ let ip = Ipv4Addr;
+ _ = quote! { #(#ip)* };
+}
diff --git a/third_party/rust/quote/tests/ui/not-repeatable.stderr b/third_party/rust/quote/tests/ui/not-repeatable.stderr
new file mode 100644
index 0000000000..264a89f9e9
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/not-repeatable.stderr
@@ -0,0 +1,35 @@
+error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied
+ --> tests/ui/not-repeatable.rs:7:9
+ |
+3 | struct Ipv4Addr;
+ | ---------------
+ | |
+ | method `quote_into_iter` not found for this struct
+ | doesn't satisfy `Ipv4Addr: Iterator`
+ | doesn't satisfy `Ipv4Addr: ToTokens`
+ | doesn't satisfy `Ipv4Addr: ext::RepIteratorExt`
+ | doesn't satisfy `Ipv4Addr: ext::RepToTokensExt`
+...
+7 | _ = quote! { #(#ip)* };
+ | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `Ipv4Addr: Iterator`
+ which is required by `Ipv4Addr: ext::RepIteratorExt`
+ `&Ipv4Addr: Iterator`
+ which is required by `&Ipv4Addr: ext::RepIteratorExt`
+ `Ipv4Addr: ToTokens`
+ which is required by `Ipv4Addr: ext::RepToTokensExt`
+ `&mut Ipv4Addr: Iterator`
+ which is required by `&mut Ipv4Addr: ext::RepIteratorExt`
+note: the traits `ToTokens` and `Iterator` must be implemented
+ --> src/to_tokens.rs
+ |
+ | pub trait ToTokens {
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ ::: $RUST/core/src/iter/traits/iterator.rs
+ |
+ | pub trait Iterator {
+ | ^^^^^^^^^^^^^^^^^^
+ = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/quote/tests/ui/wrong-type-span.rs b/third_party/rust/quote/tests/ui/wrong-type-span.rs
new file mode 100644
index 0000000000..d5601c8a06
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/wrong-type-span.rs
@@ -0,0 +1,7 @@
+use quote::quote_spanned;
+
+fn main() {
+ let span = "";
+ let x = 0i32;
+ quote_spanned!(span=> #x);
+}
diff --git a/third_party/rust/quote/tests/ui/wrong-type-span.stderr b/third_party/rust/quote/tests/ui/wrong-type-span.stderr
new file mode 100644
index 0000000000..c774a4c3af
--- /dev/null
+++ b/third_party/rust/quote/tests/ui/wrong-type-span.stderr
@@ -0,0 +1,8 @@
+error[E0308]: mismatched types
+ --> tests/ui/wrong-type-span.rs:6:20
+ |
+6 | quote_spanned!(span=> #x);
+ | ---------------^^^^------
+ | | |
+ | | expected struct `Span`, found `&str`
+ | expected due to this