@@ -937,54 +937,54 @@ impl<'c> Translation<'c> {
937937 // In this translation, there are only pointers to functions and
938938 // & becomes a no-op when applied to a function.
939939
940- let arg = self . convert_expr ( ctx. used ( ) . set_needs_address ( true ) , arg, None ) ?;
940+ let val = self . convert_expr ( ctx. used ( ) . set_needs_address ( true ) , arg, None ) ?;
941941
942942 if self . ast_context . is_function_pointer ( ctype) {
943- Ok ( arg. map ( |x| mk ( ) . call_expr ( mk ( ) . ident_expr ( "Some" ) , vec ! [ x] ) ) )
943+ return Ok ( val. map ( |x| mk ( ) . call_expr ( mk ( ) . ident_expr ( "Some" ) , vec ! [ x] ) ) ) ;
944+ }
945+
946+ let pointee_ty =
947+ self . ast_context
948+ . get_pointee_qual_type ( ctype)
949+ . ok_or_else ( || {
950+ TranslationError :: generic ( "Address-of should return a pointer" )
951+ } ) ?;
952+
953+ let mutbl = if pointee_ty. qualifiers . is_const {
954+ Mutability :: Immutable
944955 } else {
945- let pointee_ty =
946- self . ast_context
947- . get_pointee_qual_type ( ctype)
948- . ok_or_else ( || {
949- TranslationError :: generic ( "Address-of should return a pointer" )
950- } ) ?;
951-
952- let mutbl = if pointee_ty. qualifiers . is_const {
953- Mutability :: Immutable
954- } else {
955- Mutability :: Mutable
956- } ;
956+ Mutability :: Mutable
957+ } ;
957958
958- arg. result_map ( |a| {
959- let mut addr_of_arg: Box < Expr > ;
960-
961- if ctx. is_static {
962- // static variable initializers aren't able to use &mut,
963- // so we work around that by using & and an extra cast
964- // through & to *const to *mut
965- addr_of_arg = mk ( ) . addr_of_expr ( a) ;
966- if let Mutability :: Mutable = mutbl {
967- let mut qtype = pointee_ty;
968- qtype. qualifiers . is_const = true ;
969- let ty_ = self
970- . type_converter
971- . borrow_mut ( )
972- . convert_pointer ( & self . ast_context , qtype) ?;
973- addr_of_arg = mk ( ) . cast_expr ( addr_of_arg, ty_) ;
974- }
959+ Ok ( val. map ( |mut val| {
960+ if matches ! (
961+ arg_kind,
962+ CExprKind :: Literal ( ..) | CExprKind :: CompoundLiteral ( ..)
963+ ) {
964+ // Rust does not extend the lifetime of temporaries with a raw borrow,
965+ // but will do so with a regular borrow.
966+ val = mk ( ) . set_mutbl ( mutbl) . borrow_expr ( val) ;
967+
968+ if ctx. decay_ref . is_yes ( ) {
969+ val = mk ( ) . cast_expr ( val, ty)
970+ }
971+ } else {
972+ self . use_feature ( "raw_ref_op" ) ;
973+
974+ // TODO: The currently used nightly doesn't allow `&raw mut` in
975+ // static initialisers, but it's allowed since version 1.83.
976+ // So we take a `&raw const` and then cast.
977+ // Remove this exemption when the version is updated.
978+ if ctx. is_static && matches ! ( mutbl, Mutability :: Mutable ) {
979+ val = mk ( ) . raw_borrow_expr ( val) ;
980+ val = mk ( ) . cast_expr ( val, ty) ;
975981 } else {
976- // Normal case is allowed to use &mut if needed
977- addr_of_arg = mk ( ) . set_mutbl ( mutbl) . addr_of_expr ( a) ;
978-
979- // Avoid unnecessary reference to pointer decay in fn call args:
980- if ctx. decay_ref . is_no ( ) {
981- return Ok ( addr_of_arg) ;
982- }
982+ val = mk ( ) . set_mutbl ( mutbl) . raw_borrow_expr ( val) ;
983983 }
984+ }
984985
985- Ok ( mk ( ) . cast_expr ( addr_of_arg, ty) )
986- } )
987- }
986+ val
987+ } ) )
988988 }
989989 c_ast:: UnOp :: PreIncrement => self . convert_pre_increment ( ctx, cqual_type, true , arg) ,
990990 c_ast:: UnOp :: PreDecrement => self . convert_pre_increment ( ctx, cqual_type, false , arg) ,
0 commit comments