bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Issue with specific reflect breaking after upgrading from 0.9-0.10

Open CoffeeVampir3 opened this issue 1 year ago • 3 comments

Bevy 0.10

0.10

What you did

Upgraded from bevy 0.9 -> 0.10

What went wrong

The following code has stopped compiling:

use bevy::{reflect::Reflect, utils::HashSet};

#[derive(Default, Clone, Reflect, serde::Serialize, serde::Deserialize)]
pub struct NetSet<T> where T: 'static + Send + Sync + Eq + Copy + core::hash::Hash {
    set: HashSet<T>
}

There's an error for the reflect derive,

Proc-macro derive produced unparseable tokens

and one for the HashSet

expected one of `(`, `+`, `,`, `::`, `<`, or `{`, found `HashSet`
unexpected token ...

Additional information

Full 0.9 version: https://github.com/CoffeeVampir3/rusty_cg/blob/main/src/structures/netset.rs

image image

Fully expanded proc macro:

// Recursive expansion of Reflect! macro
// ======================================

#[allow(unused_mut)]
impl <T>bevy::reflect::GetTypeRegistration for NetSet<T>where T:'static+Send+Sync+Eq+Copy+core::hash::Hash HashSet<T> :bevy::reflect::Reflect,{
  fn get_type_registration() -> bevy::reflect::TypeRegistration {
    let mut registration = bevy::reflect::TypeRegistration::of:: <NetSet<T> >();
    registration.insert:: <bevy::reflect::ReflectFromPtr>(bevy::reflect::FromType:: <NetSet<T> > ::from_type());
    let ignored_indices =  ::core::iter::IntoIterator::into_iter([]);
    registration.insert:: <bevy::reflect::serde::SerializationData>(bevy::reflect::serde::SerializationData::new(ignored_indices));
    registration
  }

  }
impl <T>bevy::reflect::Typed for NetSet<T>where T:'static+Send+Sync+Eq+Copy+core::hash::Hash HashSet<T> :bevy::reflect::Reflect,{
  fn type_info() ->  &'static bevy::reflect::TypeInfo {
    static CELL:bevy::reflect::utility::GenericTypeInfoCell = bevy::reflect::utility::GenericTypeInfoCell::new();
    CELL.get_or_insert:: <Self,_>(||{
      let fields = [bevy::reflect::NamedField::new:: <HashSet<T> >("set"),];
      let info = bevy::reflect::StructInfo::new:: <Self>("NetSet", &fields);
      bevy::reflect::TypeInfo::Struct(info)
    })
  }

  }
impl <T>bevy::reflect::Struct for NetSet<T>where T:'static+Send+Sync+Eq+Copy+core::hash::Hash HashSet<T> :bevy::reflect::Reflect,{
  fn field(&self,name: &str) ->  ::core::option::Option< &dyn bevy::reflect::Reflect>{
    match name {
      "set" =>  ::core::option::Option::Some(&self.set),
      _ =>  ::core::option::Option::None,
    
      }
  }
  fn field_mut(&mut self,name: &str) ->  ::core::option::Option< &mut dyn bevy::reflect::Reflect>{
    match name {
      "set" =>  ::core::option::Option::Some(&mut self.set),
      _ =>  ::core::option::Option::None,
    
      }
  }
  fn field_at(&self,index:usize) ->  ::core::option::Option< &dyn bevy::reflect::Reflect>{
    match index {
      0usize =>  ::core::option::Option::Some(&self.set),
      _ =>  ::core::option::Option::None,
    
      }
  }
  fn field_at_mut(&mut self,index:usize) ->  ::core::option::Option< &mut dyn bevy::reflect::Reflect>{
    match index {
      0usize =>  ::core::option::Option::Some(&mut self.set),
      _ =>  ::core::option::Option::None,
    
      }
  }
  fn name_at(&self,index:usize) ->  ::core::option::Option< &str>{
    match index {
      0usize =>  ::core::option::Option::Some("set"),
      _ =>  ::core::option::Option::None,
    
      }
  }
  fn field_len(&self) -> usize {
    1usize
  }
  fn iter_fields(&self) -> bevy::reflect::FieldIter {
    bevy::reflect::FieldIter::new(self)
  }
  fn clone_dynamic(&self) -> bevy::reflect::DynamicStruct {
    let mut dynamic:bevy::reflect::DynamicStruct =  ::core::default::Default::default();
    dynamic.set_name(::std::string::ToString::to_string(bevy::reflect::Reflect::type_name(self)));
    dynamic.insert_boxed("set",bevy::reflect::Reflect::clone_value(&self.set));
    dynamic
  }

  }
impl <T>bevy::reflect::Reflect for NetSet<T>where T:'static+Send+Sync+Eq+Copy+core::hash::Hash HashSet<T> :bevy::reflect::Reflect,{
  #[inline]
  fn type_name(&self) ->  &str {
    ::core::any::type_name:: <Self>()
  }
  #[inline]
  fn get_type_info(&self) ->  &'static bevy::reflect::TypeInfo {
    <Self as bevy::reflect::Typed> ::type_info()
  }
  #[inline]
  fn into_any(self: ::std::boxed::Box<Self>) ->  ::std::boxed::Box<dyn ::core::any::Any>{
    self
  }
  #[inline]
  fn as_any(&self) ->  &dyn ::core::any::Any {
    self
  }
  #[inline]
  fn as_any_mut(&mut self) ->  &mut dyn ::core::any::Any {
    self
  }
  #[inline]
  fn into_reflect(self: ::std::boxed::Box<Self>) ->  ::std::boxed::Box<dyn bevy::reflect::Reflect>{
    self
  }
  #[inline]
  fn as_reflect(&self) ->  &dyn bevy::reflect::Reflect {
    self
  }
  #[inline]
  fn as_reflect_mut(&mut self) ->  &mut dyn bevy::reflect::Reflect {
    self
  }
  #[inline]
  fn clone_value(&self) ->  ::std::boxed::Box<dyn bevy::reflect::Reflect>{
    ::std::boxed::Box::new(bevy::reflect::Struct::clone_dynamic(self))
  }
  #[inline]
  fn set(&mut self,value: ::std::boxed::Box<dyn bevy::reflect::Reflect>) ->  ::core::result::Result<(), ::std::boxed::Box<dyn bevy::reflect::Reflect>>{
    *self =  <dyn bevy::reflect::Reflect> ::take(value)? ;
    ::core::result::Result::Ok(())
  }
  #[inline]
  fn apply(&mut self,value: &dyn bevy::reflect::Reflect){
    if let bevy::reflect::ReflectRef::Struct(struct_value) = bevy::reflect::Reflect::reflect_ref(value){
      for(i,value)in::core::iter::Iterator::enumerate(bevy::reflect::Struct::iter_fields(struct_value)){
        let name = bevy::reflect::Struct::name_at(struct_value,i).unwrap();
        bevy::reflect::Struct::field_mut(self,name).map(|v|v.apply(value));
      }
    }else {
      panic!("Attempted to apply non-struct type to struct type.");
    }
  }
  fn reflect_ref(&self) -> bevy::reflect::ReflectRef {
    bevy::reflect::ReflectRef::Struct(self)
  }
  fn reflect_mut(&mut self) -> bevy::reflect::ReflectMut {
    bevy::reflect::ReflectMut::Struct(self)
  }
  fn reflect_owned(self: ::std::boxed::Box<Self>) -> bevy::reflect::ReflectOwned {
    bevy::reflect::ReflectOwned::Struct(self)
  }
  fn reflect_partial_eq(&self,value: &dyn bevy::reflect::Reflect) ->  ::core::option::Option<bool>{
    bevy::reflect::struct_partial_eq(self,value)
  }

  }

CoffeeVampir3 avatar Mar 09 '23 00:03 CoffeeVampir3

After expanding the macro I think I've found the issue:

The emitted version of the macro (one example)

#[allow(unused_mut)]
impl <T>bevy::reflect::GetTypeRegistration for NetSet<T>where T:'static+Send+Sync+Eq+Copy+core::hash::Hash HashSet<T> :bevy::reflect::Reflect,{
  fn get_type_registration() -> bevy::reflect::TypeRegistration {
    let mut registration = bevy::reflect::TypeRegistration::of:: <NetSet<T> >();
    registration.insert:: <bevy::reflect::ReflectFromPtr>(bevy::reflect::FromType:: <NetSet<T> > ::from_type());
    let ignored_indices =  ::core::iter::IntoIterator::into_iter([]);
    registration.insert:: <bevy::reflect::serde::SerializationData>(bevy::reflect::serde::SerializationData::new(ignored_indices));
    registration
  }

there's a missing comma on the reflect emit it appears. gunna dig into the reflect proc macro and see if I can get it to work.

CoffeeVampir3 avatar Mar 09 '23 00:03 CoffeeVampir3

Closing in favor of #8014

MrGVSV avatar Mar 10 '23 06:03 MrGVSV

Lol closed the issue instead of the PR 🤦‍♂️

MrGVSV avatar Mar 10 '23 06:03 MrGVSV