Skip to content

Commit

Permalink
Add Expr::RawAddr
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Oct 17, 2024
1 parent 38ebbec commit f5c9fd3
Show file tree
Hide file tree
Showing 16 changed files with 299 additions and 29 deletions.
4 changes: 4 additions & 0 deletions src/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub(crate) fn requires_comma_to_be_match_arm(expr: &Expr) -> bool {
| Expr::Paren(_)
| Expr::Path(_)
| Expr::Range(_)
| Expr::RawAddr(_)
| Expr::Reference(_)
| Expr::Repeat(_)
| Expr::Return(_)
Expand Down Expand Up @@ -105,6 +106,7 @@ pub(crate) fn confusable_with_adjacent_block(mut expr: &Expr) -> bool {
(None, None) => stack.pop(),
}
}
Expr::RawAddr(e) => Some(&e.expr),
Expr::Reference(e) => Some(&e.expr),
Expr::Return(e) => {
if e.expr.is_none() && stack.is_empty() {
Expand Down Expand Up @@ -246,6 +248,7 @@ pub(crate) fn expr_leading_label(mut expr: &Expr) -> bool {
| Expr::Match(_)
| Expr::Paren(_)
| Expr::Path(_)
| Expr::RawAddr(_)
| Expr::Reference(_)
| Expr::Repeat(_)
| Expr::Return(_)
Expand Down Expand Up @@ -291,6 +294,7 @@ pub(crate) fn expr_trailing_brace(mut expr: &Expr) -> bool {
Some(end) => expr = end,
None => return false,
},
Expr::RawAddr(e) => expr = &e.expr,
Expr::Reference(e) => expr = &e.expr,
Expr::Return(e) => match &e.expr {
Some(e) => expr = e,
Expand Down
84 changes: 75 additions & 9 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ ast_enum_of_structs! {
/// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
Range(ExprRange),

/// Address-of operation: `&raw const place` or `&raw mut place`.
RawAddr(ExprRawAddr),

/// A referencing operation: `&a` or `&mut a`.
Reference(ExprReference),

Expand Down Expand Up @@ -574,6 +577,18 @@ ast_struct! {
}
}

ast_struct! {
/// Address-of operation: `&raw const place` or `&raw mut place`.
#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
pub struct ExprRawAddr #full {
pub attrs: Vec<Attribute>,
pub and_token: Token![&],
pub raw: Token![raw],
pub mutability: PointerMutability,
pub expr: Box<Expr>,
}
}

ast_struct! {
/// A referencing operation: `&a` or `&mut a`.
#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
Expand Down Expand Up @@ -904,6 +919,7 @@ impl Expr {
| Expr::Paren(ExprParen { attrs, .. })
| Expr::Path(ExprPath { attrs, .. })
| Expr::Range(ExprRange { attrs, .. })
| Expr::RawAddr(ExprRawAddr { attrs, .. })
| Expr::Reference(ExprReference { attrs, .. })
| Expr::Repeat(ExprRepeat { attrs, .. })
| Expr::Return(ExprReturn { attrs, .. })
Expand Down Expand Up @@ -1122,8 +1138,8 @@ pub(crate) mod parsing {
use crate::expr::{
Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe, ExprWhile, ExprYield,
Label, PointerMutability, RangeLimits,
ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe,
ExprWhile, ExprYield, Label, PointerMutability, RangeLimits,
};
use crate::expr::{
Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
Expand Down Expand Up @@ -1486,12 +1502,23 @@ pub(crate) mod parsing {
None
};
let mutability: Option<Token![mut]> = input.parse()?;
if raw.is_some() && mutability.is_none() {
input.parse::<Token![const]>()?;
}
let const_token: Option<Token![const]> = if raw.is_some() && mutability.is_none() {
Some(input.parse()?)
} else {
None
};
let expr = Box::new(unary_expr(input, allow_struct)?);
if raw.is_some() {
Ok(Expr::Verbatim(verbatim::between(&begin, input)))
if let Some(raw) = raw {
Ok(Expr::RawAddr(ExprRawAddr {
attrs,
and_token,
raw,
mutability: match mutability {
Some(mut_token) => PointerMutability::Mut(mut_token),
None => PointerMutability::Const(const_token.unwrap()),
},
expr,
}))
} else {
Ok(Expr::Reference(ExprReference {
attrs,
Expand Down Expand Up @@ -2369,6 +2396,21 @@ pub(crate) mod parsing {
}
}

#[cfg(feature = "full")]
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
impl Parse for ExprRawAddr {
fn parse(input: ParseStream) -> Result<Self> {
let allow_struct = AllowStruct(true);
Ok(ExprRawAddr {
attrs: Vec::new(),
and_token: input.parse()?,
raw: input.parse()?,
mutability: input.parse()?,
expr: Box::new(unary_expr(input, allow_struct)?),
})
}
}

#[cfg(feature = "full")]
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
impl Parse for ExprReference {
Expand Down Expand Up @@ -3029,8 +3071,8 @@ pub(crate) mod printing {
use crate::expr::{
Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe, ExprWhile, ExprYield,
Label, PointerMutability, RangeLimits,
ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprUnsafe,
ExprWhile, ExprYield, Label, PointerMutability, RangeLimits,
};
use crate::expr::{
Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
Expand Down Expand Up @@ -3156,6 +3198,8 @@ pub(crate) mod printing {
Expr::Path(e) => e.to_tokens(tokens),
#[cfg(feature = "full")]
Expr::Range(e) => print_expr_range(e, tokens, fixup),
#[cfg(feature = "full")]
Expr::RawAddr(e) => print_expr_raw_addr(e, tokens, fixup),
Expr::Reference(e) => print_expr_reference(e, tokens, fixup),
#[cfg(feature = "full")]
Expr::Repeat(e) => e.to_tokens(tokens),
Expand Down Expand Up @@ -3714,6 +3758,28 @@ pub(crate) mod printing {
}
}

#[cfg(feature = "full")]
#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
impl ToTokens for ExprRawAddr {
fn to_tokens(&self, tokens: &mut TokenStream) {
print_expr_raw_addr(self, tokens, FixupContext::NONE);
}
}

#[cfg(feature = "full")]
fn print_expr_raw_addr(e: &ExprRawAddr, tokens: &mut TokenStream, fixup: FixupContext) {
outer_attrs_to_tokens(&e.attrs, tokens);
e.and_token.to_tokens(tokens);
e.raw.to_tokens(tokens);
e.mutability.to_tokens(tokens);
print_subexpression(
&e.expr,
fixup.trailing_precedence(&e.expr) < Precedence::Prefix,
tokens,
fixup.subsequent_subexpression(),
);
}

#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
impl ToTokens for ExprReference {
fn to_tokens(&self, tokens: &mut TokenStream) {
Expand Down
15 changes: 15 additions & 0 deletions src/gen/clone.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions src/gen/debug.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/gen/eq.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions src/gen/fold.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f5c9fd3

Please sign in to comment.