@@ -681,6 +681,13 @@ bool Converter::RecordDerivesDefault(const clang::RecordDecl *decl) {
681681 return true ;
682682}
683683
684+ bool Converter::IsPassThroughRule (clang::Expr *expr) const {
685+ const auto *rule = Mapper::GetExprRule (GetCalleeOrExpr (expr));
686+ return rule && rule->body .size () == 1 &&
687+ std::holds_alternative<TranslationRule::PlaceholderFragment>(
688+ rule->body [0 ]);
689+ }
690+
684691bool Converter::RecordDerivesCopy (const clang::RecordDecl *decl) const {
685692 auto *derives = Mapper::MappedDerives (ctx_.getCanonicalTagType (decl));
686693 return derives &&
@@ -1491,7 +1498,12 @@ bool Converter::Convert(clang::Expr *expr,
14911498 NeedsImplicitScalarCast (expr->IgnoreImplicit ()->getType (),
14921499 *implicit_convert_to);
14931500 PushParen paren (*this , needs_conversion);
1501+ computed_expr_type_ = ComputedExprType::Unknown;
14941502 bool result = TraverseStmt (expr);
1503+ if (expr && computed_expr_type_ == ComputedExprType::Unknown) {
1504+ expr->dump ();
1505+ assert (false && " computed_expr_type_ not set" );
1506+ }
14951507 if (needs_conversion) {
14961508 ConvertCast (*implicit_convert_to);
14971509 computed_expr_type_ = ComputedExprType::FreshValue;
@@ -1721,17 +1733,20 @@ void Converter::ConvertVAArgCall(clang::CallExpr *expr) {
17211733bool Converter::VisitCallExpr (clang::CallExpr *expr) {
17221734 if (IsBuiltinVaStart (expr) || IsBuiltinVaEnd (expr) || IsBuiltinVaCopy (expr)) {
17231735 ConvertVAArgCall (expr);
1736+ SetFreshType (expr->getType ());
17241737 return false ;
17251738 }
17261739
17271740 // p->~T() on a scalar is a no-op
17281741 if (clang::isa<clang::CXXPseudoDestructorExpr>(
17291742 expr->getCallee ()->IgnoreParenImpCasts ())) {
1743+ SetFreshType (expr->getType ());
17301744 return false ;
17311745 }
17321746
17331747 if (auto plugin_str = TryPluginConvert (expr)) {
17341748 StrCat (*plugin_str);
1749+ SetFreshType (expr->getType ());
17351750 return false ;
17361751 }
17371752
@@ -1750,9 +1765,10 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
17501765 str = GetMappedAsString (expr, args, num_args, &ctx);
17511766 };
17521767
1753- if ((IsReferenceType (expr) ||
1754- GetReturnTypeOfFunction (expr)->isReferenceType ()) &&
1755- !isAddrOf () && !isVoid ()) {
1768+ bool deref_ref = (IsReferenceType (expr) ||
1769+ GetReturnTypeOfFunction (expr)->isReferenceType ()) &&
1770+ !isAddrOf () && !isVoid ();
1771+ if (deref_ref) {
17561772 str = " ( * " + std::move (str) + " )" ;
17571773 }
17581774
@@ -1761,6 +1777,11 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
17611777 }
17621778
17631779 StrCat (str);
1780+ if (deref_ref) {
1781+ SetValueFreshness (expr->getType ());
1782+ } else if (!IsPassThroughRule (expr)) {
1783+ SetFreshType (expr->getType ());
1784+ }
17641785 return false ;
17651786 }
17661787
@@ -1795,6 +1816,7 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
17951816 }
17961817
17971818 StrCat (str);
1819+ SetFreshType (expr->getType ());
17981820 return false ;
17991821}
18001822
@@ -1809,6 +1831,7 @@ void Converter::EmitFnPtrCall(clang::Expr *callee) {
18091831void Converter::ConvertFunctionToFunctionPointer (
18101832 const clang::FunctionDecl *fn_decl) {
18111833 StrCat (std::format (" Some({})" , Mapper::MapFunctionName (fn_decl)));
1834+ computed_expr_type_ = ComputedExprType::FreshPointer;
18121835}
18131836
18141837Converter::CallInfo Converter::CollectCallInfo (clang::CallExpr *expr) {
@@ -2256,6 +2279,7 @@ void Converter::ConvertIntegerToEnumeralCast(clang::Expr *to,
22562279 auto dst_enum = to->getType ()->getAs <clang::EnumType>();
22572280 if (src_enum && dst_enum && dst_enum->getDecl () == src_enum) {
22582281 StrCat (EnumeratorName (ec));
2282+ computed_expr_type_ = ComputedExprType::FreshValue;
22592283 return ;
22602284 }
22612285 }
@@ -2266,6 +2290,7 @@ void Converter::ConvertIntegerToEnumeralCast(clang::Expr *to,
22662290 Convert (from);
22672291 }
22682292 StrCat (keyword::kAs , GetUnsafeTypeAsString (to->getType ()));
2293+ computed_expr_type_ = ComputedExprType::FreshValue;
22692294}
22702295
22712296void Converter::ConvertIntegralToBooleanCast (clang::ImplicitCastExpr *expr) {
@@ -2285,6 +2310,7 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) {
22852310 Convert (sub_expr);
22862311 StrCat (token::kDiff );
22872312 StrCat (token::kZero );
2313+ computed_expr_type_ = ComputedExprType::FreshValue;
22882314}
22892315
22902316bool Converter::IsCastRedundantInRust (clang::Expr *expr,
@@ -2323,6 +2349,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
23232349 } else {
23242350 StrCat (dest_pointee_const ? " .as_ptr()" : " .as_mut_ptr()" );
23252351 }
2352+ computed_expr_type_ = ComputedExprType::FreshPointer;
23262353 break ;
23272354 }
23282355 case clang::CastKind::CK_BitCast: {
@@ -2334,6 +2361,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
23342361 StrCat (ConvertPointeeType (sub_expr->getType ()));
23352362 }
23362363 ConvertCast (type);
2364+ SetFreshType (type);
23372365 break ;
23382366 }
23392367 case clang::CastKind::CK_NoOp: {
@@ -2358,13 +2386,15 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
23582386 PushParen paren (*this );
23592387 Convert (sub_expr);
23602388 ConvertCast (type);
2389+ SetFreshType (type);
23612390 } else {
23622391 {
23632392 PushParen paren (*this , suffix);
23642393 Convert (sub_expr);
23652394 }
23662395 if (suffix) {
23672396 StrCat (suffix);
2397+ SetFreshType (type);
23682398 }
23692399 }
23702400 break ;
@@ -2424,6 +2454,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
24242454 ConvertCast (type);
24252455 }
24262456 }
2457+ SetFreshType (type);
24272458 }
24282459 return false ;
24292460}
@@ -2714,6 +2745,7 @@ bool Converter::ConvertIncAndDec(clang::UnaryOperator *expr) {
27142745bool Converter::VisitUnaryOperator (clang::UnaryOperator *expr) {
27152746 if (auto str = GetMappedAsString (expr); !str.empty ()) {
27162747 StrCat (str);
2748+ SetFreshType (expr->getType ());
27172749 return false ;
27182750 }
27192751
@@ -2770,6 +2802,7 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) {
27702802 default :
27712803 StrCat (expr->getOpcodeStr (opcode));
27722804 Convert (sub_expr);
2805+ SetFreshType (expr->getType ());
27732806 }
27742807 return false ;
27752808}
@@ -2882,6 +2915,9 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
28822915 ConvertFunctionToFunctionPointer (fn_decl);
28832916 return false ;
28842917 }
2918+ StrCat (str);
2919+ SetFreshType (expr->getType ());
2920+ return false ;
28852921 }
28862922
28872923 if (auto var_decl = clang::dyn_cast<clang::VarDecl>(decl)) {
@@ -2891,6 +2927,7 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
28912927 init->IgnoreUnlessSpelledInSource ())) {
28922928 PushParen paren (*this );
28932929 VisitLambdaExpr (lambda);
2930+ computed_expr_type_ = ComputedExprType::FreshValue;
28942931 return false ;
28952932 }
28962933 }
@@ -2900,10 +2937,16 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
29002937 if (!decl->getType ()->getAs <clang::ReferenceType>() && isAddrOf ()) {
29012938 StrCat (token::kRef , decl->getType ().isConstQualified () ? " " : keyword_mut_,
29022939 str);
2940+ computed_expr_type_ = ComputedExprType::FreshPointer;
29032941 return false ;
29042942 }
29052943
29062944 StrCat (str);
2945+ if (clang::isa<clang::EnumConstantDecl>(decl)) {
2946+ computed_expr_type_ = ComputedExprType::FreshValue;
2947+ return false ;
2948+ }
2949+ SetValueFreshness (expr->getType ());
29072950 return false ;
29082951}
29092952
@@ -2996,6 +3039,7 @@ bool Converter::VisitMemberExpr(clang::MemberExpr *expr) {
29963039 SetUFCSReceiver (expr->getBase (), expr->isArrow (), method);
29973040 StrCat (GetRecordName (method->getParent ()), token::kDoubleColon ,
29983041 GetMethodName (method));
3042+ SetFreshType (expr->getType ());
29993043 return false ;
30003044 }
30013045 std::string str;
@@ -3029,10 +3073,16 @@ bool Converter::VisitMemberExpr(clang::MemberExpr *expr) {
30293073 if (!isAddrOf () && member->getType ()->isFunctionPointerType ()) {
30303074 PushParen paren (*this );
30313075 StrCat (str);
3076+ SetValueFreshness (expr->getType ());
30323077 return false ;
30333078 }
30343079
30353080 StrCat (str);
3081+ if (clang::isa<clang::CXXMethodDecl>(member)) {
3082+ SetFreshType (expr->getType ());
3083+ } else {
3084+ SetValueFreshness (expr->getType ());
3085+ }
30363086 return false ;
30373087}
30383088
@@ -3144,6 +3194,7 @@ bool Converter::VisitCXXThisExpr(clang::CXXThisExpr *expr) {
31443194 PushParen paren (*this );
31453195 StrCat (keyword::kSelfValue , keyword::kAs , ToString (expr->getType ()));
31463196 }
3197+ computed_expr_type_ = ComputedExprType::FreshPointer;
31473198 return false ;
31483199}
31493200
@@ -3169,6 +3220,7 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
31693220 } else {
31703221 StrCat (GetArrayDefaultAsString (qual_type));
31713222 }
3223+ SetFreshType (qual_type);
31723224 return false ;
31733225 }
31743226
@@ -3204,6 +3256,7 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
32043256 }
32053257 }
32063258 }
3259+ SetFreshType (qual_type);
32073260 return false ;
32083261}
32093262
@@ -3407,6 +3460,9 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
34073460 if (auto str = GetMappedAsString (expr, expr->getArgs (), expr->getNumArgs ());
34083461 !str.empty ()) {
34093462 StrCat (str);
3463+ if (!IsPassThroughRule (expr)) {
3464+ SetFreshType (expr->getType ());
3465+ }
34103466 return false ;
34113467 }
34123468
@@ -3428,13 +3484,15 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
34283484 if ((ctor->isCopyConstructor () || IsDefaultedMoveConstructor (ctor)) &&
34293485 !suppress && !TypeIsCopyable (expr->getType ())) {
34303486 StrCat (" .clone()" );
3487+ SetFreshType (expr->getType ());
34313488 }
34323489 return false ;
34333490 }
34343491
34353492 if (ctor->isDefaultConstructor () && !ctor->isUserProvided ()) {
34363493 auto ty = expr->getType ();
34373494 StrCat (GetDefaultAsString (ty));
3495+ SetFreshType (expr->getType ());
34383496 return false ;
34393497 }
34403498
@@ -3444,6 +3502,7 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
34443502 } else {
34453503 ConvertCXXConstructExprArgs (expr);
34463504 }
3505+ SetFreshType (expr->getType ());
34473506 return false ;
34483507}
34493508
@@ -3541,6 +3600,12 @@ bool Converter::VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr *expr) {
35413600 return false ;
35423601}
35433602
3603+ bool Converter::VisitConstantExpr (clang::ConstantExpr *expr) {
3604+ Convert (expr->getSubExpr ());
3605+ SetFreshType (expr->getType ());
3606+ return false ;
3607+ }
3608+
35443609bool Converter::VisitLambdaExpr (clang::LambdaExpr *expr) {
35453610 if (isAddrOf () && expr->capture_size () == 0 ) {
35463611 StrCat (" Some" );
@@ -4477,13 +4542,15 @@ void Converter::ConvertAddrOf(clang::Expr *expr, clang::QualType pointer_type) {
44774542 : keyword_mut_);
44784543 Convert (expr);
44794544 ConvertCast (pointer_type);
4545+ computed_expr_type_ = ComputedExprType::FreshPointer;
44804546 } else {
44814547 StrCat (token::kRef );
44824548 if (!pointer_type->getPointeeType ().isConstQualified ()) {
44834549 StrCat (keyword_mut_);
44844550 }
44854551 Convert (expr);
44864552 ConvertCast (pointer_type);
4553+ computed_expr_type_ = ComputedExprType::FreshPointer;
44874554 }
44884555}
44894556
@@ -4495,6 +4562,7 @@ void Converter::EmitDeref(std::string inner, clang::QualType pointee_type) {
44954562 }
44964563 PushParen paren (*this );
44974564 StrCat (GetPointerDerefPrefix (pointee_type), std::move (inner));
4565+ SetValueFreshness (pointee_type);
44984566}
44994567
45004568void Converter::ConvertDeref (clang::Expr *expr) {
@@ -4555,8 +4623,8 @@ void Converter::PlaceholderCtx::dump() const {
45554623 << " , is_cpp_ptr: " << is_cpp_ptr
45564624 << " , maps_to_rust_ptr: " << maps_to_rust_ptr
45574625 << " , declared_in_rule_as_rust_ptr: "
4558- << declared_in_rule_as_rust_ptr << " , access: "
4559- << (access == TranslationRule::Access:: kRead ? " read " : " write " )
4626+ << declared_in_rule_as_rust_ptr
4627+ << " , access: " << static_cast < int >(access )
45604628 << " , param_type: " << param_type
45614629 << " , materialize_idx: " << materialize_idx << ' \n ' ;
45624630}
@@ -4594,10 +4662,10 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg,
45944662 if (ph_ctx.needs_object_receiver ()) {
45954663 Buffer buf (*this );
45964664 PushExplicitAutoref autoref (
4597- *this ,
4598- ph_ctx.is_index_base
4599- ? std::optional (ph_ctx. access == TranslationRule::Access::kWrite )
4600- : std::nullopt );
4665+ *this , ph_ctx. is_index_base
4666+ ? std::optional ( ph_ctx.access ==
4667+ TranslationRule::Access::kBorrowMut )
4668+ : std::nullopt );
46014669 PushExprKind push (*this , ExprKind::RValue);
46024670 ConvertDeref (arg);
46034671 return std::move (buf).str ();
@@ -4611,13 +4679,17 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg,
46114679 return ConvertLValue (arg);
46124680 }
46134681
4614- if (ph_ctx.access == TranslationRule::Access::kMove ) {
4682+ if (ph_ctx.access == TranslationRule::Access::kTake ) {
46154683 if (clang::isa<clang::MaterializeTemporaryExpr>(arg)) {
46164684 return ConvertRValue (arg);
46174685 }
46184686 return std::format (" std::mem::take(&mut {})" , ConvertLValue (arg));
46194687 }
46204688
4689+ if (ph_ctx.access == TranslationRule::Access::kMove ) {
4690+ return ConvertFreshRValue (arg, ph_ctx.implicit_convert_to );
4691+ }
4692+
46214693 return ConvertRValue (arg, ph_ctx.implicit_convert_to );
46224694}
46234695
@@ -4774,6 +4846,12 @@ void Converter::SetFresh() {
47744846 case ComputedExprType::FreshValue:
47754847 case ComputedExprType::FreshPointer:
47764848 break ;
4849+ case ComputedExprType::Unknown:
4850+ assert (0 && " Unreachable ComputedExprType::Unknown" );
4851+ break ;
4852+ case ComputedExprType::Pending:
4853+ assert (0 && " Unreachable ComputedExprType::Pending" );
4854+ break ;
47774855 }
47784856}
47794857
0 commit comments