diff --git a/src/analysis/function_parameters.rs b/src/analysis/function_parameters.rs index 88fcc1397..d1d2e8f49 100644 --- a/src/analysis/function_parameters.rs +++ b/src/analysis/function_parameters.rs @@ -107,6 +107,7 @@ pub enum TransformationType { array_name: String, array_length_name: String, array_length_type: String, + nullable: bool, }, IntoRaw(String), ToSome(String), @@ -176,7 +177,7 @@ impl Parameters { let transformation = Transformation { ind_c, ind_rust: None, - transformation_type: get_length_type(env, "", &c_par.name, c_par.typ), + transformation_type: get_length_type(env, "", &c_par.name, c_par.typ, c_par.nullable), }; self.transformations.push(transformation); } @@ -301,7 +302,13 @@ pub fn analyze( let transformation = Transformation { ind_c, ind_rust: None, - transformation_type: get_length_type(env, &array_name, &par.name, typ), + transformation_type: get_length_type( + env, + &array_name, + &par.name, + typ, + par.nullable, + ), }; parameters.transformations.push(transformation); } @@ -448,12 +455,14 @@ fn get_length_type( array_name: &str, length_name: &str, length_typ: TypeId, + nullable_array: Nullable, ) -> TransformationType { let array_length_type = RustType::try_new(env, length_typ).into_string(); TransformationType::Length { array_name: array_name.to_string(), array_length_name: length_name.to_string(), array_length_type, + nullable: *nullable_array, } } diff --git a/src/analysis/rust_type.rs b/src/analysis/rust_type.rs index 400f9d9ef..b42f60ecf 100644 --- a/src/analysis/rust_type.rs +++ b/src/analysis/rust_type.rs @@ -251,7 +251,6 @@ impl<'env> RustTypeBuilder<'env> { let ok = |s: &str| Ok(RustType::from(s)); let ok_and_use = |s: &str| Ok(RustType::new_and_use(&s)); let err = |s: &str| Err(TypeError::Unimplemented(s.into())); - let mut skip_option = false; let type_ = self.env.library.type_(self.type_id); let mut rust_type = match *type_ { Basic(fund) => { @@ -355,7 +354,6 @@ impl<'env> RustTypeBuilder<'env> { List(inner_tid) | SList(inner_tid) | CArray(inner_tid) | PtrArray(inner_tid) if ConversionType::of(self.env, inner_tid) == ConversionType::Pointer => { - skip_option = true; let inner_ref_mode = match self.env.type_(inner_tid) { Class(..) | Interface(..) => RefMode::None, Record(record) => match RecordType::of(record) { @@ -409,7 +407,6 @@ impl<'env> RustTypeBuilder<'env> { }; if let Some(s) = array_type { - skip_option = true; if self.ref_mode.is_ref() { Ok(format!("[{s}]").into()) } else { @@ -604,7 +601,7 @@ impl<'env> RustTypeBuilder<'env> { } } - if *self.nullable && !skip_option { + if *self.nullable { match ConversionType::of(self.env, self.type_id) { ConversionType::Pointer | ConversionType::Scalar => { rust_type = rust_type.map_any(|rust_type| { diff --git a/src/codegen/function_body_chunk.rs b/src/codegen/function_body_chunk.rs index 6bee059c9..75a0a1de3 100644 --- a/src/codegen/function_body_chunk.rs +++ b/src/codegen/function_body_chunk.rs @@ -956,11 +956,16 @@ impl Builder { if let TransformationType::Length { ref array_name, ref array_length_name, + nullable, .. } = trans.transformation_type { if let In = self.parameters[trans.ind_c] { - let value = Chunk::Custom(format!("{array_name}.len() as _")); + let value = Chunk::Custom(if nullable { + format!("{array_name}.as_ref().map(|a| a.len()).unwrap_or(0)") + } else { + format!("{array_name}.len() as _") + }); chunks.push(Chunk::Let { name: array_length_name.clone(), is_mut: false,