@@ -4595,59 +4595,65 @@ 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 ) ?;
4603-
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- } ;
46224598
4623- let call = val. map ( |x| mk ( ) . method_call_expr ( x, method, vec ! [ ] ) ) ;
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+ }
46244611
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- } ;
4612+ // Variable length arrays are already represented as pointers.
4613+ if let CTypeKind :: VariableArray ( ..) = source_ty_kind {
4614+ return Ok ( val) ;
4615+ }
46374616
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- }
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+ } ;
46474628
4648- Ok ( call)
4649- }
4629+ let val = val. map ( |val| {
4630+ if ctx. is_const {
4631+ // A constant cannot be raw-borrowed, but its lifetime will be
4632+ // extended to static if it's regular-borrowed first.
4633+ let method = match mutbl {
4634+ Mutability :: Mutable => "as_mut_ptr" ,
4635+ Mutability :: Immutable => "as_ptr" ,
4636+ } ;
4637+ mk ( ) . method_call_expr ( val, method, vec ! [ ] )
4638+ } else {
4639+ self . use_feature ( "raw_ref_op" ) ;
4640+ mk ( ) . set_mutbl ( mutbl) . raw_borrow_expr ( val)
4641+ // TODO: Add call to `ptr::as_[mut]_ptr` once that is available
4642+ // (`array_ptr_get` feature added to nightly in January 2024)
46504643 }
4644+ } ) ;
4645+
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 `!ctx.is_const` when `ptr::as_[mut]_ptr` is added above.
4649+ if source_ty_kind. element_ty ( ) != Some ( pointee. ctype )
4650+ || must_cast_mut
4651+ || !ctx. is_const
4652+ {
4653+ let target_element_ty = self . convert_type ( target_cty. ctype ) ?;
4654+ Ok ( val. map ( |val| mk ( ) . cast_expr ( val, target_element_ty) ) )
4655+ } else {
4656+ Ok ( val)
46514657 }
46524658 }
46534659
0 commit comments