Skip to content

Commit 760ff8f

Browse files
committed
---
yaml --- r: 319341 b: refs/heads/master-rebranch c: 33ee4a4 h: refs/heads/master i: 319339: 49a8ade
1 parent f6511a6 commit 760ff8f

18 files changed

+213
-149
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,4 +1457,4 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-02-a: ddd2b2976aa9bfde5f20fe37f6bd2
14571457
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-03-a: 171cc166f2abeb5ca2a4003700a8a78a108bd300
14581458
refs/heads/benlangmuir-patch-1: baaebaf39d52f3bf36710d4fe40cf212e996b212
14591459
refs/heads/i-do-redeclare: 8c4e6d5de5c1e3f0a2cedccf319df713ea22c48e
1460-
refs/heads/master-rebranch: 3d34789f6b64964fe5cf4fc9c60e0dab9fc54c4a
1460+
refs/heads/master-rebranch: 33ee4a44303c5de97df9561be6778c5cf58a87ae

branches/master-rebranch/include/swift/AST/Decl.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3045,17 +3045,19 @@ class AssociatedTypeDecl : public AbstractTypeParamDecl {
30453045
SourceLoc KeywordLoc;
30463046

30473047
/// The default definition.
3048-
TypeLoc DefaultDefinition;
3048+
TypeRepr *DefaultDefinition;
30493049

30503050
/// The where clause attached to the associated type.
30513051
TrailingWhereClause *TrailingWhere;
30523052

30533053
LazyMemberLoader *Resolver = nullptr;
30543054
uint64_t ResolverContextData;
30553055

3056+
friend class DefaultDefinitionTypeRequest;
3057+
30563058
public:
30573059
AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc, Identifier name,
3058-
SourceLoc nameLoc, TypeLoc defaultDefinition,
3060+
SourceLoc nameLoc, TypeRepr *defaultDefinition,
30593061
TrailingWhereClause *trailingWhere);
30603062
AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc, Identifier name,
30613063
SourceLoc nameLoc, TrailingWhereClause *trailingWhere,
@@ -3071,17 +3073,14 @@ class AssociatedTypeDecl : public AbstractTypeParamDecl {
30713073
bool hasDefaultDefinitionType() const {
30723074
// If we have a TypeRepr, return true immediately without kicking off
30733075
// a request.
3074-
return !DefaultDefinition.isNull() || getDefaultDefinitionType();
3076+
return DefaultDefinition || getDefaultDefinitionType();
30753077
}
30763078

30773079
/// Retrieve the default definition type.
30783080
Type getDefaultDefinitionType() const;
30793081

3080-
TypeLoc &getDefaultDefinitionLoc() {
3081-
return DefaultDefinition;
3082-
}
3083-
3084-
const TypeLoc &getDefaultDefinitionLoc() const {
3082+
/// Retrieve the default definition as written in the source.
3083+
TypeRepr *getDefaultDefinitionTypeRepr() const {
30853084
return DefaultDefinition;
30863085
}
30873086

branches/master-rebranch/include/swift/AST/TypeCheckRequests.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,30 @@ class RequirementSignatureRequest :
269269
void cacheResult(ArrayRef<Requirement> value) const;
270270
};
271271

272+
/// Compute the default definition type of an associated type.
273+
class DefaultDefinitionTypeRequest :
274+
public SimpleRequest<DefaultDefinitionTypeRequest,
275+
CacheKind::Cached,
276+
Type,
277+
AssociatedTypeDecl *> {
278+
public:
279+
using SimpleRequest::SimpleRequest;
280+
281+
private:
282+
friend SimpleRequest;
283+
284+
// Evaluation.
285+
llvm::Expected<Type> evaluate(Evaluator &evaluator, AssociatedTypeDecl *decl) const;
286+
287+
public:
288+
// Cycle handling
289+
void diagnoseCycle(DiagnosticEngine &diags) const;
290+
void noteCycleStep(DiagnosticEngine &diags) const;
291+
292+
// Caching.
293+
bool isCached() const { return true; }
294+
};
295+
272296
/// Describes the owner of a where clause, from which we can extract
273297
/// requirements.
274298
struct WhereClauseOwner {

branches/master-rebranch/include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ SWIFT_TYPEID(IsFinalRequest)
2323
SWIFT_TYPEID(IsDynamicRequest)
2424
SWIFT_TYPEID(RequirementRequest)
2525
SWIFT_TYPEID(RequirementSignatureRequest)
26+
SWIFT_TYPEID(DefaultDefinitionTypeRequest)
2627
SWIFT_TYPEID(USRGenerationRequest)
2728
SWIFT_TYPEID(StructuralTypeRequest)
2829
SWIFT_TYPEID(DefaultTypeRequest)

branches/master-rebranch/include/swift/SIL/MemAccessUtils.h

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
#ifndef SWIFT_SIL_MEMACCESSUTILS_H
1616
#define SWIFT_SIL_MEMACCESSUTILS_H
1717

18-
#include "swift/SIL/Projection.h"
1918
#include "swift/SIL/InstructionUtils.h"
19+
#include "swift/SIL/SILArgument.h"
20+
#include "swift/SIL/SILBasicBlock.h"
2021
#include "swift/SIL/SILInstruction.h"
2122
#include "llvm/ADT/DenseMap.h"
2223

@@ -28,31 +29,6 @@ inline bool accessKindMayConflict(SILAccessKind a, SILAccessKind b) {
2829
return !(a == SILAccessKind::Read && b == SILAccessKind::Read);
2930
}
3031

31-
/// Represents the identity of a stored class property as a combination
32-
/// of a base and projection.
33-
class ObjectProjection {
34-
SILValue object;
35-
Projection proj;
36-
37-
public:
38-
ObjectProjection(SILValue object, const Projection &projection)
39-
: object(object), proj(projection) {
40-
assert(object->getType().isObject());
41-
}
42-
43-
SILValue getObject() const { return object; }
44-
45-
const Projection &getProjection() const { return proj; }
46-
47-
bool operator==(const ObjectProjection &other) const {
48-
return object == other.object && proj == other.proj;
49-
}
50-
51-
bool operator!=(const ObjectProjection &other) const {
52-
return object != other.object || proj != other.proj;
53-
}
54-
};
55-
5632
/// Represents the identity of a storage object being accessed.
5733
///
5834
/// AccessedStorage may be one of several kinds of "identified" storage
@@ -107,7 +83,23 @@ class AccessedStorage {
10783
/// of access base. Otherwise, return Unidentified.
10884
static AccessedStorage::Kind classify(SILValue base);
10985

86+
/// Directly create an AccessedStorage for class property access.
87+
static AccessedStorage forClass(SILValue object, unsigned propertyIndex) {
88+
AccessedStorage storage;
89+
storage.initKind(Class, propertyIndex);
90+
storage.value = object;
91+
return storage;
92+
}
93+
11094
protected:
95+
// Checking the storage kind is far more common than other fields. Make sure
96+
// it can be byte load with no shift.
97+
static const int ReservedKindBits = 8;
98+
static_assert(ReservedKindBits >= NumKindBits, "Too many storage kinds.");
99+
100+
static const unsigned InvalidElementIndex =
101+
(1 << (32 - ReservedKindBits)) - 1;
102+
111103
// Form a bitfield that is effectively a union over any pass-specific data
112104
// with the fields used within this class as a common prefix.
113105
//
@@ -122,9 +114,13 @@ class AccessedStorage {
122114
// each begin_access to its storage object, unique access index, and summary
123115
// info for that access.
124116
union {
125-
uint64_t OpaqueBits;
126-
SWIFT_INLINE_BITFIELD_BASE(AccessedStorage, bitmax(NumKindBits, 8),
127-
Kind : bitmax(NumKindBits, 8));
117+
uint64_t opaqueBits;
118+
// elementIndex can overflow while gracefully degrading analysis. For now,
119+
// reserve an absurd number of bits at a nice alignment boundary, but this
120+
// can be reduced.
121+
SWIFT_INLINE_BITFIELD_BASE(AccessedStorage, 32, kind
122+
: ReservedKindBits,
123+
elementIndex : 32 - ReservedKindBits);
128124

129125
// Define bits for use in AccessedStorageAnalysis. Each identified storage
130126
// object is mapped to one instance of this subclass.
@@ -157,59 +153,67 @@ class AccessedStorage {
157153

158154
private:
159155
union {
156+
// For non-class storage, 'value' is the access base. For class storage
157+
// 'value' is the object base, where the access base is the class' stored
158+
// property.
160159
SILValue value;
161-
unsigned paramIndex;
162160
SILGlobalVariable *global;
163-
ObjectProjection objProj;
164161
};
165162

166-
void initKind(Kind k) {
167-
Bits.OpaqueBits = 0;
168-
Bits.AccessedStorage.Kind = k;
163+
void initKind(Kind k, unsigned elementIndex = InvalidElementIndex) {
164+
Bits.opaqueBits = 0;
165+
Bits.AccessedStorage.kind = k;
166+
Bits.AccessedStorage.elementIndex = elementIndex;
167+
}
168+
169+
unsigned getElementIndex() const { return Bits.AccessedStorage.elementIndex; }
170+
void setElementIndex(unsigned elementIndex) {
171+
Bits.AccessedStorage.elementIndex = elementIndex;
169172
}
170173

171174
public:
172175
AccessedStorage() : value() { initKind(Unidentified); }
173176

174177
AccessedStorage(SILValue base, Kind kind);
175178

176-
AccessedStorage(SILValue object, Projection projection)
177-
: objProj(object, projection) {
178-
initKind(Class);
179-
}
180-
181179
// Return true if this is a valid storage object.
182180
operator bool() const { return getKind() != Unidentified || value; }
183181

184-
Kind getKind() const { return static_cast<Kind>(Bits.AccessedStorage.Kind); }
182+
Kind getKind() const { return static_cast<Kind>(Bits.AccessedStorage.kind); }
185183

186184
// Clear any bits reserved for subclass data. Useful for up-casting back to
187185
// the base class.
188-
void resetSubclassData() { initKind(getKind()); }
186+
void resetSubclassData() {
187+
initKind(getKind(), Bits.AccessedStorage.elementIndex);
188+
}
189189

190190
SILValue getValue() const {
191-
assert(getKind() != Argument && getKind() != Global && getKind() != Class);
191+
assert(getKind() != Global && getKind() != Class);
192192
return value;
193193
}
194194

195195
unsigned getParamIndex() const {
196196
assert(getKind() == Argument);
197-
return paramIndex;
197+
return getElementIndex();
198198
}
199199

200-
SILArgument *getArgument(SILFunction *F) const {
200+
SILArgument *getArgument() const {
201201
assert(getKind() == Argument);
202-
return F->getArgument(paramIndex);
202+
return cast<SILArgument>(value);
203203
}
204204

205205
SILGlobalVariable *getGlobal() const {
206206
assert(getKind() == Global);
207207
return global;
208208
}
209209

210-
const ObjectProjection &getObjectProjection() const {
210+
SILValue getObject() const {
211211
assert(getKind() == Class);
212-
return objProj;
212+
return value;
213+
}
214+
unsigned getPropertyIndex() const {
215+
assert(getKind() == Class);
216+
return getElementIndex();
213217
}
214218

215219
/// Return true if the given storage objects have identical storage locations.
@@ -223,16 +227,16 @@ class AccessedStorage {
223227
switch (getKind()) {
224228
case Box:
225229
case Stack:
230+
case Argument:
226231
case Yield:
227232
case Nested:
228233
case Unidentified:
229234
return value == other.value;
230-
case Argument:
231-
return paramIndex == other.paramIndex;
232235
case Global:
233236
return global == other.global;
234237
case Class:
235-
return objProj == other.objProj;
238+
return value == other.value
239+
&& getElementIndex() == other.getElementIndex();
236240
}
237241
}
238242

@@ -286,19 +290,19 @@ class AccessedStorage {
286290
// Classes are not uniquely identified by their base. However, if the
287291
// underling objects have identical types and distinct property indices then
288292
// they are distinct storage locations.
289-
auto &proj = getObjectProjection();
290-
auto &otherProj = other.getObjectProjection();
291-
if (proj.getObject()->getType() == otherProj.getObject()->getType()
292-
&& proj.getProjection() != otherProj.getProjection()) {
293+
if (getObject()->getType() == other.getObject()->getType()
294+
&& getPropertyIndex() != other.getPropertyIndex()) {
293295
return true;
294296
}
295297
return false;
296298
}
297299

298300
/// Returns the ValueDecl for the underlying storage, if it can be
299-
/// determined. Otherwise returns null. For diagnostics and checking via the
300-
/// ValueDecl if we are processing a `let` variable.
301-
const ValueDecl *getDecl(SILFunction *F) const;
301+
/// determined. Otherwise returns null.
302+
///
303+
/// WARNING: This is not a constant-time operation. It is for diagnostics and
304+
/// checking via the ValueDecl if we are processing a `let` variable.
305+
const ValueDecl *getDecl() const;
302306

303307
void print(raw_ostream &os) const;
304308
void dump() const;
@@ -343,8 +347,8 @@ template <> struct DenseMapInfo<swift::AccessedStorage> {
343347
case swift::AccessedStorage::Global:
344348
return DenseMapInfo<void *>::getHashValue(storage.getGlobal());
345349
case swift::AccessedStorage::Class: {
346-
const swift::ObjectProjection &P = storage.getObjectProjection();
347-
return llvm::hash_combine(P.getObject(), P.getProjection());
350+
return llvm::hash_combine(storage.getObject(),
351+
storage.getPropertyIndex());
348352
}
349353
}
350354
llvm_unreachable("Unhandled AccessedStorageKind");

branches/master-rebranch/lib/AST/Decl.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3539,7 +3539,7 @@ SourceRange GenericTypeParamDecl::getSourceRange() const {
35393539

35403540
AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
35413541
Identifier name, SourceLoc nameLoc,
3542-
TypeLoc defaultDefinition,
3542+
TypeRepr *defaultDefinition,
35433543
TrailingWhereClause *trailingWhere)
35443544
: AbstractTypeParamDecl(DeclKind::AssociatedType, dc, name, nameLoc),
35453545
KeywordLoc(keywordLoc), DefaultDefinition(defaultDefinition),
@@ -3552,8 +3552,9 @@ AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
35523552
LazyMemberLoader *definitionResolver,
35533553
uint64_t resolverData)
35543554
: AbstractTypeParamDecl(DeclKind::AssociatedType, dc, name, nameLoc),
3555-
KeywordLoc(keywordLoc), TrailingWhere(trailingWhere),
3556-
Resolver(definitionResolver), ResolverContextData(resolverData) {
3555+
KeywordLoc(keywordLoc), DefaultDefinition(nullptr),
3556+
TrailingWhere(trailingWhere), Resolver(definitionResolver),
3557+
ResolverContextData(resolverData) {
35573558
assert(Resolver && "missing resolver");
35583559
}
35593560

@@ -3566,21 +3567,17 @@ void AssociatedTypeDecl::computeType() {
35663567
}
35673568

35683569
Type AssociatedTypeDecl::getDefaultDefinitionType() const {
3569-
if (Resolver) {
3570-
const_cast<AssociatedTypeDecl *>(this)->DefaultDefinition
3571-
= TypeLoc::withoutLoc(
3572-
Resolver->loadAssociatedTypeDefault(this, ResolverContextData));
3573-
const_cast<AssociatedTypeDecl *>(this)->Resolver = nullptr;
3574-
}
3575-
return DefaultDefinition.getType();
3570+
return evaluateOrDefault(getASTContext().evaluator,
3571+
DefaultDefinitionTypeRequest{const_cast<AssociatedTypeDecl *>(this)},
3572+
Type());
35763573
}
35773574

35783575
SourceRange AssociatedTypeDecl::getSourceRange() const {
35793576
SourceLoc endLoc;
35803577
if (auto TWC = getTrailingWhereClause()) {
35813578
endLoc = TWC->getSourceRange().End;
3582-
} else if (getDefaultDefinitionLoc().hasLocation()) {
3583-
endLoc = getDefaultDefinitionLoc().getSourceRange().End;
3579+
} else if (auto defaultDefinition = getDefaultDefinitionTypeRepr()) {
3580+
endLoc = defaultDefinition->getEndLoc();
35843581
} else if (!getInherited().empty()) {
35853582
endLoc = getInherited().back().getSourceRange().End;
35863583
} else {

branches/master-rebranch/lib/AST/TypeCheckRequests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,20 @@ void RequirementSignatureRequest::cacheResult(ArrayRef<Requirement> value) const
311311
proto->setRequirementSignature(value);
312312
}
313313

314+
//----------------------------------------------------------------------------//
315+
// DefaultDefinitionTypeRequest computation.
316+
//----------------------------------------------------------------------------//
317+
318+
void DefaultDefinitionTypeRequest::diagnoseCycle(DiagnosticEngine &diags) const {
319+
auto decl = std::get<0>(getStorage());
320+
diags.diagnose(decl, diag::circular_reference);
321+
}
322+
323+
void DefaultDefinitionTypeRequest::noteCycleStep(DiagnosticEngine &diags) const {
324+
auto decl = std::get<0>(getStorage());
325+
diags.diagnose(decl, diag::circular_reference_through);
326+
}
327+
314328
//----------------------------------------------------------------------------//
315329
// Requirement computation.
316330
//----------------------------------------------------------------------------//

0 commit comments

Comments
 (0)