Skip to content

Commit 091af54

Browse files
authored
Merge pull request #849 from HaoboGu/fix/empty_config
Fix `cannot infer type` error when there's empty config
2 parents 41c8bd0 + 4365d3d commit 091af54

2 files changed

Lines changed: 35 additions & 13 deletions

File tree

rmk-macro/src/codegen/behavior.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,6 @@ fn expand_combos(
133133
let default = quote! { ::core::default::Default::default() };
134134
match combos {
135135
Some(combos) => {
136-
let combos_def = combos.combos.iter().map(|combo| {
137-
let actions = combo.actions.iter().map(|a| parse_key(a.to_owned(), profiles));
138-
let output = parse_key(combo.output.to_owned(), profiles);
139-
let layer = match combo.layer {
140-
Some(layer) => quote! { ::core::option::Option::Some(#layer) },
141-
None => quote! { ::core::option::Option::None },
142-
};
143-
quote! { ::rmk::keyboard::combo::Combo::new(::rmk::keyboard::combo::ComboConfig::new([#(#actions),*], #output, #layer)) }
144-
});
145-
146136
let timeout = match &combos.timeout_ms {
147137
Some(millis) => {
148138
quote! { timeout: ::embassy_time::Duration::from_millis(#millis), }
@@ -157,8 +147,24 @@ fn expand_combos(
157147
None => quote! {},
158148
};
159149

160-
quote! {
161-
::rmk::config::CombosConfig {
150+
// When no combos are defined the `let v = [#(#combos_def),*]` expression
151+
// collapses to `let v = []`, which Rust can't type-infer. Emit an
152+
// all-`None` array directly in that case.
153+
let combos_field = if combos.combos.is_empty() {
154+
quote! {
155+
combos: core::array::from_fn(|_| ::core::option::Option::None),
156+
}
157+
} else {
158+
let combos_def = combos.combos.iter().map(|combo| {
159+
let actions = combo.actions.iter().map(|a| parse_key(a.to_owned(), profiles));
160+
let output = parse_key(combo.output.to_owned(), profiles);
161+
let layer = match combo.layer {
162+
Some(layer) => quote! { ::core::option::Option::Some(#layer) },
163+
None => quote! { ::core::option::Option::None },
164+
};
165+
quote! { ::rmk::keyboard::combo::Combo::new(::rmk::keyboard::combo::ComboConfig::new([#(#actions),*], #output, #layer)) }
166+
});
167+
quote! {
162168
combos: {
163169
let v = [#(#combos_def),*];
164170
core::array::from_fn(|i| {
@@ -169,6 +175,12 @@ fn expand_combos(
169175
}
170176
})
171177
},
178+
}
179+
};
180+
181+
quote! {
182+
::rmk::config::CombosConfig {
183+
#combos_field
172184
#timeout
173185
#prior_idle_time
174186
..Default::default()
@@ -185,6 +197,10 @@ fn expand_macros(macros: &Option<Macros>) -> proc_macro2::TokenStream {
185197
match macros {
186198
Some(macros) => {
187199
let macros_def = macros.macros.iter().map(|m| {
200+
if m.operations.is_empty() {
201+
// `[].into_iter().flatten().collect()` cannot infer the element type.
202+
return quote! { ::rmk::heapless::Vec::new() };
203+
}
188204
let operations = m.operations.iter().map(|op| match op {
189205
MacroOperation::Tap { keycode } => {
190206
let key = get_key_with_alias(keycode.trim().to_owned());

rmk-macro/src/codegen/layout.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,11 @@ fn expand_encoder_layer(
9090
quote! { ::rmk::encoder!(::rmk::k!(No), ::rmk::k!(No)) },
9191
);
9292

93-
quote! { [#(#encoders), *] }
93+
if encoders.is_empty() {
94+
// An empty `[]` literal has no element type for Rust to infer when
95+
// `num_encoder == 0`. Emit the typed `[expr; N]` form instead.
96+
quote! { [::rmk::encoder!(::rmk::k!(No), ::rmk::k!(No)); NUM_ENCODER] }
97+
} else {
98+
quote! { [#(#encoders), *] }
99+
}
94100
}

0 commit comments

Comments
 (0)