@@ -704,6 +704,13 @@ bool Converter::RecordDerivesDefault(const clang::RecordDecl *decl) {
704704 return true ;
705705}
706706
707+ bool Converter::IsPassThroughRule (clang::Expr *expr) const {
708+ const auto *rule = Mapper::GetExprRule (GetCalleeOrExpr (expr));
709+ return rule && rule->body .size () == 1 &&
710+ std::holds_alternative<TranslationRule::PlaceholderFragment>(
711+ rule->body [0 ]);
712+ }
713+
707714bool Converter::RecordDerivesCopy (const clang::RecordDecl *decl) const {
708715 auto *derives = Mapper::MappedDerives (ctx_.getCanonicalTagType (decl));
709716 return derives &&
@@ -1514,7 +1521,12 @@ bool Converter::Convert(clang::Expr *expr,
15141521 NeedsImplicitScalarCast (expr->IgnoreImplicit ()->getType (),
15151522 *implicit_convert_to);
15161523 PushParen paren (*this , needs_conversion);
1524+ computed_expr_type_ = ComputedExprType::Unknown;
15171525 bool result = TraverseStmt (expr);
1526+ if (expr && computed_expr_type_ == ComputedExprType::Unknown) {
1527+ expr->dump ();
1528+ assert (false && " computed_expr_type_ not set" );
1529+ }
15181530 if (needs_conversion) {
15191531 ConvertCast (*implicit_convert_to);
15201532 computed_expr_type_ = ComputedExprType::FreshValue;
@@ -1744,17 +1756,20 @@ void Converter::ConvertVAArgCall(clang::CallExpr *expr) {
17441756bool Converter::VisitCallExpr (clang::CallExpr *expr) {
17451757 if (IsBuiltinVaStart (expr) || IsBuiltinVaEnd (expr) || IsBuiltinVaCopy (expr)) {
17461758 ConvertVAArgCall (expr);
1759+ SetFreshType (expr->getType ());
17471760 return false ;
17481761 }
17491762
17501763 // p->~T() on a scalar is a no-op
17511764 if (clang::isa<clang::CXXPseudoDestructorExpr>(
17521765 expr->getCallee ()->IgnoreParenImpCasts ())) {
1766+ SetFreshType (expr->getType ());
17531767 return false ;
17541768 }
17551769
17561770 if (auto plugin_str = TryPluginConvert (expr)) {
17571771 StrCat (*plugin_str);
1772+ SetFreshType (expr->getType ());
17581773 return false ;
17591774 }
17601775
@@ -1773,9 +1788,10 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
17731788 str = GetMappedAsString (expr, args, num_args, &ctx);
17741789 };
17751790
1776- if ((IsReferenceType (expr) ||
1777- GetReturnTypeOfFunction (expr)->isReferenceType ()) &&
1778- !isAddrOf () && !isVoid ()) {
1791+ bool deref_ref = (IsReferenceType (expr) ||
1792+ GetReturnTypeOfFunction (expr)->isReferenceType ()) &&
1793+ !isAddrOf () && !isVoid ();
1794+ if (deref_ref) {
17791795 str = " ( * " + std::move (str) + " )" ;
17801796 }
17811797
@@ -1784,6 +1800,11 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
17841800 }
17851801
17861802 StrCat (str);
1803+ if (deref_ref) {
1804+ SetValueFreshness (expr->getType ());
1805+ } else if (!IsPassThroughRule (expr)) {
1806+ SetFreshType (expr->getType ());
1807+ }
17871808 return false ;
17881809 }
17891810
@@ -1818,6 +1839,7 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
18181839 }
18191840
18201841 StrCat (str);
1842+ SetFreshType (expr->getType ());
18211843 return false ;
18221844}
18231845
@@ -1832,6 +1854,7 @@ void Converter::EmitFnPtrCall(clang::Expr *callee) {
18321854void Converter::ConvertFunctionToFunctionPointer (
18331855 const clang::FunctionDecl *fn_decl) {
18341856 StrCat (std::format (" Some({})" , Mapper::MapFunctionName (fn_decl)));
1857+ computed_expr_type_ = ComputedExprType::FreshPointer;
18351858}
18361859
18371860Converter::CallInfo Converter::CollectCallInfo (clang::CallExpr *expr) {
@@ -2279,6 +2302,7 @@ void Converter::ConvertIntegerToEnumeralCast(clang::Expr *to,
22792302 auto dst_enum = to->getType ()->getAs <clang::EnumType>();
22802303 if (src_enum && dst_enum && dst_enum->getDecl () == src_enum) {
22812304 StrCat (EnumeratorName (ec));
2305+ computed_expr_type_ = ComputedExprType::FreshValue;
22822306 return ;
22832307 }
22842308 }
@@ -2289,6 +2313,7 @@ void Converter::ConvertIntegerToEnumeralCast(clang::Expr *to,
22892313 Convert (from);
22902314 }
22912315 StrCat (keyword::kAs , GetUnsafeTypeAsString (to->getType ()));
2316+ computed_expr_type_ = ComputedExprType::FreshValue;
22922317}
22932318
22942319void Converter::ConvertIntegralToBooleanCast (clang::ImplicitCastExpr *expr) {
@@ -2308,6 +2333,7 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) {
23082333 Convert (sub_expr);
23092334 StrCat (token::kDiff );
23102335 StrCat (token::kZero );
2336+ computed_expr_type_ = ComputedExprType::FreshValue;
23112337}
23122338
23132339bool Converter::IsCastRedundantInRust (clang::Expr *expr,
@@ -2346,6 +2372,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
23462372 } else {
23472373 StrCat (dest_pointee_const ? " .as_ptr()" : " .as_mut_ptr()" );
23482374 }
2375+ computed_expr_type_ = ComputedExprType::FreshPointer;
23492376 break ;
23502377 }
23512378 case clang::CastKind::CK_BitCast: {
@@ -2357,6 +2384,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
23572384 StrCat (ConvertPointeeType (sub_expr->getType ()));
23582385 }
23592386 ConvertCast (type);
2387+ SetFreshType (type);
23602388 break ;
23612389 }
23622390 case clang::CastKind::CK_NoOp: {
@@ -2381,13 +2409,15 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
23812409 PushParen paren (*this );
23822410 Convert (sub_expr);
23832411 ConvertCast (type);
2412+ SetFreshType (type);
23842413 } else {
23852414 {
23862415 PushParen paren (*this , suffix);
23872416 Convert (sub_expr);
23882417 }
23892418 if (suffix) {
23902419 StrCat (suffix);
2420+ SetFreshType (type);
23912421 }
23922422 }
23932423 break ;
@@ -2447,6 +2477,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
24472477 ConvertCast (type);
24482478 }
24492479 }
2480+ SetFreshType (type);
24502481 }
24512482 return false ;
24522483}
@@ -2737,6 +2768,7 @@ bool Converter::ConvertIncAndDec(clang::UnaryOperator *expr) {
27372768bool Converter::VisitUnaryOperator (clang::UnaryOperator *expr) {
27382769 if (auto str = GetMappedAsString (expr); !str.empty ()) {
27392770 StrCat (str);
2771+ SetFreshType (expr->getType ());
27402772 return false ;
27412773 }
27422774
@@ -2793,6 +2825,7 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) {
27932825 default :
27942826 StrCat (expr->getOpcodeStr (opcode));
27952827 Convert (sub_expr);
2828+ SetFreshType (expr->getType ());
27962829 }
27972830 return false ;
27982831}
@@ -2909,6 +2942,9 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
29092942 ConvertFunctionToFunctionPointer (fn_decl);
29102943 return false ;
29112944 }
2945+ StrCat (str);
2946+ SetFreshType (expr->getType ());
2947+ return false ;
29122948 }
29132949
29142950 if (auto var_decl = clang::dyn_cast<clang::VarDecl>(decl)) {
@@ -2918,6 +2954,7 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
29182954 init->IgnoreUnlessSpelledInSource ())) {
29192955 PushParen paren (*this );
29202956 VisitLambdaExpr (lambda);
2957+ computed_expr_type_ = ComputedExprType::FreshValue;
29212958 return false ;
29222959 }
29232960 }
@@ -2927,10 +2964,16 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) {
29272964 if (!decl->getType ()->getAs <clang::ReferenceType>() && isAddrOf ()) {
29282965 StrCat (token::kRef , decl->getType ().isConstQualified () ? " " : keyword_mut_,
29292966 str);
2967+ computed_expr_type_ = ComputedExprType::FreshPointer;
29302968 return false ;
29312969 }
29322970
29332971 StrCat (str);
2972+ if (clang::isa<clang::EnumConstantDecl>(decl)) {
2973+ computed_expr_type_ = ComputedExprType::FreshValue;
2974+ return false ;
2975+ }
2976+ SetValueFreshness (expr->getType ());
29342977 return false ;
29352978}
29362979
@@ -3023,6 +3066,7 @@ bool Converter::VisitMemberExpr(clang::MemberExpr *expr) {
30233066 SetUFCSReceiver (expr->getBase (), expr->isArrow (), method);
30243067 StrCat (GetRecordName (method->getParent ()), token::kDoubleColon ,
30253068 GetMethodName (method));
3069+ SetFreshType (expr->getType ());
30263070 return false ;
30273071 }
30283072 std::string str;
@@ -3056,10 +3100,16 @@ bool Converter::VisitMemberExpr(clang::MemberExpr *expr) {
30563100 if (!isAddrOf () && member->getType ()->isFunctionPointerType ()) {
30573101 PushParen paren (*this );
30583102 StrCat (str);
3103+ SetValueFreshness (expr->getType ());
30593104 return false ;
30603105 }
30613106
30623107 StrCat (str);
3108+ if (clang::isa<clang::CXXMethodDecl>(member)) {
3109+ SetFreshType (expr->getType ());
3110+ } else {
3111+ SetValueFreshness (expr->getType ());
3112+ }
30633113 return false ;
30643114}
30653115
@@ -3171,6 +3221,7 @@ bool Converter::VisitCXXThisExpr(clang::CXXThisExpr *expr) {
31713221 PushParen paren (*this );
31723222 StrCat (keyword::kSelfValue , keyword::kAs , ToString (expr->getType ()));
31733223 }
3224+ computed_expr_type_ = ComputedExprType::FreshPointer;
31743225 return false ;
31753226}
31763227
@@ -3196,6 +3247,7 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
31963247 } else {
31973248 StrCat (GetArrayDefaultAsString (qual_type));
31983249 }
3250+ SetFreshType (qual_type);
31993251 return false ;
32003252 }
32013253
@@ -3231,6 +3283,7 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
32313283 }
32323284 }
32333285 }
3286+ SetFreshType (qual_type);
32343287 return false ;
32353288}
32363289
@@ -3434,6 +3487,9 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
34343487 if (auto str = GetMappedAsString (expr, expr->getArgs (), expr->getNumArgs ());
34353488 !str.empty ()) {
34363489 StrCat (str);
3490+ if (!IsPassThroughRule (expr)) {
3491+ SetFreshType (expr->getType ());
3492+ }
34373493 return false ;
34383494 }
34393495
@@ -3455,13 +3511,15 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
34553511 if ((ctor->isCopyConstructor () || IsDefaultedMoveConstructor (ctor)) &&
34563512 !suppress && !TypeIsCopyable (expr->getType ())) {
34573513 StrCat (" .clone()" );
3514+ SetFreshType (expr->getType ());
34583515 }
34593516 return false ;
34603517 }
34613518
34623519 if (ctor->isDefaultConstructor () && !ctor->isUserProvided ()) {
34633520 auto ty = expr->getType ();
34643521 StrCat (GetDefaultAsString (ty));
3522+ SetFreshType (expr->getType ());
34653523 return false ;
34663524 }
34673525
@@ -3471,6 +3529,7 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
34713529 } else {
34723530 ConvertCXXConstructExprArgs (expr);
34733531 }
3532+ SetFreshType (expr->getType ());
34743533 return false ;
34753534}
34763535
@@ -3568,6 +3627,12 @@ bool Converter::VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr *expr) {
35683627 return false ;
35693628}
35703629
3630+ bool Converter::VisitConstantExpr (clang::ConstantExpr *expr) {
3631+ Convert (expr->getSubExpr ());
3632+ SetFreshType (expr->getType ());
3633+ return false ;
3634+ }
3635+
35713636bool Converter::VisitLambdaExpr (clang::LambdaExpr *expr) {
35723637 if (isAddrOf () && expr->capture_size () == 0 ) {
35733638 StrCat (" Some" );
@@ -4030,10 +4095,6 @@ void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) {
40304095 PushInitType init_type (*this , qual_type);
40314096 Convert (expr, qual_type);
40324097 }
4033- if (qual_type->isReferenceType () && !IsReferenceType (expr)) {
4034- StrCat (keyword::kAs );
4035- Convert (qual_type);
4036- }
40374098}
40384099
40394100void Converter::ConvertUnsignedArithOperand (clang::Expr *expr,
@@ -4509,13 +4570,15 @@ void Converter::ConvertAddrOf(clang::Expr *expr, clang::QualType pointer_type) {
45094570 : keyword_mut_);
45104571 Convert (expr);
45114572 ConvertCast (pointer_type);
4573+ computed_expr_type_ = ComputedExprType::FreshPointer;
45124574 } else {
45134575 StrCat (token::kRef );
45144576 if (!pointer_type->getPointeeType ().isConstQualified ()) {
45154577 StrCat (keyword_mut_);
45164578 }
45174579 Convert (expr);
45184580 ConvertCast (pointer_type);
4581+ computed_expr_type_ = ComputedExprType::FreshPointer;
45194582 }
45204583}
45214584
@@ -4527,6 +4590,7 @@ void Converter::EmitDeref(std::string inner, clang::QualType pointee_type) {
45274590 }
45284591 PushParen paren (*this );
45294592 StrCat (GetPointerDerefPrefix (pointee_type), std::move (inner));
4593+ SetValueFreshness (pointee_type);
45304594}
45314595
45324596void Converter::ConvertDeref (clang::Expr *expr) {
@@ -4587,8 +4651,8 @@ void Converter::PlaceholderCtx::dump() const {
45874651 << " , is_cpp_ptr: " << is_cpp_ptr
45884652 << " , maps_to_rust_ptr: " << maps_to_rust_ptr
45894653 << " , declared_in_rule_as_rust_ptr: "
4590- << declared_in_rule_as_rust_ptr << " , access: "
4591- << (access == TranslationRule::Access:: kRead ? " read " : " write " )
4654+ << declared_in_rule_as_rust_ptr
4655+ << " , access: " << static_cast < int >(access )
45924656 << " , param_type: " << param_type
45934657 << " , materialize_idx: " << materialize_idx << ' \n ' ;
45944658}
@@ -4626,10 +4690,10 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg,
46264690 if (ph_ctx.needs_object_receiver ()) {
46274691 Buffer buf (*this );
46284692 PushExplicitAutoref autoref (
4629- *this ,
4630- ph_ctx.is_index_base
4631- ? std::optional (ph_ctx. access == TranslationRule::Access::kWrite )
4632- : std::nullopt );
4693+ *this , ph_ctx. is_index_base
4694+ ? std::optional ( ph_ctx.access ==
4695+ TranslationRule::Access::kBorrowMut )
4696+ : std::nullopt );
46334697 PushExprKind push (*this , ExprKind::RValue);
46344698 ConvertDeref (arg);
46354699 return std::move (buf).str ();
@@ -4643,13 +4707,17 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg,
46434707 return ConvertLValue (arg);
46444708 }
46454709
4646- if (ph_ctx.access == TranslationRule::Access::kMove ) {
4710+ if (ph_ctx.access == TranslationRule::Access::kTake ) {
46474711 if (clang::isa<clang::MaterializeTemporaryExpr>(arg)) {
46484712 return ConvertRValue (arg);
46494713 }
46504714 return std::format (" std::mem::take(&mut {})" , ConvertLValue (arg));
46514715 }
46524716
4717+ if (ph_ctx.access == TranslationRule::Access::kMove ) {
4718+ return ConvertFreshRValue (arg, ph_ctx.implicit_convert_to );
4719+ }
4720+
46534721 return ConvertRValue (arg, ph_ctx.implicit_convert_to );
46544722}
46554723
@@ -4806,6 +4874,12 @@ void Converter::SetFresh() {
48064874 case ComputedExprType::FreshValue:
48074875 case ComputedExprType::FreshPointer:
48084876 break ;
4877+ case ComputedExprType::Unknown:
4878+ assert (0 && " Unreachable ComputedExprType::Unknown" );
4879+ break ;
4880+ case ComputedExprType::Pending:
4881+ assert (0 && " Unreachable ComputedExprType::Pending" );
4882+ break ;
48094883 }
48104884}
48114885
0 commit comments