Skip to content

Commit e7aef34

Browse files
authored
Fix to make incorrect return type into error (#169)
This commit introduces a compile time error for incorrect return types. For example, the following will now fail to compile: ```rust #[swift_bridge::bridge] mod ffi { extern "Rust" { fn get_reference() -> SomeType; } } fn get_reference() -> &'static SomeType { &SomeType } ``` Before this commit the above example would compile and calling `get_reference` would cause undefined behavior.
1 parent e5a0c89 commit e7aef34

10 files changed

+98
-13
lines changed

crates/swift-bridge-ir/src/bridged_type/bridged_opaque_type.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ impl BridgeableType for OpaqueForeignType {
211211
.generics
212212
.angle_bracketed_concrete_generics_tokens(types);
213213
quote! {
214-
Box::into_raw(Box::new(#expression)) as *mut super::#ty_name #generics
214+
Box::into_raw(Box::new({
215+
let val: super::#ty_name #generics = #expression;
216+
val
217+
})) as *mut super::#ty_name #generics
215218
}
216219
}
217220
} else {

crates/swift-bridge-ir/src/codegen/codegen_tests/async_function_codegen_tests.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -564,13 +564,19 @@ mod extern_rust_async_function_returns_result_opaque {
564564
Ok(ok) => {
565565
swift_bridge::result::ResultPtrAndPtr {
566566
is_ok: true,
567-
ok_or_err: Box::into_raw(Box::new(ok)) as *mut super::OkType as *mut std::ffi::c_void
567+
ok_or_err: Box::into_raw(Box::new({
568+
let val: super::OkType = ok;
569+
val
570+
})) as *mut super::OkType as *mut std::ffi::c_void
568571
}
569572
}
570573
Err(err) => {
571574
swift_bridge::result::ResultPtrAndPtr {
572575
is_ok: false,
573-
ok_or_err: Box::into_raw(Box::new(err)) as *mut super::ErrorType as *mut std::ffi::c_void
576+
ok_or_err: Box::into_raw(Box::new({
577+
let val: super::ErrorType = err;
578+
val
579+
})) as *mut super::ErrorType as *mut std::ffi::c_void
574580
}
575581
}
576582
};

crates/swift-bridge-ir/src/codegen/codegen_tests/boxed_fnonce_codegen_tests.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,10 @@ mod test_swift_takes_callback_return_opaque_rust_type {
411411
quote! {
412412
#[export_name = "__swift_bridge__$some_function$param0"]
413413
pub extern "C" fn some_function_param0(some_function_callback: *mut Box<dyn FnOnce() -> super::ARustType>) -> *mut super::ARustType {
414-
Box::into_raw(Box::new(unsafe { Box::from_raw(some_function_callback)() })) as *mut super::ARustType
414+
Box::into_raw(Box::new({
415+
let val: super::ARustType = unsafe { Box::from_raw(some_function_callback)() };
416+
val
417+
})) as *mut super::ARustType
415418
}
416419

417420
#[export_name = "__swift_bridge__$some_function$_free$param0"]

crates/swift-bridge-ir/src/codegen/codegen_tests/extern_rust_function_opaque_rust_type_return_codegen_tests.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ mod test_extern_rust_function_owned_opaque_rust_type_return {
2323
ExpectedRustTokens::Contains(quote! {
2424
#[export_name = "__swift_bridge__$some_function"]
2525
pub extern "C" fn __swift_bridge__some_function () -> *mut super::SomeType {
26-
Box::into_raw(Box::new(super::some_function())) as *mut super::SomeType
26+
Box::into_raw(Box::new({
27+
let val: super::SomeType = super::some_function();
28+
val
29+
})) as *mut super::SomeType
2730
}
2831
})
2932
}

crates/swift-bridge-ir/src/codegen/codegen_tests/generic_opaque_rust_type_codegen_tests.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,10 @@ mod generic_opaque_rust_type_return {
218218
ExpectedRustTokens::Contains(quote! {
219219
#[export_name = "__swift_bridge__$some_function"]
220220
pub extern "C" fn __swift_bridge__some_function () -> *mut super::SomeType<u32> {
221-
Box::into_raw(Box::new(super::some_function())) as *mut super::SomeType<u32>
221+
Box::into_raw(Box::new({
222+
let val: super::SomeType<u32> = super::some_function();
223+
val
224+
})) as *mut super::SomeType<u32>
222225
}
223226
})
224227
}

crates/swift-bridge-ir/src/codegen/codegen_tests/opaque_rust_type_codegen_tests.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ extension HashableTypeRef: Hashable{
126126
fn expected_c_header() -> ExpectedCHeader {
127127
ExpectedCHeader::ContainsManyAfterTrim(vec![
128128
r#"
129-
uint64_t __swift_bridge__$HashableType$_hash(void* self);
129+
uint64_t __swift_bridge__$HashableType$_hash(void* self);
130130
"#,
131131
r#"
132132
"#,
@@ -416,7 +416,10 @@ mod extern_swift_freestanding_fn_with_owned_opaque_rust_type_arg {
416416
fn expected_rust_tokens() -> ExpectedRustTokens {
417417
ExpectedRustTokens::Contains(quote! {
418418
pub fn some_function (arg: super::MyType) {
419-
unsafe { __swift_bridge__some_function( Box::into_raw(Box::new(arg)) as *mut super::MyType ) }
419+
unsafe { __swift_bridge__some_function( Box::into_raw(Box::new({
420+
let val: super::MyType = arg;
421+
val
422+
})) as *mut super::MyType ) }
420423
}
421424

422425
extern "C" {

crates/swift-bridge-ir/src/codegen/codegen_tests/result_codegen_tests.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,19 @@ mod extern_rust_fn_return_result_opaque_rust {
151151
Ok(ok) => {
152152
swift_bridge::result::ResultPtrAndPtr {
153153
is_ok: true,
154-
ok_or_err: Box::into_raw(Box::new(ok)) as *mut super::SomeType as *mut std::ffi::c_void
154+
ok_or_err: Box::into_raw(Box::new({
155+
let val: super::SomeType = ok;
156+
val
157+
})) as *mut super::SomeType as *mut std::ffi::c_void
155158
}
156159
}
157160
Err(err) => {
158161
swift_bridge::result::ResultPtrAndPtr {
159162
is_ok: false,
160-
ok_or_err: Box::into_raw(Box::new(err)) as *mut super::SomeType as *mut std::ffi::c_void
163+
ok_or_err: Box::into_raw(Box::new({
164+
let val: super::SomeType = err;
165+
val
166+
})) as *mut super::SomeType as *mut std::ffi::c_void
161167
}
162168
}
163169
}

crates/swift-bridge-ir/src/codegen/generate_rust_tokens.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,10 @@ mod tests {
507507
let expected_func = quote! {
508508
#[export_name = "__swift_bridge__$some_function"]
509509
pub extern "C" fn __swift_bridge__some_function () -> *mut super::Foo {
510-
Box::into_raw(Box::new(super::another_function())) as *mut super::Foo
510+
Box::into_raw(Box::new({
511+
let val: super::Foo = super::another_function();
512+
val
513+
})) as *mut super::Foo
511514
}
512515
};
513516

@@ -531,7 +534,10 @@ mod tests {
531534
let expected_func = quote! {
532535
#[export_name = "__swift_bridge__$some_function"]
533536
pub extern "C" fn __swift_bridge__some_function () -> *mut super::Foo {
534-
Box::into_raw(Box::new(super::some_function().into())) as *mut super::Foo
537+
Box::into_raw(Box::new({
538+
let val: super::Foo = super::some_function().into();
539+
val
540+
})) as *mut super::Foo
535541
}
536542
};
537543

@@ -630,7 +636,10 @@ mod tests {
630636
let expected = quote! {
631637
#[export_name = "__swift_bridge__$SomeType$new"]
632638
pub extern "C" fn __swift_bridge__SomeType_new () -> *mut super::SomeType {
633-
Box::into_raw(Box::new(super::SomeType::new())) as *mut super::SomeType
639+
Box::into_raw(Box::new({
640+
let val: super::SomeType = super::SomeType::new();
641+
val
642+
})) as *mut super::SomeType
634643
}
635644
};
636645

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//! # To Run
2+
//! cargo test -p swift-bridge-macro -- ui trybuild=incorrect-return-type.rs
3+
4+
pub struct SomeType;
5+
6+
#[swift_bridge::bridge]
7+
mod ffi {
8+
extern "Rust" {
9+
type SomeType;
10+
11+
#[swift_bridge(rust_name = "some_function")]
12+
fn fn1() -> SomeType;
13+
#[swift_bridge(rust_name = "another_function")]
14+
fn fn2() -> SomeType;
15+
}
16+
}
17+
18+
fn some_function() -> &'static SomeType {
19+
&SomeType
20+
}
21+
22+
fn another_function() -> Option<SomeType> {
23+
None
24+
}
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0308]: mismatched types
2+
--> tests/ui/incorrect-return-type.rs:6:1
3+
|
4+
6 | #[swift_bridge::bridge]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| expected struct `SomeType`, found `&SomeType`
8+
| expected due to this
9+
|
10+
= note: this error originates in the attribute macro `swift_bridge::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)
11+
12+
error[E0308]: mismatched types
13+
--> tests/ui/incorrect-return-type.rs:6:1
14+
|
15+
6 | #[swift_bridge::bridge]
16+
| ^^^^^^^^^^^^^^^^^^^^^^^
17+
| |
18+
| expected struct `SomeType`, found enum `Option`
19+
| expected due to this
20+
|
21+
= note: expected struct `SomeType`
22+
found enum `Option<SomeType>`
23+
= note: this error originates in the attribute macro `swift_bridge::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)