Skip to content

Commit a070bb2

Browse files
committed
---
yaml --- r: 345855 b: refs/heads/master c: 3dc5f83 h: refs/heads/master i: 345853: c9b4103 345851: 21e754c 345847: 829c607 345839: c9dcaa1 345823: b9a683f 345791: 864bfb9 345727: 2bd9e97 345599: 8571b1d
1 parent c1a2a4a commit a070bb2

File tree

12 files changed

+296
-190
lines changed

12 files changed

+296
-190
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: 1d4c7b6974cc4e2ea5b31de118e86044fca39a81
2+
refs/heads/master: 3dc5f83a3c5c8a6c1096af7b1808e97cee3ce8ca
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: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,6 +3022,14 @@ static inline bool isRawPointerKind(PointerTypeKind PTK) {
30223022
llvm_unreachable("Unhandled PointerTypeKind in switch.");
30233023
}
30243024

3025+
enum KeyPathTypeKind : unsigned char {
3026+
KPTK_AnyKeyPath,
3027+
KPTK_PartialKeyPath,
3028+
KPTK_KeyPath,
3029+
KPTK_WritableKeyPath,
3030+
KPTK_ReferenceWritableKeyPath
3031+
};
3032+
30253033
/// NominalTypeDecl - a declaration of a nominal type, like a struct.
30263034
class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
30273035
SourceRange Braces;
@@ -3243,6 +3251,9 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
32433251
/// Is this the decl for Optional<T>?
32443252
bool isOptionalDecl() const;
32453253

3254+
/// Is this a key path type?
3255+
Optional<KeyPathTypeKind> getKeyPathTypeKind() const;
3256+
32463257
private:
32473258
/// Predicate used to filter StoredPropertyRange.
32483259
struct ToStoredProperty {

trunk/include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3930,6 +3930,8 @@ NOTE(dynamic_replacement_found_function_of_type, none,
39303930
"found function %0 of type %1", (DeclName, Type))
39313931
ERROR(dynamic_replacement_not_in_extension, none,
39323932
"dynamicReplacement(for:) of %0 is not defined in an extension or at the file level", (DeclName))
3933+
ERROR(dynamic_replacement_must_not_be_dynamic, none,
3934+
"dynamicReplacement(for:) of %0 must not be dynamic itself", (DeclName))
39333935

39343936
//------------------------------------------------------------------------------
39353937
// MARK: @available

trunk/lib/AST/ASTVerifier.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2738,6 +2738,48 @@ class Verifier : public ASTWalker {
27382738
verifyCheckedBase(nominal);
27392739
}
27402740

2741+
void verifyCheckedAlways(GenericTypeParamDecl *GTPD) {
2742+
PrettyStackTraceDecl debugStack("verifying GenericTypeParamDecl", GTPD);
2743+
2744+
const DeclContext *DC = GTPD->getDeclContext();
2745+
if (!GTPD->getDeclContext()->isInnermostContextGeneric()) {
2746+
Out << "DeclContext of GenericTypeParamDecl does not have "
2747+
"generic params\n";
2748+
abort();
2749+
}
2750+
2751+
GenericParamList *paramList =
2752+
static_cast<const GenericContext *>(DC)->getGenericParams();
2753+
if (!paramList) {
2754+
Out << "DeclContext of GenericTypeParamDecl does not have "
2755+
"generic params\n";
2756+
abort();
2757+
}
2758+
2759+
unsigned currentDepth = paramList->getDepth();
2760+
if (currentDepth < GTPD->getDepth()) {
2761+
Out << "GenericTypeParamDecl has incorrect depth\n";
2762+
abort();
2763+
}
2764+
while (currentDepth > GTPD->getDepth()) {
2765+
paramList = paramList->getOuterParameters();
2766+
--currentDepth;
2767+
}
2768+
assert(paramList && "this is guaranteed by the parameter list's depth");
2769+
2770+
if (paramList->size() <= GTPD->getIndex() ||
2771+
paramList->getParams()[GTPD->getIndex()] != GTPD) {
2772+
if (llvm::is_contained(paramList->getParams(), GTPD))
2773+
Out << "GenericTypeParamDecl has incorrect index\n";
2774+
else
2775+
Out << "GenericTypeParamDecl not found in GenericParamList; "
2776+
"incorrect depth or wrong DeclContext\n";
2777+
abort();
2778+
}
2779+
2780+
verifyCheckedBase(GTPD);
2781+
}
2782+
27412783
void verifyChecked(ExtensionDecl *ext) {
27422784
// Make sure that the protocol conformances are complete.
27432785
for (auto conformance : ext->getLocalConformances()) {

trunk/lib/AST/Decl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3047,6 +3047,18 @@ bool NominalTypeDecl::isOptionalDecl() const {
30473047
return this == getASTContext().getOptionalDecl();
30483048
}
30493049

3050+
Optional<KeyPathTypeKind> NominalTypeDecl::getKeyPathTypeKind() const {
3051+
auto &ctx = getASTContext();
3052+
#define CASE(NAME) if (this == ctx.get##NAME##Decl()) return KPTK_##NAME;
3053+
CASE(KeyPath)
3054+
CASE(WritableKeyPath)
3055+
CASE(ReferenceWritableKeyPath)
3056+
CASE(AnyKeyPath)
3057+
CASE(PartialKeyPath)
3058+
#undef CASE
3059+
return None;
3060+
}
3061+
30503062
GenericTypeDecl::GenericTypeDecl(DeclKind K, DeclContext *DC,
30513063
Identifier name, SourceLoc nameLoc,
30523064
MutableArrayRef<TypeLoc> inherited,

trunk/lib/SILGen/LValue.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class PathComponent {
106106
AddressorKind, // var/subscript addressor
107107
CoroutineAccessorKind, // coroutine accessor
108108
ValueKind, // random base pointer as an lvalue
109-
KeyPathApplicationKind, // applying a key path
109+
PhysicalKeyPathApplicationKind, // applying a key path
110110

111111
// Logical LValue kinds
112112
GetterSetterKind, // property or subscript getter/setter
@@ -115,6 +115,7 @@ class PathComponent {
115115
AutoreleasingWritebackKind, // autorelease pointer on set
116116
WritebackPseudoKind, // a fake component to customize writeback
117117
OpenNonOpaqueExistentialKind, // opened class or metatype existential
118+
LogicalKeyPathApplicationKind, // applying a key path
118119
// Translation LValue kinds (a subtype of logical)
119120
OrigToSubstKind, // generic type substitution
120121
SubstToOrigKind, // generic type substitution

trunk/lib/SILGen/SILGenExpr.cpp

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3644,60 +3644,10 @@ RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) {
36443644

36453645
RValue RValueEmitter::
36463646
visitKeyPathApplicationExpr(KeyPathApplicationExpr *E, SGFContext C) {
3647-
// An rvalue key path application always occurs as a read-only projection of
3648-
// the base. The base is received maximally abstracted.
3649-
auto root = SGF.emitMaterializedRValueAsOrig(E->getBase(),
3650-
AbstractionPattern::getOpaque());
3651-
auto keyPath = SGF.emitRValueAsSingleValue(E->getKeyPath());
3652-
3653-
auto keyPathDecl = E->getKeyPath()->getType()->getAnyNominal();
3654-
FuncDecl *projectFn;
3655-
3656-
SmallVector<Type, 2> replacementTypes;
3657-
if (keyPathDecl == SGF.getASTContext().getAnyKeyPathDecl()) {
3658-
// Invoke projectKeyPathAny with the type of the base value.
3659-
// The result is always `Any?`.
3660-
projectFn = SGF.getASTContext().getProjectKeyPathAny(nullptr);
3661-
replacementTypes.push_back(E->getBase()->getType());
3662-
} else {
3663-
auto keyPathTy = E->getKeyPath()->getType()->castTo<BoundGenericType>();
3664-
if (keyPathDecl == SGF.getASTContext().getPartialKeyPathDecl()) {
3665-
// Invoke projectKeyPathPartial with the type of the base value.
3666-
// The result is always `Any`.
3667-
projectFn = SGF.getASTContext().getProjectKeyPathPartial(nullptr);
3668-
replacementTypes.push_back(keyPathTy->getGenericArgs()[0]);
3669-
} else {
3670-
projectFn = SGF.getASTContext().getProjectKeyPathReadOnly(nullptr);
3671-
// Get the root and leaf type from the key path type.
3672-
replacementTypes.push_back(keyPathTy->getGenericArgs()[0]);
3673-
replacementTypes.push_back(keyPathTy->getGenericArgs()[1]);
3674-
3675-
// Upcast the keypath to KeyPath<T, U> if it isn't already.
3676-
if (keyPathTy->getDecl() != SGF.getASTContext().getKeyPathDecl()) {
3677-
auto castToTy = BoundGenericType::get(
3678-
SGF.getASTContext().getKeyPathDecl(),
3679-
nullptr,
3680-
keyPathTy->getGenericArgs())
3681-
->getCanonicalType();
3682-
keyPath = SGF.B.createUpcast(SILLocation(E), keyPath,
3683-
SILType::getPrimitiveObjectType(castToTy));
3684-
}
3685-
}
3686-
}
3687-
3688-
auto projectionGenericSig = projectFn->getGenericSignature();
3689-
auto genericArgsMap = SubstitutionMap::get(
3690-
projectionGenericSig,
3691-
[&](SubstitutableType *type) -> Type {
3692-
auto genericParam = cast<GenericTypeParamType>(type);
3693-
auto index =
3694-
projectionGenericSig->getGenericParamOrdinal(genericParam);
3695-
return replacementTypes[index];
3696-
},
3697-
LookUpConformanceInSignature(*projectionGenericSig));
3647+
FormalEvaluationScope scope(SGF);
36983648

3699-
return SGF.emitApplyOfLibraryIntrinsic(SILLocation(E),
3700-
projectFn, genericArgsMap, {root, keyPath}, C);
3649+
auto lv = SGF.emitLValue(E, SGFAccessKind::OwnedObjectRead);
3650+
return SGF.emitLoadOfLValue(E, std::move(lv), C);
37013651
}
37023652

37033653
RValue RValueEmitter::

0 commit comments

Comments
 (0)