Skip to content

@inline never is silently ignored and does not prevent inlining #131

Description

@Unisay

Summary

The @inline <name> never pragma parses and is stored, but it has no effect on the optimizer. A binding annotated never is still inlined whenever the ordinary heuristics would inline it, so the annotation is a no-op. @inline always works as expected; only never is broken.

This surfaced while documenting the inliner for #44.

Root cause

The annotation reaches the optimizer as the binding expression's annotation, but the only place that reads it, isInlinableExpr in Backend.IR.Optimizer, collapses Just Never to the same result as Nothing:

hasInlineAnnotation = getAnn >>> \case
  Just Always -> True
  Just Never  -> False
  Nothing     -> False

Both inlining sites then decide with isInlinableExpr expr || <used once>:

  • optimizeModule inlines a top-level binding if isInlinableExpr expr || isUsedOnce qname.
  • inlineLocalBindings inlines a let binding if isInlinableExpr inlinee || countFreeRef name body == 1.

So a never-annotated binding that is a reference, a small literal, or used exactly once is still inlined through the second disjunct. Never never blocks anything Nothing would not also allow.

Expected

@inline <name> never should prevent that binding from being inlined, overriding both the isInlinableExpr heuristic and the single-use rule.

Suggested fix

Treat Just Never as a veto at both inlining sites (for example a shared getAnn expr == Just Never guard that short-circuits the whole decision), and update Note [Inline annotations and inlining heuristics], which currently documents the broken behavior.

A regression test should assert that a never-annotated, single-use binding is left in place by the optimizer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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