Skip to content

Commit 633c8c7

Browse files
bors[bot]Bromeon
andauthored
Merge #777
777: Properties are now registered in order of declaration r=Bromeon a=Bromeon Older change, not yet merged. Properties exported via `#[property]` appear in arbitrary order in the editor, and the order can change on each rustc compilation. This is due to the inner workings of `HashMap`, which orders its element non-deterministically as a [security feature](https://doc.rust-lang.org/std/collections/struct.HashMap.html). This code: ```rs #[derive(gd::NativeClass)] #[no_constructor] pub struct GodotGraph { #[property] first: i32, #[property] second: bool, #[property] third: Color, #[property] fourth: Vector2, } ``` can lead to any of these variants: ![one](https://user-images.githubusercontent.com/708488/131356360-b6d0fec0-2b51-41b6-aabc-178c4e73aacd.png) ![two](https://user-images.githubusercontent.com/708488/131356850-e53a82ee-006c-4bcf-85fc-1125009f081e.png) ![three](https://user-images.githubusercontent.com/708488/131356416-f13e677a-2f35-4702-9100-e262c34650f0.png) This PR makes the order follow the declaration order, by using `Vec` instead of `HashMap`. bors try Co-authored-by: Jan Haller <bromeon@gmail.com>
2 parents 21373fc + a048fc4 commit 633c8c7

File tree

1 file changed

+3
-4
lines changed

1 file changed

+3
-4
lines changed

gdnative-derive/src/native_script.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use proc_macro::TokenStream;
22
use proc_macro2::TokenStream as TokenStream2;
33

4-
use std::collections::HashMap;
54
use syn::spanned::Spanned;
65
use syn::{Data, DeriveInput, Fields, Ident, Meta, MetaList, NestedMeta, Path, Stmt, Type};
76

@@ -13,7 +12,7 @@ pub(crate) struct DeriveData {
1312
pub(crate) base: Type,
1413
pub(crate) register_callback: Option<Path>,
1514
pub(crate) user_data: Type,
16-
pub(crate) properties: HashMap<Ident, PropertyAttrArgs>,
15+
pub(crate) properties: Vec<(Ident, PropertyAttrArgs)>,
1716
pub(crate) no_constructor: bool,
1817
}
1918

@@ -185,7 +184,7 @@ fn parse_derive_input(input: &DeriveInput) -> Result<DeriveData, syn::Error> {
185184
};
186185

187186
// Find all fields with a `#[property]` attribute
188-
let mut properties = HashMap::new();
187+
let mut properties = Vec::new();
189188

190189
if let Fields::Named(names) = &struct_data.fields {
191190
for field in &names.named {
@@ -229,7 +228,7 @@ fn parse_derive_input(input: &DeriveInput) -> Result<DeriveData, syn::Error> {
229228
.ident
230229
.clone()
231230
.ok_or_else(|| syn::Error::new(field.ident.span(), "Fields should be named"))?;
232-
properties.insert(ident, builder.done());
231+
properties.push((ident, builder.done()));
233232
}
234233
}
235234
};

0 commit comments

Comments
 (0)