mirror of
https://github.com/topjohnwu/cxx.git
synced 2025-02-23 17:40:53 +00:00
Improve error message on unique_ptr of incomplete forward declared type
This commit is contained in:
parent
ee9b9eebad
commit
534627667d
@ -25,6 +25,8 @@ pub struct Builtins<'a> {
|
||||
pub exception: bool,
|
||||
pub relocatable: bool,
|
||||
pub friend_impl: bool,
|
||||
pub is_complete: bool,
|
||||
pub deleter_if: bool,
|
||||
pub content: Content<'a>,
|
||||
}
|
||||
|
||||
@ -226,6 +228,33 @@ pub(super) fn write(out: &mut OutFile) {
|
||||
writeln!(out, "}};");
|
||||
}
|
||||
|
||||
if builtin.is_complete {
|
||||
include.type_traits = true;
|
||||
out.next_section();
|
||||
writeln!(out, "template <typename T, typename = size_t>");
|
||||
writeln!(out, "struct is_complete : std::false_type {{}};");
|
||||
out.next_section();
|
||||
writeln!(out, "template <typename T>");
|
||||
writeln!(
|
||||
out,
|
||||
"struct is_complete<T, decltype(sizeof(T))> : std::true_type {{}};",
|
||||
);
|
||||
}
|
||||
|
||||
if builtin.deleter_if {
|
||||
out.next_section();
|
||||
writeln!(out, "template <bool> struct deleter_if {{");
|
||||
writeln!(out, " template <typename T> void operator()(T *) {{}}");
|
||||
writeln!(out, "}};");
|
||||
out.next_section();
|
||||
writeln!(out, "template <> struct deleter_if<true> {{");
|
||||
writeln!(
|
||||
out,
|
||||
" template <typename T> void operator()(T *ptr) {{ ptr->~T(); }}",
|
||||
);
|
||||
writeln!(out, "}};");
|
||||
}
|
||||
|
||||
out.end_block(Block::AnonymousNamespace);
|
||||
out.end_block(Block::InlineNamespace("cxxbridge1"));
|
||||
|
||||
|
@ -1242,6 +1242,26 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
|
||||
UniquePtr::CxxVector(_) => false,
|
||||
};
|
||||
|
||||
let conditional_delete = match ty {
|
||||
UniquePtr::Ident(ident) => {
|
||||
!out.types.structs.contains_key(&ident.rust)
|
||||
&& !out.types.enums.contains_key(&ident.rust)
|
||||
}
|
||||
UniquePtr::CxxVector(_) => false,
|
||||
};
|
||||
|
||||
if conditional_delete {
|
||||
out.builtin.is_complete = true;
|
||||
let definition = match ty {
|
||||
UniquePtr::Ident(ty) => &out.types.resolve(ty).cxx,
|
||||
UniquePtr::CxxVector(_) => unreachable!(),
|
||||
};
|
||||
writeln!(
|
||||
out,
|
||||
"static_assert(::rust::is_complete<{}>::value, \"definition of {} is required\");",
|
||||
inner, definition,
|
||||
);
|
||||
}
|
||||
writeln!(
|
||||
out,
|
||||
"static_assert(sizeof(::std::unique_ptr<{}>) == sizeof(void *), \"\");",
|
||||
@ -1298,7 +1318,16 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
|
||||
"void cxxbridge1$unique_ptr${}$drop(::std::unique_ptr<{}> *ptr) noexcept {{",
|
||||
instance, inner,
|
||||
);
|
||||
writeln!(out, " ptr->~unique_ptr();");
|
||||
if conditional_delete {
|
||||
out.builtin.deleter_if = true;
|
||||
writeln!(
|
||||
out,
|
||||
" ::rust::deleter_if<::rust::is_complete<{}>::value>{{}}(ptr);",
|
||||
inner,
|
||||
);
|
||||
} else {
|
||||
writeln!(out, " ptr->~unique_ptr();");
|
||||
}
|
||||
writeln!(out, "}}");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user