Skip to content

Commit 4843d91

Browse files
authored
Merge pull request #2774 from swiftwasm/main
[pull] swiftwasm from main
2 parents 45d85bb + b7a6bcb commit 4843d91

31 files changed

+519
-112
lines changed

include/swift/AST/Attr.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,12 @@ SIMPLE_DECL_ATTR(reasync, AtReasync,
624624
ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
625625
110)
626626

627+
DECL_ATTR(hasAsyncAlternative, HasAsyncAlternative,
628+
OnAbstractFunction | ConcurrencyOnly |
629+
ABIStableToAdd | ABIStableToRemove |
630+
APIStableToAdd | APIStableToRemove,
631+
111)
632+
627633
#undef TYPE_ATTR
628634
#undef DECL_ATTR_ALIAS
629635
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/Attr.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,6 +2140,30 @@ class TransposeAttr final
21402140
}
21412141
};
21422142

2143+
/// The `@hasAsyncAlternative` attribute marks a function as having an async
2144+
/// alternative, optionally providing a name (for cases when the alternative
2145+
/// has a different name).
2146+
class HasAsyncAlternativeAttr final : public DeclAttribute {
2147+
public:
2148+
/// An optional name of the async alternative function, where the name of the
2149+
/// attributed function is used otherwise.
2150+
const DeclNameRef Name;
2151+
2152+
HasAsyncAlternativeAttr(DeclNameRef Name, SourceLoc AtLoc, SourceRange Range)
2153+
: DeclAttribute(DAK_HasAsyncAlternative, AtLoc, Range, false),
2154+
Name(Name) {}
2155+
2156+
HasAsyncAlternativeAttr(SourceLoc AtLoc, SourceRange Range)
2157+
: DeclAttribute(DAK_HasAsyncAlternative, AtLoc, Range, false) {}
2158+
2159+
/// Determine whether this attribute has a name associated with it.
2160+
bool hasName() const { return !Name.getBaseName().empty(); }
2161+
2162+
static bool classof(const DeclAttribute *DA) {
2163+
return DA->getKind() == DAK_HasAsyncAlternative;
2164+
}
2165+
};
2166+
21432167
/// Attributes that may be applied to declarations.
21442168
class DeclAttributes {
21452169
/// Linked list of declaration attributes.

include/swift/AST/DiagnosticsParse.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,6 +1672,15 @@ ERROR(sil_inst_autodiff_invalid_witness_generic_signature,PointsToFirstBadToken,
16721672
"parameters as original function generic signature '%1'",
16731673
(StringRef, StringRef))
16741674

1675+
// hasAsyncAlternative
1676+
ERROR(requires_has_async_alternative, none,
1677+
"'%0' support is required to be explicitly enabled using "
1678+
"-experimental-has-async-alternative-attribute", (StringRef))
1679+
1680+
ERROR(has_async_alternative_invalid_name, none,
1681+
"argument of '%0' attribute must be an identifier or full function name",
1682+
(StringRef))
1683+
16751684
//------------------------------------------------------------------------------
16761685
// MARK: Generics parsing diagnostics
16771686
//------------------------------------------------------------------------------

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -779,9 +779,6 @@ NOTE(serialization_compatibility_version_mismatch,none,
779779
ERROR(serialization_allowing_invalid_decl,none,
780780
"allowing deserialization of invalid declaration %0 from module '%1'",
781781
(DeclName, StringRef))
782-
ERROR(serialization_invalid_decl,Fatal,
783-
"invalid declaration %0 read from module '%1'; "
784-
SWIFT_BUG_REPORT_MESSAGE, ())
785782

786783
ERROR(reserved_member_name,none,
787784
"type member must not be named %0, since it would conflict with the"
@@ -5625,8 +5622,8 @@ ERROR(marker_protocol_requirement, none,
56255622
ERROR(marker_protocol_inherit_nonmarker, none,
56265623
"marker protocol %0 cannot inherit non-marker protocol %1",
56275624
(DeclName, DeclName))
5628-
ERROR(marker_protocol_value,none,
5629-
"marker protocol %0 can only be used in generic constraints", (DeclName))
5625+
ERROR(marker_protocol_cast,none,
5626+
"marker protocol %0 cannot be used in a conditional cast", (DeclName))
56305627

56315628
//------------------------------------------------------------------------------
56325629
// MARK: differentiable programming diagnostics

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ namespace swift {
387387
ASTVerifierOverrideKind ASTVerifierOverride =
388388
ASTVerifierOverrideKind::NoOverride;
389389

390+
/// Allow @hasAsyncAlternative attribute
391+
bool EnableExperimentalHasAsyncAlternative = false;
392+
390393
/// Sets the target we are building for and updates platform conditions
391394
/// to match.
392395
///

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,4 +796,9 @@ def disable_ast_verifier : Flag<["-"], "disable-ast-verifier">,
796796
def new_driver_path
797797
: Separate<["-"], "new-driver-path">, MetaVarName<"<path>">,
798798
HelpText<"Path of the new driver to be used">;
799+
800+
def experimental_has_async_alternative_attribute:
801+
Flag<["-"], "experimental-has-async-alternative-attribute">,
802+
HelpText<"Allow use of @hasAsyncAlternative">;
803+
799804
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

include/swift/Sema/CSFix.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,8 @@ class MissingConformance final : public ConstraintFix {
478478

479479
bool diagnose(const Solution &solution, bool asNote = false) const override;
480480

481+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override;
482+
481483
static MissingConformance *forRequirement(ConstraintSystem &cs, Type type,
482484
Type protocolType,
483485
ConstraintLocator *locator);
@@ -489,6 +491,12 @@ class MissingConformance final : public ConstraintFix {
489491
Type getNonConformingType() { return NonConformingType; }
490492

491493
Type getProtocolType() { return ProtocolType; }
494+
495+
bool isEqual(const ConstraintFix *other) const;
496+
497+
static bool classof(const ConstraintFix *fix) {
498+
return fix->getKind() == FixKind::AddConformance;
499+
}
492500
};
493501

494502
/// Skip same-type generic requirement constraint,
@@ -1386,11 +1394,19 @@ class MoveOutOfOrderArgument final : public ConstraintFix {
13861394

13871395
bool diagnose(const Solution &solution, bool asNote = false) const override;
13881396

1397+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override;
1398+
1399+
bool isEqual(const ConstraintFix *other) const;
1400+
13891401
static MoveOutOfOrderArgument *create(ConstraintSystem &cs,
13901402
unsigned argIdx,
13911403
unsigned prevArgIdx,
13921404
ArrayRef<ParamBinding> bindings,
13931405
ConstraintLocator *locator);
1406+
1407+
static bool classof(const ConstraintFix *fix) {
1408+
return fix->getKind() == FixKind::MoveOutOfOrderArgument;
1409+
}
13941410
};
13951411

13961412
class AllowInaccessibleMember final : public AllowInvalidMemberRef {
@@ -1512,10 +1528,18 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
15121528

15131529
bool diagnose(const Solution &solution, bool asNote = false) const override;
15141530

1531+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override;
1532+
15151533
/// Determine whether give reference requires a fix and produce one.
15161534
static AllowInvalidRefInKeyPath *
15171535
forRef(ConstraintSystem &cs, ValueDecl *member, ConstraintLocator *locator);
15181536

1537+
bool isEqual(const ConstraintFix *other) const;
1538+
1539+
static bool classof(const ConstraintFix *fix) {
1540+
return fix->getKind() == FixKind::AllowInvalidRefInKeyPath;
1541+
}
1542+
15191543
private:
15201544
static AllowInvalidRefInKeyPath *create(ConstraintSystem &cs, RefKind kind,
15211545
ValueDecl *member,

lib/AST/ASTPrinter.cpp

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -968,8 +968,21 @@ class PrintAST : public ASTVisitor<PrintAST> {
968968

969969
ASTVisitor::visit(D);
970970

971-
if (haveFeatureChecks)
971+
if (haveFeatureChecks) {
972+
// If we guarded a marker protocol, print an alternative typealias
973+
// for Any.
974+
if (auto proto = dyn_cast<ProtocolDecl>(D)) {
975+
if (proto->isMarkerProtocol()) {
976+
Printer.printNewline();
977+
Printer << "#else";
978+
Printer.printNewline();
979+
printAccess(proto);
980+
Printer << "typealias " << proto->getName() << " = Any";
981+
}
982+
}
983+
972984
printCompatibilityFeatureChecksPost(Printer);
985+
}
973986

974987
if (Synthesize) {
975988
Printer.setSynthesizedTarget({});
@@ -2426,53 +2439,16 @@ static bool usesFeatureAsyncAwait(Decl *decl) {
24262439
}
24272440

24282441
static bool usesFeatureMarkerProtocol(Decl *decl) {
2429-
// Check an inheritance clause for a marker protocol.
2430-
auto checkInherited = [&](ArrayRef<TypeLoc> inherited) -> bool {
2431-
for (const auto &inheritedEntry : inherited) {
2432-
if (auto inheritedType = inheritedEntry.getType()) {
2433-
if (inheritedType->isExistentialType()) {
2434-
auto layout = inheritedType->getExistentialLayout();
2435-
for (ProtocolType *protoTy : layout.getProtocols()) {
2436-
if (protoTy->getDecl()->isMarkerProtocol())
2437-
return true;
2438-
}
2439-
}
2440-
}
2441-
}
2442-
2443-
return false;
2444-
};
2445-
2446-
// Check generic requirements for a marker protocol.
2447-
auto checkRequirements = [&](ArrayRef<Requirement> requirements) -> bool {
2448-
for (const auto &req: requirements) {
2449-
if (req.getKind() == RequirementKind::Conformance &&
2450-
req.getSecondType()->castTo<ProtocolType>()->getDecl()
2451-
->isMarkerProtocol())
2452-
return true;
2453-
}
2454-
2455-
return false;
2456-
};
2457-
24582442
if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
24592443
if (proto->isMarkerProtocol())
24602444
return true;
2461-
2462-
if (checkInherited(proto->getInherited()))
2463-
return true;
2464-
2465-
if (checkRequirements(proto->getRequirementSignature()))
2466-
return true;
24672445
}
24682446

24692447
if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
2470-
if (checkRequirements(ext->getGenericRequirements()))
2471-
return true;
2472-
2473-
if (checkInherited(ext->getInherited()))
2474-
return true;
2475-
}
2448+
if (auto proto = ext->getSelfProtocolDecl())
2449+
if (proto->isMarkerProtocol())
2450+
return true;
2451+
}
24762452

24772453
return false;
24782454
}

lib/AST/Attr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,8 @@ StringRef DeclAttribute::getAttrName() const {
12231223
return "derivative";
12241224
case DAK_Transpose:
12251225
return "transpose";
1226+
case DAK_HasAsyncAlternative:
1227+
return "hasAsyncAlternative";
12261228
}
12271229
llvm_unreachable("bad DeclAttrKind");
12281230
}

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,19 @@ const RequirementSource *RequirementSource::getMinimalConformanceSource(
820820
switch (source->kind) {
821821
case ProtocolRequirement:
822822
case InferredProtocolRequirement: {
823+
// Special handling for top-level requirement signature requirements;
824+
// pretend the root type is the subject type as written in the
825+
// protocol, and not 'Self', so that we can consider this requirement
826+
// self-derived if it depends on one of the conformances that make
827+
// the root type valid.
828+
if (requirementSignatureSelfProto) {
829+
if (source->getProtocolDecl() == requirementSignatureSelfProto &&
830+
source->parent->kind == RequirementSource::RequirementSignatureSelf) {
831+
rootType = source->getAffectedType();
832+
return false;
833+
}
834+
}
835+
823836
// Note that we've seen a protocol requirement.
824837
sawProtocolRequirement = true;
825838

@@ -2144,37 +2157,40 @@ void EquivalenceClass::dump(llvm::raw_ostream &out,
21442157
}, [&]() {
21452158
out << ", ";
21462159
});
2147-
out << "\nConformances:";
2148-
interleave(conformsTo,
2149-
[&](const std::pair<
2150-
ProtocolDecl *,
2151-
std::vector<Constraint<ProtocolDecl *>>> &entry) {
2152-
out << entry.first->getNameStr();
2153-
},
2154-
[&] { out << ", "; });
2155-
out << "\nSame-type constraints:";
2156-
llvm::interleave(
2157-
sameTypeConstraints,
2158-
[&](const Constraint<Type> &constraint) {
2159-
out << "\n " << constraint.getSubjectDependentType({})
2160-
<< " == " << constraint.value;
2160+
out << "\n";
2161+
out << "Conformance constraints:\n";
2162+
for (auto entry : conformsTo) {
2163+
out << " " << entry.first->getNameStr() << "\n";
2164+
for (auto constraint : entry.second) {
2165+
constraint.source->dump(out, &builder->getASTContext().SourceMgr, 4);
2166+
if (constraint.source->isDerivedRequirement())
2167+
out << " [derived]";
2168+
out << "\n";
2169+
}
2170+
}
2171+
2172+
out << "Same-type constraints:\n";
2173+
for (auto constraint : sameTypeConstraints) {
2174+
out << " " << constraint.getSubjectDependentType({})
2175+
<< " == " << constraint.value << "\n";
2176+
constraint.source->dump(out, &builder->getASTContext().SourceMgr, 4);
2177+
if (constraint.source->isDerivedRequirement())
2178+
out << " [derived]";
2179+
out << "\n";
2180+
}
21612181

2162-
if (constraint.source->isDerivedRequirement())
2163-
out << " [derived]";
2164-
},
2165-
[&] { out << ", "; });
21662182
if (concreteType)
2167-
out << "\nConcrete type: " << concreteType.getString();
2183+
out << "Concrete type: " << concreteType.getString() << "\n";
21682184
if (superclass)
2169-
out << "\nSuperclass: " << superclass.getString();
2185+
out << "Superclass: " << superclass.getString() << "\n";
21702186
if (layout)
2171-
out << "\nLayout: " << layout.getString();
2187+
out << "Layout: " << layout.getString() << "\n";
21722188

21732189
if (!delayedRequirements.empty()) {
2174-
out << "\nDelayed requirements:";
2190+
out << "Delayed requirements:\n";
21752191
for (const auto &req : delayedRequirements) {
2176-
out << "\n ";
21772192
req.dump(out);
2193+
out << "\n";
21782194
}
21792195
}
21802196

lib/AST/Module.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,8 +918,8 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
918918

919919
// Due to an IRGen limitation, witness tables cannot be passed from an
920920
// existential to an archetype parameter, so for now we restrict this to
921-
// @objc protocols.
922-
if (!layout.isObjC()) {
921+
// @objc protocols and marker protocols.
922+
if (!layout.isObjC() && !protocol->isMarkerProtocol()) {
923923
// There's a specific exception for protocols with self-conforming
924924
// witness tables, but the existential has to be *exactly* that type.
925925
// TODO: synthesize witness tables on-demand for protocol compositions

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
715715
}
716716
}
717717

718+
Opts.EnableExperimentalHasAsyncAlternative |=
719+
Args.hasArg(OPT_experimental_has_async_alternative_attribute);
720+
718721
return HadError || UnsupportedOS || UnsupportedArch;
719722
}
720723

0 commit comments

Comments
 (0)