Skip to content

Commit fb0ba25

Browse files
committed
Improve error for shared alias receiver type plus tests
1 parent cb2e9e9 commit fb0ba25

File tree

7 files changed

+64
-2
lines changed

7 files changed

+64
-2
lines changed

syntax/check.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,20 @@ fn check_api_fn(cx: &mut Check, efn: &ExternFn) {
227227
mutability = mutability,
228228
);
229229
cx.error(span, msg);
230+
} else if cx.types.aliases.contains_key(&receiver.ty)
231+
&& !cx.types.cxx.contains(&receiver.ty)
232+
{
233+
// We cannot add class member functions to the type generated by the other bridge, plus
234+
// we can't tell whether the alias is for a struct or enum and only the former can have
235+
// member functions.
236+
cx.error(
237+
span,
238+
"shared type aliases cannot be used as a receiver type",
239+
)
230240
} else if !cx.types.structs.contains_key(&receiver.ty)
231241
&& !cx.types.cxx.contains(&receiver.ty)
232242
&& !cx.types.rust.contains(&receiver.ty)
233243
{
234-
// TODO: Add ui test for aliases being disallowed in receiver position since we can't
235-
// tell if it's a struct or enum, unique error message
236244
cx.error(span, "unrecognized receiver type");
237245
}
238246

tests/ffi/alias.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ pub mod ffi {
3030
fn alias_c_take_unique_ptr_vector_shared(v: UniquePtr<CxxVector<Shared>>);
3131
fn alias_c_take_rust_vec_shared(v: Vec<Shared>);
3232
fn alias_c_take_enum(e: Enum);
33+
34+
fn get3(self: &C) -> usize;
35+
fn set3(self: &mut C, n: usize) -> usize;
3336
}
3437

3538
extern "Rust" {

tests/ffi/tests.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ size_t C::get() const { return this->n; }
2020

2121
size_t C::get2() const { return this->n; }
2222

23+
size_t C::get3() const { return this->n; }
24+
2325
size_t C::set(size_t n) {
2426
this->n = n;
2527
return this->n;
@@ -30,6 +32,11 @@ size_t C::set2(size_t n) {
3032
return this->n;
3133
}
3234

35+
size_t C::set3(size_t n) {
36+
this->n = n;
37+
return this->n;
38+
}
39+
3340
size_t C::set_succeed(size_t n) { return this->set2(n); }
3441

3542
size_t C::get_fail() { throw std::runtime_error("unimplemented"); }

tests/ffi/tests.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class C {
1616
size_t set(size_t n);
1717
size_t get2() const;
1818
size_t set2(size_t n);
19+
size_t get3() const;
20+
size_t set3(size_t n);
1921
size_t set_succeed(size_t n);
2022
size_t get_fail();
2123
const std::vector<uint8_t> &get_v() const;

tests/test.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,16 @@ fn test_c_method_calls() {
234234
assert!(unique_ptr.get_fail().is_err());
235235
}
236236

237+
#[test]
238+
fn test_alias_c_method_calls() {
239+
let mut unique_ptr = alias::ffi::alias_c_return_unique_ptr();
240+
241+
let old_value = unique_ptr.get3();
242+
assert_eq!(2020, old_value);
243+
assert_eq!(2021, unique_ptr.set3(2021));
244+
assert_eq!(2021, unique_ptr.get3());
245+
}
246+
237247
#[test]
238248
fn test_enum_representations() {
239249
assert_eq!(0, ffi::Enum::AVal.repr);

tests/ui/alias_receiver_type.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#[cxx::bridge]
2+
mod here {
3+
struct Shared {
4+
z: usize,
5+
}
6+
7+
extern "C" {
8+
type C;
9+
}
10+
}
11+
12+
// Rustfmt mangles the extern type alias.
13+
// https://github.com/rust-lang/rustfmt/issues/4159
14+
// ...normally would add #[rustfmt::skip], but that seems to interfere with the error spans.
15+
#[cxx::bridge]
16+
mod there {
17+
type Shared = crate::here::Shared;
18+
19+
extern "C" {
20+
type C = crate::here::C;
21+
22+
fn good(self: &C);
23+
fn bad(self: &Shared);
24+
}
25+
}
26+
27+
fn main() {}

tests/ui/alias_receiver_type.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
error: shared type aliases cannot be used as a receiver type
2+
--> $DIR/alias_receiver_type.rs:23:22
3+
|
4+
23 | fn bad(self: &Shared);
5+
| ^^^^^^^

0 commit comments

Comments
 (0)