Skip to content

Minor @inlinable improvements [4.2] #17091

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
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
4 changes: 2 additions & 2 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -894,8 +894,8 @@ class ASTContext {
/// This is usually the check you want; for example, when introducing
/// a new language feature which is only visible in Swift 5, you would
/// check for isSwiftVersionAtLeast(5).
bool isSwiftVersionAtLeast(unsigned major) const {
return LangOpts.isSwiftVersionAtLeast(major);
bool isSwiftVersionAtLeast(unsigned major, unsigned minor = 0) const {
return LangOpts.isSwiftVersionAtLeast(major, minor);
}

private:
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/Attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ DECL_ATTR(_cdecl, CDecl,

SIMPLE_DECL_ATTR(usableFromInline, UsableFromInline,
OnFunc | OnVar | OnSubscript | OnConstructor |
OnDestructor | OnStruct | OnEnum | OnClass |
OnDestructor | OnStruct | OnEnum | OnClass | OnTypeAlias |
OnProtocol | LongAttribute | UserInaccessible,
64)

Expand Down
4 changes: 2 additions & 2 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ namespace swift {
/// This is usually the check you want; for example, when introducing
/// a new language feature which is only visible in Swift 5, you would
/// check for isSwiftVersionAtLeast(5).
bool isSwiftVersionAtLeast(unsigned major) const {
return EffectiveLanguageVersion.isVersionAtLeast(major);
bool isSwiftVersionAtLeast(unsigned major, unsigned minor = 0) const {
return EffectiveLanguageVersion.isVersionAtLeast(major, minor);
}

/// Returns true if the given platform condition argument represents
Expand Down
13 changes: 11 additions & 2 deletions include/swift/Basic/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,17 @@ class Version {

/// Whether this version is greater than or equal to the given major version
/// number.
bool isVersionAtLeast(unsigned major) const {
return !empty() && Components[0] >= major;
bool isVersionAtLeast(unsigned major, unsigned minor = 0) const {
switch (size()) {
case 0:
return false;
case 1:
return ((Components[0] == major && 0 == minor) ||
(Components[0] > major));
default:
return ((Components[0] == major && Components[1] >= minor) ||
(Components[0] > major));
}
}

/// Return this Version struct with minor and sub-minor components stripped
Expand Down
27 changes: 16 additions & 11 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1466,15 +1466,17 @@ bool Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc) {
// over to the alternate parsing path.
DeclAttrKind DK = DeclAttribute::getAttrKindFromString(Tok.getText());

auto checkInvalidAttrName = [&](StringRef invalidName, StringRef correctName,
DeclAttrKind kind, Diag<StringRef, StringRef> diag) {
auto checkInvalidAttrName = [&](StringRef invalidName,
StringRef correctName,
DeclAttrKind kind,
Optional<Diag<StringRef, StringRef>> diag = None) {
if (DK == DAK_Count && Tok.getText() == invalidName) {
// We renamed @availability to @available, so if we see the former,
// treat it as the latter and emit a Fix-It.
DK = kind;

diagnose(Tok, diag, invalidName, correctName)

if (diag) {
diagnose(Tok, *diag, invalidName, correctName)
.fixItReplace(Tok.getLoc(), correctName);
}
}
};

Expand All @@ -1485,14 +1487,17 @@ bool Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc) {
// Check if attr is inlineable, and suggest inlinable instead
checkInvalidAttrName("inlineable", "inlinable", DAK_Inlinable, diag::attr_name_close_match);

// In Swift 5 and above, these become hard errors. Otherwise, emit a
// warning for compatibility.
if (!Context.isSwiftVersionAtLeast(5)) {
// In Swift 5 and above, these become hard errors. In Swift 4.2, emit a
// warning for compatibility. Otherwise, don't diagnose at all.
if (Context.isSwiftVersionAtLeast(5)) {
checkInvalidAttrName("_versioned", "usableFromInline", DAK_UsableFromInline, diag::attr_renamed);
checkInvalidAttrName("_inlineable", "inlinable", DAK_Inlinable, diag::attr_renamed);
} else if (Context.isSwiftVersionAtLeast(4, 2)) {
checkInvalidAttrName("_versioned", "usableFromInline", DAK_UsableFromInline, diag::attr_renamed_warning);
checkInvalidAttrName("_inlineable", "inlinable", DAK_Inlinable, diag::attr_renamed_warning);
} else {
checkInvalidAttrName("_versioned", "usableFromInline", DAK_UsableFromInline, diag::attr_renamed);
checkInvalidAttrName("_inlineable", "inlinable", DAK_Inlinable, diag::attr_renamed);
checkInvalidAttrName("_versioned", "usableFromInline", DAK_UsableFromInline);
checkInvalidAttrName("_inlineable", "inlinable", DAK_Inlinable);
}

if (DK == DAK_Count && Tok.getText() == "warn_unused_result") {
Expand Down
7 changes: 7 additions & 0 deletions test/Compatibility/attr_inlinable_old_spelling_4.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// RUN: %target-typecheck-verify-swift -swift-version 3
// RUN: %target-typecheck-verify-swift -swift-version 4

// In -swift-version 4 mode, the old spelling is silently parsed as the new spelling.

@_inlineable public func oldInlinableFunction() {}
@_versioned func oldVersionedFunction() {}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// RUN: %target-typecheck-verify-swift -swift-version 3
// RUN: %target-typecheck-verify-swift -swift-version 4
// RUN: %target-typecheck-verify-swift -swift-version 4.2

// Until -swift-version 5 mode, the old spelling only produces a warning.
// In -swift-version 4.2 mode, the old spelling produces a warning.

@_inlineable public func oldInlinableFunction() {}
// expected-warning@-1 {{'@_inlineable' has been renamed to '@inlinable'}}{{2-13=inlinable}}
Expand Down
22 changes: 22 additions & 0 deletions test/attr/attr_inlinable_typealias.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %target-typecheck-verify-swift

// None of this is enforced for now, but make sure we don't crash or
// do anything stupid when a typealias is annotated with @usableFromInline.

private typealias PrivateAlias = Int

internal typealias InternalAlias = Int

@usableFromInline typealias UsableFromInlineAlias = Int

public typealias PublicAlias = Int

@inlinable public func f() {
_ = PrivateAlias.self

_ = InternalAlias.self

_ = UsableFromInlineAlias.self

_ = PublicAlias.self
}