Skip to content

Infer arg types from new-object method chains and coalesce expressions - #36

Merged
TomasVotruba merged 1 commit into
mainfrom
infer-new-chain-and-coalesce-arg-types
Sep 16, 2026
Merged

TomasVotruba merged 1 commit into
mainfrom
infer-new-chain-and-coalesce-arg-types

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Problem

A parameter was narrowed to a single type when a sibling call site passed an argument the tool could not read.

$event->setTriggerRestrictedStartHour(new \DateTime()->modify('+2 hours'));
$event->setTriggerRestrictedStartHour('some');
$event->setTriggerRestrictedStartHour($element['triggerRestrictedStartHour'] ?? null);

The new \DateTime()->modify(...) chain and the ?? null coalesce contributed no type, so only 'some' was seen and the parameter became string - breaking the DateTime and null call sites.

Fix

  • Resolve a method chain rooted at new X() to the receiver class X (fluent methods are assumed to return their receiver).
  • Expand a coalesce argument A ?? B into the types of both sides, so ... ?? null keeps nullability.

The parameter above now resolves to the full union \DateTime|string|null.

Note

The receiver-type heuristic assumes a chained method returns its receiver. This is right for fluent/builder methods but wrong for one that returns something else (e.g. new \DateTime()->format(...) returns string, not DateTime). Flagging the trade-off explicitly.

Tests

Added collect cases for new-object chains (method and nullsafe) and coalesce arguments. Full suite, gofmt, vet, golangci-lint and modernize all pass.

A call like setHour(new \DateTime()->modify('+2 hours')) contributed no
type, so a sibling call passing 'some' narrowed the parameter to string
and broke the DateTime call site. Coalesce arguments ($x ?? null) were
likewise dropped, losing nullability.

Resolve a method chain rooted at new X() to the receiver class X, and
expand a coalesce argument into the types of both sides, so the parameter
resolves to the full union (e.g. \DateTime|string|null).
@TomasVotruba
TomasVotruba merged commit 40e9a6c into main Sep 16, 2026
4 checks passed
@TomasVotruba
TomasVotruba deleted the infer-new-chain-and-coalesce-arg-types branch September 16, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant