@@ -202,6 +202,9 @@ ast_enum_of_structs! {
202202 /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
203203 Range ( ExprRange ) ,
204204
205+ /// Address-of operation: `&raw const place` or `&raw mut place`.
206+ RawAddr ( ExprRawAddr ) ,
207+
205208 /// A referencing operation: `&a` or `&mut a`.
206209 Reference ( ExprReference ) ,
207210
@@ -574,6 +577,18 @@ ast_struct! {
574577 }
575578}
576579
580+ ast_struct ! {
581+ /// Address-of operation: `&raw const place` or `&raw mut place`.
582+ #[ cfg_attr( docsrs, doc( cfg( feature = "full" ) ) ) ]
583+ pub struct ExprRawAddr #full {
584+ pub attrs: Vec <Attribute >,
585+ pub and_token: Token ![ & ] ,
586+ pub raw: Token ![ raw] ,
587+ pub mutability: PointerMutability ,
588+ pub expr: Box <Expr >,
589+ }
590+ }
591+
577592ast_struct ! {
578593 /// A referencing operation: `&a` or `&mut a`.
579594 #[ cfg_attr( docsrs, doc( cfg( any( feature = "full" , feature = "derive" ) ) ) ) ]
@@ -904,6 +919,7 @@ impl Expr {
904919 | Expr :: Paren ( ExprParen { attrs, .. } )
905920 | Expr :: Path ( ExprPath { attrs, .. } )
906921 | Expr :: Range ( ExprRange { attrs, .. } )
922+ | Expr :: RawAddr ( ExprRawAddr { attrs, .. } )
907923 | Expr :: Reference ( ExprReference { attrs, .. } )
908924 | Expr :: Repeat ( ExprRepeat { attrs, .. } )
909925 | Expr :: Return ( ExprReturn { attrs, .. } )
@@ -1122,8 +1138,8 @@ pub(crate) mod parsing {
11221138 use crate :: expr:: {
11231139 Arm , ExprArray , ExprAssign , ExprAsync , ExprAwait , ExprBlock , ExprBreak , ExprClosure ,
11241140 ExprConst , ExprContinue , ExprForLoop , ExprIf , ExprInfer , ExprLet , ExprLoop , ExprMatch ,
1125- ExprRange , ExprRepeat , ExprReturn , ExprTry , ExprTryBlock , ExprUnsafe , ExprWhile , ExprYield ,
1126- Label , PointerMutability , RangeLimits ,
1141+ ExprRange , ExprRawAddr , ExprRepeat , ExprReturn , ExprTry , ExprTryBlock , ExprUnsafe ,
1142+ ExprWhile , ExprYield , Label , PointerMutability , RangeLimits ,
11271143 } ;
11281144 use crate :: expr:: {
11291145 Expr , ExprBinary , ExprCall , ExprCast , ExprField , ExprGroup , ExprIndex , ExprLit , ExprMacro ,
@@ -1486,12 +1502,23 @@ pub(crate) mod parsing {
14861502 None
14871503 } ;
14881504 let mutability: Option < Token ! [ mut ] > = input. parse ( ) ?;
1489- if raw. is_some ( ) && mutability. is_none ( ) {
1490- input. parse :: < Token ! [ const ] > ( ) ?;
1491- }
1505+ let const_token: Option < Token ! [ const ] > = if raw. is_some ( ) && mutability. is_none ( ) {
1506+ Some ( input. parse ( ) ?)
1507+ } else {
1508+ None
1509+ } ;
14921510 let expr = Box :: new ( unary_expr ( input, allow_struct) ?) ;
1493- if raw. is_some ( ) {
1494- Ok ( Expr :: Verbatim ( verbatim:: between ( & begin, input) ) )
1511+ if let Some ( raw) = raw {
1512+ Ok ( Expr :: RawAddr ( ExprRawAddr {
1513+ attrs,
1514+ and_token,
1515+ raw,
1516+ mutability : match mutability {
1517+ Some ( mut_token) => PointerMutability :: Mut ( mut_token) ,
1518+ None => PointerMutability :: Const ( const_token. unwrap ( ) ) ,
1519+ } ,
1520+ expr,
1521+ } ) )
14951522 } else {
14961523 Ok ( Expr :: Reference ( ExprReference {
14971524 attrs,
@@ -2369,6 +2396,21 @@ pub(crate) mod parsing {
23692396 }
23702397 }
23712398
2399+ #[ cfg( feature = "full" ) ]
2400+ #[ cfg_attr( docsrs, doc( cfg( feature = "parsing" ) ) ) ]
2401+ impl Parse for ExprRawAddr {
2402+ fn parse ( input : ParseStream ) -> Result < Self > {
2403+ let allow_struct = AllowStruct ( true ) ;
2404+ Ok ( ExprRawAddr {
2405+ attrs : Vec :: new ( ) ,
2406+ and_token : input. parse ( ) ?,
2407+ raw : input. parse ( ) ?,
2408+ mutability : input. parse ( ) ?,
2409+ expr : Box :: new ( unary_expr ( input, allow_struct) ?) ,
2410+ } )
2411+ }
2412+ }
2413+
23722414 #[ cfg( feature = "full" ) ]
23732415 #[ cfg_attr( docsrs, doc( cfg( feature = "parsing" ) ) ) ]
23742416 impl Parse for ExprReference {
@@ -3029,8 +3071,8 @@ pub(crate) mod printing {
30293071 use crate :: expr:: {
30303072 Arm , ExprArray , ExprAssign , ExprAsync , ExprAwait , ExprBlock , ExprBreak , ExprClosure ,
30313073 ExprConst , ExprContinue , ExprForLoop , ExprIf , ExprInfer , ExprLet , ExprLoop , ExprMatch ,
3032- ExprRange , ExprRepeat , ExprReturn , ExprTry , ExprTryBlock , ExprUnsafe , ExprWhile , ExprYield ,
3033- Label , PointerMutability , RangeLimits ,
3074+ ExprRange , ExprRawAddr , ExprRepeat , ExprReturn , ExprTry , ExprTryBlock , ExprUnsafe ,
3075+ ExprWhile , ExprYield , Label , PointerMutability , RangeLimits ,
30343076 } ;
30353077 use crate :: expr:: {
30363078 Expr , ExprBinary , ExprCall , ExprCast , ExprField , ExprGroup , ExprIndex , ExprLit , ExprMacro ,
@@ -3156,6 +3198,8 @@ pub(crate) mod printing {
31563198 Expr :: Path ( e) => e. to_tokens ( tokens) ,
31573199 #[ cfg( feature = "full" ) ]
31583200 Expr :: Range ( e) => print_expr_range ( e, tokens, fixup) ,
3201+ #[ cfg( feature = "full" ) ]
3202+ Expr :: RawAddr ( e) => print_expr_raw_addr ( e, tokens, fixup) ,
31593203 Expr :: Reference ( e) => print_expr_reference ( e, tokens, fixup) ,
31603204 #[ cfg( feature = "full" ) ]
31613205 Expr :: Repeat ( e) => e. to_tokens ( tokens) ,
@@ -3714,6 +3758,28 @@ pub(crate) mod printing {
37143758 }
37153759 }
37163760
3761+ #[ cfg( feature = "full" ) ]
3762+ #[ cfg_attr( docsrs, doc( cfg( feature = "printing" ) ) ) ]
3763+ impl ToTokens for ExprRawAddr {
3764+ fn to_tokens ( & self , tokens : & mut TokenStream ) {
3765+ print_expr_raw_addr ( self , tokens, FixupContext :: NONE ) ;
3766+ }
3767+ }
3768+
3769+ #[ cfg( feature = "full" ) ]
3770+ fn print_expr_raw_addr ( e : & ExprRawAddr , tokens : & mut TokenStream , fixup : FixupContext ) {
3771+ outer_attrs_to_tokens ( & e. attrs , tokens) ;
3772+ e. and_token . to_tokens ( tokens) ;
3773+ e. raw . to_tokens ( tokens) ;
3774+ e. mutability . to_tokens ( tokens) ;
3775+ print_subexpression (
3776+ & e. expr ,
3777+ fixup. trailing_precedence ( & e. expr ) < Precedence :: Prefix ,
3778+ tokens,
3779+ fixup. subsequent_subexpression ( ) ,
3780+ ) ;
3781+ }
3782+
37173783 #[ cfg_attr( docsrs, doc( cfg( feature = "printing" ) ) ) ]
37183784 impl ToTokens for ExprReference {
37193785 fn to_tokens ( & self , tokens : & mut TokenStream ) {
0 commit comments