Improve error message on unique_ptr of incomplete forward declared type
diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs
index 53facbf..35620db 100644
--- a/gen/src/builtin.rs
+++ b/gen/src/builtin.rs
@@ -25,6 +25,8 @@
     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 @@
         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"));
 
diff --git a/gen/src/write.rs b/gen/src/write.rs
index e33197c..a12af31 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1242,6 +1242,26 @@
         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 @@
         "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, "}}");
 }