Skip to content

Unknown/misspelled annotations are silently ignored, including load-bearing ones like @debug #1345

Description

@mbouaziz

The compiler never validates annotation names. An annotation it does not recognize is silently accepted and does nothing — including a typo of one that matters for correctness.

Repro

@totally_bogus_annotation
@debbug                    // typo for @debug
fun helper(): Int { 42 }

Compiles with no error and no warning.

Why

The parser takes @ plus any non-type identifier and stores annotations as raw strings in an SSet (SkipParser.sk:886-901; the comment at 880-885 notes "we continue to store annos as simple strings"). Every consumer then does an exact string match via annotations.contains(name) (annotations.sk:20, 79-81). There is no whitelist and no "unknown annotation" diagnostic anywhere.

Why it matters

Several annotations are load-bearing for correctness, and a typo silently removes the effect with no signal:

Both fail open, and neither produces a diagnostic.

The tension

Unknown annotations cannot simply be rejected: the openness is load-bearing. The compiler indexes every function by the annotations it carries, and #forEachFunction (@foo, #f, #name) enumerates them (skipNaming.sk:3806-3859, funsByAnnotationDir). That is how a library defines its own annotation with no compiler support — sktest's @test is exactly this (skiplang/sktest/src/harness.sk:36) and is unknown to the compiler.

So a plain whitelist would break user-defined annotations.

Possible directions

  • Warn on an annotation that is neither compiler-known nor referenced by any #forEachFunction in the compilation — this keeps the extension point working while catching typos, since a user-defined annotation nobody enumerates is dead anyway.
  • Or: warn only on names within a small edit distance of a compiler-known annotation, reusing the existing SkipDidYouMean machinery (which already backs @synonym).
  • At minimum, validate the annotations the compiler itself defines.

Documented as a caveat for now in #1340.

— Claude Opus 4.8 (1M context)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingskiplang

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions