From 92de180d7d93b05b9171498c88978ea90745af93 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 20 Jan 2023 07:53:04 -0800 Subject: [PATCH] component bindgen: accept strs as well as identifiers for wit identifiers (#5600) This is required because not all wit identifiers are Rust identifiers, so we can smuggle the invalid ones inside quotes. --- crates/component-macro/src/bindgen.rs | 18 ++++++++++++++++-- tests/all/component_model/bindgen/results.rs | 4 +++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/crates/component-macro/src/bindgen.rs b/crates/component-macro/src/bindgen.rs index 435abbb42b..d9caff8f32 100644 --- a/crates/component-macro/src/bindgen.rs +++ b/crates/component-macro/src/bindgen.rs @@ -226,9 +226,23 @@ impl Parse for Opt { } fn trappable_error_field_parse(input: ParseStream<'_>) -> Result<(String, String, String)> { - let interface = input.parse::()?.to_string(); + // Accept a Rust identifier or a string literal. This is required + // because not all wit identifiers are Rust identifiers, so we can + // smuggle the invalid ones inside quotes. + fn ident_or_str(input: ParseStream<'_>) -> Result { + let l = input.lookahead1(); + if l.peek(syn::LitStr) { + Ok(input.parse::()?.value()) + } else if l.peek(syn::Ident) { + Ok(input.parse::()?.to_string()) + } else { + Err(l.error()) + } + } + + let interface = ident_or_str(input)?; input.parse::()?; - let type_ = input.parse::()?.to_string(); + let type_ = ident_or_str(input)?; input.parse::()?; let rust_type = input.parse::()?.to_string(); Ok((interface, type_, rust_type)) diff --git a/tests/all/component_model/bindgen/results.rs b/tests/all/component_model/bindgen/results.rs index 995a2e5289..82e318948b 100644 --- a/tests/all/component_model/bindgen/results.rs +++ b/tests/all/component_model/bindgen/results.rs @@ -373,7 +373,9 @@ mod record_error { record-error: func(a: float64) -> result } }", - trappable_error_type: { imports::e2: TrappableE2 } + // Literal strings can be used for the interface and typename fields instead of + // identifiers, because wit identifiers arent always Rust identifiers. + trappable_error_type: { "imports"::"e2": TrappableE2 } }); #[test]