Skip to content

Add StrictSendableMetatypes to require Sendable requirements on metatypes #79352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 14, 2025

Conversation

DougGregor
Copy link
Member

@DougGregor DougGregor commented Feb 13, 2025

Introduce a new experimental feature StrictSendableMetatypes that stops treating all metatypes as Sendable. Instead, metatypes of generic parameters and existentials are only considered Sendable if their corresponding instance types are guaranteed to be Sendable.

Enforce this property within region isolation. Track metatype creation instructions and put them in the task's isolation domain, so that transferring them into another isolation domain produces a diagnostic. As an example:

func f<T: P>(_: T.Type) {
  let x: P.Type = T.self
  Task.detached {
    x.someStaticMethod() // oops, T.Type is not Sendable
  }
}

At the type checker level, handle direct attempts to capture metatypes by tracking generic type captures within closures, so that we can diagnose, e.g.,

func g<T: P>(_: T.Type) {
  Task.detached {
    T.someStaticMethod() // oops, T.Type is not Sendable
  }
}

Model the sendability of a type's metatype with the new marker protocol SendableMetatype, which Sendable now inherits from and which is used to determine when a metatype is Sendable. Specifically, T: SendableMetatype implies T.Type: Sendable, on which this analysis is based. Thank you to @slavapestov for the insight into this approach!

…ypes

Introduce a new experimental feature StrictSendableMetatypes that stops
treating all metatypes as `Sendable`. Instead, metatypes of generic
parameters and existentials are only considered Sendable if their
corresponding instance types are guaranteed to be Sendable.

Start with enforcing this property within region isolation. Track
metatype creation instructions and put them in the task's isolation
domain, so that transferring them into another isolation domain
produces a diagnostic. As an example:

    func f<T: P>(_: T.Type) {
      let x: P.Type = T.self
      Task.detached {
        x.someStaticMethod() // oops, T.Type is not Sendable
      }
    }
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please smoke test windows

@DougGregor
Copy link
Member Author

@swift-ci please smoke test Linux

…ries

Keep track of all of the type parameters and archetypes that are captured
by a local function or closure. Use that information to diagnose cases
where a non-Sendable metatype crosses an isolation boundary.
Introduce a marker protocol SendableMetatype that is used to indicate
when the metatype of a type will conform to Sendable. Specifically,
`T: SendableMetatype` implies `T.Type: Sendable`. When strict
metatype sendability is enabled, metatypes are only sendable when `T:
SendableMetatype`.

All nominal types implicitly conform to `SendableMetatype`, as do the
various builtin types, function types, etc. The `Sendable` marker
protocol now inherits from `SendableMetatype`, so that `T: Sendable`
implies `T.Type: Sendable`.

Thank you Slava for the excellent idea!
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor DougGregor enabled auto-merge February 14, 2025 06:57
@DougGregor DougGregor merged commit 2989770 into swiftlang:main Feb 14, 2025
3 checks passed
@DougGregor DougGregor deleted the strict-sendable-metatypes branch February 14, 2025 15:15
glessard added a commit to glessard/swift that referenced this pull request Feb 15, 2025
This change is a partial cherry-pick from commit
e24598b
found in swiftlang#79352
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.

1 participant