Skip to content

[ASTGen] Assorted fixes pt.2 #79547

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 2 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions include/swift/AST/ASTBridgingImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ swift::DeclAttributes BridgedDeclAttributes::unbridged() const {
return attrs;
}

//===----------------------------------------------------------------------===//
// MARK: AvailabilityDomain
//===----------------------------------------------------------------------===//

BridgedAvailabilityDomain::BridgedAvailabilityDomain(
swift::AvailabilityDomain domain)
: opaque(domain.getOpaqueValue()) {}
Expand All @@ -290,6 +294,23 @@ swift::AvailabilityDomain BridgedAvailabilityDomain::unbridged() const {
return swift::AvailabilityDomain::fromOpaque(opaque);
}

BridgedAvailabilityDomain BridgedAvailabilityDomain::forUniversal() {
return swift::AvailabilityDomain::forUniversal();
}
BridgedAvailabilityDomain
BridgedAvailabilityDomain::forPlatform(BridgedPlatformKind platformKind) {
return swift::AvailabilityDomain::forPlatform(unbridge(platformKind));
}
BridgedAvailabilityDomain BridgedAvailabilityDomain::forSwiftLanguage() {
return swift::AvailabilityDomain::forSwiftLanguage();
}
BridgedAvailabilityDomain BridgedAvailabilityDomain::forPackageDescription() {
return swift::AvailabilityDomain::forPackageDescription();
}
BridgedAvailabilityDomain BridgedAvailabilityDomain::forEmbedded() {
return swift::AvailabilityDomain::forEmbedded();
}

//===----------------------------------------------------------------------===//
// MARK: BridgedParamDecl
//===----------------------------------------------------------------------===//
Expand Down
21 changes: 0 additions & 21 deletions lib/AST/Bridging/AvailabilityBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,24 +152,3 @@ BridgedSourceRange
BridgedAvailabilitySpec_getVersionRange(BridgedAvailabilitySpec spec) {
return spec.unbridged()->getVersionSrcRange();
}

//===----------------------------------------------------------------------===//
// MARK: AvailabilityDomain
//===----------------------------------------------------------------------===//

BridgedAvailabilityDomain BridgedAvailabilityDomain::forUniversal() {
return swift::AvailabilityDomain::forUniversal();
}
BridgedAvailabilityDomain
BridgedAvailabilityDomain::forPlatform(BridgedPlatformKind platformKind) {
return swift::AvailabilityDomain::forPlatform(unbridge(platformKind));
}
BridgedAvailabilityDomain BridgedAvailabilityDomain::forSwiftLanguage() {
return swift::AvailabilityDomain::forSwiftLanguage();
}
BridgedAvailabilityDomain BridgedAvailabilityDomain::forPackageDescription() {
return swift::AvailabilityDomain::forPackageDescription();
}
BridgedAvailabilityDomain BridgedAvailabilityDomain::forEmbedded() {
return swift::AvailabilityDomain::forEmbedded();
}
39 changes: 33 additions & 6 deletions lib/ASTGen/Sources/ASTGen/DeclAttrs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ extension ASTGenVisitor {
fatalError("unimplemented")
case .unavailableFromAsync:
return handle(self.generateUnavailableFromAsyncAttr(attribute: node)?.asDeclAttribute)
case .none where attrName == "_unavailableInEmbedded":
return handle(self.generateUnavailableInEmbeddedAttr(attribute: node)?.asDeclAttribute)

// Simple attributes.
case .addressableSelf,
Expand Down Expand Up @@ -1778,6 +1780,30 @@ extension ASTGenVisitor {
)
}

func generateUnavailableInEmbeddedAttr(attribute node: AttributeSyntax) -> BridgedAvailableAttr? {
if ctx.langOptsHasFeature(.Embedded) {
return BridgedAvailableAttr.createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
range: self.generateAttrSourceRange(node),
domain: .forEmbedded(),
domainLoc: nil,
kind: .unavailable,
message: "unavailable in embedded Swift",
renamed: "",
introduced: BridgedVersionTuple(),
introducedRange: BridgedSourceRange(),
deprecated: BridgedVersionTuple(),
deprecatedRange: BridgedSourceRange(),
obsoleted: BridgedVersionTuple(),
obsoletedRange: BridgedSourceRange()
)
} else {
// For non-Embedded mode, ignore it.
return nil
}
}

func generateSimpleDeclAttr(attribute node: AttributeSyntax, kind: BridgedDeclAttrKind) -> BridgedDeclAttribute? {
// TODO: Diagnose extraneous arguments.
// TODO: Diagnose if `kind` is a modifier.
Expand Down Expand Up @@ -2040,17 +2066,18 @@ extension ASTGenVisitor {
kind = .weak
guard node.detail == nil else {
// TODO: Diagnose.
return nil
fatalError("invalid argument for 'weak' modifier")
}
case .unowned:
switch node.detail?.detail.keywordKind {
case .safe, nil:
switch node.detail?.detail.rawText {
case "safe", nil:
kind = .unowned
case .unsafe:
case "unsafe":
kind = .unmanaged
case _?:
case let text?:
// TODO: Diagnose
kind = .unowned
_ = text
fatalError("invalid argument for 'unowned' modifier")
}
default:
preconditionFailure("ReferenceOwnership modifier must be 'weak' or 'unowned'")
Expand Down
7 changes: 7 additions & 0 deletions test/ASTGen/attrs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,10 @@ func testNonIsolated(actor: MyActor) {
_ = actor.constFlag
_ = actor.mutableFlag
}

struct ReferenceOwnershipModifierTest<X: AnyObject> {
weak var weakValue: X?
unowned var unownedValue: X
unowned(safe) var unownedSafeValue: X
unowned(unsafe) var unmanagedValue: X
}
91 changes: 91 additions & 0 deletions test/ASTGen/embedded_availability.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// **Copied from test/embedded/availability.swift**
// RUN: %target-typecheck-verify-swift -parse-stdlib -enable-experimental-feature Embedded -enable-experimental-feature ParserASTGen

// REQUIRES: swift_in_compiler
// REQUIRES: swift_feature_Embedded
// REQUIRES: swift_feature_ParserASTGen

@_unavailableInEmbedded
public struct UnavailableInEmbedded {}
// expected-note@-1 {{'UnavailableInEmbedded' has been explicitly marked unavailable here}}

@available(*, unavailable, message: "always unavailable")
public struct UniverallyUnavailable {}
// expected-note@-1 {{'UniverallyUnavailable' has been explicitly marked unavailable here}}

@_unavailableInEmbedded
public func unavailable_in_embedded() { }
// expected-note@-1 {{'unavailable_in_embedded()' has been explicitly marked unavailable here}}

@available(*, unavailable, message: "always unavailable")
public func universally_unavailable() { }
// expected-note@-1 4 {{'universally_unavailable()' has been explicitly marked unavailable here}}

@_unavailableInEmbedded
public func unused() { } // no error

public struct S1 {} // expected-note 2 {{found this candidate}}
public struct S2 {} // expected-note 2 {{found this candidate}}

@_unavailableInEmbedded
public func has_unavailable_in_embedded_overload(_ s1: S1) { }

public func has_unavailable_in_embedded_overload(_ s2: S2) { }

@available(*, unavailable)
public func has_universally_unavailable_overload(_ s1: S1) { }

public func has_universally_unavailable_overload(_ s2: S2) { }

public struct Available {}

@_unavailableInEmbedded
extension Available {
public func unavailable_in_embedded_method( // expected-note {{'unavailable_in_embedded_method' has been explicitly marked unavailable here}}
_ uie: UnavailableInEmbedded,
_ uu: UniverallyUnavailable,
_ a: Available,
) {
unavailable_in_embedded()
universally_unavailable() // expected-error {{'universally_unavailable()' is unavailable: always unavailable}}
a.unavailable_in_embedded_method(uie, uu, a)
}
}

public func available(
_ uie: UnavailableInEmbedded, // expected-error {{'UnavailableInEmbedded' is unavailable: unavailable in embedded Swift}}
_ uu: UniverallyUnavailable, // expected-error {{'UniverallyUnavailable' is unavailable: always unavailable}}
_ a: Available,
) {
unavailable_in_embedded() // expected-error {{'unavailable_in_embedded()' is unavailable: unavailable in embedded Swift}}
universally_unavailable() // expected-error {{'universally_unavailable()' is unavailable: always unavailable}}
a.unavailable_in_embedded_method(uie, uu, a) // expected-error {{'unavailable_in_embedded_method' is unavailable: unavailable in embedded Swift}}
has_unavailable_in_embedded_overload(.init())
has_universally_unavailable_overload(.init()) // not ambiguous, selects available overload
}

@_unavailableInEmbedded
public func also_unavailable_in_embedded(
_ uie: UnavailableInEmbedded, // OK
_ uu: UniverallyUnavailable, // OK
_ a: Available,
) {
unavailable_in_embedded() // OK
universally_unavailable() // expected-error {{'universally_unavailable()' is unavailable: always unavailable}}
a.unavailable_in_embedded_method(uie, uu, a)
has_unavailable_in_embedded_overload(.init()) // expected-error {{ambiguous use of 'init()'}}
has_universally_unavailable_overload(.init()) // not ambiguous, selects available overload
}

@available(*, unavailable)
public func also_universally_unavailable(
_ uie: UnavailableInEmbedded, // OK
_ uu: UniverallyUnavailable, // OK
_ a: Available,
) {
unavailable_in_embedded()
universally_unavailable() // expected-error {{'universally_unavailable()' is unavailable: always unavailable}}
a.unavailable_in_embedded_method(uie, uu, a)
has_unavailable_in_embedded_overload(.init()) // expected-error {{ambiguous use of 'init()'}}
has_universally_unavailable_overload(.init()) // not ambiguous, selects available overload
}