Merge remote-tracking branch 'origin/master' into master-next

This commit is contained in:
swift-ci
2018-07-16 18:48:54 -07:00
13 changed files with 128 additions and 55 deletions

View File

@@ -313,6 +313,11 @@ public:
/// be satisfied.
ArrayRef<Requirement> getConditionalRequirements() const;
/// Substitute the conforming type and produce a ProtocolConformance that
/// applies to the substituted type.
ProtocolConformance *subst(Type substType,
SubstitutionMap subMap) const;
/// Substitute the conforming type and produce a ProtocolConformance that
/// applies to the substituted type.
ProtocolConformance *subst(Type substType,

View File

@@ -47,9 +47,8 @@ class ProtocolConformanceRef {
using UnionType = llvm::PointerUnion<ProtocolDecl*, ProtocolConformance*>;
UnionType Union;
explicit ProtocolConformanceRef(UnionType value) : Union(value) {
assert(value && "cannot construct ProtocolConformanceRef with null");
}
explicit ProtocolConformanceRef(UnionType value) : Union(value) {}
public:
/// Create an abstract protocol conformance reference.
explicit ProtocolConformanceRef(ProtocolDecl *proto) : Union(proto) {
@@ -63,17 +62,30 @@ public:
"cannot construct ProtocolConformanceRef with null");
}
static ProtocolConformanceRef forInvalid() {
return ProtocolConformanceRef(UnionType((ProtocolDecl *)nullptr));
}
bool isInvalid() const {
return !Union;
}
/// Create either a concrete or an abstract protocol conformance reference,
/// depending on whether ProtocolConformance is null.
explicit ProtocolConformanceRef(ProtocolDecl *protocol,
ProtocolConformance *conf);
bool isConcrete() const { return Union.is<ProtocolConformance*>(); }
bool isConcrete() const {
return !isInvalid() && Union.is<ProtocolConformance*>();
}
ProtocolConformance *getConcrete() const {
return Union.get<ProtocolConformance*>();
}
bool isAbstract() const { return Union.is<ProtocolDecl*>(); }
bool isAbstract() const {
return !isInvalid() && Union.is<ProtocolDecl*>();
}
ProtocolDecl *getAbstract() const {
return Union.get<ProtocolDecl*>();
}
@@ -87,6 +99,10 @@ public:
/// Return the protocol requirement.
ProtocolDecl *getRequirement() const;
/// Apply a substitution to the conforming type.
ProtocolConformanceRef subst(Type origType,
SubstitutionMap subMap) const;
/// Apply a substitution to the conforming type.
ProtocolConformanceRef subst(Type origType,
TypeSubstitutionFn subs,

View File

@@ -172,9 +172,7 @@ protected:
ProtocolConformanceRef remapConformance(Type type,
ProtocolConformanceRef conf) {
return conf.subst(type,
QuerySubstitutionMap{SubsMap},
LookUpConformanceInSubstitutionMap(SubsMap));
return conf.subst(type, SubsMap);
}
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {

View File

@@ -87,7 +87,6 @@ TYPE(TUPLE)
TRAILING_INFO(TUPLE_TYPE_ELT)
TYPE(FUNCTION)
TYPE(METATYPE)
TYPE(LVALUE_unused)
TYPE(INOUT)
TYPE(ARCHETYPE)
TYPE(PROTOCOL_COMPOSITION)
@@ -144,42 +143,44 @@ PATTERN(ANY)
PATTERN(TYPED)
PATTERN(VAR)
OTHER(PARAMETERLIST, 226)
OTHER(PARAMETERLIST_ELT, 227)
OTHER(FOREIGN_ERROR_CONVENTION, 228)
OTHER(DECL_CONTEXT, 229)
OTHER(XREF_TYPE_PATH_PIECE, 230)
OTHER(XREF_VALUE_PATH_PIECE, 231)
OTHER(XREF_EXTENSION_PATH_PIECE, 232)
OTHER(XREF_OPERATOR_OR_ACCESSOR_PATH_PIECE, 233)
OTHER(XREF_GENERIC_PARAM_PATH_PIECE, 234)
OTHER(XREF_INITIALIZER_PATH_PIECE, 235)
OTHER(PARAMETERLIST, 210)
OTHER(PARAMETERLIST_ELT, 211)
OTHER(FOREIGN_ERROR_CONVENTION, 212)
OTHER(DECL_CONTEXT, 213)
OTHER(XREF_TYPE_PATH_PIECE, 214)
OTHER(XREF_VALUE_PATH_PIECE, 215)
OTHER(XREF_EXTENSION_PATH_PIECE, 216)
OTHER(XREF_OPERATOR_OR_ACCESSOR_PATH_PIECE, 217)
OTHER(XREF_GENERIC_PARAM_PATH_PIECE, 218)
OTHER(XREF_INITIALIZER_PATH_PIECE, 219)
OTHER(ABSTRACT_CLOSURE_EXPR_CONTEXT, 236)
OTHER(PATTERN_BINDING_INITIALIZER_CONTEXT, 237)
OTHER(DEFAULT_ARGUMENT_INITIALIZER_CONTEXT, 238)
OTHER(TOP_LEVEL_CODE_DECL_CONTEXT, 239)
OTHER(ABSTRACT_CLOSURE_EXPR_CONTEXT, 220)
OTHER(PATTERN_BINDING_INITIALIZER_CONTEXT, 221)
OTHER(DEFAULT_ARGUMENT_INITIALIZER_CONTEXT, 222)
OTHER(TOP_LEVEL_CODE_DECL_CONTEXT, 223)
OTHER(GENERIC_PARAM_LIST, 240)
OTHER(GENERIC_PARAM_LIST, 230)
TRAILING_INFO(GENERIC_PARAM)
TRAILING_INFO(GENERIC_REQUIREMENT)
TRAILING_INFO(LAYOUT_REQUIREMENT)
OTHER(GENERIC_SIGNATURE, 244)
OTHER(SIL_GENERIC_ENVIRONMENT, 245)
OTHER(SUBSTITUTION_MAP, 246)
OTHER(GENERIC_SIGNATURE, 234)
OTHER(SIL_GENERIC_ENVIRONMENT, 235)
OTHER(SUBSTITUTION_MAP, 236)
OTHER(LOCAL_DISCRIMINATOR, 248)
OTHER(PRIVATE_DISCRIMINATOR, 249)
OTHER(LOCAL_DISCRIMINATOR, 237)
OTHER(PRIVATE_DISCRIMINATOR, 238)
OTHER(ABSTRACT_PROTOCOL_CONFORMANCE, 250)
OTHER(NORMAL_PROTOCOL_CONFORMANCE, 251)
OTHER(SPECIALIZED_PROTOCOL_CONFORMANCE, 252)
OTHER(INHERITED_PROTOCOL_CONFORMANCE, 253)
OTHER(SIL_LAYOUT, 197) // FIXME: Note out-of-order
OTHER(NORMAL_PROTOCOL_CONFORMANCE_ID, 198) // FIXME: Note out-of-order
OTHER(PROTOCOL_CONFORMANCE_XREF, 199) // FIXME: Note out-of-order
OTHER(MEMBERS, 254)
OTHER(XREF, 255)
OTHER(ABSTRACT_PROTOCOL_CONFORMANCE, 240)
OTHER(NORMAL_PROTOCOL_CONFORMANCE, 241)
OTHER(SPECIALIZED_PROTOCOL_CONFORMANCE, 242)
OTHER(INHERITED_PROTOCOL_CONFORMANCE, 243)
OTHER(INVALID_PROTOCOL_CONFORMANCE, 244)
OTHER(SIL_LAYOUT, 245)
OTHER(NORMAL_PROTOCOL_CONFORMANCE_ID, 246)
OTHER(PROTOCOL_CONFORMANCE_XREF, 247)
OTHER(MEMBERS, 248)
OTHER(XREF, 249)
#undef RECORD
#undef DECLTYPERECORDNODES_HAS_RECORD_VAL

View File

@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t VERSION_MINOR = 426; // SIL key path external components with local attempts
const uint16_t VERSION_MINOR = 427; // Invalid conformances
using DeclIDField = BCFixed<31>;
@@ -1287,6 +1287,11 @@ namespace decls_block {
DeclIDField // the protocol
>;
/// A placeholder for an invalid conformance.
using InvalidProtocolConformanceLayout = BCRecordLayout<
INVALID_PROTOCOL_CONFORMANCE
>;
using NormalProtocolConformanceLayout = BCRecordLayout<
NORMAL_PROTOCOL_CONFORMANCE,
DeclIDField, // the protocol

View File

@@ -2853,7 +2853,9 @@ static void dumpProtocolConformanceRefRec(
const ProtocolConformanceRef conformance, llvm::raw_ostream &out,
unsigned indent,
llvm::SmallPtrSetImpl<const ProtocolConformance *> &visited) {
if (conformance.isConcrete()) {
if (conformance.isInvalid()) {
out.indent(indent) << "(invalid_conformance)";
} else if (conformance.isConcrete()) {
dumpProtocolConformanceRec(conformance.getConcrete(), out, indent, visited);
} else {
out.indent(indent) << "(abstract_conformance protocol="

View File

@@ -74,6 +74,8 @@ ProtocolConformanceRef::ProtocolConformanceRef(ProtocolDecl *protocol,
}
ProtocolDecl *ProtocolConformanceRef::getRequirement() const {
assert(!isInvalid());
if (isConcrete()) {
return getConcrete()->getProtocol();
} else {
@@ -81,10 +83,21 @@ ProtocolDecl *ProtocolConformanceRef::getRequirement() const {
}
}
ProtocolConformanceRef
ProtocolConformanceRef::subst(Type origType,
SubstitutionMap subMap) const {
return subst(origType,
QuerySubstitutionMap{subMap},
LookUpConformanceInSubstitutionMap(subMap));
}
ProtocolConformanceRef
ProtocolConformanceRef::subst(Type origType,
TypeSubstitutionFn subs,
LookupConformanceFn conformances) const {
if (isInvalid())
return *this;
auto substType = origType.subst(subs, conformances,
SubstFlags::UseErrorType);
@@ -96,8 +109,7 @@ ProtocolConformanceRef::subst(Type origType,
// If this is a class, we need to traffic in the actual type that
// implements the protocol, not 'Self' and not any subclasses (with their
// inherited conformances).
substType =
substType->eraseDynamicSelfType()->getSuperclassForDecl(classDecl);
substType = substType->getSuperclassForDecl(classDecl);
}
return ProtocolConformanceRef(
getConcrete()->subst(substType, subs, conformances));
@@ -130,6 +142,8 @@ ProtocolConformanceRef::getTypeWitnessByName(Type type,
ProtocolConformanceRef conformance,
Identifier name,
LazyResolver *resolver) {
assert(!conformance.isInvalid());
// Find the named requirement.
AssociatedTypeDecl *assocType = nullptr;
auto members = conformance.getRequirement()->lookupDirect(name);
@@ -739,9 +753,7 @@ ProtocolConformanceRef::getAssociatedConformance(Type conformingType,
SubstitutionMap::getProtocolSubstitutions(getRequirement(),
conformingType, *this);
auto abstractConf = ProtocolConformanceRef(protocol);
return abstractConf.subst(assocType,
QuerySubstitutionMap{subMap},
LookUpConformanceInSubstitutionMap(subMap));
return abstractConf.subst(assocType, subMap);
}
ProtocolConformanceRef
@@ -942,9 +954,7 @@ SpecializedProtocolConformance::getAssociatedConformance(Type assocType,
? conformance.getConcrete()->getType()
: GenericConformance->getAssociatedType(assocType, resolver));
return conformance.subst(origType,
QuerySubstitutionMap{subMap},
LookUpConformanceInSubstitutionMap(subMap));
return conformance.subst(origType, subMap);
}
ConcreteDeclRef
@@ -1027,6 +1037,14 @@ bool ProtocolConformance::isVisibleFrom(const DeclContext *dc) const {
return true;
}
ProtocolConformance *
ProtocolConformance::subst(Type substType,
SubstitutionMap subMap) const {
return subst(substType,
QuerySubstitutionMap{subMap},
LookUpConformanceInSubstitutionMap(subMap));
}
ProtocolConformance *
ProtocolConformance::subst(Type substType,
TypeSubstitutionFn subs,
@@ -1351,14 +1369,14 @@ ProtocolConformance *ProtocolConformance::getCanonicalConformance() {
/// Check of all types used by the conformance are canonical.
bool ProtocolConformanceRef::isCanonical() const {
if (isAbstract())
if (isAbstract() || isInvalid())
return true;
return getConcrete()->isCanonical();
}
ProtocolConformanceRef
ProtocolConformanceRef::getCanonicalConformanceRef() const {
if (isAbstract())
if (isAbstract() || isInvalid())
return *this;
return ProtocolConformanceRef(getConcrete()->getCanonicalConformance());
}

View File

@@ -224,7 +224,7 @@ SubstitutionMap SubstitutionMap::get(GenericSignature *genericSig,
auto protoType = req.getSecondType()->castTo<ProtocolType>();
auto proto = protoType->getDecl();
auto conformance = lookupConformance(depTy, replacement, proto)
.getValueOr(ProtocolConformanceRef(proto));
.getValueOr(ProtocolConformanceRef::forInvalid());
conformances.push_back(conformance);
}
@@ -369,6 +369,9 @@ SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const {
continue;
}
if (conformance->isInvalid())
return conformance;
// If we've hit an abstract conformance, everything from here on out is
// abstract.
// FIXME: This may not always be true, but it holds for now.
@@ -444,7 +447,7 @@ SubstitutionMap SubstitutionMap::subst(TypeSubstitutionFn subs,
ProtocolDecl *proto) ->Optional<ProtocolConformanceRef> {
auto conformance =
lookupConformance(dependentType, proto)
.getValueOr(ProtocolConformanceRef(proto));
.getValueOr(ProtocolConformanceRef::forInvalid());
auto substType = dependentType.subst(*this, SubstFlags::UseErrorType);
return conformance.subst(substType, subs, conformances);
});
@@ -610,6 +613,9 @@ void SubstitutionMap::verify() const {
auto conformance = getConformances()[conformanceIndex];
if (conformance.isInvalid())
continue;
// An existential type can have an abstract conformance to
// AnyObject or an @objc protocol.
if (conformance.isAbstract() &&

View File

@@ -70,6 +70,9 @@ MetatypeInst *SILGenBuilder::createMetatype(SILLocation loc, SILType metatype) {
if (!decl)
return false;
if (isa<ProtocolDecl>(decl))
return false;
auto *genericSig = decl->getGenericSignature();
if (!genericSig)
return false;

View File

@@ -1998,9 +1998,14 @@ Type simplifyTypeImpl(ConstraintSystem &cs, Type type, Fn getFixedTypeFn) {
Type lookupBaseType = newBase->getWithoutSpecifierType();
if (lookupBaseType->mayHaveMembers()) {
auto subs = lookupBaseType->getContextSubstitutionMap(
cs.DC->getParentModule(),
assocType->getDeclContext());
auto *proto = assocType->getProtocol();
auto conformance = cs.DC->getParentModule()->lookupConformance(
lookupBaseType, proto);
if (!conformance)
return DependentMemberType::get(lookupBaseType, assocType);
auto subs = SubstitutionMap::getProtocolSubstitutions(
proto, lookupBaseType, *conformance);
auto result = assocType->getDeclaredInterfaceType().subst(subs);
if (result && !result->hasError())

View File

@@ -469,6 +469,10 @@ ProtocolConformanceRef ModuleFile::readConformance(
unsigned kind = Cursor.readRecord(next.ID, scratch);
switch (kind) {
case INVALID_PROTOCOL_CONFORMANCE: {
return ProtocolConformanceRef::forInvalid();
}
case ABSTRACT_PROTOCOL_CONFORMANCE: {
DeclID protoID;
AbstractProtocolConformanceLayout::readRecord(scratch, protoID);

View File

@@ -179,6 +179,7 @@ namespace sil_block {
= decls_block::SPECIALIZED_PROTOCOL_CONFORMANCE,
INHERITED_PROTOCOL_CONFORMANCE
= decls_block::INHERITED_PROTOCOL_CONFORMANCE,
INVALID_PROTOCOL_CONFORMANCE = decls_block::INVALID_PROTOCOL_CONFORMANCE,
GENERIC_PARAM = decls_block::GENERIC_PARAM,
GENERIC_REQUIREMENT = decls_block::GENERIC_REQUIREMENT,
LAYOUT_REQUIREMENT = decls_block::LAYOUT_REQUIREMENT,

View File

@@ -862,6 +862,8 @@ void Serializer::writeBlockInfoBlock() {
// These layouts can exist in both decl blocks and sil blocks.
#define BLOCK_RECORD_WITH_NAMESPACE(K, X) emitRecordID(Out, X, #X, nameBuffer)
BLOCK_RECORD_WITH_NAMESPACE(sil_block,
decls_block::INVALID_PROTOCOL_CONFORMANCE);
BLOCK_RECORD_WITH_NAMESPACE(sil_block,
decls_block::ABSTRACT_PROTOCOL_CONFORMANCE);
BLOCK_RECORD_WITH_NAMESPACE(sil_block,
@@ -1640,6 +1642,12 @@ Serializer::writeConformance(ProtocolConformanceRef conformanceRef,
GenericEnvironment *genericEnv) {
using namespace decls_block;
if (conformanceRef.isInvalid()) {
unsigned abbrCode = abbrCodes[InvalidProtocolConformanceLayout::Code];
InvalidProtocolConformanceLayout::emitRecord(Out, ScratchRecord, abbrCode);
return;
}
if (conformanceRef.isAbstract()) {
unsigned abbrCode = abbrCodes[AbstractProtocolConformanceLayout::Code];
AbstractProtocolConformanceLayout::emitRecord(Out, ScratchRecord, abbrCode,
@@ -4073,6 +4081,7 @@ void Serializer::writeAllDeclsAndTypes() {
registerDeclTypeAbbr<NormalProtocolConformanceLayout>();
registerDeclTypeAbbr<SpecializedProtocolConformanceLayout>();
registerDeclTypeAbbr<InheritedProtocolConformanceLayout>();
registerDeclTypeAbbr<InvalidProtocolConformanceLayout>();
registerDeclTypeAbbr<NormalProtocolConformanceIdLayout>();
registerDeclTypeAbbr<ProtocolConformanceXrefLayout>();