Enforce pinning on mut opaque C++ types
diff --git a/syntax/check.rs b/syntax/check.rs
index 73ce885..5876cf7 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -151,6 +151,24 @@
cx.error(ty, "references with explicit lifetimes are not supported");
}
+ if ty.mutability.is_some() && !ty.pinned {
+ if let Some(requires_pin) = match &ty.inner {
+ Type::Ident(ident) if ident.rust == CxxString || is_opaque_cxx(cx, &ident.rust) => {
+ Some(ident.rust.to_string())
+ }
+ Type::CxxVector(_) => Some("CxxVector<...>".to_owned()),
+ _ => None,
+ } {
+ cx.error(
+ ty,
+ format!(
+ "mutable reference to C++ type requires a pin -- use Pin<&mut {}>",
+ requires_pin,
+ ),
+ );
+ }
+ }
+
match ty.inner {
Type::Fn(_) | Type::Void(_) => {}
Type::Ref(_) => {
@@ -370,13 +388,14 @@
Type::CxxVector(_) | Type::Slice(_) | Type::Void(_) => return true,
_ => return false,
};
- ident == CxxString
- || cx.types.cxx.contains(ident)
- && !cx.types.structs.contains_key(ident)
- && !cx.types.enums.contains_key(ident)
- && !(cx.types.aliases.contains_key(ident)
- && cx.types.required_trivial.contains_key(ident))
- || cx.types.rust.contains(ident)
+ ident == CxxString || is_opaque_cxx(cx, ident) || cx.types.rust.contains(ident)
+}
+
+fn is_opaque_cxx(cx: &mut Check, ty: &Ident) -> bool {
+ cx.types.cxx.contains(ty)
+ && !cx.types.structs.contains_key(ty)
+ && !cx.types.enums.contains_key(ty)
+ && !(cx.types.aliases.contains_key(ty) && cx.types.required_trivial.contains_key(ty))
}
fn span_for_struct_error(strct: &Struct) -> TokenStream {