Skip to content

Remove unsafe generic-body convenience properties from OperationSyntax #12

@jonathanvdc

Description

@jonathanvdc

Description

OperationSyntax currently exposes several public properties that implicitly assume the operation has a generic MLIR body by calling Body.GetGenericBody() internally.

This is problematic because GetGenericBody() may throw when the operation uses a custom assembly body. As a result, these properties present an unsafe and misleading API: they look universally valid but can fail at runtime depending on the operation shape.

Problem

The following properties (and similar ones) are affected:

public GenericOperationBodySyntax GenericBody => Body.GetGenericBody();
public DelimitedSyntaxList<SyntaxToken> OperandList => GenericBody.OperandList;
public DelimitedSyntaxList<SyntaxToken> SuccessorList => GenericBody.SuccessorList;
public IReadOnlyList<RegionSyntax> Regions => GenericBody.Regions;
public DelimitedSyntaxList<NamedAttributeSyntax> Attributes => GenericBody.Attributes;
public SyntaxToken? TypeSignatureColonToken => GenericBody.TypeSignatureColonToken;
public TypeSyntax? TypeSignatureSyntax => GenericBody.TypeSignatureSyntax;

These APIs:

  • hide the distinction between generic and custom operation bodies
  • encourage unsafe usage patterns
  • can lead to runtime exceptions in otherwise reasonable-looking code

Proposed Change

Remove these properties (and any similar ones) from OperationSyntax.

Update all dependent code to explicitly handle the Body shape instead of relying on implicit assumptions. Callers should:

  • inspect Body directly (e.g., via type checks or pattern matching), and
  • only access generic-body-specific data when the body is known to be GenericOperationBodySyntax

Expected Usage After Change

Before:

var operands = operation.OperandList;
var attributes = operation.Attributes;

After:

if (operation.Body is GenericOperationBodySyntax genericBody)
{
    var operands = genericBody.OperandList;
    var attributes = genericBody.Attributes;
}

Benefits

  • Eliminates a class of runtime exceptions
  • Makes the API more explicit and harder to misuse
  • Forces callers to correctly model MLIR’s distinction between generic and custom assembly
  • Avoids introducing another long-term abstraction (TryGetGenericBody) that would need to be removed later
  • Improves maintainability by aligning the API with the actual data model

Scope

  • Remove:
    • GenericBody
    • OperandList
    • SuccessorList
    • Regions
    • Attributes
    • TypeSignatureColonToken
    • TypeSignatureSyntax
  • Update all internal call sites to branch on Body
  • Update generated code in MLIR.Generators if needed

Notes

  • This change intentionally pushes responsibility to call sites to handle body kinds explicitly
  • Audit for any remaining APIs that implicitly call GetGenericBody()
  • TryGetGenericBody(...) will be removed in a follow-up once call sites are migrated

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions