Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bevy_reflect: Reflect remote types #6042

Merged
merged 31 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
23b66db
Added reflect_remote macro
MrGVSV Sep 19, 2022
c8b3167
Added remote field attribute
MrGVSV Sep 20, 2022
0865c49
Add test for nested remote types
MrGVSV Sep 20, 2022
ae72190
Add remote FromReflect support
MrGVSV Sep 21, 2022
6004560
Change wording
MrGVSV Sep 21, 2022
5e20858
Add test for taking remote type
MrGVSV Sep 21, 2022
d4886d9
Alter Reflect::*_any methods to return remote type
MrGVSV Sep 21, 2022
c10e58f
Better safety documentation
MrGVSV Sep 21, 2022
5dd3b5b
Add nested generics to remote type test
MrGVSV Sep 21, 2022
da4edb6
Fix reflect_remote not working with generics
MrGVSV Dec 21, 2022
9ae61e1
Add compile fail tests for reflect_remote
MrGVSV Jan 3, 2023
77bc819
Added remote field assertions
MrGVSV Jan 3, 2023
58d1ba1
Test concrete remote generic
MrGVSV Jan 3, 2023
d1a6277
Improved remote reflect assertions
MrGVSV Mar 16, 2023
396290a
Add more compile-time assertions for remote types
MrGVSV Mar 17, 2023
e0c977a
Fix assertion type mismatch order
MrGVSV May 30, 2023
c932800
Add the ReflectRemote trait
MrGVSV May 30, 2023
7476757
Move transmutations into ReflectRemote
MrGVSV Jul 14, 2023
e0af6a2
Fix compile tests
MrGVSV Jul 31, 2023
7aba2a6
Use permalink
MrGVSV Jul 31, 2023
cf5d5f2
Update comment
MrGVSV Nov 3, 2023
4c6bad1
Fix compile fail tests
MrGVSV Mar 12, 2024
57ebad3
Remove outdated doc
MrGVSV Aug 12, 2024
9571607
Change remote field attribute to take type path directly
MrGVSV Aug 12, 2024
8e0a99d
Add clarifying comment for transmute_copy usage
MrGVSV Aug 12, 2024
924363f
Remove vis on generated remote type
MrGVSV Aug 12, 2024
f898f0b
Silence clippy::multiple_bound_locations warning
MrGVSV Aug 12, 2024
c1496d2
Undo vis removal for generated wrapper type
MrGVSV Aug 12, 2024
d17ea00
Add test for remote reflecting an actual external type
MrGVSV Aug 12, 2024
0103072
Add support for remote reflection of value types
MrGVSV Aug 12, 2024
d8f7d9b
Fix CI errors
MrGVSV Aug 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/bevy_reflect/compile_fail/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ harness = false
[[test]]
name = "func"
harness = false

[[test]]
name = "remote"
harness = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use bevy_reflect::Reflect;

mod external_crate {
pub struct TheirFoo {
pub value: u32,
}
}

#[repr(transparent)]
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct MyFoo(#[reflect(ignore)] pub external_crate::TheirFoo);

#[derive(Reflect)]
//~^ ERROR: the trait bound `MyFoo: ReflectRemote` is not satisfied
#[reflect(from_reflect = false)]
struct MyStruct {
// Reason: `MyFoo` does not implement `ReflectRemote` (from `#[reflect_remote]` attribute)
#[reflect(remote = MyFoo)]
//~^ ERROR: the trait bound `MyFoo: ReflectRemote` is not satisfied
foo: external_crate::TheirFoo,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//@check-pass
use bevy_reflect::{reflect_remote, Reflect};

mod external_crate {
pub struct TheirFoo {
pub value: u32,
}
}

#[reflect_remote(external_crate::TheirFoo)]
struct MyFoo {
pub value: u32,
}

#[derive(Reflect)]
struct MyStruct {
#[reflect(remote = MyFoo)]
foo: external_crate::TheirFoo,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
mod structs {
use bevy_reflect::reflect_remote;

mod external_crate {
pub struct TheirStruct {
pub value: u32,
}
}

#[reflect_remote(external_crate::TheirStruct)]
//~^ ERROR: `?` operator has incompatible types
struct MyStruct {
// Reason: Should be `u32`
pub value: bool,
//~^ ERROR: mismatched types
}
}

mod tuple_structs {
use bevy_reflect::reflect_remote;

mod external_crate {
pub struct TheirStruct(pub u32);
}

#[reflect_remote(external_crate::TheirStruct)]
//~^ ERROR: `?` operator has incompatible types
struct MyStruct(
// Reason: Should be `u32`
pub bool,
//~^ ERROR: mismatched types
);
}

mod enums {
use bevy_reflect::reflect_remote;

mod external_crate {
pub enum TheirStruct {
Unit,
Tuple(u32),
Struct { value: usize },
}
}

#[reflect_remote(external_crate::TheirStruct)]
//~^ ERROR: variant `enums::external_crate::TheirStruct::Unit` does not have a field named `0`
//~| ERROR: variant `enums::external_crate::TheirStruct::Unit` has no field named `0`
//~| ERROR: `?` operator has incompatible types
//~| ERROR: `?` operator has incompatible types
enum MyStruct {
// Reason: Should be unit variant
Unit(i32),
// Reason: Should be `u32`
Tuple(bool),
//~^ ERROR: mismatched types
// Reason: Should be `usize`
Struct { value: String },
//~^ ERROR: mismatched types
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//@check-pass

mod structs {
use bevy_reflect::reflect_remote;

mod external_crate {
pub struct TheirStruct {
pub value: u32,
}
}

#[reflect_remote(external_crate::TheirStruct)]
struct MyStruct {
pub value: u32,
}
}

mod tuple_structs {
use bevy_reflect::reflect_remote;

mod external_crate {
pub struct TheirStruct(pub u32);
}

#[reflect_remote(external_crate::TheirStruct)]
struct MyStruct(pub u32);
}

mod enums {
use bevy_reflect::reflect_remote;

mod external_crate {
pub enum TheirStruct {
Unit,
Tuple(u32),
Struct { value: usize },
}
}

#[reflect_remote(external_crate::TheirStruct)]
enum MyStruct {
Unit,
Tuple(u32),
Struct { value: usize },
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use bevy_reflect::{reflect_remote, std_traits::ReflectDefault};

mod external_crate {
#[derive(Debug, Default)]
pub struct TheirType {
pub value: String,
}
}

#[derive(Debug, Default)]
#[reflect_remote(external_crate::TheirType)]
#[reflect(Debug, Default)]
struct MyType {
pub value: String,
//~^ ERROR: no field `value` on type `&MyType`
//~| ERROR: struct `MyType` has no field named `value`
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@check-pass
use bevy_reflect::{reflect_remote, std_traits::ReflectDefault};

mod external_crate {
#[derive(Debug, Default)]
pub struct TheirType {
pub value: String,
}
}

#[reflect_remote(external_crate::TheirType)]
#[derive(Debug, Default)]
#[reflect(Debug, Default)]
struct MyType {
pub value: String,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
mod external_crate {
pub struct TheirOuter<T> {
pub inner: TheirInner<T>,
}
pub struct TheirInner<T>(pub T);
}

mod missing_attribute {
use bevy_reflect::{FromReflect, GetTypeRegistration, reflect_remote};

#[reflect_remote(super::external_crate::TheirOuter<T>)]
struct MyOuter<T: FromReflect + GetTypeRegistration> {
// Reason: Missing `#[reflect(remote = ...)]` attribute
pub inner: super::external_crate::TheirInner<T>,
}

#[reflect_remote(super::external_crate::TheirInner<T>)]
struct MyInner<T>(pub T);
}

mod incorrect_inner_type {
use bevy_reflect::{FromReflect, GetTypeRegistration, reflect_remote};

#[reflect_remote(super::external_crate::TheirOuter<T>)]
//~^ ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
//~| ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
//~| ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
//~| ERROR: `TheirInner<T>` can not be used as a dynamic type path
//~| ERROR: `?` operator has incompatible types
struct MyOuter<T: FromReflect + GetTypeRegistration> {
// Reason: Should not use `MyInner<T>` directly
pub inner: MyInner<T>,
//~^ ERROR: mismatched types
}

#[reflect_remote(super::external_crate::TheirInner<T>)]
struct MyInner<T>(pub T);
}

mod mismatched_remote_type {
use bevy_reflect::{FromReflect, GetTypeRegistration, reflect_remote};

#[reflect_remote(super::external_crate::TheirOuter<T>)]
//~^ ERROR: mismatched types
//~| ERROR: mismatched types
struct MyOuter<T: FromReflect + GetTypeRegistration> {
// Reason: Should be `MyInner<T>`
#[reflect(remote = MyOuter<T>)]
//~^ ERROR: mismatched types
pub inner: super::external_crate::TheirInner<T>,
}

#[reflect_remote(super::external_crate::TheirInner<T>)]
struct MyInner<T>(pub T);
}

mod mismatched_remote_generic {
use bevy_reflect::{FromReflect, GetTypeRegistration, reflect_remote};

#[reflect_remote(super::external_crate::TheirOuter<T>)]
//~^ ERROR: `?` operator has incompatible types
//~| ERROR: mismatched types
//~| ERROR: mismatched types
struct MyOuter<T: FromReflect + GetTypeRegistration> {
// Reason: `TheirOuter::inner` is not defined as `TheirInner<bool>`
#[reflect(remote = MyInner<bool>)]
pub inner: super::external_crate::TheirInner<bool>,
//~^ ERROR: mismatched types
}

#[reflect_remote(super::external_crate::TheirInner<T>)]
struct MyInner<T>(pub T);
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@check-pass
use bevy_reflect::{FromReflect, GetTypeRegistration, reflect_remote, Reflect, Typed};

mod external_crate {
pub struct TheirOuter<T> {
pub inner: TheirInner<T>,
}
pub struct TheirInner<T>(pub T);
}

#[reflect_remote(external_crate::TheirOuter<T>)]
struct MyOuter<T: FromReflect + Typed + GetTypeRegistration> {
#[reflect(remote = MyInner<T>)]
pub inner: external_crate::TheirInner<T>,
}

#[reflect_remote(external_crate::TheirInner<T>)]
struct MyInner<T: Reflect>(pub T);

fn main() {}
Loading