From 66ba9a0a666bb9cc3181c1bcf08a52729d7a0084 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 4 Jul 2022 09:20:52 -0700 Subject: [PATCH 1/2] Preserve clippy attrs on extern "Rust" fn #[cxx::bridge] mod ffi { extern "Rust" { #[allow(clippy::too_many_arguments)] fn repro(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) -> bool; } } Before: warning: this function has too many arguments (8/7) --> src/main.rs:5:12 | 5 | fn repro(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) -> bool; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(clippy::too_many_arguments)]` on by default = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments After: no lint. --- macro/src/expand.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/macro/src/expand.rs b/macro/src/expand.rs index 8ca2c4af2..7e93368b6 100644 --- a/macro/src/expand.rs +++ b/macro/src/expand.rs @@ -787,6 +787,7 @@ fn expand_function_pointer_trampoline( prevent_unwind_label, None, Some(&efn.generics), + &efn.attrs, body_span, ); let var = &var.rust; @@ -937,6 +938,7 @@ fn expand_rust_function_shim(efn: &ExternFn, types: &Types) -> TokenStream { prevent_unwind_label, invoke, None, + &efn.attrs, body_span, ) } @@ -949,6 +951,7 @@ fn expand_rust_function_shim_impl( prevent_unwind_label: String, invoke: Option<&Ident>, outer_generics: Option<&Generics>, + attrs: &OtherAttrs, body_span: Span, ) -> TokenStream { let generics = outer_generics.unwrap_or(&sig.generics); @@ -1123,6 +1126,7 @@ fn expand_rust_function_shim_impl( }; quote_spanned! {span=> + #attrs #[doc(hidden)] #[export_name = #link_name] unsafe extern "C" fn #local_name #generics(#(#all_args,)* #outparam #pointer) #ret { From 30427e0205ef459c26b1418fc2850f034b635608 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 4 Jul 2022 09:25:21 -0700 Subject: [PATCH 2/2] Propagate attrs from extern mod onto all contents #[cxx::bridge] mod ffi { #[allow(clippy::too_many_arguments)] extern "Rust" { fn repro(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) -> bool; } } Before: warning: this function has too many arguments (8/7) --> src/main.rs:5:12 | 5 | fn repro(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) -> bool; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(clippy::too_many_arguments)]` on by default = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments After: no lint. --- syntax/attrs.rs | 5 +++++ syntax/parse.rs | 55 ++++++++++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/syntax/attrs.rs b/syntax/attrs.rs index cb40295b9..46d010e0a 100644 --- a/syntax/attrs.rs +++ b/syntax/attrs.rs @@ -268,12 +268,17 @@ fn parse_rust_name_attribute(input: ParseStream) -> Result { } } +#[derive(Clone)] pub struct OtherAttrs(Vec); impl OtherAttrs { pub fn none() -> Self { OtherAttrs(Vec::new()) } + + pub fn extend(&mut self, other: Self) { + self.0.extend(other.0); + } } impl ToTokens for OtherAttrs { diff --git a/syntax/parse.rs b/syntax/parse.rs index dee24c2fa..1754c6006 100644 --- a/syntax/parse.rs +++ b/syntax/parse.rs @@ -360,7 +360,7 @@ fn parse_foreign_mod( let mut cfg = CfgExpr::Unconditional; let mut namespace = namespace.clone(); - attrs::parse( + let attrs = attrs::parse( cx, foreign_mod.attrs, attrs::Parser { @@ -374,11 +374,11 @@ fn parse_foreign_mod( for foreign in foreign_mod.items { match foreign { ForeignItem::Type(foreign) => { - let ety = parse_extern_type(cx, foreign, lang, trusted, &cfg, &namespace); + let ety = parse_extern_type(cx, foreign, lang, trusted, &cfg, &namespace, &attrs); items.push(ety); } ForeignItem::Fn(foreign) => { - match parse_extern_fn(cx, foreign, lang, trusted, &cfg, &namespace) { + match parse_extern_fn(cx, foreign, lang, trusted, &cfg, &namespace, &attrs) { Ok(efn) => items.push(efn), Err(err) => cx.push(err), } @@ -393,7 +393,7 @@ fn parse_foreign_mod( } } ForeignItem::Verbatim(tokens) => { - match parse_extern_verbatim(cx, tokens, lang, trusted, &cfg, &namespace) { + match parse_extern_verbatim(cx, tokens, lang, trusted, &cfg, &namespace, &attrs) { Ok(api) => items.push(api), Err(err) => cx.push(err), } @@ -463,6 +463,7 @@ fn parse_extern_type( trusted: bool, extern_block_cfg: &CfgExpr, namespace: &Namespace, + attrs: &OtherAttrs, ) -> Api { let mut cfg = extern_block_cfg.clone(); let mut doc = Doc::new(); @@ -470,7 +471,8 @@ fn parse_extern_type( let mut namespace = namespace.clone(); let mut cxx_name = None; let mut rust_name = None; - let attrs = attrs::parse( + let mut attrs = attrs.clone(); + attrs.extend(attrs::parse( cx, foreign_type.attrs, attrs::Parser { @@ -482,7 +484,7 @@ fn parse_extern_type( rust_name: Some(&mut rust_name), ..Default::default() }, - ); + )); let type_token = foreign_type.type_token; let visibility = visibility_pub(&foreign_type.vis, type_token.span); @@ -523,13 +525,15 @@ fn parse_extern_fn( trusted: bool, extern_block_cfg: &CfgExpr, namespace: &Namespace, + attrs: &OtherAttrs, ) -> Result { let mut cfg = extern_block_cfg.clone(); let mut doc = Doc::new(); let mut namespace = namespace.clone(); let mut cxx_name = None; let mut rust_name = None; - let attrs = attrs::parse( + let mut attrs = attrs.clone(); + attrs.extend(attrs::parse( cx, mem::take(&mut foreign_fn.attrs), attrs::Parser { @@ -540,7 +544,7 @@ fn parse_extern_fn( rust_name: Some(&mut rust_name), ..Default::default() }, - ); + )); let generics = &foreign_fn.sig.generics; if generics.where_clause.is_some() @@ -708,20 +712,22 @@ fn parse_extern_verbatim( trusted: bool, extern_block_cfg: &CfgExpr, namespace: &Namespace, + attrs: &OtherAttrs, ) -> Result { |input: ParseStream| -> Result { - let attrs = input.call(Attribute::parse_outer)?; + let unparsed_attrs = input.call(Attribute::parse_outer)?; let visibility: Visibility = input.parse()?; if input.peek(Token![type]) { parse_extern_verbatim_type( cx, - attrs, + unparsed_attrs, visibility, input, lang, trusted, extern_block_cfg, namespace, + attrs, ) } else if input.peek(Token![fn]) { parse_extern_verbatim_fn(input) @@ -738,13 +744,14 @@ fn parse_extern_verbatim( fn parse_extern_verbatim_type( cx: &mut Errors, - attrs: Vec, + unparsed_attrs: Vec, visibility: Visibility, input: ParseStream, lang: Lang, trusted: bool, extern_block_cfg: &CfgExpr, namespace: &Namespace, + attrs: &OtherAttrs, ) -> Result { let type_token: Token![type] = input.parse()?; let ident: Ident = input.parse()?; @@ -791,7 +798,7 @@ fn parse_extern_verbatim_type( // type Alias = crate::path::to::Type; parse_type_alias( cx, - attrs, + unparsed_attrs, visibility, type_token, ident, @@ -800,12 +807,13 @@ fn parse_extern_verbatim_type( lang, extern_block_cfg, namespace, + attrs, ) } else if lookahead.peek(Token![:]) || lookahead.peek(Token![;]) { // type Opaque: Bound2 + Bound2; parse_extern_type_bounded( cx, - attrs, + unparsed_attrs, visibility, type_token, ident, @@ -815,6 +823,7 @@ fn parse_extern_verbatim_type( trusted, extern_block_cfg, namespace, + attrs, ) } else { Err(lookahead.error()) @@ -829,7 +838,7 @@ fn parse_extern_verbatim_fn(input: ParseStream) -> Result { fn parse_type_alias( cx: &mut Errors, - attrs: Vec, + unparsed_attrs: Vec, visibility: Visibility, type_token: Token![type], ident: Ident, @@ -838,6 +847,7 @@ fn parse_type_alias( lang: Lang, extern_block_cfg: &CfgExpr, namespace: &Namespace, + attrs: &OtherAttrs, ) -> Result { let eq_token: Token![=] = input.parse()?; let ty: RustType = input.parse()?; @@ -849,9 +859,10 @@ fn parse_type_alias( let mut namespace = namespace.clone(); let mut cxx_name = None; let mut rust_name = None; - let attrs = attrs::parse( + let mut attrs = attrs.clone(); + attrs.extend(attrs::parse( cx, - attrs, + unparsed_attrs, attrs::Parser { cfg: Some(&mut cfg), doc: Some(&mut doc), @@ -861,7 +872,7 @@ fn parse_type_alias( rust_name: Some(&mut rust_name), ..Default::default() }, - ); + )); if lang == Lang::Rust { let span = quote!(#type_token #semi_token); @@ -889,7 +900,7 @@ fn parse_type_alias( fn parse_extern_type_bounded( cx: &mut Errors, - attrs: Vec, + unparsed_attrs: Vec, visibility: Visibility, type_token: Token![type], ident: Ident, @@ -899,6 +910,7 @@ fn parse_extern_type_bounded( trusted: bool, extern_block_cfg: &CfgExpr, namespace: &Namespace, + attrs: &OtherAttrs, ) -> Result { let mut bounds = Vec::new(); let colon_token: Option = input.parse()?; @@ -939,9 +951,10 @@ fn parse_extern_type_bounded( let mut namespace = namespace.clone(); let mut cxx_name = None; let mut rust_name = None; - let attrs = attrs::parse( + let mut attrs = attrs.clone(); + attrs.extend(attrs::parse( cx, - attrs, + unparsed_attrs, attrs::Parser { cfg: Some(&mut cfg), doc: Some(&mut doc), @@ -951,7 +964,7 @@ fn parse_extern_type_bounded( rust_name: Some(&mut rust_name), ..Default::default() }, - ); + )); let visibility = visibility_pub(&visibility, type_token.span); let name = pair(namespace, &ident, cxx_name, rust_name);