You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Preserve literal types in the expression resolver (PHPStan-style) #293
The expression resolver (resolve_rhs_expression) currently widens
scalar literals to their base types (string, int, float) at
the point of resolution. This means compound expressions like
ternaries, match, and null-coalesce lose literal precision and require
a separate post-hoc narrowing pass in the diagnostic path
(narrow_literal_type) to recover it.
PHPStan preserves literal types from the start and only widens where
specifically needed. Adopting this approach would make the type system
more precise across the board — diagnostics, hover, completion — and
eliminate the need for the narrowing workaround.
Current state
resolve_rhs_expression returns PhpType::string() for Expression::Literal(Literal::String(...)), etc.
The diagnostic path uses narrow_literal_type() to recover
precise literal types for argument type checking.
Array shape and list element tracking depend on the widened types
(array{name: string} vs array{name: 'John'}).
What needs to change
Make resolve_rhs_expression return literal types for scalar
literals (PhpType::literal_string_raw, literal_int, literal_float).
Add a widening step in the array shape and list tracking layers
so that $arr['name'] = 'John' still infers array{name: string} rather than array{name: 'John'}.
Audit and update tests — an initial attempt showed 15 failures
in shape/list tracking tests that expect widened types.
Once the resolver preserves literals, remove the narrow_literal_type workaround from the diagnostic path.
Context
Discovered while fixing #180. The narrowing approach works for the
immediate issue but is architecturally fragile — it requires
enumerating every compound expression form rather than getting
precision for free from the resolver.
Activity