@@ -496,12 +496,19 @@ ConverterRefCount::MaterializeTemp(const std::string &binding_name,
496496 clang::QualType param_type,
497497 clang::Expr *expr) {
498498 auto pointee = param_type.getNonReferenceType ();
499- auto value = ConvertFreshRValue (expr, pointee);
500- auto type_str = ToStringBase (pointee);
501499 const auto *decl = in_const_initializer_ ? keyword::kStatic : keyword::kLet ;
502-
503- auto binding = std::format (" {} {} : Value<{}> = Rc::new(RefCell::new({}));" ,
504- decl, binding_name, type_str, value);
500+ std::string binding;
501+ if (pointee->isConstantArrayType ()) {
502+ PushConversionKind push (*this , ConversionKind::FullRefCount);
503+ binding = std::format (" {} {} : {} = {};" , decl, binding_name,
504+ ToString (pointee),
505+ BoxValue (ConvertVarInitValue (pointee, expr)));
506+ } else {
507+ auto value = ConvertFreshRValue (expr, pointee);
508+ auto type_str = ToStringBase (pointee);
509+ binding = std::format (" {} {} : Value<{}> = Rc::new(RefCell::new({}));" ,
510+ decl, binding_name, type_str, value);
511+ }
505512 auto ref =
506513 in_const_initializer_ ? " .with(Value::as_pointer)" : " .as_pointer()" ;
507514 return {binding, binding_name + ref};
@@ -1499,6 +1506,10 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
14991506 ToString (sub_expr->IgnoreParens ())));
15001507 computed_expr_type_ = ComputedExprType::FreshPointer;
15011508 return false ;
1509+ } else if (auto ptr = ConvertArrayPointerDeref (sub_expr); !ptr.empty ()) {
1510+ StrCat (ptr);
1511+ computed_expr_type_ = ComputedExprType::FreshPointer;
1512+ return false ;
15021513 } else {
15031514 // we need to write (var.as_pointer as Ptr<T>) because Rust isn't
15041515 // smart enough to pick the right specialization
@@ -2569,6 +2580,9 @@ std::string ConverterRefCount::ConvertVarInitValue(clang::QualType qual_type,
25692580 return std::format (" Ptr::<{}>::from_string_literal({})" , code_unit,
25702581 ToString (expr->IgnoreParens ()->IgnoreImplicit ()));
25712582 }
2583+ if (auto ptr = ConvertArrayPointerDeref (expr); !ptr.empty ()) {
2584+ return ptr;
2585+ }
25722586 }
25732587 return ConvertFreshPointer (expr, qual_type);
25742588 }
@@ -3185,6 +3199,18 @@ bool ConverterRefCount::DerefReadsValue(clang::QualType pointee_type) {
31853199 return pointee_type.isPODType (ctx_) && !pointee_type->isRecordType ();
31863200}
31873201
3202+ std::string ConverterRefCount::ConvertArrayPointerDeref (clang::Expr *expr) {
3203+ auto *op =
3204+ clang::dyn_cast<clang::UnaryOperator>(expr->IgnoreParenNoopCasts (ctx_));
3205+ if (!op || op->getOpcode () != clang::UO_Deref ||
3206+ !op->getType ()->isArrayType ()) {
3207+ return {};
3208+ }
3209+ PushConversionKind push (*this , ConversionKind::Unboxed);
3210+ return std::format (" ({}{}.as_pointer())" , ConvertRValue (op->getSubExpr ()),
3211+ GetPointerDerefSuffix (op->getType ()));
3212+ }
3213+
31883214const char *
31893215ConverterRefCount::GetPointerDerefSuffix (clang::QualType pointee_type) {
31903216 return DerefReadsValue (pointee_type) ? " .read()" : " .upgrade().deref()" ;
0 commit comments