Allow &mut calls on Trivial extern types only.
Previously we allowed extern types to be used as un-pinned
reference parameters only if there happened to be some other
use of the type in some way which required it to be Trivial.
With this change,
* Opaque extern types must always be pinned when used as mutable
reference parameters;
* Trivial extern types need never be pinned when used as mutable
reference parameters.
diff --git a/syntax/check.rs b/syntax/check.rs
index 3b7b513..80426f9 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -189,7 +189,7 @@
cx.error(
ty,
format!(
- "mutable reference to C++ type requires a pin -- use Pin<&mut {}>",
+ "mutable reference to C++ type requires a pin -- use Pin<&mut {}> or declare the type Trivial in a cxx::ExternType impl",
requires_pin,
),
);
@@ -332,6 +332,10 @@
TrivialReason::FunctionReturn(efn) => format!("a return value of `{}`", efn.name.rust),
TrivialReason::BoxTarget => format!("Box<{}>", ety.name.rust),
TrivialReason::VecElement => format!("a vector element in Vec<{}>", ety.name.rust),
+ TrivialReason::UnpinnedMutableReferenceFunctionArgument(efn) => format!(
+ "a non-pinned mutable reference argument of {}",
+ efn.name.rust
+ ),
};
let msg = format!(
"needs a cxx::ExternType impl in order to be used as {}",
@@ -385,7 +389,7 @@
cx.error(
span,
format!(
- "mutable reference to C++ type requires a pin -- use `self: Pin<&mut {}>`",
+ "mutable reference to opaque C++ type requires a pin -- use `self: Pin<&mut {}>` or declare the type Trivial in a cxx::ExternType impl",
receiver.ty.rust,
),
);