mirror of
https://gitee.com/openharmony/third_party_rust_cxx
synced 2024-11-23 23:29:50 +00:00
Display all known reasons why type must be Trivial.
This generates multiple Rust-side and C++-side error messages when a given opaque C++ type is being used in contexts which allow only a Trivial type. Previously, we showed just the first message and discarded all others.
This commit is contained in:
parent
7b443f71b0
commit
f831a5abcf
@ -117,8 +117,8 @@ fn write_data_structures<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) {
|
||||
out.next_section();
|
||||
for api in apis {
|
||||
if let Api::TypeAlias(ety) = api {
|
||||
if let Some(reason) = out.types.required_trivial.get(&ety.name.rust) {
|
||||
check_trivial_extern_type(out, &ety.name, reason)
|
||||
if let Some(reasons) = out.types.required_trivial.get(&ety.name.rust) {
|
||||
check_trivial_extern_type(out, &ety.name, reasons)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -366,7 +366,7 @@ fn check_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trivial_extern_type(out: &mut OutFile, id: &Pair, reason: &TrivialReason) {
|
||||
fn check_trivial_extern_type(out: &mut OutFile, id: &Pair, reasons: &[TrivialReason]) {
|
||||
// NOTE: The following static assertion is just nice-to-have and not
|
||||
// necessary for soundness. That's because triviality is always declared by
|
||||
// the user in the form of an unsafe impl of cxx::ExternType:
|
||||
@ -402,14 +402,16 @@ fn check_trivial_extern_type(out: &mut OutFile, id: &Pair, reason: &TrivialReaso
|
||||
|
||||
let id = id.to_fully_qualified();
|
||||
out.builtin.relocatable = true;
|
||||
writeln!(out, "static_assert(");
|
||||
writeln!(out, " ::rust::IsRelocatable<{}>::value,", id);
|
||||
writeln!(
|
||||
out,
|
||||
" \"type {} is not move constructible and trivially destructible in C++ yet is used as a trivial type in Rust ({})\");",
|
||||
id,
|
||||
reason
|
||||
);
|
||||
for reason in reasons {
|
||||
writeln!(out, "static_assert(");
|
||||
writeln!(out, " ::rust::IsRelocatable<{}>::value,", id);
|
||||
writeln!(
|
||||
out,
|
||||
" \"type {} is not move constructible and trivially destructible in C++ yet is used as a trivial type in Rust ({})\");",
|
||||
id,
|
||||
reason
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
|
||||
|
@ -324,13 +324,15 @@ fn check_api_type(cx: &mut Check, ety: &ExternType) {
|
||||
cx.error(span, "extern type bounds are not implemented yet");
|
||||
}
|
||||
|
||||
if let Some(reason) = cx.types.required_trivial.get(&ety.name.rust) {
|
||||
let what = reason.describe_in_context(&ety);
|
||||
let msg = format!(
|
||||
"needs a cxx::ExternType impl in order to be used as {}",
|
||||
what,
|
||||
);
|
||||
cx.error(ety, msg);
|
||||
if let Some(reasons) = cx.types.required_trivial.get(&ety.name.rust) {
|
||||
for reason in reasons {
|
||||
let what = reason.describe_in_context(&ety);
|
||||
let msg = format!(
|
||||
"needs a cxx::ExternType impl in order to be used as {}",
|
||||
what,
|
||||
);
|
||||
cx.error(ety, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ pub struct Types<'a> {
|
||||
pub rust: Set<&'a Ident>,
|
||||
pub aliases: Map<&'a Ident, &'a TypeAlias>,
|
||||
pub untrusted: Map<&'a Ident, &'a ExternType>,
|
||||
pub required_trivial: Map<&'a Ident, TrivialReason<'a>>,
|
||||
pub required_trivial: Map<&'a Ident, Vec<TrivialReason<'a>>>,
|
||||
pub explicit_impls: Set<&'a Impl>,
|
||||
pub resolutions: Map<&'a RustName, &'a Pair>,
|
||||
pub struct_improper_ctypes: UnorderedSet<&'a Ident>,
|
||||
@ -169,14 +169,17 @@ impl<'a> Types<'a> {
|
||||
// we check that this is permissible. We do this _after_ scanning all
|
||||
// the APIs above, in case some function or struct references a type
|
||||
// which is declared subsequently.
|
||||
let mut required_trivial = Map::new();
|
||||
let mut required_trivial: Map<_, Vec<_>> = Map::new();
|
||||
|
||||
let mut insist_extern_types_are_trivial = |ident: &'a RustName, reason| {
|
||||
if cxx.contains(&ident.rust)
|
||||
&& !structs.contains_key(&ident.rust)
|
||||
&& !enums.contains_key(&ident.rust)
|
||||
{
|
||||
required_trivial.entry(&ident.rust).or_insert(reason);
|
||||
required_trivial
|
||||
.entry(&ident.rust)
|
||||
.or_default()
|
||||
.push(reason);
|
||||
}
|
||||
};
|
||||
for api in apis {
|
||||
|
@ -22,6 +22,18 @@ error: needs a cxx::ExternType impl in order to be used as a field of `S`
|
||||
10 | type C;
|
||||
| ^^^^^^
|
||||
|
||||
error: needs a cxx::ExternType impl in order to be used as an argument of `f`
|
||||
--> $DIR/by_value_not_supported.rs:10:9
|
||||
|
|
||||
10 | type C;
|
||||
| ^^^^^^
|
||||
|
||||
error: needs a cxx::ExternType impl in order to be used as a return value of `f`
|
||||
--> $DIR/by_value_not_supported.rs:10:9
|
||||
|
|
||||
10 | type C;
|
||||
| ^^^^^^
|
||||
|
||||
error: passing opaque C++ type by value is not supported
|
||||
--> $DIR/by_value_not_supported.rs:16:14
|
||||
|
|
||||
|
@ -1,16 +1,16 @@
|
||||
error: mutable reference to C++ type requires a pin -- use Pin<&mut Opaque>
|
||||
error: mutable reference to C++ type requires a pin -- use Pin<&mut Opaque> or declare the type Trivial in a cxx::ExternType impl
|
||||
--> $DIR/pin_mut_opaque.rs:5:19
|
||||
|
|
||||
5 | fn f(arg: &mut Opaque);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: mutable reference to C++ type requires a pin -- use Pin<&mut CxxString>
|
||||
error: mutable reference to C++ type requires a pin -- use Pin<&mut CxxString> or declare the type Trivial in a cxx::ExternType impl
|
||||
--> $DIR/pin_mut_opaque.rs:8:17
|
||||
|
|
||||
8 | fn s(s: &mut CxxString);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: mutable reference to C++ type requires a pin -- use Pin<&mut CxxVector<...>>
|
||||
error: mutable reference to C++ type requires a pin -- use Pin<&mut CxxVector<...>> or declare the type Trivial in a cxx::ExternType impl
|
||||
--> $DIR/pin_mut_opaque.rs:9:17
|
||||
|
|
||||
9 | fn v(v: &mut CxxVector<u8>);
|
||||
@ -22,13 +22,25 @@ error: needs a cxx::ExternType impl in order to be used as a non-pinned mutable
|
||||
4 | type Opaque;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: mutable reference to C++ type requires a pin -- use `self: Pin<&mut Opaque>`
|
||||
error: needs a cxx::ExternType impl in order to be used as a non-pinned mutable reference argument of g
|
||||
--> $DIR/pin_mut_opaque.rs:4:9
|
||||
|
|
||||
4 | type Opaque;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: needs a cxx::ExternType impl in order to be used as a non-pinned mutable reference argument of h
|
||||
--> $DIR/pin_mut_opaque.rs:4:9
|
||||
|
|
||||
4 | type Opaque;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: mutable reference to opaque C++ type requires a pin -- use `self: Pin<&mut Opaque>` or declare the type Trivial in a cxx::ExternType impl
|
||||
--> $DIR/pin_mut_opaque.rs:6:14
|
||||
|
|
||||
6 | fn g(&mut self);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: mutable reference to C++ type requires a pin -- use `self: Pin<&mut Opaque>`
|
||||
error: mutable reference to opaque C++ type requires a pin -- use `self: Pin<&mut Opaque>` or declare the type Trivial in a cxx::ExternType impl
|
||||
--> $DIR/pin_mut_opaque.rs:7:20
|
||||
|
|
||||
7 | fn h(self: &mut Opaque);
|
||||
|
Loading…
Reference in New Issue
Block a user