astral-sh/ruff · error · ValueError

`&T*` is unsupported; use `Box<[T]>`: {rule}

Error message

`&T*` is unsupported; use `Box<[T]>`: {rule}

What it means

split_sequence_type() maps AST DSL sequence rules to Rust collection kinds. A '&' in a rule denotes a reference type (e.g. '&Token*'), which the generated AST cannot own, so the generator rejects it outright and points to the supported owned spelling Box<[T]>.

Source

Thrown at crates/ruff_python_ast/generate.py:241

    if open_bracket_index == -1:
        return rust_type_str
    close_bracket_index = rust_type_str.rfind(">")
    if close_bracket_index == -1 or close_bracket_index <= open_bracket_index:
        raise ValueError(f"Brackets are not balanced for type {rust_type_str}")
    inner_type = rust_type_str[open_bracket_index + 1 : close_bracket_index].strip()
    inner_type = inner_type.replace("crate::", "")
    return inner_type


class SequenceKind(Enum):
    VEC = "vec"
    BOXED_SLICE = "boxed_slice"
    THIN_VEC = "thin_vec"


def split_sequence_type(rule: str) -> tuple[SequenceKind | None, str]:
    if "&" in rule:
        raise ValueError(f"`&T*` is unsupported; use `Box<[T]>`: {rule}")

    if "*" in rule:
        if rule.endswith("*") and rule.count("*") == 1:
            return SequenceKind.VEC, rule[:-1]
        raise ValueError(f"`*` must be at the end: {rule}")

    for prefix, suffix, sequence_kind in (
        ("Vec<", ">", SequenceKind.VEC),
        ("ThinVec<", ">", SequenceKind.THIN_VEC),
        ("Box<[", "]>", SequenceKind.BOXED_SLICE),
    ):
        if rule.startswith(prefix):
            if not rule.endswith(suffix):
                raise ValueError(f"Unclosed collection type: {rule}")
            return sequence_kind, rule[len(prefix) : -len(suffix)]

    return None, rule

View on GitHub (pinned to d1087a4b9e)

Solutions

  1. Replace the reference-sequence rule with the owned slice form Box<[T]>.
  2. For a single owned value use Box<T>; for a growable sequence use Vec<T> or the T* shorthand.
  3. Re-run the generator and review the output.

Example fix

# before
names: &Token*

# after
names: Box<[Token]>
Defensive patterns

Strategy: validation

Validate before calling

def rule_ok(rule: str) -> bool:
    return '&' not in rule  # reference types are rejected; use Box<[T]>

Prevention

When it happens

Trigger: Writing an AST field rule that contains '&', such as 'names: &Token*' or 'keywords: &str*', then running the generate.py script.

Common situations: Porting a hand-written AST struct that stored borrowed slices; attempting to avoid boxing by storing references in a node; refactoring old ruff_python_ast code into the DSL.

Related errors


AI-assisted analysis of astral-sh/ruff@d1087a4b9e (2026-08-20). Data as JSON: /api/errors/c7e107216281fbae. Report an issue: GitHub.