Skip to content

Commit c540520

Browse files
committed
Move aggregate initialziation of array in rules
1 parent dac3147 commit c540520

11 files changed

Lines changed: 70 additions & 27 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,19 +3626,16 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
36263626
}
36273627
} else if (qual_type->isRecordType()) {
36283628
const auto *record = qual_type->getAsRecordDecl();
3629-
if (record->getQualifiedNameAsString() == "std::array") {
3630-
if (auto init = clang::dyn_cast<clang::InitListExpr>(expr->getInit(0))) {
3631-
StrCat("vec!");
3632-
VisitInitListExpr(init);
3633-
} else {
3634-
StrCat(GetDefaultAsString(qual_type));
3635-
}
3629+
if (syntactic->getNumInits() == 0) {
3630+
StrCat(GetDefaultAsString(qual_type));
36363631
SetFreshType(qual_type);
36373632
return false;
36383633
}
36393634

3640-
if (syntactic->getNumInits() == 0) {
3641-
StrCat(GetDefaultAsString(qual_type));
3635+
if (auto str =
3636+
GetMappedAsString(expr, expr->getInits(), expr->getNumInits());
3637+
!str.empty()) {
3638+
StrCat(str);
36423639
SetFreshType(qual_type);
36433640
return false;
36443641
}

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,26 +1882,24 @@ bool ConverterRefCount::VisitInitListExpr(clang::InitListExpr *expr) {
18821882

18831883
if (qual_type->isRecordType()) {
18841884
const auto *record = qual_type->getAsRecordDecl();
1885-
if (record->getQualifiedNameAsString() == "std::array") {
1886-
if (auto init = clang::dyn_cast<clang::InitListExpr>(expr->getInit(0))) {
1887-
StrCat("vec!");
1888-
PushConversionKind push(*this, ConversionKind::Unboxed);
1889-
ConverterRefCount::VisitInitListExpr(init);
1890-
} else {
1885+
if (syntactic->getNumInits() == 0) {
1886+
{
18911887
PushConversionKind push(*this, ConversionKind::Unboxed);
18921888
StrCat(GetDefaultAsString(qual_type));
18931889
}
18941890
computed_expr_type_ = ComputedExprType::FreshValue;
18951891
return false;
18961892
}
18971893

1898-
if (syntactic->getNumInits() == 0) {
1899-
{
1900-
PushConversionKind push(*this, ConversionKind::Unboxed);
1901-
StrCat(GetDefaultAsString(qual_type));
1894+
{
1895+
PushConversionKind push(*this, ConversionKind::Unboxed);
1896+
if (auto str =
1897+
GetMappedAsString(expr, expr->getInits(), expr->getNumInits());
1898+
!str.empty()) {
1899+
StrCat(str);
1900+
computed_expr_type_ = ComputedExprType::FreshValue;
1901+
return false;
19021902
}
1903-
computed_expr_type_ = ComputedExprType::FreshValue;
1904-
return false;
19051903
}
19061904

19071905
if (record->isUnion()) {

‎cpp2rust/converter/rules/expr_matcher.cpp‎

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <vector>
2323

2424
#include "converter/rules/decls.h"
25+
#include "converter/rules/rule_keys.h"
2526

2627
namespace cpp2rust::AstMatcher {
2728

@@ -60,8 +61,15 @@ struct RewrittenOperatorUsage {
6061
bool operator==(const RewrittenOperatorUsage &) const = default;
6162
};
6263

63-
using ResolvedDecl = std::variant<std::monostate, const clang::Decl *,
64-
MacroUsage, RewrittenOperatorUsage>;
64+
struct AggregateUsage {
65+
RuleKeys::TypeKey type;
66+
67+
bool operator==(const AggregateUsage &) const = default;
68+
};
69+
70+
using ResolvedDecl =
71+
std::variant<std::monostate, const clang::Decl *, MacroUsage,
72+
RewrittenOperatorUsage, AggregateUsage>;
6573

6674
ResolvedDecl getResolvedDecl(clang::ASTContext &ctx, const clang::Expr *expr,
6775
bool must_resolve) {
@@ -85,6 +93,14 @@ ResolvedDecl getResolvedDecl(clang::ASTContext &ctx, const clang::Expr *expr,
8593
if (auto cast = llvm::dyn_cast<clang::ExplicitCastExpr>(expr)) {
8694
return getResolvedDecl(ctx, cast->getSubExpr(), must_resolve);
8795
}
96+
if (auto list = llvm::dyn_cast<clang::InitListExpr>(expr);
97+
list && list->getType()->isRecordType()) {
98+
return AggregateUsage{*RuleKeys::GetTypeKey(list->getType())};
99+
}
100+
if (auto construct = llvm::dyn_cast<clang::CXXUnresolvedConstructExpr>(expr);
101+
construct && construct->isListInitialization()) {
102+
return AggregateUsage{*RuleKeys::GetTypeKey(construct->getTypeAsWritten())};
103+
}
88104
if (auto call = llvm::dyn_cast<clang::CallExpr>(expr)) {
89105
if (auto callee = call->getDirectCallee()) {
90106
return callee->getCanonicalDecl();
@@ -149,6 +165,8 @@ std::vector<clang::Expr *> getOperands(clang::ASTContext &ctx,
149165
operands.insert(operands.end(), call->arg_begin(), call->arg_end());
150166
} else if (auto construct = llvm::dyn_cast<clang::CXXConstructExpr>(expr)) {
151167
operands.assign(construct->arg_begin(), construct->arg_end());
168+
} else if (auto list = llvm::dyn_cast<clang::InitListExpr>(expr)) {
169+
operands.assign(list->inits().begin(), list->inits().end());
152170
} else if (auto member = llvm::dyn_cast<clang::MemberExpr>(expr)) {
153171
auto macro_base =
154172
RuleDecls::GetMacroMemberBase(ctx.getSourceManager(), member);
@@ -320,6 +338,17 @@ MatchResult matchTemplate(clang::Sema &sema, const clang::Expr *use,
320338
auto explicit_args = getResultArgs(sema, rule, use);
321339
auto specialization =
322340
deduce(sema, rule, explicit_args, getOperands(ctx, use));
341+
if (!specialization) {
342+
return std::nullopt;
343+
}
344+
if (std::holds_alternative<AggregateUsage>(usage_decl)) {
345+
auto returned = RuleDecls::GetReturned(rule->getTemplatedDecl());
346+
if (getResolvedDecl(ctx, returned, /*must_resolve=*/false) != usage_decl) {
347+
return std::nullopt;
348+
}
349+
checkCallable(sema, use, rule->getTemplatedDecl());
350+
return specialization->getTemplateSpecializationArgs()->asArray();
351+
}
323352
auto returned =
324353
substituteSpecializationInRuleTmpl(sema, rule, specialization);
325354
if (!returned ||

‎cpp2rust/converter/rules/rule_keys.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ std::optional<ExprKey> getExprKey(clang::ASTContext &ctx,
183183
if (llvm::isa<clang::ArraySubscriptExpr>(expr)) {
184184
return getOperatorKey(ctx, clang::OO_Subscript);
185185
}
186+
if (auto list = llvm::dyn_cast<clang::InitListExpr>(expr);
187+
list && list->getType()->isRecordType()) {
188+
return getConstructorKey(getParent(list->getType()));
189+
}
186190
return std::nullopt;
187191
}
188192

‎cpp2rust/converter/rules/rules_loader.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,13 @@ std::string ExprKey(clang::ASTContext &ctx, const clang::Expr *expr) {
489489
if (auto construct = llvm::dyn_cast<clang::CXXConstructExpr>(expr)) {
490490
return FunctionKey(construct->getConstructor());
491491
}
492+
if (auto list = llvm::dyn_cast<clang::InitListExpr>(expr)) {
493+
if (auto record = list->getType()->getAsRecordDecl();
494+
record && !IsUserDefinedDecl(record)) {
495+
return ConstructorKey(ClassKey(record));
496+
}
497+
return {};
498+
}
492499
if (auto member = llvm::dyn_cast<clang::MemberExpr>(expr)) {
493500
if (RuleDecls::GetMacroMemberBase(ctx.getSourceManager(), member)) {
494501
return clang::Lexer::getImmediateMacroName(member->getMemberLoc(),

‎rules/array/src.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@ template <typename T1, std::size_t T2>
4141
std::array<T1, T2> &f7(std::array<T1, T2> &dst, const std::array<T1, T2> &src) {
4242
return dst = src;
4343
}
44+
45+
template <typename T1, std::size_t T2> std::array<T1, T2> f8(T1 (&&a0)[T2]) {
46+
return std::array<T1, T2>{a0};
47+
}

‎rules/array/tgt_unsafe.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@ unsafe fn f6<T1: Clone>(a0: Vec<T1>) -> Vec<T1> {
3838
unsafe fn f7<T1: Clone>(a0: &mut Vec<T1>, a1: Vec<T1>) {
3939
*a0 = a1.clone()
4040
}
41+
42+
unsafe fn f8<T1, const T2: usize>(a0: [T1; T2]) -> Vec<T1> {
43+
Vec::from(a0)
44+
}

‎tests/unit/out/refcount/init_list.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn main_0() -> i32 {
4545
let mut i2: i32 = 0_i32;
4646
let mut carr1: [i32; 2] = [1, 2];
4747
let mut carr2: [i32; 3] = [1, 0_i32, 0_i32];
48-
let arr: Value<Vec<i32>> = Rc::new(RefCell::new(vec![1, 2, 3]));
48+
let arr: Value<Vec<i32>> = Rc::new(RefCell::new(Vec::from([1, 2, 3])));
4949
let mut vec_: Vec<i32> = vec![1, 2, 3];
5050
({ f_0(vec![1, 2, 3, 4]) });
5151
let p: Value<Pair> = Rc::new(RefCell::new(Pair { a: 1, b: 2 }));

‎tests/unit/out/refcount/vector_subscript_direct.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ fn main_0() -> i32 {
181181
.read())
182182
== 8)
183183
);
184-
let a: Value<Vec<i32>> = Rc::new(RefCell::new(vec![4, 5, 6]));
184+
let a: Value<Vec<i32>> = Rc::new(RefCell::new(Vec::from([4, 5, 6])));
185185
let __rhs = ({ (*a.borrow())[0_usize] } + { (*a.borrow())[2_usize] });
186186
(*a.borrow_mut())[1_usize] = __rhs;
187187
assert!(({ (*a.borrow())[1_usize] } == 10));

‎tests/unit/out/unsafe/init_list.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ unsafe fn main_0() -> i32 {
4747
let mut i2: i32 = 0_i32;
4848
let mut carr1: [i32; 2] = [1, 2];
4949
let mut carr2: [i32; 3] = [1, 0_i32, 0_i32];
50-
let mut arr: Vec<i32> = vec![1, 2, 3];
50+
let mut arr: Vec<i32> = Vec::from([1, 2, 3]);
5151
let mut vec_: Vec<i32> = vec![1, 2, 3];
5252
(unsafe { f_0(vec![1, 2, 3, 4]) });
5353
let mut p: Pair = Pair { a: 1, b: 2 };

0 commit comments

Comments
 (0)