Preserve visibility token's span on struct field
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index c063cf3..1944642 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -157,7 +157,7 @@
let fields = strct.fields.iter().map(|field| {
// This span on the pub makes "private type in public interface" errors
// appear in the right place.
- let vis = Token);
+ let vis = field.visibility;
quote!(#vis #field)
});
let mut derives = None;
diff --git a/syntax/impls.rs b/syntax/impls.rs
index d70e7cc..c7e1a2c 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -1,5 +1,5 @@
use crate::syntax::{
- Array, ExternFn, Impl, Include, Receiver, Ref, Signature, SliceRef, Ty1, Type,
+ Array, ExternFn, Impl, Include, Receiver, Ref, Signature, SliceRef, Ty1, Type, Var,
};
use std::borrow::Borrow;
use std::hash::{Hash, Hasher};
@@ -292,6 +292,36 @@
}
}
+impl Eq for Var {}
+
+impl PartialEq for Var {
+ fn eq(&self, other: &Var) -> bool {
+ let Var {
+ visibility: _,
+ ident,
+ ty,
+ } = self;
+ let Var {
+ visibility: _,
+ ident: ident2,
+ ty: ty2,
+ } = other;
+ ident == ident2 && ty == ty2
+ }
+}
+
+impl Hash for Var {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ let Var {
+ visibility: _,
+ ident,
+ ty,
+ } = self;
+ ident.hash(state);
+ ty.hash(state);
+ }
+}
+
impl Eq for Receiver {}
impl PartialEq for Receiver {
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 0fc7a9d..8247d19 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -148,8 +148,8 @@
pub throws_tokens: Option<(kw::Result, Token![<], Token![>])>,
}
-#[derive(Eq, PartialEq, Hash)]
pub struct Var {
+ pub visibility: Token![pub],
pub ident: Ident,
pub ty: Type,
}
diff --git a/syntax/parse.rs b/syntax/parse.rs
index ab17be4..a178421 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -104,7 +104,17 @@
continue;
}
};
- fields.push(Var { ident, ty });
+ let visibility = Token => vis.pub_token.span,
+ Visibility::Crate(vis) => vis.crate_token.span,
+ Visibility::Restricted(vis) => vis.pub_token.span,
+ Visibility::Inherited => ident.span(),
+ });
+ fields.push(Var {
+ visibility,
+ ident,
+ ty,
+ });
}
let struct_token = item.struct_token;
@@ -510,7 +520,12 @@
};
let ty = parse_type(&arg.ty)?;
if ident != "self" {
- args.push_value(Var { ident, ty });
+ let visibility = Token);
+ args.push_value(Var {
+ visibility,
+ ident,
+ ty,
+ });
if let Some(comma) = comma {
args.push_punct(*comma);
}
@@ -1076,7 +1091,12 @@
Some(ident) => ident.0.clone(),
None => format_ident!("arg{}", i),
};
- Ok(Var { ident, ty })
+ let visibility = Token);
+ Ok(Var {
+ visibility,
+ ident,
+ ty,
+ })
})
.collect::<Result<_>>()?;
diff --git a/tests/ui/deny_missing_docs.stderr b/tests/ui/deny_missing_docs.stderr
index c9cb8c9..d0da255 100644
--- a/tests/ui/deny_missing_docs.stderr
+++ b/tests/ui/deny_missing_docs.stderr
@@ -12,16 +12,16 @@
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: missing documentation for a struct field
- --> $DIR/deny_missing_docs.rs:12:13
+ --> $DIR/deny_missing_docs.rs:12:9
|
12 | pub undocumented_field: u8,
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a struct field
- --> $DIR/deny_missing_docs.rs:18:13
+ --> $DIR/deny_missing_docs.rs:18:9
|
18 | pub documented_field: u8,
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a struct
--> $DIR/deny_missing_docs.rs:9:1