@@ -4595,60 +4595,67 @@ impl<'c> Translation<'c> {
45954595 . is_some ( )
45964596 } )
45974597 . unwrap_or ( false ) ;
4598- match expr_kind {
4599- Some ( & CExprKind :: Literal ( _, CLiteral :: String ( ref bytes, 1 ) ) )
4600- if is_const && !translate_as_macro =>
4601- {
4602- let target_ty = self . convert_type ( target_cty. ctype ) ?;
46034598
4604- let mut bytes = bytes. to_owned ( ) ;
4605- bytes. push ( 0 ) ;
4606- let byte_literal = mk ( ) . lit_expr ( bytes) ;
4607- let val =
4608- mk ( ) . cast_expr ( byte_literal, mk ( ) . ptr_ty ( mk ( ) . path_ty ( vec ! [ "u8" ] ) ) ) ;
4609- let val = mk ( ) . cast_expr ( val, target_ty) ;
4610- Ok ( WithStmts :: new_val ( val) )
4611- }
4612- _ => {
4613- // Variable length arrays are already represented as pointers.
4614- if let CTypeKind :: VariableArray ( ..) = source_ty_kind {
4615- Ok ( val)
4616- } else {
4617- let method = if is_const || ctx. is_static {
4618- "as_ptr"
4619- } else {
4620- "as_mut_ptr"
4621- } ;
4599+ if let ( Some ( & CExprKind :: Literal ( _, CLiteral :: String ( ref bytes, 1 ) ) ) , true , false ) =
4600+ ( expr_kind, is_const, translate_as_macro)
4601+ {
4602+ let target_ty = self . convert_type ( target_cty. ctype ) ?;
4603+
4604+ let mut bytes = bytes. to_owned ( ) ;
4605+ bytes. push ( 0 ) ;
4606+ let byte_literal = mk ( ) . lit_expr ( bytes) ;
4607+ let val = mk ( ) . cast_expr ( byte_literal, mk ( ) . ptr_ty ( mk ( ) . path_ty ( vec ! [ "u8" ] ) ) ) ;
4608+ let val = mk ( ) . cast_expr ( val, target_ty) ;
4609+ return Ok ( WithStmts :: new_val ( val) ) ;
4610+ }
46224611
4623- let call = val. map ( |x| mk ( ) . method_call_expr ( x, method, vec ! [ ] ) ) ;
4612+ // Variable length arrays are already represented as pointers.
4613+ if let CTypeKind :: VariableArray ( ..) = source_ty_kind {
4614+ return Ok ( val) ;
4615+ }
46244616
4625- // If the target pointee type is different from the source element type,
4626- // then we need to cast the ptr type as well.
4627- let call = match source_ty_kind. element_ty ( ) {
4628- None => call,
4629- Some ( source_element_ty) if source_element_ty == pointee. ctype => {
4630- call
4631- }
4632- Some ( _) => {
4633- let target_ty = self . convert_type ( target_cty. ctype ) ?;
4634- call. map ( |ptr| mk ( ) . cast_expr ( ptr, target_ty) )
4635- }
4636- } ;
4617+ let ( mutbl, must_cast_mut) = if is_const {
4618+ ( Mutability :: Immutable , false )
4619+ } else if ctx. is_static {
4620+ // TODO: The currently used nightly doesn't allow `&raw mut` in
4621+ // static initialisers, but it's allowed since version 1.83.
4622+ // So we take a `&raw const` and then cast.
4623+ // Remove `must_cast_mut` variable when the version is updated.
4624+ ( Mutability :: Immutable , true )
4625+ } else {
4626+ ( Mutability :: Mutable , false )
4627+ } ;
46374628
4638- // Static arrays can now use as_ptr. Can also cast that const ptr to a
4639- // mutable pointer as we do here:
4640- if ctx. is_static && !is_const {
4641- return Ok ( call. map ( |val| {
4642- let inferred_type = mk ( ) . infer_ty ( ) ;
4643- let ptr_type = mk ( ) . mutbl ( ) . ptr_ty ( inferred_type) ;
4644- mk ( ) . cast_expr ( val, ptr_type)
4645- } ) ) ;
4646- }
4629+ val. result_map ( |mut val| {
4630+ if translate_as_macro {
4631+ // Values that translate into temporaries can't be raw-borrowed in Rust,
4632+ // and must be regular-borrowed first.
4633+ // By borrowing, the lifetime will be extended to static.
4634+ let method = match mutbl {
4635+ Mutability :: Mutable => "as_mut_ptr" ,
4636+ Mutability :: Immutable => "as_ptr" ,
4637+ } ;
4638+ val = mk ( ) . method_call_expr ( val, method, vec ! [ ] ) ;
4639+ } else {
4640+ self . use_feature ( "raw_ref_op" ) ;
4641+ val = mk ( ) . set_mutbl ( mutbl) . raw_borrow_expr ( val) ;
4642+ // TODO: Add call to `ptr::as_[mut]_ptr` once that is available
4643+ // (`array_ptr_get` feature added to nightly in January 2024)
4644+ }
46474645
4648- Ok ( call)
4649- }
4646+ // If the target pointee type is different from the source element type,
4647+ // then we need to cast the ptr type as well.
4648+ // TODO: Remove `!translate_as_macro` when `ptr::as_[mut]_ptr` is added above.
4649+ if source_ty_kind. element_ty ( ) != Some ( pointee. ctype )
4650+ || must_cast_mut
4651+ || !translate_as_macro
4652+ {
4653+ let target_element_ty = self . convert_type ( target_cty. ctype ) ?;
4654+ val = mk ( ) . cast_expr ( val, target_element_ty) ;
46504655 }
4651- }
4656+
4657+ Ok ( val)
4658+ } )
46524659 }
46534660
46544661 CastKind :: NullToPointer => {
0 commit comments