Skip to content

Commit d3c2c5d

Browse files
committed
---
yaml --- r: 344989 b: refs/heads/master c: da52325 h: refs/heads/master i: 344987: 7b38ec2
1 parent 55f3533 commit d3c2c5d

20 files changed

+712
-476
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 0b1649287cc250f5e34b4a1d6f79e2bdfc5990a9
2+
refs/heads/master: da52325f89d652aac035922193b375d6d32a90d8
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/Decl.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,22 @@ class RequirementRepr {
12141214
SecondType.getSourceRange().End);
12151215
}
12161216

1217+
/// Retrieve the first or subject type representation from the \c repr,
1218+
/// or \c nullptr if \c repr is null.
1219+
static TypeRepr *getFirstTypeRepr(const RequirementRepr *repr) {
1220+
if (!repr) return nullptr;
1221+
return repr->FirstType.getTypeRepr();
1222+
}
1223+
1224+
/// Retrieve the second or constraint type representation from the \c repr,
1225+
/// or \c nullptr if \c repr is null.
1226+
static TypeRepr *getSecondTypeRepr(const RequirementRepr *repr) {
1227+
if (!repr) return nullptr;
1228+
assert(repr->getKind() == RequirementReprKind::TypeConstraint ||
1229+
repr->getKind() == RequirementReprKind::SameType);
1230+
return repr->SecondType.getTypeRepr();
1231+
}
1232+
12171233
LLVM_ATTRIBUTE_DEPRECATED(
12181234
void dump() const LLVM_ATTRIBUTE_USED,
12191235
"only for use within the debugger");
@@ -6636,6 +6652,9 @@ inline EnumElementDecl *EnumDecl::getUniqueElement(bool hasValue) const {
66366652
std::pair<DefaultArgumentKind, Type>
66376653
getDefaultArgumentInfo(ValueDecl *source, unsigned Index);
66386654

6655+
/// Display Decl subclasses.
6656+
void simple_display(llvm::raw_ostream &out, const Decl *decl);
6657+
66396658
/// Display ValueDecl subclasses.
66406659
void simple_display(llvm::raw_ostream &out, const ValueDecl *decl);
66416660

trunk/include/swift/AST/GenericSignatureBuilder.h

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -574,19 +574,8 @@ class GenericSignatureBuilder {
574574
///
575575
/// \returns true if this requirement makes the set of requirements
576576
/// inconsistent, in which case a diagnostic will have been issued.
577-
ConstraintResult addRequirement(const RequirementRepr *req,
578-
ModuleDecl *inferForModule);
579-
580-
/// \brief Add a new requirement.
581-
///
582-
/// \param inferForModule Infer additional requirements from the types
583-
/// relative to the given module.
584-
///
585-
/// \returns true if this requirement makes the set of requirements
586-
/// inconsistent, in which case a diagnostic will have been issued.
587-
ConstraintResult addRequirement(const RequirementRepr *Req,
577+
ConstraintResult addRequirement(const Requirement &req,
588578
FloatingRequirementSource source,
589-
const SubstitutionMap *subMap,
590579
ModuleDecl *inferForModule);
591580

592581
/// \brief Add an already-checked requirement.
@@ -600,7 +589,9 @@ class GenericSignatureBuilder {
600589
/// \returns true if this requirement makes the set of requirements
601590
/// inconsistent, in which case a diagnostic will have been issued.
602591
ConstraintResult addRequirement(const Requirement &req,
592+
const RequirementRepr *reqRepr,
603593
FloatingRequirementSource source,
594+
const SubstitutionMap *subMap,
604595
ModuleDecl *inferForModule);
605596

606597
/// \brief Add all of a generic signature's parameters and requirements.
@@ -618,7 +609,9 @@ class GenericSignatureBuilder {
618609
/// where \c Dictionary requires that its key type be \c Hashable,
619610
/// the requirement \c K : Hashable is inferred from the parameter type,
620611
/// because the type \c Dictionary<K,V> cannot be formed without it.
621-
void inferRequirements(ModuleDecl &module, TypeLoc type,
612+
void inferRequirements(ModuleDecl &module,
613+
Type type,
614+
const TypeRepr *typeRepr,
622615
FloatingRequirementSource source);
623616

624617
/// Infer requirements from the given pattern, recursively.
@@ -1744,6 +1737,15 @@ inline bool isErrorResult(GenericSignatureBuilder::ConstraintResult result) {
17441737
/// Canonical ordering for dependent types.
17451738
int compareDependentTypes(Type type1, Type type2);
17461739

1740+
template<typename T>
1741+
Type GenericSignatureBuilder::Constraint<T>::getSubjectDependentType(
1742+
TypeArrayView<GenericTypeParamType> genericParams) const {
1743+
if (auto type = subject.dyn_cast<Type>())
1744+
return type;
1745+
1746+
return subject.get<PotentialArchetype *>()->getDependentType(genericParams);
1747+
}
1748+
17471749
} // end namespace swift
17481750

17491751
#endif

trunk/include/swift/AST/LayoutConstraint.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,10 @@ struct LayoutConstraintLoc {
343343
bool hasLocation() const { return Loc.isValid(); }
344344
LayoutConstraint getLayoutConstraint() const { return Layout; }
345345

346+
void setLayoutConstraint(LayoutConstraint value) {
347+
Layout = value;
348+
}
349+
346350
bool isNull() const { return Layout.isNull(); }
347351

348352
LayoutConstraintLoc clone(ASTContext &ctx) const { return *this; }

trunk/include/swift/AST/LazyResolver.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ class LazyResolver {
6363
/// Resolve the generic environment of the given protocol.
6464
virtual void resolveProtocolEnvironment(ProtocolDecl *proto) = 0;
6565

66-
/// Resolve the trailing where clause of the given protocol in-place.
67-
virtual void resolveTrailingWhereClause(ProtocolDecl *proto) = 0;
68-
6966
/// Bind an extension to its extended type.
7067
virtual void bindExtension(ExtensionDecl *ext) = 0;
7168

trunk/include/swift/AST/TypeCheckRequests.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@
2222
#include "swift/AST/TypeResolutionStage.h"
2323
#include "swift/Basic/Statistic.h"
2424
#include "llvm/ADT/Hashing.h"
25+
#include "llvm/ADT/STLExtras.h"
2526
#include "llvm/ADT/TinyPtrVector.h"
2627

2728
namespace swift {
2829

30+
class GenericParamList;
31+
class RequirementRepr;
2932
struct TypeLoc;
3033

3134
/// Display a nominal type or extension thereof.
@@ -209,6 +212,85 @@ class IsDynamicRequest :
209212
void cacheResult(bool value) const;
210213
};
211214

215+
/// Describes the owner of a where clause, from which we can extract
216+
/// requirements.
217+
struct WhereClauseOwner {
218+
/// The declaration context in which the where clause will be evaluated.
219+
DeclContext *dc;
220+
221+
/// The source of the where clause, which can be a generic parameter list
222+
/// or a declaration that can have a where clause.
223+
llvm::PointerUnion<GenericParamList *, Decl *> source;
224+
225+
WhereClauseOwner(Decl *decl);
226+
227+
WhereClauseOwner(DeclContext *dc, GenericParamList *genericParams)
228+
: dc(dc), source(genericParams) { }
229+
230+
SourceLoc getLoc() const;
231+
232+
friend hash_code hash_value(const WhereClauseOwner &owner) {
233+
return hash_combine(hash_value(owner.dc), hash_value(owner.source));
234+
}
235+
236+
friend bool operator==(const WhereClauseOwner &lhs,
237+
const WhereClauseOwner &rhs) {
238+
return lhs.dc == rhs.dc && lhs.source == rhs.source;
239+
}
240+
241+
friend bool operator!=(const WhereClauseOwner &lhs,
242+
const WhereClauseOwner &rhs) {
243+
return !(lhs == rhs);
244+
}
245+
};
246+
247+
void simple_display(llvm::raw_ostream &out, const WhereClauseOwner &owner);
248+
249+
/// Retrieve a requirement from the where clause of the given declaration.
250+
class RequirementRequest :
251+
public SimpleRequest<RequirementRequest,
252+
CacheKind::SeparatelyCached,
253+
Requirement,
254+
WhereClauseOwner,
255+
unsigned,
256+
TypeResolutionStage> {
257+
public:
258+
using SimpleRequest::SimpleRequest;
259+
260+
/// Retrieve the array of requirements from the given owner.
261+
static MutableArrayRef<RequirementRepr> getRequirements(WhereClauseOwner);
262+
263+
/// Visit each of the requirements in the given owner,
264+
///
265+
/// \returns true after short-circuiting if the callback returned \c true
266+
/// for any of the requirements.
267+
static bool visitRequirements(
268+
WhereClauseOwner, TypeResolutionStage stage,
269+
llvm::function_ref<bool(Requirement, RequirementRepr*)> callback);
270+
271+
private:
272+
friend class SimpleRequest;
273+
274+
/// Retrieve the requirement this request operates on.
275+
RequirementRepr &getRequirement() const;
276+
277+
// Evaluation.
278+
llvm::Expected<Requirement> evaluate(Evaluator &evaluator,
279+
WhereClauseOwner,
280+
unsigned index,
281+
TypeResolutionStage stage) const;
282+
283+
public:
284+
// Cycle handling
285+
void diagnoseCycle(DiagnosticEngine &diags) const;
286+
void noteCycleStep(DiagnosticEngine &diags) const;
287+
288+
// Separate caching.
289+
bool isCached() const;
290+
Optional<Requirement> getCachedResult() const;
291+
void cacheResult(Requirement value) const;
292+
};
293+
212294
/// The zone number for the type checker.
213295
#define SWIFT_TYPE_CHECKER_REQUESTS_TYPEID_ZONE 10
214296

trunk/include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ SWIFT_TYPEID(EnumRawTypeRequest)
2020
SWIFT_TYPEID(OverriddenDeclsRequest)
2121
SWIFT_TYPEID(IsObjCRequest)
2222
SWIFT_TYPEID(IsDynamicRequest)
23+
SWIFT_TYPEID(RequirementRequest)

trunk/lib/AST/AccessRequests.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/DiagnosticsCommon.h"
1919
#include "swift/AST/LazyResolver.h"
2020
#include "swift/AST/Module.h"
21+
#include "swift/AST/TypeCheckRequests.h"
2122
#include "swift/AST/Types.h"
2223

2324
#include "llvm/Support/MathExtras.h"
@@ -212,12 +213,12 @@ DefaultAndMaxAccessLevelRequest::evaluate(Evaluator &evaluator,
212213
AccessLevel::FilePrivate);
213214
}
214215

215-
if (const GenericParamList *genericParams = ED->getGenericParams()) {
216-
auto getTypeAccess = [ED](const TypeLoc &TL) -> AccessLevel {
217-
if (!TL.getType())
216+
if (GenericParamList *genericParams = ED->getGenericParams()) {
217+
auto getTypeAccess = [ED](Type type, TypeRepr *typeRepr) -> AccessLevel {
218+
if (!type)
218219
return AccessLevel::Public;
219220
auto accessScope =
220-
TypeReprAccessScopeChecker::getAccessScope(TL.getTypeRepr(),
221+
TypeReprAccessScopeChecker::getAccessScope(typeRepr,
221222
ED->getDeclContext());
222223
// This is an error case and will be diagnosed elsewhere.
223224
if (!accessScope.hasValue())
@@ -236,21 +237,30 @@ DefaultAndMaxAccessLevelRequest::evaluate(Evaluator &evaluator,
236237

237238
// Only check the trailing 'where' requirements. Other requirements come
238239
// from the extended type and have already been checked.
239-
for (const RequirementRepr &req : genericParams->getTrailingRequirements()){
240-
switch (req.getKind()) {
241-
case RequirementReprKind::TypeConstraint:
242-
maxAccess = std::min(getTypeAccess(req.getSubjectLoc()), maxAccess);
243-
maxAccess = std::min(getTypeAccess(req.getConstraintLoc()), maxAccess);
244-
break;
245-
case RequirementReprKind::LayoutConstraint:
246-
maxAccess = std::min(getTypeAccess(req.getSubjectLoc()), maxAccess);
247-
break;
248-
case RequirementReprKind::SameType:
249-
maxAccess = std::min(getTypeAccess(req.getFirstTypeLoc()), maxAccess);
250-
maxAccess = std::min(getTypeAccess(req.getSecondTypeLoc()), maxAccess);
251-
break;
252-
}
253-
}
240+
RequirementRequest::visitRequirements(
241+
WhereClauseOwner(ED, genericParams),
242+
TypeResolutionStage::Interface,
243+
[&](Requirement req, RequirementRepr *reqRepr) {
244+
switch (req.getKind()) {
245+
case RequirementKind::Conformance:
246+
case RequirementKind::Superclass:
247+
case RequirementKind::SameType:
248+
maxAccess = std::min(getTypeAccess(
249+
req.getSecondType(),
250+
RequirementRepr::getSecondTypeRepr(reqRepr)),
251+
maxAccess);
252+
LLVM_FALLTHROUGH;
253+
254+
case RequirementKind::Layout:
255+
maxAccess = std::min(getTypeAccess(
256+
req.getFirstType(),
257+
RequirementRepr::getFirstTypeRepr(reqRepr)),
258+
maxAccess);
259+
break;
260+
}
261+
262+
return false;
263+
});
254264
}
255265

256266
AccessLevel defaultAccess;

trunk/lib/AST/Decl.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6173,6 +6173,25 @@ NominalTypeDecl *TypeOrExtensionDecl::getBaseNominal() const {
61736173
}
61746174
bool TypeOrExtensionDecl::isNull() const { return Decl.isNull(); }
61756175

6176+
void swift::simple_display(llvm::raw_ostream &out, const Decl *decl) {
6177+
if (!decl) {
6178+
out << "(null)";
6179+
return;
6180+
}
6181+
6182+
if (auto value = dyn_cast<ValueDecl>(decl)) {
6183+
simple_display(out, value);
6184+
} else if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
6185+
out << "extension of ";
6186+
if (auto typeRepr = ext->getExtendedTypeLoc().getTypeRepr())
6187+
typeRepr->print(out);
6188+
else
6189+
ext->getSelfNominalTypeDecl()->dumpRef(out);
6190+
} else {
6191+
out << "(unknown decl)";
6192+
}
6193+
}
6194+
61766195
void swift::simple_display(llvm::raw_ostream &out, const ValueDecl *decl) {
61776196
if (decl) decl->dumpRef(out);
61786197
else out << "(null)";

trunk/lib/AST/GenericSignature.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,8 @@ static bool hasNonCanonicalSelfProtocolRequirement(
786786

787787
/// Retrieve the best requirement source from the list
788788
static const RequirementSource *
789-
getBestRequirementSource(ArrayRef<GSBConstraint<ProtocolDecl *>> constraints) {
789+
getBestRequirementSource(GenericSignatureBuilder &builder,
790+
ArrayRef<GSBConstraint<ProtocolDecl *>> constraints) {
790791
const RequirementSource *bestSource = nullptr;
791792
bool bestIsNonCanonical = false;
792793

@@ -802,6 +803,16 @@ getBestRequirementSource(ArrayRef<GSBConstraint<ProtocolDecl *>> constraints) {
802803
for (const auto &constraint : constraints) {
803804
auto source = constraint.source;
804805

806+
// Skip self-recursive sources.
807+
bool derivedViaConcrete = false;
808+
if (source->getMinimalConformanceSource(
809+
builder,
810+
constraint.getSubjectDependentType({ }),
811+
constraint.value,
812+
derivedViaConcrete)
813+
!= source)
814+
continue;
815+
805816
// If there is a non-canonical protocol requirement next to the root,
806817
// skip this requirement source.
807818
bool isNonCanonical =
@@ -907,7 +918,8 @@ void GenericSignature::buildConformanceAccessPath(
907918
assert(conforms != equivClass->conformsTo.end());
908919

909920
// Compute the root type, canonicalizing it w.r.t. the protocol context.
910-
auto conformsSource = getBestRequirementSource(conforms->second);
921+
auto conformsSource = getBestRequirementSource(inProtoSigBuilder,
922+
conforms->second);
911923
assert(conformsSource != source || !requirementSignatureProto);
912924
Type localRootType = conformsSource->getRootType();
913925
localRootType = inProtoSig->getCanonicalTypeInContext(localRootType);
@@ -977,7 +989,7 @@ GenericSignature::getConformanceAccessPath(Type type, ProtocolDecl *protocol) {
977989
assert(conforms != equivClass->conformsTo.end());
978990

979991
// Canonicalize the root type.
980-
auto source = getBestRequirementSource(conforms->second);
992+
auto source = getBestRequirementSource(builder, conforms->second);
981993
Type rootType = source->getRootType()->getCanonicalType(this);
982994

983995
// Build the path.

0 commit comments

Comments
 (0)