Skip to content

Commit 59a90f6

Browse files
committed
Merge branch 'master' into remove-emplace-back-plugin
2 parents e98f81e + 1ce3815 commit 59a90f6

142 files changed

Lines changed: 1041 additions & 1148 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎cpp2rust/converter/converter.cpp‎

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,10 @@ bool Converter::RecordDerivesDefault(const clang::RecordDecl *decl) {
686686
}
687687

688688
for (auto f : decl->fields()) {
689+
if (f->hasInClassInitializer()) {
690+
return false;
691+
}
692+
689693
// Records that contain function pointer do not derive Default
690694
if (auto ptr_ty = f->getType()->getAs<clang::PointerType>()) {
691695
if (ptr_ty->getPointeeType()->isFunctionType()) {
@@ -1096,6 +1100,10 @@ std::string Converter::GetMethodName(const clang::CXXMethodDecl *decl) {
10961100
if (clang::isa<clang::CXXDestructorDecl>(decl)) {
10971101
return kDestructorName;
10981102
}
1103+
if (const char *name = GetCopyOrMoveName(decl);
1104+
name && CanUseCopyOrMoveName(decl, name)) {
1105+
return name;
1106+
}
10991107
if (IsOverloadedMethod(decl)) {
11001108
return GetOverloadedFunctionName(decl);
11011109
}
@@ -1145,6 +1153,10 @@ std::string Converter::GetSelfMaybeWithMut(const clang::CXXMethodDecl *decl) {
11451153

11461154
std::string Converter::GetCtorName(clang::CXXConstructorDecl *decl) {
11471155
if (decl->isCopyOrMoveConstructor()) {
1156+
if (const char *name = GetCopyOrMoveName(decl);
1157+
CanUseCopyOrMoveName(decl, name)) {
1158+
return name;
1159+
}
11481160
return GetOverloadedFunctionName(decl);
11491161
}
11501162
return GetNumberOfConvertingCtors(decl->getParent()) != 1
@@ -3328,7 +3340,7 @@ void Converter::ConvertMemberExpr(clang::MemberExpr *expr) {
33283340
if (auto *method = clang::dyn_cast<clang::CXXMethodDecl>(member);
33293341
method && IsOverloadedMethod(method)) {
33303342
StrCat(token::kDot);
3331-
StrCat(GetOverloadedFunctionName(method));
3343+
StrCat(GetMethodName(method));
33323344
} else if (!name_override.empty()) {
33333345
StrCat(token::kDot, name_override);
33343346
} else if (member->getDeclName().isIdentifier()) {
@@ -3370,6 +3382,7 @@ bool Converter::VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr *expr) {
33703382
}
33713383

33723384
bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
3385+
auto *syntactic = expr->isSyntacticForm() ? expr : expr->getSyntacticForm();
33733386
if (auto form = expr->getSemanticForm())
33743387
expr = form;
33753388

@@ -3395,6 +3408,12 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
33953408
return false;
33963409
}
33973410

3411+
if (syntactic->getNumInits() == 0) {
3412+
StrCat(GetDefaultAsString(qual_type));
3413+
SetFreshType(qual_type);
3414+
return false;
3415+
}
3416+
33983417
StrCat(GetUnsafeTypeAsString(qual_type));
33993418
PushBrace brace(*this);
34003419
int i = 0;
@@ -4038,18 +4057,6 @@ std::string Converter::GetDefaultAsStringFallback(clang::QualType qual_type) {
40384057
return getTypedLiteral("0.0", ToString(qual_type));
40394058
}
40404059

4041-
if (auto record = qual_type->getAsRecordDecl();
4042-
record && in_const_initializer_) {
4043-
if (auto cxx = clang::dyn_cast<clang::CXXRecordDecl>(record)) {
4044-
ENSURE(GetUserDefinedDefaultConstructor(cxx) == nullptr &&
4045-
"Default initializing globals using default constructor is not "
4046-
"supported");
4047-
}
4048-
Buffer buf(*this);
4049-
EmitDefaultStructLiteral(record);
4050-
return std::move(buf).str();
4051-
}
4052-
40534060
if (auto record = qual_type->getAsRecordDecl()) {
40544061
if (ctx_.getSourceManager().isInSystemHeader(record->getLocation()) &&
40554062
qual_type.isPODType(ctx_)) {
@@ -4708,8 +4715,13 @@ void Converter::EmitDefaultStructLiteral(const clang::RecordDecl *decl) {
47084715
StrCat(GetRecordName(decl));
47094716
PushBrace brace(*this);
47104717
for (auto *field : decl->fields()) {
4711-
StrCat(GetNamedDeclAsString(field), token::kColon,
4712-
GetDefaultAsString(field->getType()), token::kComma);
4718+
StrCat(GetNamedDeclAsString(field), token::kColon);
4719+
if (auto *init = field->getInClassInitializer()) {
4720+
ConvertVarInit(field->getType(), init);
4721+
} else {
4722+
StrCat(GetDefaultAsString(field->getType()));
4723+
}
4724+
StrCat(token::kComma);
47134725
}
47144726
}
47154727

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,44 @@ bool IsOverloadedMethod(const clang::CXXMethodDecl *decl) {
288288
}) > 1;
289289
}
290290

291+
const char *GetCopyOrMoveName(const clang::CXXMethodDecl *method) {
292+
if (auto *ctor = clang::dyn_cast<clang::CXXConstructorDecl>(method)) {
293+
if (ctor->isCopyConstructor()) {
294+
return "copy_from";
295+
}
296+
if (ctor->isMoveConstructor()) {
297+
return "move_from";
298+
}
299+
return nullptr;
300+
}
301+
if (method->isCopyAssignmentOperator()) {
302+
return "copy_assign";
303+
}
304+
if (method->isMoveAssignmentOperator()) {
305+
return "move_assign";
306+
}
307+
return nullptr;
308+
}
309+
310+
bool CanUseCopyOrMoveName(const clang::CXXMethodDecl *decl,
311+
const std::string &name) {
312+
const auto *record = decl->getParent();
313+
bool is_unique_member =
314+
std::count_if(record->method_begin(), record->method_end(),
315+
[&name](const clang::CXXMethodDecl *method) {
316+
const char *method_name = GetCopyOrMoveName(method);
317+
return !method->isDeleted() && method_name &&
318+
method_name == name;
319+
}) == 1;
320+
bool is_unique_name =
321+
std::none_of(record->method_begin(), record->method_end(),
322+
[&name](const clang::CXXMethodDecl *method) {
323+
return method->getDeclName().isIdentifier() &&
324+
method->getName() == name;
325+
});
326+
return is_unique_member && is_unique_name;
327+
}
328+
291329
bool IsUserDefinedCopyConstructor(const clang::CXXConstructorDecl *ctor) {
292330
return ctor->isCopyConstructor() && ctor->isUserProvided() &&
293331
IsUserDefinedDecl(ctor);

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ void ForEachTemplateInstantiatedMethod(
7474

7575
bool IsOverloadedMethod(const clang::CXXMethodDecl *decl);
7676

77+
const char *GetCopyOrMoveName(const clang::CXXMethodDecl *method);
78+
79+
bool CanUseCopyOrMoveName(const clang::CXXMethodDecl *decl,
80+
const std::string &name);
81+
7782
bool IsUserDefinedCopyConstructor(const clang::CXXConstructorDecl *ctor);
7883

7984
bool IsConvertibleCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor);

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,7 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) {
15951595
}
15961596

15971597
bool ConverterRefCount::VisitInitListExpr(clang::InitListExpr *expr) {
1598+
auto *syntactic = expr->isSyntacticForm() ? expr : expr->getSyntacticForm();
15981599
if (auto form = expr->getSemanticForm())
15991600
expr = form;
16001601

@@ -1620,6 +1621,15 @@ bool ConverterRefCount::VisitInitListExpr(clang::InitListExpr *expr) {
16201621
return false;
16211622
}
16221623

1624+
if (syntactic->getNumInits() == 0) {
1625+
{
1626+
PushConversionKind push(*this, ConversionKind::Unboxed);
1627+
StrCat(GetDefaultAsString(qual_type));
1628+
}
1629+
computed_expr_type_ = ComputedExprType::FreshValue;
1630+
return false;
1631+
}
1632+
16231633
StrCat(GetUnsafeTypeAsString(qual_type));
16241634
{
16251635
PushBrace brace(*this);
@@ -2111,6 +2121,18 @@ std::string ConverterRefCount::GetDefaultAsString(clang::QualType qual_type) {
21112121

21122122
std::string
21132123
ConverterRefCount::GetDefaultAsStringFallback(clang::QualType qual_type) {
2124+
auto canonical = qual_type.getUnqualifiedType().getCanonicalType();
2125+
if (canonical->isBooleanType() ||
2126+
(canonical->isIntegerType() && !canonical->isEnumeralType()) ||
2127+
canonical->isFloatingType()) {
2128+
std::string unboxed;
2129+
{
2130+
PushConversionKind push(*this, ConversionKind::Unboxed);
2131+
unboxed = Converter::GetDefaultAsStringFallback(qual_type);
2132+
}
2133+
return BoxValue(std::move(unboxed));
2134+
}
2135+
21142136
return std::format("<{}>::default()", ToString(qual_type));
21152137
}
21162138

‎docs/src/codegen/types/classes.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ behind pointers, is emitted at the end of the file as an empty
9090

9191
A constructor becomes an associated function named after the class. It opens
9292
with `let mut this = Self { ... }`, one field per member initializer, then runs
93-
the C++ body and returns `this`. Only implicit or defaulted copy and move
94-
constructors are supported: a user-defined one stops the translation, and the
95-
implicit copy is what the `Clone` impl represents.
93+
the C++ body and returns `this`. Copy and move constructors become `copy_from`
94+
and `move_from` (see [Naming](./naming.md)); the `Clone` impl calls `copy_from`
95+
when the copy constructor is user-defined.
9696

9797
Methods take `&self` when `const` and `&mut self` otherwise in the unsafe model.
9898
In the refcount model they always take `&self`, since mutation goes through the

‎docs/src/codegen/types/naming.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@ name unless they are overloaded, in which case the parameter types are appended
2727
(`method_i32`, `method_i32_const`). `operator<` is emitted as `lt`; comparison
2828
operators additionally produce the corresponding trait impls (`PartialOrd`,
2929
`Ord`, `PartialEq`).
30+
31+
Copy and move constructors are named `copy_from` and `move_from`, and copy and
32+
move assignment operators `copy_assign` and `move_assign`, as long as the class
33+
has only one member of that kind and no method already uses the name; otherwise
34+
they get the overloaded form.

‎tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl S {
2424
let this: Ptr<S> = __this.as_pointer();
2525
Rc::try_unwrap(__this).ok().unwrap().into_inner()
2626
}
27-
pub fn S_pmutS_rv(_a0: Ptr<S>) -> Self {
27+
pub fn move_from(_a0: Ptr<S>) -> Self {
2828
let __this: Value<S> = Rc::new(RefCell::new(Self {
2929
v: Rc::new(RefCell::new(std::mem::take(
3030
&mut (*(*_a0.upgrade().deref()).v.borrow_mut()),
@@ -41,9 +41,7 @@ impl Default for S {
4141
fn default() -> Self {
4242
S {
4343
v: Rc::new(RefCell::new(Default::default())),
44-
n: Rc::new(RefCell::new(
45-
(0..2).map(|_| <i32>::default()).collect::<Box<[i32]>>(),
46-
)),
44+
n: Rc::new(RefCell::new((0..2).map(|_| 0_i32).collect::<Box<[i32]>>())),
4745
}
4846
}
4947
}
@@ -84,18 +82,18 @@ fn main_0() -> i32 {
8482
pub fn shuffle_1(x: i32) -> i32 {
8583
let x: Value<i32> = Rc::new(RefCell::new(x));
8684
let a: Value<S> = Rc::new(RefCell::new(S::new({ (*x.borrow()) })));
87-
let b: Value<S> = Rc::new(RefCell::new(S::S_pmutS_rv({ a.as_pointer() })));
85+
let b: Value<S> = Rc::new(RefCell::new(S::move_from({ a.as_pointer() })));
8886
assert!((*(*a.borrow()).v.borrow()).is_empty());
8987
let c: Value<S> = Rc::new(RefCell::new(S::new({ 1 })));
90-
({ SImpl::operator_assign_pmutS_rv(&c.as_pointer(), b.as_pointer()) });
88+
({ SImpl::move_assign(&c.as_pointer(), b.as_pointer()) });
9189
assert!((*(*b.borrow()).v.borrow()).is_empty());
9290
return ({ sum_0(c.as_pointer()) });
9391
}
9492
pub trait SImpl {
95-
fn operator_assign_pmutS_rv(&self, _a0: Ptr<S>) -> Ptr<S>;
93+
fn move_assign(&self, _a0: Ptr<S>) -> Ptr<S>;
9694
}
9795
impl SImpl for Ptr<S> {
98-
fn operator_assign_pmutS_rv(&self, _a0: Ptr<S>) -> Ptr<S> {
96+
fn move_assign(&self, _a0: Ptr<S>) -> Ptr<S> {
9997
((*(*self).upgrade().deref()).v.as_pointer() as Ptr<Vec<i32>>).write(std::mem::take(
10098
&mut (*(*_a0.upgrade().deref()).v.borrow_mut()),
10199
));

‎tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ impl S {
2020
};
2121
this
2222
}
23-
pub unsafe fn S_pmutS_rv(_a0: *mut S) -> Self {
23+
pub unsafe fn move_from(_a0: *mut S) -> Self {
2424
let mut this = Self {
2525
v: std::mem::take(&mut (*_a0).v),
2626
n: std::array::from_fn::<_, 2, _>(|__i: usize| (*_a0).n[(__i)]),
2727
};
2828
this
2929
}
30-
pub unsafe fn operator_assign_pmutS_rv(&mut self, _a0: *mut S) -> *mut S {
30+
pub unsafe fn move_assign(&mut self, _a0: *mut S) -> *mut S {
3131
self.v = std::mem::take(&mut (*_a0).v);
3232
{
3333
if 8_usize != 0 {
@@ -67,10 +67,10 @@ unsafe fn main_0() -> i32 {
6767
}
6868
pub unsafe fn shuffle_1(mut x: i32) -> i32 {
6969
let mut a: S = S::new({ x });
70-
let mut b: S = S::S_pmutS_rv({ &mut a });
70+
let mut b: S = S::move_from({ &mut a });
7171
assert!(a.v.is_empty());
7272
let mut c: S = S::new({ 1 });
73-
(unsafe { S::operator_assign_pmutS_rv(&mut c, &mut b) });
73+
(unsafe { S::move_assign(&mut c, &mut b) });
7474
assert!(b.v.is_empty());
7575
return (unsafe { sum_0(&c) });
7676
}

‎tests/multi-file/template_method_late_instantiation/out/refcount/template_method_late_instantiation.rs‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::io::prelude::*;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
9-
#[derive(Default)]
9+
#[derive()]
1010
pub struct S_int_ {
1111
pub x: Value<i32>,
1212
}
@@ -19,6 +19,13 @@ impl Clone for S_int_ {
1919
Rc::try_unwrap(__this).ok().unwrap().into_inner()
2020
}
2121
}
22+
impl Default for S_int_ {
23+
fn default() -> Self {
24+
S_int_ {
25+
x: Rc::new(RefCell::new(0)),
26+
}
27+
}
28+
}
2229
impl ByteRepr for S_int_ {
2330
fn byte_size() -> usize {
2431
4

‎tests/multi-file/template_method_late_instantiation/out/unsafe/template_method_late_instantiation.rs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
99
#[repr(C)]
10-
#[derive(Copy, Clone, Default)]
10+
#[derive(Copy, Clone)]
1111
pub struct S_int_ {
1212
pub x: i32,
1313
}
@@ -16,6 +16,11 @@ impl S_int_ {
1616
self.x = v;
1717
}
1818
}
19+
impl Default for S_int_ {
20+
fn default() -> Self {
21+
S_int_ { x: 0 }
22+
}
23+
}
1924
pub fn main() {
2025
unsafe {
2126
__cpp2rust_init_globals();

0 commit comments

Comments
 (0)