github carthage-software/mago 1.14.1
Mago 1.14.1

5 hours ago

Mago 1.14.1

Mago 1.14.1 is a patch release focused on fixing false positives across the analyzer's generics and type inference system. Highlights include proper template inference for spread arguments, template constraint violation detection during class instantiation, correct class-string<T> inference from $object::class, improved array_filter handling for union array types, and fixes for variable definedness tracking in try-catch blocks. The formatter also receives several fixes, and the Docker image now includes git for --staged support.

🐛 Bug Fixes

Analyzer

  • Fixed template inference for spread arguments to variadic parameters: Spread arguments like ...$list where $list is list<Child> now correctly infer the template type (e.g., T=Child) instead of falling back to the constraint default (#1368)
  • Detect template constraint violations during class instantiation: When constructing a generic class like new ViewTable(models: [new Model()]), the analyzer now correctly reports an error if the inferred type doesn't satisfy the template constraint (e.g., T of Textable) (#1355)
  • Fixed $object::class to infer class-string<T> for generic parameters: When $object is typed as a generic parameter T of object, $object::class now correctly produces class-string<T> instead of bare class-string (#1372)
  • Fixed method_exists/property_exists narrowing string to never: When method_exists($className, 'method') is used with a string variable, the variable is now narrowed to class-string in the truthy branch instead of being discarded as never (#1374)
  • Preserved generic class-string<T> identity during match exhaustiveness narrowing: Match expressions that compare a class-string<T> against class constants no longer lose the generic parameter T, preventing false positive return type mismatches (#1375)
  • Fixed array_filter return type for union array types: array_filter now correctly removes nullable types when the input array comes from a match expression or other constructs that produce a union of array types (#1365)
  • Fixed variable definedness tracking in try-catch with multiple leaving paths: When a catch block has multiple exit paths (e.g., throw in one branch and continue in another), variables assigned in the try block are now correctly considered defined after the try-catch (#1352)
  • Fixed false positive for incompatible-property-hook-parameter-type: The analyzer now uses the effective type (considering @var docblock narrowing) when checking property hook parameter compatibility (#1342)
  • Fixed false positive property-type-coercion for unresolved generic parameters: When instantiating generic classes without explicit type arguments (e.g., new WeakMap()), unresolved generic parameters now use placeholder types instead of constraint defaults, preventing false coercion warnings when assigned to typed properties (#1346)
  • Fixed debug panic from stale by-reference counters: Resolved a debug-mode assertion failure caused by stale by-reference counters during analysis (#1242)

Codex

  • Preserved all union members when replacing class-string generic templates: Fixed a bug where class-string<A>|class-string<B> passed to a class-string<T> parameter would lose one of the union members during template resolution (#1341, #1344)
  • Fixed closure/arrow function skipping in incremental builds: Closures and arrow functions are no longer skipped during incremental builds in watch mode, preventing types from becoming unknown references (#1359, #1363)

Formatter

  • Preserved parentheses around unbounded constructs in binary expressions: Parentheses around require, include, print, and similar constructs are now preserved when used in binary expressions (#1348, #1353)
  • Stabilized chain-breaking heuristic for method chains: Fixed an idempotency issue where method chains with complex arguments could produce different output on repeated formatting passes (#1351, #1371)
  • Removed unnecessary parentheses around new in partial application: The formatter no longer wraps new expressions in unnecessary parentheses when used in array or argument contexts (#1370, #1373)

Linter

  • Marked str-contains/str-starts-with fixers as potentially unsafe: The auto-fixers for these rules are now flagged as potentially unsafe since the transformation may change behavior in edge cases (#1358)

Docker

  • Installed git in Docker image: The Docker image now includes git, enabling --staged options for lint and format commands (#1362, #1369)

🙏 Thank You

Contributors

A huge thank you to everyone who contributed code to this release:

Issue Reporters

Thank you to everyone who reported issues that shaped this release:


Full Changelog: 1.14.0...1.14.1

Don't miss a new mago release

NewReleases is sending notifications on new releases.