Store passthrough attributes for diagnostic lint levels
diff --git a/syntax/attrs.rs b/syntax/attrs.rs
index 9ad3d51..7f50dcb 100644
--- a/syntax/attrs.rs
+++ b/syntax/attrs.rs
@@ -39,7 +39,8 @@
pub(crate) _more: (),
}
-pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) {
+pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Vec<Attribute> {
+ let mut passthrough_attrs = Vec::new();
for attr in attrs {
if attr.path.is_ident("doc") {
match parse_doc_attribute.parse2(attr.tokens.clone()) {
@@ -49,7 +50,10 @@
continue;
}
}
- Err(err) => return cx.push(err),
+ Err(err) => {
+ cx.push(err);
+ break;
+ }
}
} else if attr.path.is_ident("derive") {
match attr.parse_args_with(|attr: ParseStream| parse_derive_attribute(cx, attr)) {
@@ -59,7 +63,10 @@
continue;
}
}
- Err(err) => return cx.push(err),
+ Err(err) => {
+ cx.push(err);
+ break;
+ }
}
} else if attr.path.is_ident("repr") {
match attr.parse_args_with(parse_repr_attribute) {
@@ -69,7 +76,10 @@
continue;
}
}
- Err(err) => return cx.push(err),
+ Err(err) => {
+ cx.push(err);
+ break;
+ }
}
} else if attr.path.is_ident("namespace") {
match parse_namespace_attribute.parse2(attr.tokens.clone()) {
@@ -79,7 +89,10 @@
continue;
}
}
- Err(err) => return cx.push(err),
+ Err(err) => {
+ cx.push(err);
+ break;
+ }
}
} else if attr.path.is_ident("cxx_name") {
match parse_function_alias_attribute.parse2(attr.tokens.clone()) {
@@ -89,7 +102,10 @@
continue;
}
}
- Err(err) => return cx.push(err),
+ Err(err) => {
+ cx.push(err);
+ break;
+ }
}
} else if attr.path.is_ident("rust_name") {
match parse_function_alias_attribute.parse2(attr.tokens.clone()) {
@@ -99,7 +115,10 @@
continue;
}
}
- Err(err) => return cx.push(err),
+ Err(err) => {
+ cx.push(err);
+ break;
+ }
}
} else if attr.path.is_ident("allow")
|| attr.path.is_ident("warn")
@@ -107,10 +126,13 @@
|| attr.path.is_ident("forbid")
{
// https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes
+ passthrough_attrs.push(attr);
continue;
}
- return cx.error(attr, "unsupported attribute");
+ cx.error(attr, "unsupported attribute");
+ break;
}
+ passthrough_attrs
}
fn parse_doc_attribute(input: ParseStream) -> Result<LitStr> {
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 624a64d..4504fe6 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -298,12 +298,14 @@
fn eq(&self, other: &Var) -> bool {
let Var {
doc: _,
+ attrs: _,
visibility: _,
ident,
ty,
} = self;
let Var {
doc: _,
+ attrs: _,
visibility: _,
ident: ident2,
ty: ty2,
@@ -316,6 +318,7 @@
fn hash<H: Hasher>(&self, state: &mut H) {
let Var {
doc: _,
+ attrs: _,
visibility: _,
ident,
ty,
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 092f403..c478d3c 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -1,7 +1,7 @@
// Functionality that is shared between the cxxbridge macro and the cmd.
pub mod atom;
-mod attrs;
+pub mod attrs;
pub mod check;
pub mod derive;
mod discriminant;
@@ -32,7 +32,7 @@
use proc_macro2::{Ident, Span};
use syn::punctuated::Punctuated;
use syn::token::{Brace, Bracket, Paren};
-use syn::{Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
+use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
pub use self::atom::Atom;
pub use self::derive::{Derive, Trait};
@@ -72,6 +72,7 @@
pub lang: Lang,
pub doc: Doc,
pub derives: Vec<Derive>,
+ pub attrs: Vec<Attribute>,
pub type_token: Token![type],
pub name: Pair,
pub generics: Lifetimes,
@@ -84,6 +85,7 @@
pub struct Struct {
pub doc: Doc,
pub derives: Vec<Derive>,
+ pub attrs: Vec<Attribute>,
pub visibility: Token![pub],
pub struct_token: Token![struct],
pub name: Pair,
@@ -94,6 +96,7 @@
pub struct Enum {
pub doc: Doc,
pub derives: Vec<Derive>,
+ pub attrs: Vec<Attribute>,
pub enum_token: Token![enum],
pub name: Pair,
pub brace_token: Brace,
@@ -106,6 +109,7 @@
pub struct ExternFn {
pub lang: Lang,
pub doc: Doc,
+ pub attrs: Vec<Attribute>,
pub name: Pair,
pub sig: Signature,
pub semi_token: Token![;],
@@ -115,6 +119,7 @@
pub struct TypeAlias {
pub doc: Doc,
pub derives: Vec<Derive>,
+ pub attrs: Vec<Attribute>,
pub type_token: Token![type],
pub name: Pair,
pub generics: Lifetimes,
@@ -151,6 +156,7 @@
pub struct Var {
pub doc: Doc,
+ pub attrs: Vec<Attribute>,
pub visibility: Token![pub],
pub ident: Ident,
pub ty: Type,
@@ -170,6 +176,7 @@
pub struct Variant {
pub doc: Doc,
+ pub attrs: Vec<Attribute>,
pub name: Pair,
pub discriminant: Discriminant,
pub expr: Option<Expr>,
diff --git a/syntax/parse.rs b/syntax/parse.rs
index 1ea4db4..87f43b2 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -57,15 +57,14 @@
}
fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) -> Result<Api> {
- let attrs = mem::take(&mut item.attrs);
let mut doc = Doc::new();
let mut derives = Vec::new();
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- attrs::parse(
+ let attrs = attrs::parse(
cx,
- attrs,
+ mem::take(&mut item.attrs),
attrs::Parser {
doc: Some(&mut doc),
derives: Some(&mut derives),
@@ -100,7 +99,7 @@
for field in named_fields.named {
let ident = field.ident.unwrap();
let mut doc = Doc::new();
- attrs::parse(
+ let attrs = attrs::parse(
cx,
field.attrs,
attrs::Parser {
@@ -123,6 +122,7 @@
});
fields.push(Var {
doc,
+ attrs,
visibility,
ident,
ty,
@@ -142,6 +142,7 @@
Ok(Api::Struct(Struct {
doc,
derives,
+ attrs,
visibility,
struct_token,
name,
@@ -157,7 +158,7 @@
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- attrs::parse(
+ let attrs = attrs::parse(
cx,
item.attrs,
attrs::Parser {
@@ -213,6 +214,7 @@
Ok(Api::Enum(Enum {
doc,
derives,
+ attrs,
enum_token,
name,
brace_token,
@@ -228,13 +230,12 @@
mut variant: RustVariant,
discriminants: &mut DiscriminantSet,
) -> Result<Variant> {
- let attrs = mem::take(&mut variant.attrs);
let mut doc = Doc::new();
let mut cxx_name = None;
let mut rust_name = None;
- attrs::parse(
+ let attrs = attrs::parse(
cx,
- attrs,
+ mem::take(&mut variant.attrs),
attrs::Parser {
doc: Some(&mut doc),
cxx_name: Some(&mut cxx_name),
@@ -266,6 +267,7 @@
Ok(Variant {
doc,
+ attrs,
name,
discriminant,
expr,
@@ -403,7 +405,7 @@
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- attrs::parse(
+ let attrs = attrs::parse(
cx,
foreign_type.attrs,
attrs::Parser {
@@ -434,6 +436,7 @@
lang,
doc,
derives,
+ attrs,
type_token,
name,
generics,
@@ -451,14 +454,13 @@
trusted: bool,
namespace: &Namespace,
) -> Result<Api> {
- let attrs = mem::take(&mut foreign_fn.attrs);
let mut doc = Doc::new();
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- attrs::parse(
+ let attrs = attrs::parse(
cx,
- attrs,
+ mem::take(&mut foreign_fn.attrs),
attrs::Parser {
doc: Some(&mut doc),
namespace: Some(&mut namespace),
@@ -542,9 +544,11 @@
let ty = parse_type(&arg.ty)?;
if ident != "self" {
let doc = Doc::new();
+ let attrs = Vec::new();
let visibility = Token);
args.push_value(Var {
doc,
+ attrs,
visibility,
ident,
ty,
@@ -591,6 +595,7 @@
}(ExternFn {
lang,
doc,
+ attrs,
name,
sig: Signature {
unsafety,
@@ -701,7 +706,7 @@
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- attrs::parse(
+ let attrs = attrs::parse(
cx,
attrs,
attrs::Parser {
@@ -725,6 +730,7 @@
Ok(Api::TypeAlias(TypeAlias {
doc,
derives,
+ attrs,
type_token,
name,
generics,
@@ -783,7 +789,7 @@
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- attrs::parse(
+ let attrs = attrs::parse(
cx,
attrs,
attrs::Parser {
@@ -805,6 +811,7 @@
lang,
doc,
derives,
+ attrs,
type_token,
name,
generics,
@@ -1115,9 +1122,11 @@
None => format_ident!("arg{}", i),
};
let doc = Doc::new();
+ let attrs = Vec::new();
let visibility = Token);
Ok(Var {
doc,
+ attrs,
visibility,
ident,
ty,