Skip to content

Commit

Permalink
Suppress spurious unneeded parenthesis warnings from the generated co…
Browse files Browse the repository at this point in the history
…de when a parenthesis-delimited expression is interpolated as the only argument of a function call.
  • Loading branch information
CensoredUsername committed Sep 26, 2024
1 parent ff5517d commit 899cda3
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 13 deletions.
49 changes: 40 additions & 9 deletions plugin/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! This module contains various infrastructure that is common across all assembler backends
use proc_macro2::{Span, TokenTree, TokenStream, Literal, Group};
use proc_macro2::{Span, TokenTree, TokenStream, Literal, Group, Delimiter};
use quote::ToTokens;
use syn::spanned::Spanned;
use syn::parse;
Expand Down Expand Up @@ -246,13 +246,13 @@ impl Stmt {
}


// Takes an arbitrary tokenstream as input, and ensures it can be interpolated safely.
// returns a tokentree representing either a single token, or a delimited group.
//
// If the given tokenstream contains multiple tokens, it will be parenthesized.
//
// this will panic if given an empty tokenstream.
// this would use delimiter::None if not for https://github.com/rust-lang/rust/issues/67062
/// Takes an arbitrary tokenstream as input, and ensures it can be interpolated safely.
/// returns a tokentree representing either a single token, or a delimited group.
///
/// If the given tokenstream contains multiple tokens, it will be parenthesized.
///
/// this will panic if given an empty tokenstream.
/// this would use delimiter::None if not for https://github.com/rust-lang/rust/issues/67062
pub fn delimited<T: ToTokens>(expr: T) -> TokenTree {
let stream = expr.into_token_stream();

Expand All @@ -269,7 +269,38 @@ pub fn delimited<T: ToTokens>(expr: T) -> TokenTree {
proc_macro2::Delimiter::Parenthesis, stream
);
group.set_span(span);
proc_macro2::TokenTree::Group(group)
TokenTree::Group(group)
}

/// Checks if the given tokenstream is a parenthesized expression to work around rustc giving
/// Unnecessary parenthesis warnings in macro-generated code, if this tokentree were to be used
/// as the argument to a single argument function
///
/// i.e. `function(#arg)` expanding to `function((expr))`, which should instead be expanded to
/// `function(expr)`
///
/// To check if this is valid, we should a: test that this tokentree node is a parenthesis delimited
/// node and b: there are no commas in its internal tokentree, because then it'd be a tuple, and
/// this transform would be invalid
pub fn is_parenthesized(expr: &TokenTree) -> bool {
match expr {
TokenTree::Group(group) => {
if group.delimiter() != Delimiter::Parenthesis {
return false
}

for item in group.stream() {
if let TokenTree::Punct(punct) = item {
if punct.as_char() == ',' {
return false
}
}
}

true
},
_ => false
}
}

/// Create a bitmask with `scale` bits set
Expand Down
19 changes: 15 additions & 4 deletions plugin/src/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use quote::{quote, quote_spanned, ToTokens};

use byteorder::{ByteOrder, LittleEndian};

use crate::common::{Size, Stmt, delimited, Relocation};
use crate::common::{Size, Stmt, delimited, is_parenthesized, Relocation};

use std::convert::TryInto;

Expand Down Expand Up @@ -103,9 +103,20 @@ pub fn serialize(name: &TokenTree, stmts: Vec<Stmt>) -> TokenStream {

// and construct the appropriate method call
let method = syn::Ident::new(method, Span::mixed_site());
output.extend(quote! {
#name . #method ( #( #args ),* ) ;
})

if args.len() == 1 && is_parenthesized(&args[0]) {
// special case for not emitting redundant parenthesis to work around an annoying error
let mut args = args;
let arg = args.pop().unwrap();
output.extend(quote! {
#name . #method #arg ;
})

} else {
output.extend(quote! {
#name . #method ( #( #args ),* ) ;
})
}
}

// if we have nothing to emit, expand to nothing. Else, wrap it into a block.
Expand Down

0 comments on commit 899cda3

Please sign in to comment.