Skip to content

Commit 3701416

Browse files
committed
Improve hygien of generated code
Previous code would fail if one field was named 'index', because it was creating a variable with the same name, overwriting the function parameter
1 parent 3568010 commit 3701416

File tree

3 files changed

+80
-65
lines changed

3 files changed

+80
-65
lines changed

soa-derive-internal/src/slice.rs

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,18 @@ pub fn derive(input: &Input) -> TokenStream {
1717
let doc_url = format!("[`{0}`](struct.{0}.html)", input.name);
1818
let vec_doc_url = format!("[`{0}`](struct.{0}.html)", input.vec_name());
1919

20-
let fields_names = input.fields.iter()
21-
.map(|field| field.ident.clone().unwrap())
20+
let fields_names = &input.fields.iter()
21+
.map(|field| field.ident.as_ref().unwrap())
2222
.collect::<Vec<_>>();
23-
let fields_names_1 = &fields_names;
24-
let fields_names_2 = &fields_names;
2523
let first_field = &fields_names[0];
26-
let slice_names_1 = &input.fields.iter()
27-
.map(|field| field.ident.as_ref().unwrap().to_string())
28-
.map(|ident| Ident::new(&format!("{}_slice_1", ident), Span::call_site()))
24+
25+
let fields_names_hygienic_1 = input.fields.iter()
26+
.map(|field| field.ident.as_ref().unwrap())
27+
.map(|ident| Ident::new(&format!("___soa_derive_private_1_{}", ident), Span::call_site()))
2928
.collect::<Vec<_>>();
30-
let slice_names_2 = &input.fields.iter()
31-
.map(|field| field.ident.as_ref().unwrap().to_string())
32-
.map(|ident| Ident::new(&format!("{}_slice_2", ident), Span::call_site()))
29+
let fields_names_hygienic_2 = input.fields.iter()
30+
.map(|field| field.ident.as_ref().unwrap())
31+
.map(|ident| Ident::new(&format!("___soa_derive_private_2_{}", ident), Span::call_site()))
3332
.collect::<Vec<_>>();
3433

3534
let fields_types = &input.fields.iter()
@@ -52,7 +51,7 @@ pub fn derive(input: &Input) -> TokenStream {
5251
#visibility struct #slice_name<'a> {
5352
#(
5453
#[doc = #fields_doc]
55-
pub #fields_names_1: &'a [#fields_types],
54+
pub #fields_names: &'a [#fields_types],
5655
)*
5756
}
5857

@@ -64,7 +63,7 @@ pub fn derive(input: &Input) -> TokenStream {
6463
/// the length of all fields should be the same.
6564
pub fn len(&self) -> usize {
6665
let len = self.#first_field.len();
67-
#(debug_assert_eq!(self.#fields_names_1.len(), len);)*
66+
#(debug_assert_eq!(self.#fields_names.len(), len);)*
6867
len
6968
}
7069

@@ -74,7 +73,7 @@ pub fn derive(input: &Input) -> TokenStream {
7473
/// the length of all fields should be the same.
7574
pub fn is_empty(&self) -> bool {
7675
let empty = self.#first_field.is_empty();
77-
#(debug_assert_eq!(self.#fields_names_1.is_empty(), empty);)*
76+
#(debug_assert_eq!(self.#fields_names.is_empty(), empty);)*
7877
empty
7978
}
8079

@@ -86,9 +85,9 @@ pub fn derive(input: &Input) -> TokenStream {
8685
None
8786
} else {
8887
#(
89-
let #fields_names_1 = self.#fields_names_2.first().unwrap();
88+
let #fields_names_hygienic_1 = self.#fields_names.first().unwrap();
9089
)*
91-
Some(#ref_name{#(#fields_names_1: #fields_names_2),*})
90+
Some(#ref_name{#(#fields_names: #fields_names_hygienic_1),*})
9291
}
9392
}
9493

@@ -100,10 +99,10 @@ pub fn derive(input: &Input) -> TokenStream {
10099
None
101100
} else {
102101
#(
103-
let (#fields_names_1, #slice_names_1) = self.#fields_names_2.split_first().unwrap();
102+
let (#fields_names_hygienic_1, #fields_names_hygienic_2) = self.#fields_names.split_first().unwrap();
104103
)*
105-
let ref_ = #ref_name{#(#fields_names_1: #fields_names_2),*};
106-
let slice = #slice_name{#(#fields_names_1: #slice_names_1),*};
104+
let ref_ = #ref_name{#(#fields_names: #fields_names_hygienic_1),*};
105+
let slice = #slice_name{#(#fields_names: #fields_names_hygienic_2),*};
107106
Some((ref_, slice))
108107
}
109108
}
@@ -116,9 +115,9 @@ pub fn derive(input: &Input) -> TokenStream {
116115
None
117116
} else {
118117
#(
119-
let #fields_names_1 = self.#fields_names_2.last().unwrap();
118+
let #fields_names_hygienic_1 = self.#fields_names.last().unwrap();
120119
)*
121-
Some(#ref_name{#(#fields_names_1: #fields_names_2),*})
120+
Some(#ref_name{#(#fields_names: #fields_names_hygienic_1),*})
122121
}
123122
}
124123

@@ -130,10 +129,10 @@ pub fn derive(input: &Input) -> TokenStream {
130129
None
131130
} else {
132131
#(
133-
let (#fields_names_1, #slice_names_1) = self.#fields_names_2.split_last().unwrap();
132+
let (#fields_names_hygienic_1, #fields_names_hygienic_2) = self.#fields_names.split_last().unwrap();
134133
)*
135-
let ref_ = #ref_name{#(#fields_names_1: #fields_names_2),*};
136-
let slice = #slice_name{#(#fields_names_1: #slice_names_1),*};
134+
let ref_ = #ref_name{#(#fields_names: #fields_names_hygienic_1),*};
135+
let slice = #slice_name{#(#fields_names: #fields_names_hygienic_2),*};
137136
Some((ref_, slice))
138137
}
139138
}
@@ -143,10 +142,10 @@ pub fn derive(input: &Input) -> TokenStream {
143142
/// ::split_at()`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_at).
144143
pub fn split_at(&self, mid: usize) -> (#slice_name<'a>, #slice_name<'a>) {
145144
#(
146-
let (#slice_names_1, #slice_names_2) = self.#fields_names_2.split_at(mid);
145+
let (#fields_names_hygienic_1, #fields_names_hygienic_2) = self.#fields_names.split_at(mid);
147146
)*
148-
let left = #slice_name{#(#fields_names_1: #slice_names_1),*};
149-
let right = #slice_name{#(#fields_names_1: #slice_names_2),*};
147+
let left = #slice_name{#(#fields_names: #fields_names_hygienic_1),*};
148+
let right = #slice_name{#(#fields_names: #fields_names_hygienic_2),*};
150149
(left, right)
151150
}
152151

@@ -193,7 +192,7 @@ pub fn derive(input: &Input) -> TokenStream {
193192
'a: 'b
194193
{
195194
#slice_name {
196-
#(#fields_names_1: &self.#fields_names_2,)*
195+
#(#fields_names: &self.#fields_names,)*
197196
}
198197
}
199198

@@ -202,14 +201,14 @@ pub fn derive(input: &Input) -> TokenStream {
202201
/// ::as_ptr()`](https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr).
203202
pub fn as_ptr(&self) -> #ptr_name {
204203
#ptr_name {
205-
#(#fields_names_1: self.#fields_names_2.as_ptr(),)*
204+
#(#fields_names: self.#fields_names.as_ptr(),)*
206205
}
207206
}
208207

209208
/// Similar to [`std::slice::from_raw_parts()`](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html).
210209
pub unsafe fn from_raw_parts<'b>(data: #ptr_name, len: usize) -> #slice_name<'b> {
211210
#slice_name {
212-
#(#fields_names_1: ::std::slice::from_raw_parts(data.#fields_names_2, len),)*
211+
#(#fields_names: ::std::slice::from_raw_parts(data.#fields_names, len),)*
213212
}
214213
}
215214
}
@@ -224,7 +223,7 @@ pub fn derive(input: &Input) -> TokenStream {
224223
/// ::to_vec()`](https://doc.rust-lang.org/std/primitive.slice.html#method.to_vec).
225224
pub fn to_vec(&self) -> #vec_name {
226225
#vec_name {
227-
#(#fields_names_1: self.#fields_names_2.to_vec(),)*
226+
#(#fields_names: self.#fields_names.to_vec(),)*
228227
}
229228
}
230229
}

0 commit comments

Comments
 (0)