Skip to content

Check that signatures of @usableFromInline declarations only reference @usableFromInline or public types #16586

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
6 changes: 2 additions & 4 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2162,9 +2162,6 @@ class ValueDecl : public Decl {
llvm::PointerIntPair<Type, 3, OptionalEnum<AccessLevel>> TypeAndAccess;
unsigned LocalDiscriminator = 0;

private:
bool isUsableFromInline() const;

protected:
ValueDecl(DeclKind K,
llvm::PointerUnion<DeclContext *, ASTContext *> context,
Expand Down Expand Up @@ -2238,6 +2235,8 @@ class ValueDecl : public Decl {
SourceLoc getNameLoc() const { return NameLoc; }
SourceLoc getLoc() const { return NameLoc; }

bool isUsableFromInline() const;

bool hasAccess() const {
return TypeAndAccess.getInt().hasValue();
}
Expand Down Expand Up @@ -2266,7 +2265,6 @@ class ValueDecl : public Decl {
if (treatUsableFromInlineAsPublic &&
result == AccessLevel::Internal &&
isUsableFromInline()) {
assert(!useDC);
return AccessLevel::Public;
}
if (useDC && (result == AccessLevel::Internal ||
Expand Down
104 changes: 104 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,28 @@ WARNING(pattern_type_access_inferred_warn,none,
"because its type %6 uses "
"%select{a private|a fileprivate|an internal|%error|%error}5 type",
(bool, bool, bool, AccessLevel, bool, AccessLevel, Type))
ERROR(pattern_type_not_usable_from_inline,none,
"type referenced from a '@usableFromInline' "
"%select{%select{variable|constant}0|property}1 "
"must be '@usableFromInline' or public",
(bool, bool))
WARNING(pattern_type_not_usable_from_inline_warn,none,
"type referenced from a '@usableFromInline' "
"%select{%select{variable|constant}0|property}1 "
"should be '@usableFromInline' or public",
(bool, bool))
ERROR(pattern_type_not_usable_from_inline_inferred,none,
"type referenced from a '@usableFromInline' "
"%select{%select{variable|constant}0|property}1 "
"with inferred type %2 "
"must be '@usableFromInline' or public",
(bool, bool, Type))
WARNING(pattern_type_not_usable_from_inline_inferred_warn,none,
"type referenced from a '@usableFromInline' "
"%select{%select{variable|constant}0|property}1 "
"with inferred type %2 "
"should be '@usableFromInline' or public",
(bool, bool, Type))
ERROR(pattern_binds_no_variables,none,
"%select{property|global variable}0 declaration does not bind any "
"variables",
Expand Down Expand Up @@ -1346,6 +1368,16 @@ WARNING(type_alias_underlying_type_access_warn,none,
"because its underlying type uses "
"%select{a private|a fileprivate|an internal|%error|%error}2 type",
(bool, AccessLevel, AccessLevel, bool))
ERROR(type_alias_underlying_type_not_usable_from_inline,none,
"type referenced from the underlying type of a "
"'@usableFromInline' type alias "
"must be '@usableFromInline' or public",
())
WARNING(type_alias_underlying_type_not_usable_from_inline_warn,none,
"type referenced from the underlying type of a "
"'@usableFromInline' type alias "
"should be '@usableFromInline' or public",
())

// Subscripts
ERROR(subscript_type_access,none,
Expand All @@ -1363,6 +1395,14 @@ WARNING(subscript_type_access_warn,none,
"because its %select{index|element type}3 uses "
"%select{a private|a fileprivate|an internal|%error|%error}2 type",
(bool, AccessLevel, AccessLevel, bool))
ERROR(subscript_type_usable_from_inline,none,
"%select{index type|element type}0 of a '@usableFromInline' subscript "
"must be '@usableFromInline' or public",
(bool))
WARNING(subscript_type_usable_from_inline_warn,none,
"%select{index type|element type}0 of a '@usableFromInline' subscript "
"should be '@usableFromInline' or public",
(bool))

// Functions
ERROR(function_type_access,none,
Expand All @@ -1381,6 +1421,16 @@ WARNING(function_type_access_warn,none,
"because its %select{parameter|result}5 uses "
"%select{a private|a fileprivate|an internal|%error|%error}3 type",
(bool, AccessLevel, bool, AccessLevel, unsigned, bool))
ERROR(function_type_usable_from_inline,none,
"the %select{parameter|result}1 of a "
"'@usableFromInline' %select{function|method|initializer}0 "
"must be '@usableFromInline' or public",
(unsigned, bool))
WARNING(function_type_usable_from_inline_warn,none,
"the %select{parameter|result}1 of a "
"'@usableFromInline' %select{function|method|initializer}0 "
"should be '@usableFromInline' or public",
(unsigned, bool))
ERROR(noreturn_not_supported,none,
"'@noreturn' has been removed; functions that never return should have a "
"return type of 'Never' instead", ())
Expand Down Expand Up @@ -1585,6 +1635,12 @@ WARNING(protocol_access_warn,none,
"%select{protocol should not refine|protocol's 'where' clause should not use}2}0 "
"%select{a private|a fileprivate|an internal|%error|%error}3 protocol",
(bool, AccessLevel, bool, AccessLevel, bool))
ERROR(protocol_usable_from_inline,none,
"protocol %select{refined|used}0 by '@usableFromInline' protocol "
"must be '@usableForInline' or public", (bool))
WARNING(protocol_usable_from_inline_warn,none,
"protocol %select{refined|used}0 by '@usableFromInline' protocol "
"should be '@usableForInline' or public", (bool))
ERROR(protocol_property_must_be_computed_var,none,
"immutable property requirement must be declared as 'var' with a "
"'{ get }' specifier", ())
Expand Down Expand Up @@ -1627,6 +1683,16 @@ WARNING(associated_type_access_warn,none,
"%select{a private|a fileprivate|an internal|%error|%error}1 type in its "
"%select{default definition|requirement}2 ",
(AccessLevel, AccessLevel, unsigned))
ERROR(associated_type_not_usable_from_inline,none,
"type referenced from a "
"%select{default definition|requirement}0 of an associated type in a "
"'@usableFromInline' protocol must be '@usableFromInline' or public",
(unsigned))
WARNING(associated_type_not_usable_from_inline_warn,none,
"type referenced from a "
"%select{default definition|requirement}0 of an associated type in a "
"'@usableFromInline' protocol should be '@usableFromInline' or public",
(unsigned))

NOTE(bad_associated_type_deduction,none,
"unable to infer associated type %0 for protocol %1",
Expand Down Expand Up @@ -1879,6 +1945,16 @@ WARNING(generic_param_access_warn,none,
"because its generic %select{parameter|requirement}5 uses "
"%select{a private|a fileprivate|an internal|%error|%error}3 type",
(DescriptiveDeclKind, bool, AccessLevel, AccessLevel, bool, bool))
ERROR(generic_param_usable_from_inline,none,
"type referenced from a "
"generic %select{parameter|requirement}1 of a '@usableFromInline' %0 "
"must be '@usableFromInline' or public",
(DescriptiveDeclKind, bool))
WARNING(generic_param_usable_from_inline_warn,none,
"type referenced from a "
"generic %select{parameter|requirement}1 of a '@usableFromInline' %0 "
"should be '@usableFromInline' or public",
(DescriptiveDeclKind, bool))

ERROR(override_multiple_decls_base,none,
"declaration %0 cannot override more than one superclass declaration",
Expand Down Expand Up @@ -2108,6 +2184,12 @@ WARNING(enum_case_access_warn,none,
"enum case in %select{a private|a fileprivate|an internal|a public|%error}0 enum "
"uses %select{a private|a fileprivate|an internal|%error|%error}1 type",
(AccessLevel, AccessLevel))
ERROR(enum_case_usable_from_inline,none,
"type of enum case in '@usableFromInline' enum "
"must be '@usableFromInline' or public", ())
WARNING(enum_case_usable_from_inline_warn,none,
"type of enum case in '@usableFromInline' enum "
"should be '@usableFromInline' or public", ())
ERROR(enum_stored_property,none,
"enums must not contain stored properties", ())

Expand Down Expand Up @@ -2145,6 +2227,17 @@ WARNING(enum_raw_type_access_warn,none,
"%select{a private|a fileprivate|an internal|%error|%error}2 type",
(bool, AccessLevel, AccessLevel, bool))

ERROR(enum_raw_type_not_usable_from_inline,none,
"type referenced from the raw type of a "
"'@usableFromInline' enum "
"must be '@usableFromInline' or public",
())
WARNING(enum_raw_type_not_usable_from_inline_warn,none,
"type referenced from the raw type of a "
"'@usableFromInline' enum "
"should be '@usableFromInline' or public",
())

ERROR(empty_enum_raw_type,none,
"an enum with no cases cannot declare a raw type", ())
ERROR(enum_raw_value_without_raw_type,none,
Expand Down Expand Up @@ -3263,6 +3356,17 @@ WARNING(class_super_access_warn,none,
"|uses %select{a private|a fileprivate|an internal|%error|%error}2 "
"type as a generic parameter}4",
(bool, AccessLevel, AccessLevel, bool, bool))
ERROR(class_super_not_usable_from_inline,none,
"%select{type referenced from |}0the superclass of "
"a '@usableFromInline' class "
"must be '@usableFromInline' or public",
(bool))
WARNING(class_super_not_usable_from_inline_warn,none,
"%select{type referenced from |}0the superclass of "
"a '@usableFromInline' class "
"should be '@usableFromInline' or public",
(bool))

ERROR(dot_protocol_on_non_existential,none,
"cannot use 'Protocol' with non-protocol type %0", (Type))
ERROR(tuple_single_element,none,
Expand Down
4 changes: 4 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2148,6 +2148,10 @@ bool ValueDecl::isUsableFromInline() const {
if (EED->getParentEnum()->getAttrs().hasAttribute<UsableFromInlineAttr>())
return true;

if (auto *ATD = dyn_cast<AssociatedTypeDecl>(this))
if (ATD->getProtocol()->getAttrs().hasAttribute<UsableFromInlineAttr>())
return true;

return false;
}

Expand Down
1 change: 1 addition & 0 deletions lib/Sema/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ add_swift_library(swiftSema STATIC
PlaygroundTransform.cpp
ResilienceDiagnostics.cpp
SourceLoader.cpp
TypeCheckAccess.cpp
TypeCheckAttr.cpp
TypeCheckAvailability.cpp
TypeCheckCaptures.cpp
Expand Down
Loading