Merge pull request #17313 from slavapestov/inlinable-warning-tweak-4.2
Small @inlinable tweaks for [4.2]
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 7205a8e..b22c14b 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -3835,6 +3835,11 @@
"cannot be referenced from " FRAGILE_FUNC_KIND "3",
(DescriptiveDeclKind, DeclName, AccessLevel, unsigned))
+WARNING(resilience_decl_unavailable_warn,
+ none, "%0 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
+ "should not be referenced from " FRAGILE_FUNC_KIND "3",
+ (DescriptiveDeclKind, DeclName, AccessLevel, unsigned))
+
#undef FRAGILE_FUNC_KIND
NOTE(resilience_decl_declared_here_public,
diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp
index e2ca4ca..578bea4 100644
--- a/lib/Sema/DerivedConformanceRawRepresentable.cpp
+++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp
@@ -121,6 +121,22 @@
toRawDecl->setBody(body);
}
+static void maybeMarkAsInlinable(DerivedConformance &derived,
+ AbstractFunctionDecl *afd) {
+ ASTContext &C = derived.TC.Context;
+ auto parentDC = derived.getConformanceContext();
+ if (parentDC->getParentModule()->getResilienceStrategy() !=
+ ResilienceStrategy::Resilient) {
+ AccessScope access =
+ afd->getFormalAccessScope(nullptr,
+ /*treatUsableFromInlineAsPublic*/true);
+ if (auto *attr = afd->getAttrs().getAttribute<UsableFromInlineAttr>())
+ attr->setInvalid();
+ if (access.isPublic())
+ afd->getAttrs().add(new (C) InlinableAttr(/*implicit*/false));
+ }
+}
+
static VarDecl *deriveRawRepresentable_raw(DerivedConformance &derived) {
ASTContext &C = derived.TC.Context;
@@ -143,14 +159,7 @@
// If the containing module is not resilient, make sure clients can get at
// the raw value without function call overhead.
- if (parentDC->getParentModule()->getResilienceStrategy() !=
- ResilienceStrategy::Resilient) {
- AccessScope access =
- enumDecl->getFormalAccessScope(nullptr,
- /*treatUsableFromInlineAsPublic*/true);
- if (access.isPublic())
- getterDecl->getAttrs().add(new (C) InlinableAttr(/*implicit*/false));
- }
+ maybeMarkAsInlinable(derived, getterDecl);
derived.addMembersToConformanceContext({getterDecl, propDecl, pbDecl});
@@ -350,14 +359,7 @@
// If the containing module is not resilient, make sure clients can construct
// an instance without function call overhead.
- if (parentDC->getParentModule()->getResilienceStrategy() !=
- ResilienceStrategy::Resilient) {
- AccessScope access =
- enumDecl->getFormalAccessScope(nullptr,
- /*treatUsableFromInlineAsPublic*/true);
- if (access.isPublic())
- initDecl->getAttrs().add(new (C) InlinableAttr(/*implicit*/false));
- }
+ maybeMarkAsInlinable(derived, initDecl);
C.addSynthesizedDecl(initDecl);
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index 70d72e9..b0d9d4f 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -86,6 +86,13 @@
}
}
+/// A uniquely-typed boolean to reduce the chances of accidentally inverting
+/// a check.
+enum class DowngradeToWarning: bool {
+ No,
+ Yes
+};
+
bool TypeChecker::diagnoseInlinableDeclRef(SourceLoc loc,
const ValueDecl *D,
const DeclContext *DC,
@@ -119,11 +126,18 @@
if (D->isDynamic())
return false;
- // FIXME: Figure out what to do with typealiases
- if (isa<TypeAliasDecl>(D))
- return false;
+ DowngradeToWarning downgradeToWarning = DowngradeToWarning::No;
- diagnose(loc, diag::resilience_decl_unavailable,
+ // Swift 4.2 did not perform any checks for type aliases.
+ if (!Context.isSwiftVersionAtLeast(5) &&
+ isa<TypeAliasDecl>(D))
+ downgradeToWarning = DowngradeToWarning::Yes;
+
+ auto diagID = diag::resilience_decl_unavailable;
+ if (downgradeToWarning == DowngradeToWarning::Yes)
+ diagID = diag::resilience_decl_unavailable_warn;
+
+ diagnose(loc, diagID,
D->getDescriptiveKind(), D->getFullName(),
D->getFormalAccessScope().accessLevelForDiagnostics(),
static_cast<unsigned>(Kind));
@@ -136,6 +150,6 @@
D->getDescriptiveKind(), D->getFullName());
}
- return true;
+ return (downgradeToWarning == DowngradeToWarning::No);
}
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 971b46a..7aa453b 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -1979,9 +1979,7 @@
// On internal declarations, @inlinable implies @usableFromInline.
if (VD->getAttrs().hasAttribute<InlinableAttr>()) {
- if (attr->isImplicit())
- attr->setInvalid();
- else
+ if (TC.Context.isSwiftVersionAtLeast(4,2))
diagnoseAndRemoveAttr(attr, diag::inlinable_implies_usable_from_inline);
return;
}
diff --git a/test/Compatibility/attr_inlinable_old_spelling_4.swift b/test/Compatibility/attr_inlinable_old_spelling_4.swift
index ab7d51b..4488d2e 100644
--- a/test/Compatibility/attr_inlinable_old_spelling_4.swift
+++ b/test/Compatibility/attr_inlinable_old_spelling_4.swift
@@ -5,3 +5,6 @@
@_inlineable public func oldInlinableFunction() {}
@_versioned func oldVersionedFunction() {}
+
+// No warning here
+@_inlineable @_versioned func redundantAttribute() {}
diff --git a/test/Compatibility/attr_inlinable_old_spelling_42.swift b/test/Compatibility/attr_inlinable_old_spelling_42.swift
index 0cc4c4f..c4df55a 100644
--- a/test/Compatibility/attr_inlinable_old_spelling_42.swift
+++ b/test/Compatibility/attr_inlinable_old_spelling_42.swift
@@ -7,3 +7,6 @@
@_versioned func oldVersionedFunction() {}
// expected-warning@-1 {{'@_versioned' has been renamed to '@usableFromInline'}}{{2-12=usableFromInline}}
+
+@inlinable @usableFromInline func redundantAttribute() {}
+// expected-warning@-1 {{'@inlinable' declaration is already '@usableFromInline'}}
diff --git a/test/Compatibility/attr_inlinable_typealias.swift b/test/Compatibility/attr_inlinable_typealias.swift
new file mode 100644
index 0000000..fde1daa
--- /dev/null
+++ b/test/Compatibility/attr_inlinable_typealias.swift
@@ -0,0 +1,23 @@
+// RUN: %target-typecheck-verify-swift -swift-version 4
+
+private typealias PrivateAlias = Int
+// expected-note@-1 {{type alias 'PrivateAlias' is not '@usableFromInline' or public}}
+
+internal typealias InternalAlias = Int
+// expected-note@-1 {{type alias 'InternalAlias' is not '@usableFromInline' or public}}
+
+@usableFromInline typealias UsableFromInlineAlias = Int
+
+public typealias PublicAlias = Int
+
+@inlinable public func f() {
+ _ = PrivateAlias.self
+ // expected-warning@-1 {{type alias 'PrivateAlias' is private and should not be referenced from an '@inlinable' function}}
+
+ _ = InternalAlias.self
+ // expected-warning@-1 {{type alias 'InternalAlias' is internal and should not be referenced from an '@inlinable' function}}
+
+ _ = UsableFromInlineAlias.self
+
+ _ = PublicAlias.self
+}
diff --git a/test/SIL/Serialization/Inputs/def_generic.swift b/test/SIL/Serialization/Inputs/def_generic.swift
index 44140dc..a4fc851 100644
--- a/test/SIL/Serialization/Inputs/def_generic.swift
+++ b/test/SIL/Serialization/Inputs/def_generic.swift
@@ -1,15 +1,12 @@
@_fixed_layout
public class A<T> {
- typealias Element = T
- @usableFromInline
- @inlinable
- func convertFromArrayLiteral(_ elements: Element...) -> A {
+ @usableFromInline typealias Element = T
+
+ @inlinable func convertFromArrayLiteral(_ elements: Element...) -> A {
return A()
}
- @usableFromInline
- @inlinable
- init() {}
+ @inlinable init() {}
@inlinable public subscript<U>(value: T) -> U? {
return nil
diff --git a/test/attr/attr_inlinable.swift b/test/attr/attr_inlinable.swift
index 649a0aa..efea113 100644
--- a/test/attr/attr_inlinable.swift
+++ b/test/attr/attr_inlinable.swift
@@ -1,7 +1,7 @@
-// RUN: %target-typecheck-verify-swift -swift-version 4
-// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-testing
-// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-resilience
-// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-resilience -enable-testing
+// RUN: %target-typecheck-verify-swift -swift-version 4.2
+// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-testing
+// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-resilience
+// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-resilience -enable-testing
@inlinable struct TestInlinableStruct {}
// expected-error@-1 {{'@inlinable' attribute cannot be applied to this declaration}}
diff --git a/test/attr/attr_inlinable_typealias.swift b/test/attr/attr_inlinable_typealias.swift
index 480d280..850ad8b 100644
--- a/test/attr/attr_inlinable_typealias.swift
+++ b/test/attr/attr_inlinable_typealias.swift
@@ -1,11 +1,10 @@
-// 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.
+// RUN: %target-typecheck-verify-swift -swift-version 5
private typealias PrivateAlias = Int
+// expected-note@-1 {{type alias 'PrivateAlias' is not '@usableFromInline' or public}}
internal typealias InternalAlias = Int
+// expected-note@-1 {{type alias 'InternalAlias' is not '@usableFromInline' or public}}
@usableFromInline typealias UsableFromInlineAlias = Int
@@ -13,8 +12,10 @@
@inlinable public func f() {
_ = PrivateAlias.self
+ // expected-error@-1 {{type alias 'PrivateAlias' is private and cannot be referenced from an '@inlinable' function}}
_ = InternalAlias.self
+ // expected-error@-1 {{type alias 'InternalAlias' is internal and cannot be referenced from an '@inlinable' function}}
_ = UsableFromInlineAlias.self