Skip to content

Allow value generics within the stdlib #83710

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

tbkka
Copy link
Contributor

@tbkka tbkka commented Aug 13, 2025

Value Generics require support from libswiftCore, but that means it is always okay to use value generics within libswiftCore itself, since the runtime support is necessarily present.

Value Generics require support from libswiftCore, but that
means it is always okay to use value generics within libswiftCore
itself, since the runtime support is necessarily present.
@tbkka tbkka requested review from Azoy and tshortli August 13, 2025 23:51
@tbkka
Copy link
Contributor Author

tbkka commented Aug 13, 2025

@tshortli I'd appreciate if you could double-check my reasoning here.

@tshortli
Copy link
Contributor

The reasoning is not totally sound because making this change means that someone working on the stdlib could introduce a new API that leverages ValueGenerics and the compiler will no longer check whether the public facing availability of the API is correct.

I suspect that we ought do something more nuanced that doesn't completely sacrifice the checking that I described above. One option would be to only relax this check when "strict availability checking" is disabled in the build configuration (which is what controls whether SwiftStdlibDeploymentTarget maps to relaxed platform availability). That way we can use ValueGenerics in a more relaxed way in the same configurations that we're already making availability checking compromises in, but there's still some build configuration that actually verifies that new stdlib APIs have consistent availability.

@tshortli
Copy link
Contributor

The other observation about this that I have is that ValueGenerics are not special; any language feature that requires runtime support should probably have the same availability checking relaxation applied to it for the same reasons. I think we ideally ought to refactor things so that there is a funnel point for all runtime feature checks that behaves consistently. I wouldn't blame you if you thought that aspect should be handled by someone else in follow up, though.

@tbkka
Copy link
Contributor Author

tbkka commented Aug 14, 2025

I did some experiments and found out that a slight refinement seems like it would meet both of our needs: This now ignores only non-public stdlib types.

I believe this answers your concern: Public stdlib types are still unconditionally checked.

I think this can also provide an answer to my concern in #82750: I'm going to experiment with having a separate internal version of InlineArray specifically for use within the library.

@tbkka
Copy link
Contributor Author

tbkka commented Aug 14, 2025

@Azoy @glessard @lorentey -- This would make it possible to add an internal struct _InlineArray for use inside of the standard library itself. That internal version would have no availability constraints. But the public struct InlineArray (which could be a thin wrapper around the internal type) would continue to have availability limitations to ensure correct client usage. If you think that's a reasonable direction, let me know and I'll land this change in preparation for that.

@Azoy
Copy link
Contributor

Azoy commented Aug 14, 2025

Can't we change the availability of InlineArray to use the new StdlibDeploymentTarget macro?

@tbkka
Copy link
Contributor Author

tbkka commented Aug 14, 2025

@Azoy Not without some work.

One problem is that StdlibDeploymentTarget and SwiftStdlib aren't really compatible, and the compiler in essence marks value generics as availability(SwiftStdlib 6.2), so that results in InlineArray being incompatible with StdlibDeploymentTarget as-is. My change here suppresses the availability check on value generics for internal types and functions.

We could change the compiler enforcement to use the equivalent of StdlibDeploymentTarget 6.2 (which I think is essentially what @tshortli was suggesting above). I'll try doing that and see what happens.

The core problem I'm trying to resolve for #82750 is that debugDescription has always existed and I'm trying to reimplement it in terms of new features such as Span and InlineArray. With our current availability model, that means that it must either do a runtime availability check, or only be implemented in terms of capabilities that are not themselves availability-restricted.

@tbkka
Copy link
Contributor Author

tbkka commented Aug 15, 2025

I don't think using StdlibDeploymentTarget helps here at all, actually. That just guarantees that every stdlib feature (including future features) can be built on the current host machine. It does not avoid unnecessary runtime calls for if #available checks when a feature depends on another feature that is provided by the stdlib itself (and which can therefore be unconditionally used without checking regardless of the minimum target OS version). In particular, our default at-desk builds specify an old target version.

This is a serious problem for our long-term goal of reimplementing core stdlib and runtime capabilities in Swift rather than C/C++. The C/C++ versions have no availability check overhead, and to achieve performance parity for new Swift versions, we need to be able to similarly guarantee no runtime availability checking for these. We want that parity to be apparent and testable in a variety of environments, and StdlibDeploymentTarget is insufficient for this.

@al45tair should be able to check my reasoning here.

If I'm right, then the only really practical approach here is to have duplicate interfaces for core services like InlineArray, Span, etc: One internal version that is not availability-limited for use within the stdlib itself, and another public version that is availability-limited to ensure correct usage by clients.

This PR enables that approach.

@al45tair
Copy link
Contributor

It does not avoid unnecessary runtime calls for if #available checks when a feature depends on another feature that is provided by the stdlib itself

It will do, but only if the if #available is also using StdlibDeploymentTarget. The issue here is that you might then have to change other things to use StdlibDeploymentTarget and so on.

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.

4 participants