@@ -2715,62 +2715,39 @@ impl<'c> Translation<'c> {
27152715 . ok_or_else ( || format_err ! ( "bad condition type" ) ) ?;
27162716
27172717 let null_pointer_case =
2718- |negated : bool , ptr : CExprId | -> TranslationResult < WithStmts < Box < Expr > > > {
2718+ |ptr : CExprId , is_null : bool | -> TranslationResult < WithStmts < Box < Expr > > > {
27192719 let val = self . convert_expr ( ctx. used ( ) . decay_ref ( ) , ptr, None ) ?;
27202720 let ptr_type = self . ast_context [ ptr]
27212721 . kind
27222722 . get_type ( )
27232723 . ok_or_else ( || format_err ! ( "bad pointer type for condition" ) ) ?;
2724- val. and_then ( |e| {
2725- Ok ( WithStmts :: new_val (
2726- if self . ast_context . is_function_pointer ( ptr_type) {
2727- if negated {
2728- mk ( ) . method_call_expr ( e, "is_some" , vec ! [ ] )
2729- } else {
2730- mk ( ) . method_call_expr ( e, "is_none" , vec ! [ ] )
2731- }
2732- } else {
2733- // TODO: `pointer::is_null` becomes stably const in Rust 1.84.
2734- if ctx. is_const {
2735- return Err ( format_translation_err ! (
2736- None ,
2737- "cannot check nullity of pointer in `const` context" ,
2738- ) ) ;
2739- }
2740- let is_null = mk ( ) . method_call_expr ( e, "is_null" , vec ! [ ] ) ;
2741- if negated {
2742- mk ( ) . unary_expr ( UnOp :: Not ( Default :: default ( ) ) , is_null)
2743- } else {
2744- is_null
2745- }
2746- } ,
2747- ) )
2748- } )
2724+
2725+ val. result_map ( |val| self . convert_pointer_is_null ( ctx, ptr_type, val, is_null) )
27492726 } ;
27502727
27512728 match self . ast_context [ cond_id] . kind {
27522729 CExprKind :: Binary ( _, c_ast:: BinOp :: EqualEqual , null_expr, ptr, _, _)
27532730 if self . ast_context . is_null_expr ( null_expr) =>
27542731 {
2755- null_pointer_case ( !target , ptr )
2732+ null_pointer_case ( ptr , target )
27562733 }
27572734
27582735 CExprKind :: Binary ( _, c_ast:: BinOp :: EqualEqual , ptr, null_expr, _, _)
27592736 if self . ast_context . is_null_expr ( null_expr) =>
27602737 {
2761- null_pointer_case ( !target , ptr )
2738+ null_pointer_case ( ptr , target )
27622739 }
27632740
27642741 CExprKind :: Binary ( _, c_ast:: BinOp :: NotEqual , null_expr, ptr, _, _)
27652742 if self . ast_context . is_null_expr ( null_expr) =>
27662743 {
2767- null_pointer_case ( target , ptr )
2744+ null_pointer_case ( ptr , !target )
27682745 }
27692746
27702747 CExprKind :: Binary ( _, c_ast:: BinOp :: NotEqual , ptr, null_expr, _, _)
27712748 if self . ast_context . is_null_expr ( null_expr) =>
27722749 {
2773- null_pointer_case ( target , ptr )
2750+ null_pointer_case ( ptr , !target )
27742751 }
27752752
27762753 CExprKind :: Unary ( _, c_ast:: UnOp :: Not , subexpr_id, _) => {
@@ -4480,79 +4457,35 @@ impl<'c> Translation<'c> {
44804457
44814458 match kind {
44824459 CastKind :: BitCast | CastKind :: NoOp => {
4483- if self . ast_context . is_function_pointer ( target_cty. ctype )
4484- || self . ast_context . is_function_pointer ( source_cty. ctype )
4485- {
4486- let source_ty = self
4487- . type_converter
4488- . borrow_mut ( )
4489- . convert ( & self . ast_context , source_cty. ctype ) ?;
4490- let target_ty = self
4491- . type_converter
4492- . borrow_mut ( )
4493- . convert ( & self . ast_context , target_cty. ctype ) ?;
4494-
4495- if source_ty == target_ty {
4496- return Ok ( val) ;
4497- }
4498-
4499- self . import_type ( source_cty. ctype ) ;
4500- self . import_type ( target_cty. ctype ) ;
4501-
4502- val. and_then ( |val| {
4503- Ok ( WithStmts :: new_unsafe_val ( transmute_expr (
4504- source_ty, target_ty, val,
4505- ) ) )
4506- } )
4507- } else {
4508- // Normal case
4509- let target_ty = self . convert_type ( target_cty. ctype ) ?;
4510- Ok ( val. map ( |val| mk ( ) . cast_expr ( val, target_ty) ) )
4511- }
4460+ self . convert_pointer_to_pointer_cast ( source_cty. ctype , target_cty. ctype , val)
45124461 }
45134462
4514- CastKind :: IntegralToPointer
4515- if self . ast_context . is_function_pointer ( target_cty. ctype ) =>
4516- {
4517- let target_ty = self . convert_type ( target_cty. ctype ) ?;
4518- val. and_then ( |x| {
4519- self . use_crate ( ExternCrate :: Libc ) ;
4520- let intptr_t = mk ( ) . abs_path_ty ( vec ! [ "libc" , "intptr_t" ] ) ;
4521- let intptr = mk ( ) . cast_expr ( x, intptr_t. clone ( ) ) ;
4522- if ctx. is_const {
4523- return Err ( format_translation_err ! (
4524- None ,
4525- "cannot transmute integers to Option<fn ...> in `const` context" ,
4526- ) ) ;
4527- }
4528- Ok ( WithStmts :: new_unsafe_val ( transmute_expr (
4529- intptr_t, target_ty, intptr,
4530- ) ) )
4531- } )
4463+ CastKind :: IntegralToPointer => {
4464+ self . convert_integral_to_pointer_cast ( ctx, source_cty. ctype , target_cty. ctype , val)
45324465 }
45334466
4534- CastKind :: IntegralToPointer
4535- | CastKind :: PointerToIntegral
4536- | CastKind :: IntegralCast
4467+ CastKind :: PointerToIntegral => self . convert_pointer_to_integral_cast (
4468+ ctx,
4469+ source_cty. ctype ,
4470+ target_cty. ctype ,
4471+ val,
4472+ expr,
4473+ ) ,
4474+
4475+ CastKind :: IntegralCast
45374476 | CastKind :: FloatingCast
45384477 | CastKind :: FloatingToIntegral
45394478 | CastKind :: IntegralToFloating
45404479 | CastKind :: BooleanToSignedIntegral => {
4541- if kind == CastKind :: PointerToIntegral && ctx. is_const {
4542- return Err ( format_translation_err ! (
4543- None ,
4544- "cannot observe pointer values in `const` context" ,
4545- ) ) ;
4546- }
45474480 let target_ty = self . convert_type ( target_cty. ctype ) ?;
4548- let source_ty = self . convert_type ( source_cty. ctype ) ?;
45494481
45504482 if let CTypeKind :: LongDouble = target_ty_kind {
45514483 if ctx. is_const {
45524484 return Err ( format_translation_err ! (
4553- None ,
4554- "f128 cannot be used in constants because `f128::f128::new` is not `const`" ,
4555- ) ) ;
4485+ None ,
4486+ "f128 cannot be used in constants because \
4487+ `f128::f128::new` is not `const`",
4488+ ) ) ;
45564489 }
45574490
45584491 self . use_crate ( ExternCrate :: F128 ) ;
@@ -4575,35 +4508,13 @@ impl<'c> Translation<'c> {
45754508 )
45764509 } )
45774510 } else if target_ty_kind. is_floating_type ( ) && source_ty_kind. is_bool ( ) {
4578- val. and_then ( |x| {
4579- Ok ( WithStmts :: new_val ( mk ( ) . cast_expr (
4580- mk ( ) . cast_expr ( x, mk ( ) . path_ty ( vec ! [ "u8" ] ) ) ,
4581- target_ty,
4582- ) ) )
4583- } )
4584- } else if target_ty_kind. is_pointer ( ) && source_ty_kind. is_bool ( ) {
4585- val. and_then ( |x| {
4586- self . use_crate ( ExternCrate :: Libc ) ;
4587- Ok ( WithStmts :: new_val ( mk ( ) . cast_expr (
4588- mk ( ) . cast_expr ( x, mk ( ) . abs_path_ty ( vec ! [ "libc" , "size_t" ] ) ) ,
4589- target_ty,
4590- ) ) )
4591- } )
4511+ Ok ( val. map ( |val| {
4512+ mk ( ) . cast_expr ( mk ( ) . cast_expr ( val, mk ( ) . path_ty ( vec ! [ "u8" ] ) ) , target_ty)
4513+ } ) )
4514+ } else if let & CTypeKind :: Enum ( ..) = source_ty_kind {
4515+ val. result_map ( |val| self . convert_cast_from_enum ( target_cty. ctype , val) )
45924516 } else {
4593- // Other numeric casts translate to Rust `as` casts,
4594- // unless the cast is to a function pointer then use `transmute`.
4595- val. and_then ( |x| {
4596- if self . ast_context . is_function_pointer ( source_cty. ctype ) {
4597- Ok ( WithStmts :: new_unsafe_val ( transmute_expr (
4598- source_ty, target_ty, x,
4599- ) ) )
4600- } else if let & CTypeKind :: Enum ( ..) = source_ty_kind {
4601- self . convert_cast_from_enum ( target_cty. ctype , x)
4602- . map ( WithStmts :: new_val)
4603- } else {
4604- Ok ( WithStmts :: new_val ( mk ( ) . cast_expr ( x, target_ty) ) )
4605- }
4606- } )
4517+ Ok ( val. map ( |val| mk ( ) . cast_expr ( val, target_ty) ) )
46074518 }
46084519 }
46094520
@@ -4917,25 +4828,8 @@ impl<'c> Translation<'c> {
49174828 ) -> TranslationResult < Box < Expr > > {
49184829 let ty = & self . ast_context . resolve_type ( ty_id) . kind ;
49194830
4920- Ok ( if self . ast_context . is_function_pointer ( ty_id) {
4921- if target {
4922- mk ( ) . method_call_expr ( val, "is_some" , vec ! [ ] )
4923- } else {
4924- mk ( ) . method_call_expr ( val, "is_none" , vec ! [ ] )
4925- }
4926- } else if ty. is_pointer ( ) {
4927- // TODO: `pointer::is_null` becomes stably const in Rust 1.84.
4928- if ctx. is_const {
4929- return Err ( format_translation_err ! (
4930- None ,
4931- "cannot check nullity of pointer in `const` context" ,
4932- ) ) ;
4933- }
4934- let mut res = mk ( ) . method_call_expr ( val, "is_null" , vec ! [ ] ) ;
4935- if target {
4936- res = mk ( ) . unary_expr ( UnOp :: Not ( Default :: default ( ) ) , res)
4937- }
4938- res
4831+ Ok ( if ty. is_pointer ( ) {
4832+ self . convert_pointer_is_null ( ctx, ty_id, val, !target) ?
49394833 } else if ty. is_bool ( ) {
49404834 if target {
49414835 val
0 commit comments