cxx/syntax/cfg.rs
David Tolnay 92f405d4c8
Work around new dead_code warnings
warning: field `0` is never read
      --> macro/src/syntax/mod.rs:52:13
       |
    52 |     Include(Include),
       |     ------- ^^^^^^^
       |     |
       |     field in this variant
       |
       = note: `#[warn(dead_code)]` on by default
    help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
       |
    52 |     Include(()),
       |             ~~

    warning: fields `0` and `1` are never read
     --> macro/src/syntax/cfg.rs:9:8
      |
    9 |     Eq(Ident, Option<LitStr>),
      |     -- ^^^^^  ^^^^^^^^^^^^^^
      |     |
      |     fields in this variant
      |
    help: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields
      |
    9 |     Eq((), ()),
      |        ~~  ~~

    warning: field `0` is never read
      --> macro/src/syntax/cfg.rs:11:9
       |
    11 |     Any(Vec<CfgExpr>),
       |     --- ^^^^^^^^^^^^
       |     |
       |     field in this variant
       |
    help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
       |
    11 |     Any(()),
       |         ~~

    warning: field `0` is never read
      --> macro/src/syntax/cfg.rs:12:9
       |
    12 |     Not(Box<CfgExpr>),
       |     --- ^^^^^^^^^^^^
       |     |
       |     field in this variant
       |
    help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
       |
    12 |     Not(()),
       |         ~~

    warning: field `0` is never read
       --> src/lib.rs:551:13
        |
    551 | struct void(core::ffi::c_void);
        |        ---- ^^^^^^^^^^^^^^^^^
        |        |
        |        field in this struct
        |
        = note: `#[warn(dead_code)]` on by default
    help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
        |
    551 | struct void(());
        |             ~~

    warning: field `0` is never read
       --> tests/ffi/lib.rs:411:26
        |
    411 | pub struct Reference<'a>(&'a String);
        |            ---------     ^^^^^^^^^^
        |            |
        |            field in this struct
        |
        = note: `#[warn(dead_code)]` on by default
    help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
        |
    411 | pub struct Reference<'a>(());
        |                          ~~
2024-01-05 18:58:33 -08:00

81 lines
2.5 KiB
Rust

use proc_macro2::Ident;
use std::mem;
use syn::parse::{Error, ParseStream, Result};
use syn::{parenthesized, token, Attribute, LitStr, Token};
#[derive(Clone)]
pub(crate) enum CfgExpr {
Unconditional,
#[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
Eq(Ident, Option<LitStr>),
All(Vec<CfgExpr>),
#[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
Any(Vec<CfgExpr>),
#[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
Not(Box<CfgExpr>),
}
impl CfgExpr {
pub(crate) fn merge(&mut self, expr: CfgExpr) {
if let CfgExpr::Unconditional = self {
*self = expr;
} else if let CfgExpr::All(list) = self {
list.push(expr);
} else {
let prev = mem::replace(self, CfgExpr::Unconditional);
*self = CfgExpr::All(vec![prev, expr]);
}
}
}
pub(crate) fn parse_attribute(attr: &Attribute) -> Result<CfgExpr> {
attr.parse_args_with(|input: ParseStream| {
let cfg_expr = input.call(parse_single)?;
input.parse::<Option<Token![,]>>()?;
Ok(cfg_expr)
})
}
fn parse_single(input: ParseStream) -> Result<CfgExpr> {
let ident: Ident = input.parse()?;
let lookahead = input.lookahead1();
if input.peek(token::Paren) {
let content;
parenthesized!(content in input);
if ident == "all" {
let list = content.call(parse_multiple)?;
Ok(CfgExpr::All(list))
} else if ident == "any" {
let list = content.call(parse_multiple)?;
Ok(CfgExpr::Any(list))
} else if ident == "not" {
let expr = content.call(parse_single)?;
content.parse::<Option<Token![,]>>()?;
Ok(CfgExpr::Not(Box::new(expr)))
} else {
Err(Error::new(ident.span(), "unrecognized cfg expression"))
}
} else if lookahead.peek(Token![=]) {
input.parse::<Token![=]>()?;
let string: LitStr = input.parse()?;
Ok(CfgExpr::Eq(ident, Some(string)))
} else if lookahead.peek(Token![,]) || input.is_empty() {
Ok(CfgExpr::Eq(ident, None))
} else {
Err(lookahead.error())
}
}
fn parse_multiple(input: ParseStream) -> Result<Vec<CfgExpr>> {
let mut vec = Vec::new();
while !input.is_empty() {
let expr = input.call(parse_single)?;
vec.push(expr);
if input.is_empty() {
break;
}
input.parse::<Token![,]>()?;
}
Ok(vec)
}