Parse crate::X in newtype as (crate::X) not crate(::X)
diff --git a/src/data.rs b/src/data.rs
index fbbdb70..3d1924a 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -261,11 +261,13 @@
}))
)
|
- keyword!(crate) => { |tok| {
- Visibility::Crate(VisCrate {
- crate_token: tok,
- })
- } }
+ do_parse!(
+ crate_token: keyword!(crate) >>
+ not!(punct!(::)) >>
+ (Visibility::Crate(VisCrate {
+ crate_token: crate_token,
+ }))
+ )
|
do_parse!(
pub_token: keyword!(pub) >>
diff --git a/tests/test_derive_input.rs b/tests/test_derive_input.rs
index a5377e7..3ddbb4b 100644
--- a/tests/test_derive_input.rs
+++ b/tests/test_derive_input.rs
@@ -713,3 +713,43 @@
assert_eq!(expected, struct_body.fields.iter().collect::<Vec<_>>());
}
+
+#[test]
+fn test_ambiguous_crate() {
+ // The field type is `(crate::X)` not `crate (::X)`.
+ let raw = "struct S(crate::X);";
+
+ let expected = DeriveInput {
+ ident: ident("S"),
+ vis: Visibility::Inherited,
+ attrs: vec![],
+ generics: Generics::default(),
+ data: Data::Struct(DataStruct {
+ struct_token: Default::default(),
+ fields: Fields::Unnamed(FieldsUnnamed {
+ paren_token: Default::default(),
+ unnamed: punctuated![Field {
+ attrs: Vec::new(),
+ vis: Visibility::Inherited,
+ ident: None,
+ colon_token: None,
+ ty: Type::Path(TypePath {
+ qself: None,
+ path: Path {
+ leading_colon: None,
+ segments: punctuated![
+ ident("crate").into(),
+ ident("X").into(),
+ ],
+ },
+ }),
+ }],
+ }),
+ semi_token: Some(Default::default()),
+ }),
+ };
+
+ let actual = syn::parse_str(raw).unwrap();
+
+ assert_eq!(expected, actual);
+}