Skip to content

Conversation

@natecook1000
Copy link
Member

Accessing CommandLine.arguments is a sendability violation, since it's global mutable state. This marks the setter as deprecated, so that we can potentially make it unavailable in Swift 6 mode.

(I also wrote some docs for CommandLine.arguments.)

Accessing CommandLine.arguments is a sendability violation, since it's global mutable state. This marks the setter as deprecated, so that we can potentially make it unavailable in Swift 6 mode.
@natecook1000 natecook1000 requested a review from a team as a code owner November 18, 2023 21:01
@natecook1000
Copy link
Member Author

@swift-ci Please test

@natecook1000
Copy link
Member Author

This starts to address #66213, which will take multiple steps due to ABI/source compatibility concerns.

Copy link
Contributor

@glessard glessard left a comment

Choose a reason for hiding this comment

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

This seems like the right first step. I wouldn't mind a test that checks that the warning is emitted as expected.

@natecook1000
Copy link
Member Author

@swift-ci Please test

/// Usage: command <number>
public static var arguments: [String] {
get { _arguments }
@available(swift, deprecated: 5.10, message: "CommandLine.arguments will be immutable in a future version")
Copy link
Contributor

Choose a reason for hiding this comment

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

I might suggest something stronger like:

"Do not modify CommandLine.arguments. It will become read-only in a future version of Swift."

Right now there are no instructions to the developer, so it may be unclear what you're asking them to do.

Copy link

Choose a reason for hiding this comment

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

I feel like the first question someone will be asking themselves when they encounter this deprecation is "What else should I use then?!", so I think it's worth addressing that question somewhere in the docs.

Copy link
Contributor

Choose a reason for hiding this comment

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

I suspect the set of developers who are mutating this property is small, but if anybody asks, "pass your own mutable copy of this array where needed" seems like simple and sound advice.

// safely initialize the swift arguments.
public static var arguments: [String]
@usableFromInline
internal static var _arguments: [String]
Copy link
Contributor

Choose a reason for hiding this comment

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

And long-term the goal is to make this let, yeah?

internal static var _arguments: [String]
= (0..<Int(argc)).map { String(cString: _unsafeArgv[$0]!) }

/// An array that provides access to this program's command line arguments.
Copy link
Contributor

Choose a reason for hiding this comment

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

As far as I can see, this property is currently undocumented. Thanks for writing up something for it!

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah! There were actually some minimal docs there, but they were blocked from attaching by a regular comment between them and the declaration.

@grynspan
Copy link
Contributor

@swift-ci please test macOS

@Azoy
Copy link
Contributor

Azoy commented Jan 31, 2024

@swift-ci please test

@Azoy
Copy link
Contributor

Azoy commented Mar 6, 2024

@swift-ci please test

/// $ command ZZZ
/// Error: Please provide a number to square.
/// Usage: command <number>
public static var arguments: [String] {
Copy link
Member

Choose a reason for hiding this comment

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

I think this needs to be marked @_alwaysEmitIntoClient

Copy link
Contributor

Choose a reason for hiding this comment

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

What are the ABI stability implications of doing that? Existing code will have references to arguments that were not emitted into their binaries; does that work with @_alwaysEmitIntoClient? And presumably we're OK with making _arguments into ABI if we're doing that?

Copy link
Member

@hborla hborla Mar 12, 2024

Choose a reason for hiding this comment

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

I misunderstood why the ABI test failed! It's the accessor symbols for _arguments that were added.

The typical pattern for this is to leave the ABI declaration exactly as-is and change public to @usableFromInline internal, and make the new public API @_alwaysEmitIntoClient. But I think this change here is conceptually fine because changing a stored property to a computed one is ABI compatible, and the new _arguments variable is only used on newer runtimes while old runtimes will use the stored variable accessors directly.

I think the fix is to remove @usableFromInline from _arguments. I don't think it needs to be there.

@MaxDesiatov MaxDesiatov requested a review from al45tair March 11, 2024 21:51
Copy link
Contributor

@al45tair al45tair left a comment

Choose a reason for hiding this comment

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

LGTM.

@grynspan
Copy link
Contributor

I still think the deprecation message needs a tweak, but the implementation is good. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

7 participants