Skip to content

Commit 174ed79

Browse files
committed
Make PtrLen a generic pointer (only <const void> and <void> are used currently, though)
1 parent d26a1be commit 174ed79

File tree

4 files changed

+38
-19
lines changed

4 files changed

+38
-19
lines changed

gen/src/builtin.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ pub(super) fn write(out: &mut OutFile) {
148148

149149
if builtin.ptr_len {
150150
out.begin_block(Block::Namespace("repr"));
151+
writeln!(out, "template <typename T>");
151152
writeln!(out, "struct PtrLen final {{");
152-
writeln!(out, " const void *ptr;");
153+
writeln!(out, " T *ptr;");
153154
writeln!(out, " size_t len;");
154155
writeln!(out, "}};");
155156
out.end_block(Block::Namespace("repr"));
@@ -163,7 +164,7 @@ pub(super) fn write(out: &mut OutFile) {
163164
if builtin.rust_str_new_unchecked {
164165
writeln!(
165166
out,
166-
" static Str new_unchecked(repr::PtrLen repr) noexcept {{",
167+
" static Str new_unchecked(repr::PtrLen<const void> repr) noexcept {{",
167168
);
168169
writeln!(out, " Str str;");
169170
writeln!(out, " str.ptr = static_cast<const char *>(repr.ptr);");
@@ -172,8 +173,8 @@ pub(super) fn write(out: &mut OutFile) {
172173
writeln!(out, " }}");
173174
}
174175
if builtin.rust_str_repr {
175-
writeln!(out, " static repr::PtrLen repr(Str str) noexcept {{");
176-
writeln!(out, " return repr::PtrLen{{str.ptr, str.len}};");
176+
writeln!(out, " static repr::PtrLen<const void> repr(Str str) noexcept {{");
177+
writeln!(out, " return repr::PtrLen<const void>{{str.ptr, str.len}};");
177178
writeln!(out, " }}");
178179
}
179180
writeln!(out, "}};");
@@ -187,7 +188,7 @@ pub(super) fn write(out: &mut OutFile) {
187188
if builtin.rust_slice_new {
188189
writeln!(
189190
out,
190-
" static Slice<T> slice(repr::PtrLen repr) noexcept {{",
191+
" static Slice<T> slice(repr::PtrLen<const void> repr) noexcept {{",
191192
);
192193
writeln!(
193194
out,
@@ -196,11 +197,20 @@ pub(super) fn write(out: &mut OutFile) {
196197
writeln!(out, " }}");
197198
}
198199
if builtin.rust_slice_repr {
200+
writeln!(out, " template <typename U = T>");
201+
writeln!(
202+
out,
203+
" static typename std::enable_if<std::is_const<U>::value, repr::PtrLen<const void>>::type repr(Slice<T> slice) noexcept {{",
204+
);
205+
writeln!(out, " return repr::PtrLen<const void>{{slice.ptr, slice.len}};");
206+
writeln!(out, " }}");
207+
208+
writeln!(out, " template <typename U = T>");
199209
writeln!(
200210
out,
201-
" static repr::PtrLen repr(Slice<T> slice) noexcept {{",
211+
" static typename std::enable_if<!std::is_const<U>::value, repr::PtrLen<void>>::type repr(Slice<T> slice) noexcept {{",
202212
);
203-
writeln!(out, " return repr::PtrLen{{slice.ptr, slice.len}};");
213+
writeln!(out, " return repr::PtrLen<void>{{slice.ptr, slice.len}};");
204214
writeln!(out, " }}");
205215
}
206216
writeln!(out, "}};");
@@ -211,7 +221,7 @@ pub(super) fn write(out: &mut OutFile) {
211221
writeln!(out, "template <>");
212222
writeln!(out, "class impl<Error> final {{");
213223
writeln!(out, "public:");
214-
writeln!(out, " static Error error(repr::PtrLen repr) noexcept {{");
224+
writeln!(out, " static Error error(repr::PtrLen<const void> repr) noexcept {{");
215225
writeln!(out, " Error error;");
216226
writeln!(out, " error.msg = static_cast<const char *>(repr.ptr);");
217227
writeln!(out, " error.len = repr.len;");

gen/src/write.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
343343
}
344344
if efn.throws {
345345
out.builtin.ptr_len = true;
346-
write!(out, "::rust::repr::PtrLen ");
346+
write!(out, "::rust::repr::PtrLen<const void> ");
347347
} else {
348348
write_extern_return_type_space(out, &efn.ret);
349349
}
@@ -417,7 +417,7 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
417417
if efn.throws {
418418
out.builtin.ptr_len = true;
419419
out.builtin.trycatch = true;
420-
writeln!(out, "::rust::repr::PtrLen throw$;");
420+
writeln!(out, "::rust::repr::PtrLen<const void> throw$;");
421421
writeln!(out, " ::rust::behavior::trycatch(");
422422
writeln!(out, " [&] {{");
423423
write!(out, " ");
@@ -566,7 +566,7 @@ fn write_rust_function_decl_impl(
566566
out.next_section();
567567
if sig.throws {
568568
out.builtin.ptr_len = true;
569-
write!(out, "::rust::repr::PtrLen ");
569+
write!(out, "::rust::repr::PtrLen<const void> ");
570570
} else {
571571
write_extern_return_type_space(out, &sig.ret);
572572
}
@@ -712,7 +712,7 @@ fn write_rust_function_shim_impl(
712712
}
713713
if sig.throws {
714714
out.builtin.ptr_len = true;
715-
write!(out, "::rust::repr::PtrLen error$ = ");
715+
write!(out, "::rust::repr::PtrLen<const void> error$ = ");
716716
}
717717
write!(out, "{}(", invoke);
718718
let mut needs_comma = false;
@@ -838,9 +838,14 @@ fn write_extern_return_type_space(out: &mut OutFile, ty: &Option<Type>) {
838838
write_type(out, &ty.inner);
839839
write!(out, " *");
840840
}
841-
Some(Type::Str(_)) | Some(Type::SliceRefU8(_)) => {
841+
Some(Type::Str(ty)) | Some(Type::SliceRefU8(ty)) => {
842842
out.builtin.ptr_len = true;
843-
write!(out, "::rust::repr::PtrLen ");
843+
844+
if ty.mutable {
845+
write!(out, "::rust::repr::PtrLen<void> ");
846+
} else {
847+
write!(out, "::rust::repr::PtrLen<const void> ");
848+
}
844849
}
845850
Some(ty) if out.types.needs_indirect_abi(ty) => write!(out, "void "),
846851
_ => write_return_type(out, ty),
@@ -853,9 +858,13 @@ fn write_extern_arg(out: &mut OutFile, arg: &Var) {
853858
write_type_space(out, &ty.inner);
854859
write!(out, "*");
855860
}
856-
Type::Str(_) | Type::SliceRefU8(_) => {
861+
Type::Str(ty) | Type::SliceRefU8(ty) => {
857862
out.builtin.ptr_len = true;
858-
write!(out, "::rust::repr::PtrLen ");
863+
if ty.mutable {
864+
write!(out, "::rust::repr::PtrLen<void> ");
865+
} else {
866+
write!(out, "::rust::repr::PtrLen<const void> ");
867+
}
859868
}
860869
_ => write_type_space(out, &arg.ty),
861870
}

tests/cxx_gen.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn test_extern_c_function() {
2020
let output = str::from_utf8(&generated.implementation).unwrap();
2121
// To avoid continual breakage we won't test every byte.
2222
// Let's look for the major features.
23-
assert!(output.contains("void cxxbridge1$do_cpp_thing(::rust::repr::PtrLen foo)"));
23+
assert!(output.contains("void cxxbridge1$do_cpp_thing(::rust::repr::PtrLen<const void> foo)"));
2424
}
2525

2626
#[test]
@@ -30,5 +30,5 @@ fn test_impl_annotation() {
3030
let source = BRIDGE0.parse().unwrap();
3131
let generated = generate_header_and_cc(source, &opt).unwrap();
3232
let output = str::from_utf8(&generated.implementation).unwrap();
33-
assert!(output.contains("ANNOTATION void cxxbridge1$do_cpp_thing(::rust::repr::PtrLen foo)"));
33+
assert!(output.contains("ANNOTATION void cxxbridge1$do_cpp_thing(::rust::repr::PtrLen<const void> foo)"));
3434
}

tests/ffi/tests.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ rust::Box<R> c_try_return_box();
150150
const rust::String &c_try_return_ref(const rust::String &);
151151
rust::Str c_try_return_str(rust::Str);
152152
rust::Slice<const uint8_t> c_try_return_sliceu8(rust::Slice<const uint8_t>);
153-
rust::Slice<uint8_t> c_try_return_sliceu8(rust::Slice<uint8_t>);
153+
rust::Slice<uint8_t> c_try_return_mutsliceu8(rust::Slice<uint8_t>);
154154
rust::String c_try_return_rust_string();
155155
std::unique_ptr<std::string> c_try_return_unique_ptr_string();
156156
rust::Vec<uint8_t> c_try_return_rust_vec();

0 commit comments

Comments
 (0)