Skip to content

Vector0 quantities do not enforce the non-negativity invariant #50

@matt-edmondson

Description

@matt-edmondson

Summary

docs/strategy-unified-vector-quantities.md defines IVector0<TSelf, T> as a magnitude-only quantity that "enforces non-negativity as a type-level invariant", citing examples like:

Speed<double> s = Speed.FromMetersPerSecond(-1.0);   // throws: magnitude cannot be negative

In practice, no enforcement exists. Generated Vector0 quantities (Speed, Mass, Distance, Energy, Area, …) accept any value, including negatives.

Evidence

Semantics.Quantities/Generated/.../Mass.g.cs:

public static Mass<T> FromKilogram(T value) => Create(value);

No guard. grep -E "cannot be negative|ArgumentOutOfRange|absolute zero" Generated/.../{Speed,Mass,Temperature}.g.cs returns nothing.

Semantics.Quantities/PhysicalQuantity.cs also does not validate; it is a thin wrapper exposing Value.

Suggested next step

Decide where the constraint lives:

  1. Emit a guard inside the Create / From* factories of any quantity declared as Vector0 in dimensions.json, throwing ArgumentException (per CLAUDE.md's validation guidance) when T.Sign(value) < 0.
  2. Or move the guard into a shared helper on PhysicalQuantity<T> / a Vector0<T> base.

Either way, add tests in Semantics.Test that assert negative-input rejection across every Vector0 quantity.

Area / Severity

SourceGenerators / Quantities · incomplete

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions