Skip to content

Commit 4cc6411

Browse files
authored
Merge pull request #79983 from DougGregor/isolated-conformances-alignment
Align isolated conformances with the current proposal
2 parents 1fafebc + 01b2789 commit 4cc6411

39 files changed

+759
-166
lines changed

include/swift/AST/ASTContext.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ class ASTContext final {
279279
struct Implementation;
280280
Implementation &getImpl() const;
281281

282+
struct GlobalCache;
283+
284+
/// Retrieve a reference to the global cache within this ASTContext,
285+
/// which is a place where we can stash side tables without having to
286+
/// recompile the world every time we add a side table. See
287+
/// "swift/AST/ASTContextGlobalCache.h"
288+
GlobalCache &getGlobalCache() const;
289+
282290
friend ConstraintCheckerArenaRAII;
283291

284292
void operator delete(void *Data) throw();
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===--- ASTContextGlobalCache.h - AST Context Cache ------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the ASTContext::GlobalCache type. DO NOT include this
14+
// header from any other header: it should only be included in those .cpp
15+
// files that need to access the side tables. There are no include guards to
16+
// force the issue.
17+
//
18+
//===----------------------------------------------------------------------===//
19+
20+
#include "swift/AST/ASTContext.h"
21+
22+
namespace swift {
23+
24+
/// A collection of side tables associated with the ASTContext itself, meant
25+
// as
26+
struct ASTContext::GlobalCache {
27+
/// Mapping from normal protocol conformances to the explicitly-specified
28+
/// global actor isolations, e.g., when the conformance was spelled
29+
/// `@MainActor P` or similar.
30+
llvm::DenseMap<const NormalProtocolConformance *, TypeExpr *>
31+
conformanceExplicitGlobalActorIsolation;
32+
};
33+
34+
} // end namespace

include/swift/AST/ConformanceAttributes.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
namespace swift {
1919

20+
class TypeExpr;
21+
2022
/// Describes all of the attributes that can occur on a conformance.
2123
struct ConformanceAttributes {
2224
/// The location of the "unchecked" attribute, if present.
@@ -28,9 +30,15 @@ struct ConformanceAttributes {
2830
/// The location of the "unsafe" attribute if present.
2931
SourceLoc unsafeLoc;
3032

31-
/// The location of the "@isolated" attribute if present.
32-
SourceLoc isolatedLoc;
33-
33+
/// The location of the "nonisolated" modifier, if present.
34+
SourceLoc nonisolatedLoc;
35+
36+
/// The location of the '@' prior to the global actor type.
37+
SourceLoc globalActorAtLoc;
38+
39+
/// The global actor type to which this conformance is isolated.
40+
TypeExpr *globalActorType = nullptr;
41+
3442
/// Merge other conformance attributes into this set.
3543
ConformanceAttributes &
3644
operator |=(const ConformanceAttributes &other) {
@@ -40,8 +48,12 @@ struct ConformanceAttributes {
4048
preconcurrencyLoc = other.preconcurrencyLoc;
4149
if (other.unsafeLoc.isValid())
4250
unsafeLoc = other.unsafeLoc;
43-
if (other.isolatedLoc.isValid())
44-
isolatedLoc = other.isolatedLoc;
51+
if (other.nonisolatedLoc.isValid())
52+
nonisolatedLoc = other.nonisolatedLoc;
53+
if (other.globalActorType && !globalActorType) {
54+
globalActorAtLoc = other.globalActorAtLoc;
55+
globalActorType = other.globalActorType;
56+
}
4557
return *this;
4658
}
4759
};

include/swift/AST/Decl.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,16 +1806,20 @@ struct InheritedEntry : public TypeLoc {
18061806
/// This is true in cases like ~Copyable but not (P & ~Copyable).
18071807
bool IsSuppressed : 1;
18081808

1809+
/// The global actor isolation provided (for a conformance).
1810+
TypeExpr *globalActorIsolationType = nullptr;
1811+
18091812
public:
18101813
InheritedEntry(const TypeLoc &typeLoc);
18111814

18121815
InheritedEntry(const TypeLoc &typeLoc, ProtocolConformanceOptions options,
18131816
bool isSuppressed = false)
18141817
: TypeLoc(typeLoc), RawOptions(options.toRaw()),
1815-
IsSuppressed(isSuppressed) {}
1818+
IsSuppressed(isSuppressed),
1819+
globalActorIsolationType(options.getGlobalActorIsolationType()) {}
18161820

18171821
ProtocolConformanceOptions getOptions() const {
1818-
return ProtocolConformanceOptions(RawOptions);
1822+
return ProtocolConformanceOptions(RawOptions, globalActorIsolationType);
18191823
}
18201824

18211825
bool isUnchecked() const {
@@ -1827,8 +1831,12 @@ struct InheritedEntry : public TypeLoc {
18271831
bool isPreconcurrency() const {
18281832
return getOptions().contains(ProtocolConformanceFlags::Preconcurrency);
18291833
}
1830-
bool isIsolated() const {
1831-
return getOptions().contains(ProtocolConformanceFlags::Isolated);
1834+
bool isNonisolated() const {
1835+
return getOptions().contains(ProtocolConformanceFlags::Nonisolated);
1836+
}
1837+
1838+
TypeExpr *getGlobalActorIsolationType() const {
1839+
return globalActorIsolationType;
18321840
}
18331841

18341842
ExplicitSafety getExplicitSafety() const {

include/swift/AST/DiagnosticsSema.def

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8319,31 +8319,28 @@ ERROR(attr_abi_incompatible_with_silgen_name,none,
83198319
//===----------------------------------------------------------------------===//
83208320
// MARK: Isolated conformances
83218321
//===----------------------------------------------------------------------===//
8322-
ERROR(isolated_conformance_not_global_actor_isolated,none,
8323-
"isolated conformance is only permitted on global-actor-isolated types",
8324-
())
83258322
ERROR(isolated_conformance_experimental_feature,none,
83268323
"isolated conformances require experimental feature "
83278324
" 'IsolatedConformances'", ())
83288325
ERROR(nonisolated_conformance_depends_on_isolated_conformance,none,
8329-
"conformance of %0 to %1 depends on %2 conformance of %3 to %4; mark it as 'isolated'",
8330-
(Type, DeclName, ActorIsolation, Type, DeclName))
8326+
"conformance of %0 to %1 depends on %2 conformance of %3 to %4; mark it as '%5'",
8327+
(Type, DeclName, ActorIsolation, Type, DeclName, StringRef))
83318328
ERROR(isolated_conformance_mismatch_with_associated_isolation,none,
83328329
"%0 conformance of %1 to %2 cannot depend on %3 conformance of %4 to %5",
83338330
(ActorIsolation, Type, DeclName, ActorIsolation, Type, DeclName))
83348331
NOTE(add_isolated_to_conformance,none,
8335-
"add 'isolated' to the %0 conformance to restrict it to %1 code",
8336-
(DeclName, ActorIsolation))
8332+
"add '%0' to the %1 conformance to restrict it to %2 code",
8333+
(StringRef, DeclName, ActorIsolation))
83378334
ERROR(isolated_conformance_with_sendable,none,
8338-
"isolated conformance of %0 to %1 cannot be used to satisfy conformance "
8335+
"%4 conformance of %0 to %1 cannot be used to satisfy conformance "
83398336
"requirement for a %select{`Sendable`|`SendableMetatype`}2 type "
8340-
"parameter %3", (Type, DeclName, bool, Type))
8337+
"parameter %3", (Type, DeclName, bool, Type, ActorIsolation))
83418338
ERROR(isolated_conformance_with_sendable_simple,none,
8342-
"isolated conformance of %0 to %1 cannot be used to satisfy conformance "
8343-
"requirement for a `Sendable` type parameter ",
8344-
(Type, DeclName))
8339+
"%2 conformance of %0 to %1 cannot be used to satisfy "
8340+
"conformance requirement for a `Sendable` type parameter ",
8341+
(Type, DeclName, ActorIsolation))
83458342
ERROR(isolated_conformance_wrong_domain,none,
8346-
"%0 isolated conformance of %1 to %2 cannot be used in %3 context",
8343+
"%0 conformance of %1 to %2 cannot be used in %3 context",
83478344
(ActorIsolation, Type, DeclName, ActorIsolation))
83488345

83498346
//===----------------------------------------------------------------------===//

include/swift/AST/ProtocolConformance.h

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance
147147
SWIFT_INLINE_BITFIELD_EMPTY(RootProtocolConformance, ProtocolConformance);
148148

149149
SWIFT_INLINE_BITFIELD_FULL(NormalProtocolConformance, RootProtocolConformance,
150-
1+1+1+
150+
1+1+1+1+1+
151151
bitmax(NumProtocolConformanceOptions,8)+
152152
bitmax(NumProtocolConformanceStateBits,8)+
153153
bitmax(NumConformanceEntryKindBits,8),
@@ -161,6 +161,12 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance
161161
/// this conformance.
162162
IsPreconcurrencyEffectful : 1,
163163

164+
/// Whether the computed actor isolation is nonisolated.
165+
IsComputedNonisolated : 1,
166+
167+
/// Whether there is an explicit global actor specified for this
168+
/// conformance.
169+
HasExplicitGlobalActor : 1,
164170
: NumPadBits,
165171

166172
/// Options.
@@ -240,6 +246,14 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance
240246
/// Otherwise a new conformance will be created.
241247
ProtocolConformance *getCanonicalConformance();
242248

249+
/// Determine the actor isolation of this conformance.
250+
ActorIsolation getIsolation() const;
251+
252+
/// Determine whether this conformance is isolated to an actor.
253+
bool isIsolated() const {
254+
return getIsolation().isActorIsolated();
255+
}
256+
243257
/// Return true if the conformance has a witness for the given associated
244258
/// type.
245259
bool hasTypeWitness(AssociatedTypeDecl *assocType) const;
@@ -529,6 +543,7 @@ class NormalProtocolConformance : public RootProtocolConformance,
529543
{
530544
friend class ValueWitnessRequest;
531545
friend class TypeWitnessRequest;
546+
friend class ConformanceIsolationRequest;
532547

533548
/// The protocol being conformed to.
534549
ProtocolDecl *Protocol;
@@ -570,6 +585,20 @@ class NormalProtocolConformance : public RootProtocolConformance,
570585

571586
void resolveLazyInfo() const;
572587

588+
/// Retrieve the explicitly-specified global actor isolation.
589+
TypeExpr *getExplicitGlobalActorIsolation() const;
590+
591+
// Record the explicitly-specified global actor isolation.
592+
void setExplicitGlobalActorIsolation(TypeExpr *typeExpr);
593+
594+
bool isComputedNonisolated() const {
595+
return Bits.NormalProtocolConformance.IsComputedNonisolated;
596+
}
597+
598+
void setComputedNonnisolated(bool value = true) {
599+
Bits.NormalProtocolConformance.IsComputedNonisolated = value;
600+
}
601+
573602
public:
574603
NormalProtocolConformance(Type conformingType, ProtocolDecl *protocol,
575604
SourceLoc loc, DeclContext *dc,
@@ -593,6 +622,9 @@ class NormalProtocolConformance : public RootProtocolConformance,
593622
Bits.NormalProtocolConformance.HasComputedAssociatedConformances = false;
594623
Bits.NormalProtocolConformance.SourceKind =
595624
unsigned(ConformanceEntryKind::Explicit);
625+
Bits.NormalProtocolConformance.IsComputedNonisolated = false;
626+
Bits.NormalProtocolConformance.HasExplicitGlobalActor = false;
627+
setExplicitGlobalActorIsolation(options.getGlobalActorIsolationType());
596628
}
597629

598630
/// Get the protocol being conformed to.
@@ -634,7 +666,8 @@ class NormalProtocolConformance : public RootProtocolConformance,
634666
void setInvalid() { Bits.NormalProtocolConformance.IsInvalid = true; }
635667

636668
ProtocolConformanceOptions getOptions() const {
637-
return ProtocolConformanceOptions(Bits.NormalProtocolConformance.Options);
669+
return ProtocolConformanceOptions(Bits.NormalProtocolConformance.Options,
670+
getExplicitGlobalActorIsolation());
638671
}
639672

640673
/// Whether this is an "unchecked" conformance.
@@ -669,11 +702,6 @@ class NormalProtocolConformance : public RootProtocolConformance,
669702
return getOptions().contains(ProtocolConformanceFlags::Preconcurrency);
670703
}
671704

672-
/// Whether this is an isolated conformance.
673-
bool isIsolated() const {
674-
return getOptions().contains(ProtocolConformanceFlags::Isolated);
675-
}
676-
677705
/// Retrieve the location of `@preconcurrency`, if there is one and it is
678706
/// known.
679707
SourceLoc getPreconcurrencyLoc() const { return PreconcurrencyLoc; }

0 commit comments

Comments
 (0)