swc-project/swc · error
not implemented
Error message
not implemented
What it means
`RefRewriter` in swc_ecma_utils replaces identifiers with expressions according to a `QueryRef` mapping (`query_jsx` for JSX positions). When rewriting the object position of a JSX member element (`<Foo.Bar />`), a `query_jsx` result of `JSXElementName::JSXNamespacedName` has no `JSXObject` equivalent, so `exit_jsx_object` panics via `unimplemented!()`. No in-tree query implementation returns namespaced names for that position.
Source
Thrown at crates/swc_ecma_utils/src/lib.rs:2564
}
};
}
pub fn exit_jsx_element_name(&mut self, n: &mut JSXElementName) {
if let JSXElementName::Ident(ident) = n {
if let Some(expr) = self.query.query_jsx(ident) {
*n = expr;
}
}
}
pub fn exit_jsx_object(&mut self, n: &mut JSXObject) {
if let JSXObject::Ident(ident) = n {
if let Some(expr) = self.query.query_jsx(ident) {
*n = match expr {
JSXElementName::Ident(ident) => ident.into(),
JSXElementName::JSXMemberExpr(expr) => Box::new(expr).into(),
JSXElementName::JSXNamespacedName(..) => unimplemented!(),
#[cfg(swc_ast_unknown)]
_ => return,
}
}
}
}
pub fn exit_object_pat_prop(&mut self, n: &mut ObjectPatProp) {
if let ObjectPatProp::Assign(AssignPatProp { key, value, .. }) = n {
if let Some(expr) = self.query.query_lhs(&key.id) {
let value = value
.take()
.map(|default_value| {
let left = expr.clone().try_into().unwrap();
Box::new(default_value.make_assign_to(op!("="), left))
})
.unwrap_or(expr);
View on GitHub (pinned to d7d7434666)
Solutions
- In your `query_jsx`, return only `Ident` or `JSXMemberExpr` — e.g. encode a namespace as the member expression `ns.tag`
- Skip replacement when the identifier may appear as a JSX member object
- Report upstream to turn the panic into a graceful skip
Example fix
// Rust QueryRef impl
// before
fn query_jsx(&self, i: &Ident) -> Option<JSXElementName> {
Some(JSXElementName::JSXNamespacedName(...)) // panics in <Foo.Bar />
}
// after
fn query_jsx(&self, i: &Ident) -> Option<JSXElementName> {
Some(JSXElementName::Ident(make_replacement_ident(i)))
} Defensive patterns
Strategy: type-guard
Type guard
// Rust: guard query_jsx results so they are usable in member-object position
fn jsx_name_usable_as_object(n: &JSXElementName) -> bool {
matches!(n, JSXElementName::Ident(..) | JSXElementName::JSXMemberExpr(..))
} Prevention
- In custom QueryRef impls, return only Ident or JSXMemberExpr from query_jsx
- Encode namespaces as member expressions (`ns.tag`) rather than JSXNamespacedName when replacing identifiers that may appear in `<Foo.Bar />`
When it happens
Trigger: Provide a custom `QueryRef` implementation whose `query_jsx` returns `JSXNamespacedName` for an identifier that appears as the object of `<Foo.Bar />` in JSX using the RefRewriter.
Common situations: Custom bundler or plugin code using RefRewriter for aliasing/inlining in JSX-heavy codebases; replacing JSX tag aliases with namespaced names.
Related errors
AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16).
Data as JSON: /api/errors/5c3b6198132f427a.
Report an issue: GitHub.