Skip to content

Conversation

@hamishknight
Copy link
Contributor

@hamishknight hamishknight commented Oct 31, 2025

  • Ensure associatedtype inference never considers id and actorSystem properties for a distributed actor since doing so would either result in cycles or resolving using Identifiable's default id
  • Consolidate synthesis logic that was previously duplicated across witness derivation and separate requests to trigger synthesis
  • Always synthesize id and actorSystem for a distributed actor, allowing redeclaration checking to diagnose user-defined versions
  • Lazily compute the interface types for id and actorSystem, ensuring the synthesis logic doesn't kick semantic requests
  • Install id and actorSystem as part of synthesizeSemanticMembersIfNeeded to ensure they're always injected into name lookup results (this is the actual fix for rdar://162800185)
  • Remove Identifiable derivation code and ImplicitMemberAction::ResolveDistributedActor, neither of which should be necessary now

rdar://162800185

@hamishknight hamishknight force-pushed the panic-at-the-distro branch 3 times, most recently from a2e17a7 to 8dea46d Compare November 1, 2025 10:49
@hamishknight hamishknight changed the title [WIP] A DistributedActor fix and cleanup [Sema] Fix and cleanup distributed id/actorSystem synthesis Nov 2, 2025
@hamishknight hamishknight force-pushed the panic-at-the-distro branch 3 times, most recently from 09b4f75 to 996f65a Compare November 2, 2025 14:39
@hamishknight hamishknight marked this pull request as ready for review November 2, 2025 14:40
@xedin
Copy link
Contributor

xedin commented Nov 2, 2025

Thanks, @hamishknight! I will take a look on Monday.

@ktoso
Copy link
Contributor

ktoso commented Nov 3, 2025

Thanks a lot Hamish! Looks promising, I'll do a proper review and also verify on some projects, thank you!

And use this in `evaluateMembersRequest`.
Avoid relying on the cycle detection logic to exclude these and
enforce that we never consider them since computing their interface
type relies on the type witnesses already being resolved. This also
means we can no longer pick up Identifiable's default implementation
`id`, which we never want for a `distributed` actor. This then lets 
us remove the special-cased eager inference logic.
…Request`

This is checking a conformance for something defined in the Distributed
module itself, so things would be very broken if it failed.
…ystemOfActor`

Make sure we produce an error for a broken stdlib and produce ErrorType
instead.
These can be inlined into their respective requests.
Have the witness derivation logic call into the synthesis requests.
Only fallback to name lookup for serialized modules and swift
interfaces. This means we can then implement the user-declared
`id`/`actorSystem` error as part of redeclaration checking.
Delay their interface type computation until they are actually
type-checked. This ensures their synthesis logic doesn't produce
cycles.
Now that the synthesis logic for these doesn't involve kicking
semantic requests we can synthesize directly as part of name lookup.
This ensures they get synthesized for secondaries and we don't try
and use Identifiable's default `id`.

rdar://162800185
This shouldn't be necessary anymore since we we'll no longer try to
infer `ID` from Identifiable's default implmentation of `id`.
The member names that triggered this don't even match the requirements
in the Distributed module anymore, and
`installDistributedActorIfNecessary` was only called for structs which
can't be distributed actors. Rip it out.
@hamishknight
Copy link
Contributor Author

Noticed we could replace a couple more checks for id/actorSystem, pushed an extra commit for that

@hamishknight hamishknight force-pushed the panic-at-the-distro branch 2 times, most recently from d5eb1b2 to 3bc7e5b Compare November 3, 2025 13:27
Use `isSpecialDistributedProperty` or the synthesis requests instead.
While here, also make `isSpecialDistributedProperty` agnostic to
interface and serialized module cases.
@hamishknight
Copy link
Contributor Author

@swift-ci please test

@hamishknight
Copy link
Contributor Author

@swift-ci please test source compatibility

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, thank you!

Copy link
Contributor

@ktoso ktoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I also confirmed in an adopter project this solves the issue!

bool *wouldConflictInSwift5 = nullptr,
bool skipProtocolExtensionCheck = false);

enum class SpecialDistributedProperty {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor:

Suggested change
enum class SpecialDistributedProperty {
enum class SpecialDistributedActorProperty {

Just to that it's clearer that we mean specifically properties of a distributed actor; (a "distributed property" exists and is distributed var {} but that's different)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do a follow up with a rename, we can merge this as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and fixed this in #85309 since there were a couple of other things I also noticed

nonisolated var actorSystem: DefaultDistributedActorSystem { fatalError() }
// expected-error@-1 {{property 'actorSystem' cannot be defined explicitly, as it conflicts with distributed actor synthesized stored property}}
// expected-note@-2 {{candidate exactly matches}}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch, thank you

import Distributed

func foo<T: DistributedActor>(_: T.Type) where T.ActorSystem == LocalTestingDistributedActorSystem {}
func bar() { foo(A.self) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this doesn't quite reproduce rdar://162800185;
This works fine on existing main already, so we're missing something here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it does, we chatted offline :-)

// but the id synthesis will force itself to be FIRST anyway, so it works out.
nominal->addMember(propDecl, /*hint=*/idProperty, insertAtHead);
nominal->addMember(pbDecl, /*hint=*/idProperty, insertAtHead);
return propDecl;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this refactor to requests is neat, and we keep the ordering guarantee nicely this way too

@ktoso ktoso merged commit 0f58eb2 into swiftlang:main Nov 4, 2025
5 of 7 checks passed
@hamishknight hamishknight deleted the panic-at-the-distro branch November 4, 2025 08:45
kavon added a commit that referenced this pull request Nov 4, 2025
[Sema] A couple of minor follow-ups to #85245
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants