swc-project/swc · error

#[derive(Spanned)]: #[span(lo)] and #[span(hi)] is required

Error message

#[derive(Spanned)]: #[span(lo)] and #[span(hi)] is required

What it means

Compile-time panic from `#[derive(Spanned)]` (crates/ast_node/src/spanned.rs). Once any field has a `#[span(...)]` list attribute, the macro requires exactly one `#[span(lo)]` field and one `#[span(hi)]` field to compose `lo_field.span().with_hi(hi_field.span().hi())`. If either marker is missing, it panics.

Source

Thrown at crates/ast_node/src/spanned.rs:207

        return simple_field(span_field);
    }

    let fields: Vec<_> = bindings
        .iter()
        .map(|b| (b, MyField::from_field(b.field())))
        .collect();

    // TODO: Only one field should be `#[span(lo)]`.
    let lo = fields.iter().find(|&(_, f)| f.lo);
    let hi = fields.iter().find(|&(_, f)| f.hi);

    match (lo, hi) {
        (Some((lo_field, _)), Some((hi_field, _))) => {
            // Create a new span from lo_field.lo(), hi_field.hi()
            Box::new(parse_quote!(swc_common::Spanned::span(#lo_field)
                .with_hi(swc_common::Spanned::span(#hi_field).hi())))
        }
        _ => panic!("#[derive(Spanned)]: #[span(lo)] and #[span(hi)] is required"),
    }
}

/// Search for `#[span]`
fn has_empty_span_attr(attrs: &[Attribute]) -> bool {
    attrs.iter().any(|attr| {
        if !is_attr_name(attr, "span") {
            return false;
        }

        match &attr.meta {
            Meta::Path(..) => true,
            Meta::List(t) => t.tokens.is_empty(),
            _ => false,
        }
    })
}

View on GitHub (pinned to 5176682b65)

Solutions

  1. Add the missing marker: one field `#[span(lo)]` and a different field `#[span(hi)]`
  2. If a single field determines the whole span, drop the list attributes and use bare `#[span]` on that field instead

Example fix

// before
struct Range {
    #[span(lo)]
    start: Ident,
    end: Ident,
}

// after
struct Range {
    #[span(lo)]
    start: Ident,
    #[span(hi)]
    end: Ident,
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Annotating a field with `#[span(lo)]` but forgetting `#[span(hi)]` on another field (or vice versa) in a Spanned-deriving struct.

Common situations: Building wrapper nodes whose span starts at one child's start and ends at another child's end and only marking one end.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/318bf2b9ca4096f1. Report an issue: GitHub.