Skip to content

Commit fd19441

Browse files
authored
Merge pull request #4341 from swiftwasm/main
2 parents 6ce2e1d + da35280 commit fd19441

File tree

108 files changed

+927
-725
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+927
-725
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,3 +830,10 @@ the compiler.
830830

831831
This `async` function uses the pre-SE-0338 semantics of unsafely inheriting the caller's executor. This is an underscored feature because the right way of inheriting an executor is to pass in the required executor and switch to it. Unfortunately, there are functions in the standard library which need to inherit their caller's executor but cannot change their ABI because they were not defined as `@_alwaysEmitIntoClient` in the initial release.
832832

833+
## `@_spi_available(platform, version)`
834+
835+
Like `@available`, this attribute indicates a decl is available only as an SPI.
836+
This implies several behavioral changes comparing to regular `@available`:
837+
1. Type checker diagnoses when a client accidently exposes such a symbol in library APIs.
838+
2. When emitting public interfaces, `@_spi_available` is printed as `@available(platform, unavailable)`.
839+
3. ClangImporter imports ObjC macros `SPI_AVAILABLE` and `__SPI_AVAILABLE` to this attribute.

include/swift/AST/Attr.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,14 +632,16 @@ class AvailableAttr : public DeclAttribute {
632632
const llvm::VersionTuple &Obsoleted,
633633
SourceRange ObsoletedRange,
634634
PlatformAgnosticAvailabilityKind PlatformAgnostic,
635-
bool Implicit)
635+
bool Implicit,
636+
bool IsSPI)
636637
: DeclAttribute(DAK_Available, AtLoc, Range, Implicit),
637638
Message(Message), Rename(Rename), RenameDecl(RenameDecl),
638639
INIT_VER_TUPLE(Introduced), IntroducedRange(IntroducedRange),
639640
INIT_VER_TUPLE(Deprecated), DeprecatedRange(DeprecatedRange),
640641
INIT_VER_TUPLE(Obsoleted), ObsoletedRange(ObsoletedRange),
641642
PlatformAgnostic(PlatformAgnostic),
642-
Platform(Platform)
643+
Platform(Platform),
644+
IsSPI(IsSPI)
643645
{}
644646

645647
#undef INIT_VER_TUPLE
@@ -685,6 +687,9 @@ class AvailableAttr : public DeclAttribute {
685687
/// The platform of the availability.
686688
const PlatformKind Platform;
687689

690+
/// Whether this is available as SPI.
691+
const bool IsSPI;
692+
688693
/// Whether this is a language-version-specific entity.
689694
bool isLanguageVersionSpecific() const;
690695

include/swift/AST/Availability.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,12 @@ class UnavailabilityReason {
209209
/// [lattice]: http://mathworld.wolfram.com/Lattice.html
210210
class AvailabilityContext {
211211
VersionRange OSVersion;
212+
llvm::Optional<bool> SPI;
212213
public:
213214
/// Creates a context that requires certain versions of the target OS.
214-
explicit AvailabilityContext(VersionRange OSVersion) : OSVersion(OSVersion) {}
215+
explicit AvailabilityContext(VersionRange OSVersion,
216+
llvm::Optional<bool> SPI = llvm::None)
217+
: OSVersion(OSVersion), SPI(SPI) {}
215218

216219
/// Creates a context that imposes the constraints of the ASTContext's
217220
/// deployment target.
@@ -291,6 +294,10 @@ class AvailabilityContext {
291294
void unionWith(AvailabilityContext other) {
292295
OSVersion.unionWith(other.getOSVersion());
293296
}
297+
298+
bool isAvailableAsSPI() const {
299+
return SPI && *SPI;
300+
}
294301
};
295302

296303

include/swift/AST/Decl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,8 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
10301030
// an @_spi context.
10311031
bool isSPI() const;
10321032

1033+
bool isAvailableAsSPI() const;
1034+
10331035
// List the SPI groups declared with @_spi or inherited by this decl.
10341036
//
10351037
// SPI groups are inherited from the parent contexts only if the local decl

include/swift/AST/DiagnosticsSema.def

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ ERROR(could_not_use_instance_member_on_type,none,
142142
"%select{| instance of nested}3 type %0",
143143
(Type, DeclNameRef, Type, bool))
144144
ERROR(could_not_use_member_on_existential,none,
145-
"member %1 cannot be used on value of protocol type %0; consider using a"
145+
"member %1 cannot be used on value of type %0; consider using a"
146146
" generic constraint instead",
147147
(Type, DeclNameRef))
148148
FIXIT(replace_with_type,"%0",(Type))
@@ -1542,6 +1542,9 @@ ERROR(optional_attribute_initializer,none,
15421542
ERROR(unavailable_method_non_objc_protocol,none,
15431543
"protocol members can only be marked unavailable in an @objc protocol",
15441544
())
1545+
ERROR(spi_available_malformed,none,
1546+
"SPI available only supports introducing version on specific platform",
1547+
())
15451548
ERROR(missing_in_class_init_1,none,
15461549
"stored property %0 requires an initial value%select{| or should be "
15471550
"@NSManaged}1", (Identifier, bool))
@@ -1945,9 +1948,8 @@ ERROR(type_cannot_conform_to_nsobject,none,
19451948
ERROR(use_of_equal_instead_of_equality,none,
19461949
"use of '=' in a boolean context, did you mean '=='?", ())
19471950
ERROR(type_cannot_conform, none,
1948-
"%select{type %1|protocol %1 as a type}0 cannot conform to "
1949-
"%select{%3|the protocol itself}2",
1950-
(bool, Type, bool, Type))
1951+
"type %0 cannot conform to %1",
1952+
(Type, Type))
19511953
NOTE(only_concrete_types_conform_to_protocols,none,
19521954
"only concrete types such as structs, enums and classes can conform to protocols",
19531955
())
@@ -2455,8 +2457,8 @@ ERROR(protocol_composition_one_class,none,
24552457
"contains class %1", (Type, Type))
24562458

24572459
ERROR(requires_conformance_nonprotocol,none,
2458-
"type %0 constrained to non-protocol, non-class type '%1'",
2459-
(Type, StringRef))
2460+
"type %0 constrained to non-protocol, non-class type %1",
2461+
(Type, Type))
24602462
NOTE(requires_conformance_nonprotocol_fixit,none,
24612463
"use '%0 == %1' to require '%0' to be '%1'",
24622464
(StringRef, StringRef))
@@ -2777,9 +2779,9 @@ WARNING(anyobject_class_inheritance_deprecated,Deprecation,
27772779
ERROR(multiple_inheritance,none,
27782780
"multiple inheritance from classes %0 and %1", (Type, Type))
27792781
ERROR(inheritance_from_non_protocol_or_class,none,
2780-
"inheritance from non-protocol, non-class type '%0'", (StringRef))
2782+
"inheritance from non-protocol, non-class type %0", (Type))
27812783
ERROR(inheritance_from_non_protocol,none,
2782-
"inheritance from non-protocol type '%0'", (StringRef))
2784+
"inheritance from non-protocol type %0", (Type))
27832785
ERROR(inheritance_from_anyobject,none,
27842786
"only protocols can inherit from 'AnyObject'", ())
27852787
ERROR(inheritance_from_parameterized_protocol,none,
@@ -3589,7 +3591,7 @@ ERROR(construct_protocol_value,none,
35893591
"value of type %0 is a protocol; it cannot be instantiated",
35903592
(Type))
35913593
ERROR(construct_protocol_by_name,none,
3592-
"protocol type %0 cannot be instantiated",
3594+
"type %0 cannot be instantiated",
35933595
(Type))
35943596

35953597
// Operators

include/swift/AST/PrintOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,13 @@ struct PrintOptions {
548548
return result;
549549
}
550550

551+
/// The print options used for formatting diagnostic arguments.
552+
static PrintOptions forDiagnosticArguments() {
553+
PrintOptions result;
554+
result.PrintExplicitAny = true;
555+
return result;
556+
}
557+
551558
/// Retrieve the set of options suitable for diagnostics printing.
552559
static PrintOptions printForDiagnostics(AccessLevel accessFilter,
553560
bool printFullConvention) {

include/swift/AST/Types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5330,7 +5330,7 @@ class ExistentialType final : public TypeBase {
53305330
ConstraintType(constraintType) {}
53315331

53325332
public:
5333-
static Type get(Type constraint);
5333+
static Type get(Type constraint, bool forceExistential = false);
53345334

53355335
Type getConstraintType() const { return ConstraintType; }
53365336

@@ -6663,9 +6663,9 @@ inline bool TypeBase::hasSimpleTypeRepr() const {
66636663
return false;
66646664

66656665
case TypeKind::Metatype:
6666-
case TypeKind::ExistentialMetatype:
66676666
return !cast<const AnyMetatypeType>(this)->hasRepresentation();
66686667

6668+
case TypeKind::ExistentialMetatype:
66696669
case TypeKind::Existential:
66706670
return false;
66716671

include/swift/Strings.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ constexpr static const StringLiteral BUILTIN_TYPE_NAME_PREFIX = "Builtin.";
6464
constexpr static const StringLiteral CLANG_MODULE_DEFUALT_SPI_GROUP_NAME =
6565
"OBJC_DEFAULT_SPI_GROUP";
6666

67+
/// The attribute name for @_spi_available
68+
constexpr static const StringLiteral SPI_AVAILABLE_ATTRNAME =
69+
"_spi_available";
70+
6771
/// A composition class containing a StringLiteral for the names of
6872
/// Swift builtins. The reason we use this is to ensure that we when
6973
/// necessary slice off the "Builtin." prefix from these names in a

lib/AST/ASTContext.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4260,15 +4260,17 @@ ProtocolType::ProtocolType(ProtocolDecl *TheDecl, Type Parent,
42604260
RecursiveTypeProperties properties)
42614261
: NominalType(TypeKind::Protocol, &Ctx, TheDecl, Parent, properties) { }
42624262

4263-
Type ExistentialType::get(Type constraint) {
4263+
Type ExistentialType::get(Type constraint, bool forceExistential) {
42644264
auto &C = constraint->getASTContext();
4265-
// FIXME: Any and AnyObject don't yet use ExistentialType.
4266-
if (constraint->isAny() || constraint->isAnyObject())
4267-
return constraint;
4265+
if (!forceExistential) {
4266+
// FIXME: Any and AnyObject don't yet use ExistentialType.
4267+
if (constraint->isAny() || constraint->isAnyObject())
4268+
return constraint;
42684269

4269-
// ExistentialMetatypeType is already an existential type.
4270-
if (constraint->is<ExistentialMetatypeType>())
4271-
return constraint;
4270+
// ExistentialMetatypeType is already an existential type.
4271+
if (constraint->is<ExistentialMetatypeType>())
4272+
return constraint;
4273+
}
42724274

42734275
assert(constraint->isConstraintType());
42744276

lib/AST/ASTPrinter.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5171,6 +5171,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
51715171
} else if (auto existential = dyn_cast<ExistentialType>(T.getPointer())) {
51725172
if (!Options.PrintExplicitAny)
51735173
return isSimpleUnderPrintOptions(existential->getConstraintType());
5174+
} else if (auto existential = dyn_cast<ExistentialMetatypeType>(T.getPointer())) {
5175+
if (!Options.PrintExplicitAny)
5176+
return isSimpleUnderPrintOptions(existential->getInstanceType());
51745177
}
51755178
return T->hasSimpleTypeRepr();
51765179
}
@@ -5591,10 +5594,32 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
55915594
}
55925595
}
55935596

5594-
if (T->is<ExistentialMetatypeType>() && Options.PrintExplicitAny)
5595-
Printer << "any ";
5597+
Type instanceType = T->getInstanceType();
5598+
if (Options.PrintExplicitAny) {
5599+
if (T->is<ExistentialMetatypeType>()) {
5600+
Printer << "any ";
5601+
5602+
// FIXME: We need to replace nested existential metatypes so that
5603+
// we don't print duplicate 'any'. This will be unnecessary once
5604+
// ExistentialMetatypeType is split into ExistentialType(MetatypeType).
5605+
instanceType = Type(instanceType).transform([](Type type) -> Type {
5606+
if (auto existential = type->getAs<ExistentialMetatypeType>())
5607+
return MetatypeType::get(existential->getInstanceType());
5608+
5609+
return type;
5610+
});
5611+
} else if (instanceType->isAny() || instanceType->isAnyObject()) {
5612+
// FIXME: 'any' is needed to distinguish between '(any Any).Type'
5613+
// and 'any Any.Type'. However, this combined with the above hack
5614+
// to replace nested existential metatypes with metatypes causes
5615+
// a bug in printing nested existential metatypes for Any and AnyObject,
5616+
// e.g. 'any (any Any).Type.Type'. This will be fixed by using
5617+
// ExistentialType for Any and AnyObject.
5618+
instanceType = ExistentialType::get(instanceType, /*forceExistential=*/true);
5619+
}
5620+
}
55965621

5597-
printWithParensIfNotSimple(T->getInstanceType());
5622+
printWithParensIfNotSimple(instanceType);
55985623

55995624
// We spell normal metatypes of existential types as .Protocol.
56005625
if (isa<MetatypeType>(T) &&
@@ -6294,7 +6319,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
62946319
if (printNamedOpaque())
62956320
return;
62966321

6297-
visit(T->getExistentialType());
6322+
auto constraint = T->getExistentialType();
6323+
if (auto existential = constraint->getAs<ExistentialType>())
6324+
constraint = existential->getConstraintType();
6325+
6326+
visit(constraint);
62986327
return;
62996328
}
63006329
case PrintOptions::OpaqueReturnTypePrintingMode::StableReference: {

lib/AST/Attr.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/AST/Types.h"
3030
#include "swift/Basic/Defer.h"
3131
#include "swift/Basic/QuotedString.h"
32+
#include "swift/Strings.h"
3233
#include "llvm/ADT/SmallString.h"
3334
#include "llvm/ADT/StringSwitch.h"
3435
#include "llvm/Support/ErrorHandling.h"
@@ -126,6 +127,7 @@ DeclAttrKind DeclAttribute::getAttrKindFromString(StringRef Str) {
126127
#define DECL_ATTR(X, CLASS, ...) .Case(#X, DAK_##CLASS)
127128
#define DECL_ATTR_ALIAS(X, CLASS) .Case(#X, DAK_##CLASS)
128129
#include "swift/AST/Attr.def"
130+
.Case(SPI_AVAILABLE_ATTRNAME, DAK_Available)
129131
.Default(DAK_Count);
130132
}
131133

@@ -370,6 +372,9 @@ static bool isShortAvailable(const DeclAttribute *DA) {
370372
if (!AvailAttr)
371373
return false;
372374

375+
if (AvailAttr->IsSPI)
376+
return false;
377+
373378
if (!AvailAttr->Introduced.hasValue())
374379
return false;
375380

@@ -968,9 +973,23 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
968973
}
969974

970975
case DAK_Available: {
971-
Printer.printAttrName("@available");
972-
Printer << "(";
973976
auto Attr = cast<AvailableAttr>(this);
977+
if (!Options.PrintSPIs && Attr->IsSPI) {
978+
assert(Attr->hasPlatform());
979+
assert(Attr->Introduced.hasValue());
980+
Printer.printAttrName("@available");
981+
Printer << "(";
982+
Printer << Attr->platformString();
983+
Printer << ", unavailable)";
984+
break;
985+
}
986+
if (Attr->IsSPI) {
987+
std::string atSPI = (llvm::Twine("@") + SPI_AVAILABLE_ATTRNAME).str();
988+
Printer.printAttrName(atSPI);
989+
} else {
990+
Printer.printAttrName("@available");
991+
}
992+
Printer << "(";
974993
printAvailableAttr(Attr, Printer, Options);
975994
Printer << ")";
976995
break;
@@ -1599,7 +1618,7 @@ AvailableAttr::createPlatformAgnostic(ASTContext &C,
15991618
NoVersion, SourceRange(),
16001619
NoVersion, SourceRange(),
16011620
Obsoleted, SourceRange(),
1602-
Kind, /* isImplicit */ false);
1621+
Kind, /* isImplicit */ false, /*SPI*/false);
16031622
}
16041623

16051624
AvailableAttr *AvailableAttr::createForAlternative(
@@ -1610,7 +1629,7 @@ AvailableAttr *AvailableAttr::createForAlternative(
16101629
NoVersion, SourceRange(),
16111630
NoVersion, SourceRange(),
16121631
NoVersion, SourceRange(),
1613-
PlatformAgnosticAvailabilityKind::None, /*Implicit=*/true);
1632+
PlatformAgnosticAvailabilityKind::None, /*Implicit=*/true, /*SPI*/false);
16141633
}
16151634

16161635
bool AvailableAttr::isActivePlatform(const ASTContext &ctx) const {
@@ -1628,7 +1647,8 @@ AvailableAttr *AvailableAttr::clone(ASTContext &C, bool implicit) const {
16281647
Obsoleted ? *Obsoleted : llvm::VersionTuple(),
16291648
implicit ? SourceRange() : ObsoletedRange,
16301649
PlatformAgnostic,
1631-
implicit);
1650+
implicit,
1651+
IsSPI);
16321652
}
16331653

16341654
Optional<OriginallyDefinedInAttr::ActiveVersion>

0 commit comments

Comments
 (0)