Merge pull request #12662 from eeckstein/globalopt-assert
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 6fc95dd..8fa09bc 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1635,17 +1635,18 @@
(DescriptiveDeclKind, DeclName, DeclName))
// "Near matches"
-WARNING(optional_req_near_match,none,
- "%0 %1 nearly matches optional requirement %2 of protocol %3",
- (DescriptiveDeclKind, DeclName, DeclName, DeclName))
+WARNING(req_near_match,none,
+ "%0 %1 nearly matches %select{defaulted|optional}2 requirement %3 "
+ "of protocol %4",
+ (DescriptiveDeclKind, DeclName, bool, DeclName, DeclName))
NOTE(optional_req_nonobjc_near_match_add_objc,none,
"add '@objc' to provide an Objective-C entrypoint", ())
-NOTE(optional_req_near_match_move,none,
+NOTE(req_near_match_move,none,
"move %0 to %select{an|another}1 extension to silence this warning",
(DeclName, unsigned))
-NOTE(optional_req_near_match_nonobjc,none,
+NOTE(req_near_match_nonobjc,none,
"add '@nonobjc' to silence this %select{warning|error}0", (bool))
-NOTE(optional_req_near_match_access,none,
+NOTE(req_near_match_access,none,
"make %0 %select{ERROR|private|private|non-public|non-public}1 to silence this "
"warning", (DeclName, AccessLevel))
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index 508f9e2..cd38cde 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -91,9 +91,12 @@
using UnresolvedType = llvm::PointerUnion<PotentialArchetype *, Type>;
class ResolvedType;
- using RequirementRHS =
+ using UnresolvedRequirementRHS =
llvm::PointerUnion3<Type, PotentialArchetype *, LayoutConstraint>;
+ using RequirementRHS =
+ llvm::PointerUnion3<Type, PotentialArchetype *, LayoutConstraint>;
+
/// The location of a requirement as written somewhere in the source.
typedef llvm::PointerUnion<const TypeRepr *, const RequirementRepr *>
WrittenRequirementLoc;
@@ -158,7 +161,7 @@
/// the equivalence class that is held together by derived constraints.
struct DerivedSameTypeComponent {
/// The potential archetype that acts as the anchor for this component.
- PotentialArchetype *anchor;
+ UnresolvedType anchor;
/// The (best) requirement source within the component that makes the
/// potential archetypes in this component equivalent to the concrete
@@ -223,15 +226,13 @@
/// archetype in this equivalence class to a concrete type along with
/// that concrete type as written.
Optional<ConcreteConstraint>
- findAnyConcreteConstraintAsWritten(
- PotentialArchetype *preferredPA = nullptr) const;
+ findAnyConcreteConstraintAsWritten(Type preferredType = Type()) const;
/// Find a source of the superclass constraint in this equivalence class
/// that has a type equivalence to \c superclass, along with that
/// superclass type as written.
Optional<ConcreteConstraint>
- findAnySuperclassConstraintAsWritten(
- PotentialArchetype *preferredPA = nullptr) const;
+ findAnySuperclassConstraintAsWritten(Type preferredType = Type()) const;
/// Determine whether conformance to the given protocol is satisfied by
/// a superclass requirement.
@@ -267,8 +268,8 @@
/// The cached archetype anchor.
struct {
- /// The cached archetype anchor itself.
- PotentialArchetype *anchor = nullptr;
+ /// The cached anchor itself.
+ Type anchor;
/// The number of members of the equivalence class when the archetype
/// anchor was cached.
@@ -339,7 +340,7 @@
/// as appropriate based on \c unresolvedHandling.
ConstraintResult handleUnresolvedRequirement(RequirementKind kind,
UnresolvedType lhs,
- RequirementRHS rhs,
+ UnresolvedRequirementRHS rhs,
FloatingRequirementSource source,
EquivalenceClass *unresolvedEquivClass,
UnresolvedHandlingKind unresolvedHandling);
@@ -536,13 +537,14 @@
///
/// \param f A function object that will be passed each requirement
/// and requirement source.
- void enumerateRequirements(llvm::function_ref<
+ void enumerateRequirements(
+ ArrayRef<GenericTypeParamType *> genericParams,
+ llvm::function_ref<
void (RequirementKind kind,
- PotentialArchetype *archetype,
+ Type type,
RequirementRHS constraint,
const RequirementSource *source)> f);
-public:
/// Retrieve the generic parameters used to describe the generic
/// signature being built.
ArrayRef<GenericTypeParamType *> getGenericParams() const;
@@ -727,30 +729,36 @@
/// class of the given potential archetype.
void checkConcreteTypeConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *pa);
+ EquivalenceClass *equivClass);
/// Check the superclass constraints within the equivalence
/// class of the given potential archetype.
void checkSuperclassConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *pa);
+ EquivalenceClass *equivClass);
/// Check conformance constraints within the equivalence class of the
/// given potential archetype.
void checkConformanceConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *pa);
+ EquivalenceClass *equivClass);
/// Check layout constraints within the equivalence class of the given
/// potential archetype.
void checkLayoutConstraints(ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *pa);
+ EquivalenceClass *equivClass);
/// Check same-type constraints within the equivalence class of the
/// given potential archetype.
void checkSameTypeConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *pa);
+ EquivalenceClass *equivClass);
+
+ /// Realize a potential archetype for the given type.
+ ///
+ /// The resolved archetype will be written back into the unresolved type,
+ /// to make the next resolution more efficient.
+ PotentialArchetype *realizePotentialArchetype(UnresolvedType &type);
public:
/// \brief Try to resolve the equivalence class of the given type.
@@ -1656,20 +1664,6 @@
const_cast<PotentialArchetype *>(this));
}
- /// \brief Retrieve the potential archetype to be used as the anchor for
- /// potential archetype computations.
- PotentialArchetype *getArchetypeAnchor(GenericSignatureBuilder &builder);
-
- /// \brief Retrieve (or create) a nested type that is the current best
- /// nested archetype anchor (locally) with the given name.
- ///
- /// When called on the archetype anchor, this will produce the named
- /// archetype anchor.
- PotentialArchetype *getNestedArchetypeAnchor(
- Identifier name,
- GenericSignatureBuilder &builder,
- ArchetypeResolutionKind kind);
-
/// Update the named nested type when we know this type conforms to the given
/// protocol.
///
@@ -1727,7 +1721,7 @@
Kind kind;
UnresolvedType lhs;
- RequirementRHS rhs;
+ UnresolvedRequirementRHS rhs;
FloatingRequirementSource source;
/// Dump a debugging representation of this delayed requirement class.
diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h
index 7f1904c..84376c5 100644
--- a/include/swift/SIL/TypeLowering.h
+++ b/include/swift/SIL/TypeLowering.h
@@ -531,9 +531,9 @@
llvm::SmallVector<DependentTypeState, 1> DependentTypes;
- llvm::DenseMap<SILDeclRef, SILConstantInfo> ConstantTypes;
+ llvm::DenseMap<SILDeclRef, SILConstantInfo *> ConstantTypes;
- llvm::DenseMap<OverrideKey, SILConstantInfo> ConstantOverrideTypes;
+ llvm::DenseMap<OverrideKey, SILConstantInfo *> ConstantOverrideTypes;
llvm::DenseMap<AnyFunctionRef, CaptureInfo> LoweredCaptures;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 8aefea5..ac5aba6 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2874,7 +2874,7 @@
if (auto objcAttr = conflicts[0]->getAttrs().getAttribute<ObjCAttr>())
hasExplicitObjCAttribute = !objcAttr->isImplicit();
if (!hasExplicitObjCAttribute)
- Diags.diagnose(conflicts[0], diag::optional_req_near_match_nonobjc, true)
+ Diags.diagnose(conflicts[0], diag::req_near_match_nonobjc, true)
.fixItInsert(
conflicts[0]->getAttributeInsertionLoc(/*forModifier=*/false),
"@nonobjc ");
diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp
index 053e189..87a506b 100644
--- a/lib/AST/ASTWalker.cpp
+++ b/lib/AST/ASTWalker.cpp
@@ -137,6 +137,12 @@
if (doIt(Inherit))
return true;
}
+ if (auto *Where = ED->getTrailingWhereClause()) {
+ for(auto &Req: Where->getRequirements()) {
+ if (doIt(Req))
+ return true;
+ }
+ }
for (Decl *M : ED->getMembers()) {
if (doIt(M))
return true;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 6a079db..7551830 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3401,7 +3401,7 @@
}
GenericParamList *ProtocolDecl::createGenericParams(DeclContext *dc) {
- auto *outerGenericParams = dc->getParent()->getGenericParamsOfContext();
+ auto *outerGenericParams = getParent()->getGenericParamsOfContext();
// The generic parameter 'Self'.
auto &ctx = getASTContext();
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index e4e89e9..2b31ca1 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -975,6 +975,16 @@
return;
}
+ // If we have a superclass or concrete requirement, the conformance
+ // we need is stored in it.
+ if (source->kind == RequirementSource::Superclass ||
+ source->kind == RequirementSource::Concrete) {
+ auto conformance = source->getProtocolConformance();
+ assert(conformance.getRequirement() == conformingProto);
+ path.path.push_back({source->getAffectedType(), conformingProto});
+ return;
+ }
+
// If we still have a parent, keep going.
if (source->parent) {
buildPath(reqs, source->parent, conformingProto, rootType,
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 6ab1b65..0ce322a 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -61,6 +61,8 @@
typedef EquivalenceClass::DerivedSameTypeComponent DerivedSameTypeComponent;
typedef GenericSignatureBuilder::DelayedRequirement DelayedRequirement;
typedef GenericSignatureBuilder::ResolvedType ResolvedType;
+ typedef GenericSignatureBuilder::UnresolvedType GSBUnresolvedType;
+ typedef GenericSignatureBuilder::RequirementRHS RequirementRHS;
} // end anonymous namespace
namespace llvm {
@@ -391,6 +393,20 @@
};
} // end namespace llvm
+namespace {
+ /// Retrieve the type described by the given unresolved tyoe.
+ Type getUnresolvedType(GSBUnresolvedType type,
+ ArrayRef<GenericTypeParamType *> genericParams) {
+ if (auto concrete = type.dyn_cast<Type>())
+ return concrete;
+
+ if (auto pa = type.dyn_cast<PotentialArchetype *>())
+ return pa->getDependentType(genericParams);
+
+ return Type();
+ }
+}
+
#pragma mark Requirement sources
#ifndef NDEBUG
@@ -1681,8 +1697,7 @@
}
Optional<ConcreteConstraint>
-EquivalenceClass::findAnyConcreteConstraintAsWritten(
- PotentialArchetype *preferredPA) const {
+EquivalenceClass::findAnyConcreteConstraintAsWritten(Type preferredType) const {
// If we don't have a concrete type, there's no source.
if (!concreteType) return None;
@@ -1691,7 +1706,8 @@
for (const auto &constraint : concreteTypeConstraints) {
if (constraint.source->getLoc().isValid()) {
result = constraint;
- if (!preferredPA || constraint.isSubjectEqualTo(preferredPA))
+ if (!preferredType ||
+ constraint.getSubjectDependentType({ })->isEqual(preferredType))
return result;
}
}
@@ -1701,7 +1717,7 @@
Optional<ConcreteConstraint>
EquivalenceClass::findAnySuperclassConstraintAsWritten(
- PotentialArchetype *preferredPA) const {
+ Type preferredType) const {
// If we don't have a superclass, there's no source.
if (!superclass) return None;
@@ -1712,7 +1728,8 @@
constraint.value->isEqual(superclass)) {
result = constraint;
- if (!preferredPA || constraint.isSubjectEqualTo(preferredPA))
+ if (!preferredType ||
+ constraint.getSubjectDependentType({ })->isEqual(preferredType))
return result;
}
}
@@ -1915,11 +1932,108 @@
return populateResult((nestedTypeNameCache[name] = std::move(entry)));
}
+/// Determine whether any part of this potential archetype's path to the
+/// root contains the given equivalence class.
+static bool pathContainsEquivalenceClass(GenericSignatureBuilder &builder,
+ PotentialArchetype *pa,
+ EquivalenceClass *equivClass) {
+ // Chase the potential archetype up to the root.
+ for (; pa; pa = pa->getParent()) {
+ // Check whether this potential archetype is in the given equivalence
+ // class.
+ if (pa->getOrCreateEquivalenceClass(builder) == equivClass)
+ return true;
+ }
+
+ return false;
+}
+
Type EquivalenceClass::getAnchor(
GenericSignatureBuilder &builder,
ArrayRef<GenericTypeParamType *> genericParams) {
- auto anchorPA = members.front()->getArchetypeAnchor(builder);
- return anchorPA->getDependentType(genericParams);
+ // Check whether the cache is valid.
+ if (archetypeAnchorCache.anchor &&
+ archetypeAnchorCache.numMembers == members.size()) {
+ ++NumArchetypeAnchorCacheHits;
+
+ // Reparent the anchor using genericParams.
+ return archetypeAnchorCache.anchor.subst(
+ [&](SubstitutableType *dependentType) {
+ if (auto gp = dyn_cast<GenericTypeParamType>(dependentType)) {
+ unsigned index =
+ GenericParamKey(gp).findIndexIn(genericParams);
+ return Type(genericParams[index]);
+ }
+
+ return Type(dependentType);
+ },
+ MakeAbstractConformanceForGenericType());
+ }
+
+ // Map the members of this equivalence class to the best associated type
+ // within that equivalence class.
+ llvm::SmallDenseMap<EquivalenceClass *, AssociatedTypeDecl *> nestedTypes;
+
+ PotentialArchetype *bestGenericParam = nullptr;
+ for (auto member : members) {
+ // If the member is a generic parameter, keep the best generic parameter.
+ if (member->isGenericParam()) {
+ if (!bestGenericParam ||
+ compareDependentTypes(&member, &bestGenericParam) < 0)
+ bestGenericParam = member;
+ continue;
+ }
+
+ // If we saw a generic parameter, ignore any nested types.
+ if (bestGenericParam) continue;
+
+ // If the nested type doesn't have an associated type, skip it.
+ auto assocType = member->getResolvedAssociatedType();
+ if (!assocType) continue;
+
+ // Dig out the equivalence class of the parent.
+ auto parentEquivClass =
+ member->getParent()->getOrCreateEquivalenceClass(builder);
+
+ // If the path from this member to the root contains this equivalence
+ // class, it cannot be part of the anchor.
+ if (pathContainsEquivalenceClass(builder, member->getParent(), this))
+ continue;
+
+ // Take the best associated type for this equivalence class.
+ assocType = assocType->getAssociatedTypeAnchor();
+ auto &bestAssocType = nestedTypes[parentEquivClass];
+ if (!bestAssocType ||
+ compareAssociatedTypes(assocType, bestAssocType) < 0)
+ bestAssocType = assocType;
+ }
+
+ // If we found a generic parameter, return that.
+ if (bestGenericParam)
+ return bestGenericParam->getDependentType(genericParams);
+
+ // Determine the best anchor among the parent equivalence classes.
+ Type bestParentAnchor;
+ AssociatedTypeDecl *bestAssocType = nullptr;
+ std::pair<EquivalenceClass *, Identifier> bestNestedType;
+ for (const auto &nestedType : nestedTypes) {
+ auto parentAnchor = nestedType.first->getAnchor(builder, genericParams);
+ if (!bestParentAnchor ||
+ compareDependentTypes(parentAnchor, bestParentAnchor) < 0) {
+ bestParentAnchor = parentAnchor;
+ bestAssocType = nestedType.second;
+ }
+ }
+
+ // Form the anchor type.
+ Type anchorType = DependentMemberType::get(bestParentAnchor, bestAssocType);
+
+ // Record the cache miss and update the cache.
+ ++NumArchetypeAnchorCacheMisses;
+ archetypeAnchorCache.anchor = anchorType;
+ archetypeAnchorCache.numMembers = members.size();
+
+ return anchorType;
}
Type EquivalenceClass::getTypeInContext(GenericSignatureBuilder &builder,
@@ -2157,7 +2271,7 @@
ConstraintResult GenericSignatureBuilder::handleUnresolvedRequirement(
RequirementKind kind,
UnresolvedType lhs,
- RequirementRHS rhs,
+ UnresolvedRequirementRHS rhs,
FloatingRequirementSource source,
EquivalenceClass *unresolvedEquivClass,
UnresolvedHandlingKind unresolvedHandling) {
@@ -2272,7 +2386,7 @@
// appropriately.
const RequirementSource *superclassSource;
if (auto writtenSource =
- equivClass->findAnySuperclassConstraintAsWritten(nullptr))
+ equivClass->findAnySuperclassConstraintAsWritten())
superclassSource = writtenSource->source;
else
superclassSource = equivClass->superclassConstraints.front().source;
@@ -2287,22 +2401,8 @@
/// Realize a potential archetype for this type parameter.
PotentialArchetype *ResolvedType::realizePotentialArchetype(
GenericSignatureBuilder &builder) {
- if (auto pa = getPotentialArchetypeIfKnown())
- return pa;
-
- // Resolve the potential archetype now.
- Type type = this->type.get<Type>();
- assert(type->isTypeParameter());
- auto pa =
- builder.maybeResolveEquivalenceClass(type,
- ArchetypeResolutionKind::WellFormed,
- /*wantExactPotentialArchetype=*/true)
- .getPotentialArchetypeIfKnown();
- assert(pa && "Not a resolvable type!");
-
- // Cache the potential archetype, now that it's been realized.
- this->type = pa;
- return pa;
+ // Realize and cache the potential archetype.
+ return builder.realizePotentialArchetype(type);
}
Type ResolvedType::getDependentType(GenericSignatureBuilder &builder) const {
@@ -2328,7 +2428,8 @@
// Dig out the associated type.
AssociatedTypeDecl *assocType = nullptr;
- if (auto depMemTy = nested.getDependentType(builder)->getAs<DependentMemberType>())
+ if (auto depMemTy =
+ nested.getDependentType(builder)->getAs<DependentMemberType>())
assocType = depMemTy->getAssocType();
if (!assocType) return;
@@ -2546,60 +2647,6 @@
llvm_unreachable("potential archetype total order failure");
}
-PotentialArchetype *PotentialArchetype::getArchetypeAnchor(
- GenericSignatureBuilder &builder) {
- // Find the best archetype within this equivalence class.
- PotentialArchetype *rep = getRepresentative();
- PotentialArchetype *anchor;
- if (auto parent = getParent()) {
- // For a nested type, retrieve the parent archetype anchor first.
- auto parentAnchor = parent->getArchetypeAnchor(builder);
- assert(parentAnchor->getNestingDepth() <= parent->getNestingDepth());
- anchor = parentAnchor->getNestedArchetypeAnchor(
- getNestedName(), builder,
- ArchetypeResolutionKind::CompleteWellFormed);
-
- // FIXME: Hack for cases where we couldn't resolve the nested type.
- if (!anchor)
- anchor = rep;
- } else {
- anchor = rep;
- }
-
- auto equivClass = rep->getEquivalenceClassIfPresent();
- if (!equivClass) return anchor;
-
- // Check whether
- if (equivClass->archetypeAnchorCache.anchor &&
- equivClass->archetypeAnchorCache.numMembers
- == equivClass->members.size()) {
- ++NumArchetypeAnchorCacheHits;
- return equivClass->archetypeAnchorCache.anchor;
- }
-
- // Find the best type within this equivalence class.
- for (auto pa : equivClass->members) {
- if (compareDependentTypes(&pa, &anchor) < 0)
- anchor = pa;
- }
-
-#if SWIFT_GSB_EXPENSIVE_ASSERTIONS
- // Make sure that we did, in fact, get one that is better than all others.
- for (auto pa : equivClass->members) {
- assert((pa == anchor || compareDependentTypes(&anchor, &pa) < 0) &&
- compareDependentTypes(&pa, &anchor) >= 0 &&
- "archetype anchor isn't a total order");
- }
-#endif
-
- // Record the cache miss and update the cache.
- ++NumArchetypeAnchorCacheMisses;
- equivClass->archetypeAnchorCache.anchor = anchor;
- equivClass->archetypeAnchorCache.numMembers = equivClass->members.size();
-
- return anchor;
-}
-
namespace {
/// Function object used to suppress conflict diagnoses when we know we'll
/// see them again later.
@@ -2667,32 +2714,6 @@
SameTypeConflictCheckedLater());
}
-PotentialArchetype *PotentialArchetype::getNestedArchetypeAnchor(
- Identifier name,
- GenericSignatureBuilder &builder,
- ArchetypeResolutionKind kind) {
- SmallVector<TypeDecl *, 4> concreteDecls;
- auto bestType =
- getOrCreateEquivalenceClass(builder)->lookupNestedType(builder, name,
- &concreteDecls);
-
- // We didn't find any type with this name.
- if (!bestType) return nullptr;
-
- // Resolve the nested type.
- auto resultPA = updateNestedTypeForConformance(builder, bestType, kind);
-
- // Update for all of the concrete decls with this name, which will introduce
- // various same-type constraints.
- for (auto concreteDecl : concreteDecls) {
- (void)updateNestedTypeForConformance(builder, concreteDecl,
- ArchetypeResolutionKind::WellFormed);
- }
-
- return resultPA;
-}
-
-
PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
GenericSignatureBuilder &builder,
TypeDecl *type,
@@ -3091,6 +3112,20 @@
});
}
+PotentialArchetype *GenericSignatureBuilder::realizePotentialArchetype(
+ UnresolvedType &type) {
+ if (auto pa = type.dyn_cast<PotentialArchetype *>())
+ return pa;
+
+ auto pa = maybeResolveEquivalenceClass(type.get<Type>(),
+ ArchetypeResolutionKind::WellFormed,
+ /*wantExactPotentialArchetype=*/true)
+ .getPotentialArchetypeIfKnown();
+ if (pa) type = pa;
+
+ return pa;
+}
+
ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
Type type,
ArchetypeResolutionKind resolutionKind,
@@ -3119,11 +3154,14 @@
// Find the nested type declaration for this.
auto baseEquivClass = resolvedBase.getEquivalenceClass(*this);
TypeDecl *nestedTypeDecl;
+ SmallVector<TypeDecl *, 4> concreteDecls;
if (auto assocType = depMemTy->getAssocType()) {
nestedTypeDecl = assocType;
} else {
nestedTypeDecl =
- baseEquivClass->lookupNestedType(*this, depMemTy->getName());
+ baseEquivClass->lookupNestedType(*this, depMemTy->getName(),
+ &concreteDecls);
+
if (!nestedTypeDecl) {
return ResolvedType::forUnresolved(baseEquivClass);
}
@@ -3146,6 +3184,15 @@
if (!nestedPA)
return ResolvedType::forUnresolved(baseEquivClass);
+ if (resolutionKind != ArchetypeResolutionKind::AlreadyKnown) {
+ // Update for all of the concrete decls with this name, which will
+ // introduce various same-type constraints.
+ for (auto concreteDecl : concreteDecls) {
+ (void)basePA->updateNestedTypeForConformance(*this, concreteDecl,
+ resolutionKind);
+ }
+ }
+
// If base resolved to the anchor, then the nested potential archetype
// we found is the resolved potential archetype. Return it directly,
// so it doesn't need to be resolved again.
@@ -3786,8 +3833,8 @@
}
/// Map an unresolved type to a requirement right-hand-side.
-static GenericSignatureBuilder::RequirementRHS
-toRequirementRHS(GenericSignatureBuilder::UnresolvedType unresolved) {
+static GenericSignatureBuilder::UnresolvedRequirementRHS
+toUnresolvedRequirementRHS(GenericSignatureBuilder::UnresolvedType unresolved) {
if (auto pa = unresolved.dyn_cast<PotentialArchetype *>())
return pa;
@@ -3803,7 +3850,7 @@
if (!resolvedConstraint) {
return handleUnresolvedRequirement(
RequirementKind::Conformance, subject,
- toRequirementRHS(constraint), source,
+ toUnresolvedRequirementRHS(constraint), source,
resolvedConstraint.getUnresolvedEquivClass(),
unresolvedHandling);
}
@@ -4036,7 +4083,8 @@
if (equivClass2 && equivClass2->superclass) {
const RequirementSource *source2;
if (auto existingSource2 =
- equivClass2->findAnySuperclassConstraintAsWritten(OrigT2))
+ equivClass2->findAnySuperclassConstraintAsWritten(
+ OrigT2->getDependentType(getGenericParams())))
source2 = existingSource2->source;
else
source2 = equivClass2->superclassConstraints.front().source;
@@ -4215,7 +4263,8 @@
auto resolved1 = resolve(paOrT1, source);
if (!resolved1) {
return handleUnresolvedRequirement(RequirementKind::SameType, paOrT1,
- toRequirementRHS(paOrT2), source,
+ toUnresolvedRequirementRHS(paOrT2),
+ source,
resolved1.getUnresolvedEquivClass(),
unresolvedHandling);
}
@@ -4223,7 +4272,8 @@
auto resolved2 = resolve(paOrT2, source);
if (!resolved2) {
return handleUnresolvedRequirement(RequirementKind::SameType, paOrT1,
- toRequirementRHS(paOrT2), source,
+ toUnresolvedRequirementRHS(paOrT2),
+ source,
resolved2.getUnresolvedEquivClass(),
unresolvedHandling);
}
@@ -4798,8 +4848,6 @@
// Check for recursive or conflicting same-type bindings and superclass
// constraints.
for (auto &equivClass : Impl->EquivalenceClasses) {
- auto archetype = equivClass.members.front()->getRepresentative();
-
if (equivClass.concreteType) {
// Check for recursive same-type bindings.
if (isRecursiveConcreteType(&equivClass, /*isSuperclass=*/false)) {
@@ -4809,13 +4857,13 @@
Diags.diagnose(constraint->source->getLoc(),
diag::recursive_same_type_constraint,
- archetype->getDependentType(genericParams),
+ constraint->getSubjectDependentType(genericParams),
constraint->value);
}
equivClass.recursiveConcreteType = true;
} else {
- checkConcreteTypeConstraints(genericParams, archetype);
+ checkConcreteTypeConstraints(genericParams, &equivClass);
}
}
@@ -4833,12 +4881,12 @@
equivClass.recursiveSuperclassType = true;
} else {
- checkSuperclassConstraints(genericParams, archetype);
+ checkSuperclassConstraints(genericParams, &equivClass);
}
}
- checkConformanceConstraints(genericParams, archetype);
- checkLayoutConstraints(genericParams, archetype);
+ checkConformanceConstraints(genericParams, &equivClass);
+ checkLayoutConstraints(genericParams, &equivClass);
};
// FIXME: Expand all conformance requirements. This is expensive :(
@@ -4847,10 +4895,9 @@
}
// Check same-type constraints.
- for (const auto &equivClass : Impl->EquivalenceClasses) {
- checkSameTypeConstraints(genericParams,
- equivClass.members[0]->getRepresentative());
- };
+ for (auto &equivClass : Impl->EquivalenceClasses) {
+ checkSameTypeConstraints(genericParams, &equivClass);
+ }
// Check for generic parameters which have been made concrete or equated
// with each other.
@@ -4928,7 +4975,7 @@
/// Turn a requirement right-hand side into an unresolved type.
static GenericSignatureBuilder::UnresolvedType asUnresolvedType(
- GenericSignatureBuilder::RequirementRHS rhs) {
+ GenericSignatureBuilder::UnresolvedRequirementRHS rhs) {
if (auto pa = rhs.dyn_cast<PotentialArchetype *>())
return GenericSignatureBuilder::UnresolvedType(pa);
@@ -5291,11 +5338,7 @@
void GenericSignatureBuilder::checkConformanceConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *pa) {
- auto equivClass = pa->getEquivalenceClassIfPresent();
- if (!equivClass || equivClass->conformsTo.empty())
- return;
-
+ EquivalenceClass *equivClass) {
for (auto &entry : equivClass->conformsTo) {
// Remove self-derived constraints.
assert(!entry.second.empty() && "No constraints to work with?");
@@ -5343,7 +5386,8 @@
namespace swift {
bool operator<(const DerivedSameTypeComponent &lhs,
const DerivedSameTypeComponent &rhs) {
- return compareDependentTypes(&lhs.anchor, &rhs.anchor) < 0;
+ return compareDependentTypes(getUnresolvedType(lhs.anchor, { }),
+ getUnresolvedType(rhs.anchor, { })) < 0;
}
} // namespace swift
@@ -5479,7 +5523,9 @@
componentOf[depType] = componentIndex;
// If this is a better anchor, record it.
- if (compareDependentTypes(&pa, &components[componentIndex].anchor) < 0)
+ if (compareDependentTypes(
+ depType,
+ getUnresolvedType(components[componentIndex].anchor, { })) < 0)
components[componentIndex].anchor = pa;
}
@@ -5796,7 +5842,9 @@
auto &newComponent = newComponents[newRepresentativeIndex];
// If the old component has a better anchor, keep it.
- if (compareDependentTypes(&oldComponent.anchor, &newComponent.anchor) < 0)
+ if (compareDependentTypes(
+ getUnresolvedType(oldComponent.anchor, { }),
+ getUnresolvedType(newComponent.anchor, { })) < 0)
newComponent.anchor = oldComponent.anchor;
// If the old component has a better concrete type source, keep it.
@@ -5818,9 +5866,8 @@
void GenericSignatureBuilder::checkSameTypeConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *pa) {
- auto equivClass = pa->getEquivalenceClassIfPresent();
- if (!equivClass || !equivClass->derivedSameTypeComponents.empty())
+ EquivalenceClass *equivClass) {
+ if (!equivClass->derivedSameTypeComponents.empty())
return;
bool anyDerivedViaConcrete = false;
@@ -6022,10 +6069,7 @@
void GenericSignatureBuilder::checkConcreteTypeConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *representative) {
- auto equivClass = representative->getOrCreateEquivalenceClass(*this);
- assert(equivClass->concreteType && "No concrete type to check");
-
+ EquivalenceClass *equivClass) {
checkConstraintList<Type>(
genericParams, equivClass->concreteTypeConstraints,
[&](const ConcreteConstraint &constraint) {
@@ -6059,8 +6103,7 @@
void GenericSignatureBuilder::checkSuperclassConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *representative) {
- auto equivClass = representative->getOrCreateEquivalenceClass(*this);
+ EquivalenceClass *equivClass) {
assert(equivClass->superclass && "No superclass constraint?");
// FIXME: We should be substituting in the canonical type in context so
@@ -6148,9 +6191,8 @@
void GenericSignatureBuilder::checkLayoutConstraints(
ArrayRef<GenericTypeParamType *> genericParams,
- PotentialArchetype *pa) {
- auto equivClass = pa->getEquivalenceClassIfPresent();
- if (!equivClass || !equivClass->layout) return;
+ EquivalenceClass *equivClass) {
+ if (!equivClass->layout) return;
checkConstraintList<LayoutConstraint>(
genericParams, equivClass->layoutConstraints,
@@ -6188,98 +6230,103 @@
return bestSource;
}
+
+ using SameTypeComponentRef = std::pair<EquivalenceClass *, unsigned>;
+
} // end anonymous namespace
-void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
+static int compareSameTypeComponents(const SameTypeComponentRef *lhsPtr,
+ const SameTypeComponentRef *rhsPtr){
+ Type lhsType = getUnresolvedType(
+ lhsPtr->first->derivedSameTypeComponents[lhsPtr->second].anchor,
+ { });
+ Type rhsType = getUnresolvedType(
+ rhsPtr->first->derivedSameTypeComponents[rhsPtr->second].anchor,
+ { });
+
+ return compareDependentTypes(lhsType, rhsType);
+}
+
+void GenericSignatureBuilder::enumerateRequirements(
+ ArrayRef<GenericTypeParamType *> genericParams,
+ llvm::function_ref<
void (RequirementKind kind,
- PotentialArchetype *archetype,
- GenericSignatureBuilder::RequirementRHS constraint,
+ Type type,
+ RequirementRHS constraint,
const RequirementSource *source)> f) {
- // Collect all archetypes.
- SmallVector<PotentialArchetype *, 8> archetypes;
+ // Collect all of the subject types that will be involved in constraints.
+ SmallVector<SameTypeComponentRef, 8> subjects;
for (auto &equivClass : Impl->EquivalenceClasses) {
if (equivClass.derivedSameTypeComponents.empty()) {
- checkSameTypeConstraints(getGenericParams(),
- equivClass.members.front()->getRepresentative());
+ checkSameTypeConstraints(getGenericParams(), &equivClass);
}
- for (const auto &component : equivClass.derivedSameTypeComponents) {
- archetypes.push_back(component.anchor);
- }
+ for (unsigned i : indices(equivClass.derivedSameTypeComponents))
+ subjects.push_back({&equivClass, i});
}
- // Sort the archetypes in canonical order.
- llvm::array_pod_sort(archetypes.begin(), archetypes.end(),
- compareDependentTypes);
+ // Sort the subject types in canonical order.
+ llvm::array_pod_sort(subjects.begin(), subjects.end(),
+ compareSameTypeComponents);
- auto genericParams = getGenericParams();
- for (auto *archetype : archetypes) {
- // Check whether this archetype is one of the anchors within its
- // connected component. If so, we may need to emit a same-type constraint.
- //
- // FIXME: O(n) in the number of implied connected components within the
- // equivalence class. The equivalence class should be small, but...
- auto equivClass = archetype->getOrCreateEquivalenceClass(*this);
+ for (const auto &subject : subjects) {
+ // Dig out the subject type and its corresponding component.
+ auto equivClass = subject.first;
+ auto &component = equivClass->derivedSameTypeComponents[subject.second];
+ Type subjectType = getUnresolvedType(component.anchor, genericParams);
- assert(!equivClass->derivedSameTypeComponents.empty() &&
- "Didn't compute derived same-type components?");
- auto knownAnchor =
- std::find_if(equivClass->derivedSameTypeComponents.begin(),
- equivClass->derivedSameTypeComponents.end(),
- [&](const DerivedSameTypeComponent &component) {
- return component.anchor == archetype;
- });
+ // If this equivalence class is bound to a concrete type, equate the
+ // anchor with a concrete type.
+ if (Type concreteType = equivClass->concreteType) {
+ // If the parent of this anchor is also a concrete type, don't
+ // create a requirement.
+ if (!subjectType->is<GenericTypeParamType>() &&
+ maybeResolveEquivalenceClass(
+ subjectType->castTo<DependentMemberType>()->getBase(),
+ ArchetypeResolutionKind::WellFormed,
+ /*wantExactPotentialArchetype=*/false)
+ .getEquivalenceClass(*this)->concreteType)
+ continue;
+
+ auto source =
+ component.concreteTypeSource
+ ? component.concreteTypeSource
+ : RequirementSource::forAbstract(*this, subjectType);
+
+ // Drop recursive and invalid concrete-type constraints.
+ if (equivClass->recursiveConcreteType ||
+ equivClass->invalidConcreteType)
+ continue;
+
+ f(RequirementKind::SameType, subjectType, concreteType, source);
+ continue;
+ }
+
std::function<void()> deferredSameTypeRequirement;
- if (knownAnchor != equivClass->derivedSameTypeComponents.end()) {
- // If this equivalence class is bound to a concrete type, equate the
- // anchor with a concrete type.
- if (Type concreteType = equivClass->concreteType) {
- // If the parent of this anchor is also a concrete type, don't
- // create a requirement.
- if (!archetype->isGenericParam() &&
- archetype->getParent()->isConcreteType())
- continue;
-
- auto source =
- knownAnchor->concreteTypeSource
- ? knownAnchor->concreteTypeSource
- : RequirementSource::forAbstract(*this,
- archetype->getDependentType(getGenericParams()));
-
- // Drop recursive and invalid concrete-type constraints.
- if (equivClass->recursiveConcreteType ||
- equivClass->invalidConcreteType)
- continue;
-
- f(RequirementKind::SameType, archetype, concreteType, source);
- continue;
- }
-
- // If we're at the last anchor in the component, do nothing;
- auto nextAnchor = knownAnchor;
- ++nextAnchor;
- if (nextAnchor != equivClass->derivedSameTypeComponents.end() /* &&
- !equivClass->areAllRequirementsDerived()*/) {
- // Form a same-type constraint from this anchor within the component
- // to the next.
- // FIXME: Distinguish between explicit and inferred here?
- auto otherPA = nextAnchor->anchor;
- deferredSameTypeRequirement =
- [&f, archetype, otherPA, this, genericParams] {
- f(RequirementKind::SameType, archetype, otherPA,
- RequirementSource::forAbstract(
- *this,
- archetype->getDependentType(genericParams)));
- };
- }
+ // If we're at the last anchor in the component, do nothing;
+ if (subject.second + 1 != equivClass->derivedSameTypeComponents.size()) {
+ // Form a same-type constraint from this anchor within the component
+ // to the next.
+ // FIXME: Distinguish between explicit and inferred here?
+ auto &nextComponent =
+ equivClass->derivedSameTypeComponents[subject.second + 1];
+ Type otherSubjectType =
+ getUnresolvedType(nextComponent.anchor, genericParams);
+ deferredSameTypeRequirement =
+ [&f, subjectType, otherSubjectType, this, genericParams] {
+ f(RequirementKind::SameType, subjectType, otherSubjectType,
+ RequirementSource::forAbstract(*this, otherSubjectType));
+ };
}
+
SWIFT_DEFER {
if (deferredSameTypeRequirement) deferredSameTypeRequirement();
};
- // If this is not the archetype anchor, we're done.
- if (archetype != archetype->getArchetypeAnchor(*this))
+ // If this is not the first component anchor in its equivalence class,
+ // we're done.
+ if (subject.second > 0)
continue;
// If we have a superclass, produce a superclass requirement
@@ -6291,12 +6338,9 @@
});
if (!bestSource)
- bestSource =
- RequirementSource::forAbstract(
- *this,
- archetype->getDependentType(genericParams));
+ bestSource = RequirementSource::forAbstract(*this, subjectType);
- f(RequirementKind::Superclass, archetype, equivClass->superclass,
+ f(RequirementKind::Superclass, subjectType, equivClass->superclass,
*bestSource);
}
@@ -6308,12 +6352,9 @@
return layout == equivClass->layout;
});
if (!bestSource)
- bestSource =
- RequirementSource::forAbstract(
- *this,
- archetype->getDependentType(genericParams));
+ bestSource = RequirementSource::forAbstract(*this, subjectType);
- f(RequirementKind::Layout, archetype, equivClass->layout, *bestSource);
+ f(RequirementKind::Layout, subjectType, equivClass->layout, *bestSource);
}
// Enumerate conformance requirements.
@@ -6341,7 +6382,7 @@
// Enumerate the conformance requirements.
for (auto proto : protocols) {
assert(protocolSources.count(proto) == 1 && "Missing conformance?");
- f(RequirementKind::Conformance, archetype,
+ f(RequirementKind::Conformance, subjectType,
proto->getDeclaredInterfaceType(),
protocolSources.find(proto)->second);
}
@@ -6354,29 +6395,30 @@
void GenericSignatureBuilder::dump(llvm::raw_ostream &out) {
out << "Requirements:";
- enumerateRequirements([&](RequirementKind kind,
- PotentialArchetype *archetype,
- GenericSignatureBuilder::RequirementRHS constraint,
+ enumerateRequirements(getGenericParams(),
+ [&](RequirementKind kind,
+ Type type,
+ RequirementRHS constraint,
const RequirementSource *source) {
switch (kind) {
case RequirementKind::Conformance:
case RequirementKind::Superclass:
out << "\n ";
- out << archetype->getDebugName() << " : "
+ out << type.getString() << " : "
<< constraint.get<Type>().getString() << " [";
source->print(out, &Context.SourceMgr);
out << "]";
break;
case RequirementKind::Layout:
out << "\n ";
- out << archetype->getDebugName() << " : "
+ out << type.getString() << " : "
<< constraint.get<LayoutConstraint>().getString() << " [";
source->print(out, &Context.SourceMgr);
out << "]";
break;
case RequirementKind::SameType:
out << "\n ";
- out << archetype->getDebugName() << " == " ;
+ out << type.getString() << " == " ;
if (auto secondType = constraint.dyn_cast<Type>()) {
out << secondType.getString();
} else {
@@ -6412,9 +6454,11 @@
static void collectRequirements(GenericSignatureBuilder &builder,
ArrayRef<GenericTypeParamType *> params,
SmallVectorImpl<Requirement> &requirements) {
- builder.enumerateRequirements([&](RequirementKind kind,
- GenericSignatureBuilder::PotentialArchetype *archetype,
- GenericSignatureBuilder::RequirementRHS type,
+ builder.enumerateRequirements(
+ params,
+ [&](RequirementKind kind,
+ Type depTy,
+ RequirementRHS type,
const RequirementSource *source) {
// Filter out derived requirements... except for concrete-type requirements
// on generic parameters. The exception is due to the canonicalization of
@@ -6422,31 +6466,26 @@
// they have been mapped to a concrete type.
if (source->isDerivedRequirement() &&
!(kind == RequirementKind::SameType &&
- archetype->isGenericParam() &&
+ depTy->is<GenericTypeParamType>() &&
type.is<Type>()))
return;
- auto depTy = archetype->getDependentType(params);
-
if (depTy->hasError())
return;
Type repTy;
if (auto concreteTy = type.dyn_cast<Type>()) {
- // Maybe we were equated to a concrete type...
+ // Maybe we were equated to a concrete or dependent type...
repTy = concreteTy;
// Drop requirements involving concrete types containing
// unresolved associated types.
if (repTy->findUnresolvedDependentMemberType())
return;
- } else if (auto layoutConstraint = type.dyn_cast<LayoutConstraint>()) {
+ } else {
+ auto layoutConstraint = type.get<LayoutConstraint>();
requirements.push_back(Requirement(kind, depTy, layoutConstraint));
return;
- } else {
- // ...or to a dependent type.
- repTy = type.get<GenericSignatureBuilder::PotentialArchetype *>()
- ->getDependentType(params);
}
if (repTy->hasError())
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index eec64f7..3acbc1c 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -1924,7 +1924,7 @@
const SILConstantInfo &TypeConverter::getConstantInfo(SILDeclRef constant) {
auto found = ConstantTypes.find(constant);
if (found != ConstantTypes.end())
- return found->second;
+ return *found->second;
// First, get a function type for the constant. This creates the
// right type for a getter or setter.
@@ -1956,14 +1956,17 @@
silFnType.print(llvm::dbgs());
llvm::dbgs() << "\n");
- auto result = ConstantTypes.try_emplace(constant,
- formalInterfaceType,
- bridgedTypes.Pattern,
- loweredInterfaceType,
- silFnType,
- genericEnv);
- assert(result.second);
- return result.first->second;
+ auto resultBuf = M.allocate(sizeof(SILConstantInfo),
+ alignof(SILConstantInfo));
+
+ auto result = ::new (resultBuf) SILConstantInfo{formalInterfaceType,
+ bridgedTypes.Pattern,
+ loweredInterfaceType,
+ silFnType,
+ genericEnv};
+ auto inserted = ConstantTypes.insert({constant, result});
+ assert(inserted.second);
+ return *result;
}
/// Returns the SILParameterInfo for the given declaration's `self` parameter.
@@ -2092,7 +2095,7 @@
auto found = ConstantOverrideTypes.find({derived, base});
if (found != ConstantOverrideTypes.end())
- return found->second;
+ return *found->second;
assert(requiresNewVTableEntry(base) && "base must not be an override");
@@ -2146,14 +2149,18 @@
derived);
// Build the SILConstantInfo and cache it.
- auto result = ConstantOverrideTypes.try_emplace({derived, base},
+ auto resultBuf = M.allocate(sizeof(SILConstantInfo),
+ alignof(SILConstantInfo));
+ auto result = ::new (resultBuf) SILConstantInfo{
derivedInterfaceTy,
bridgedTypes.Pattern,
overrideLoweredInterfaceTy,
fnTy,
- derivedInfo.GenericEnv);
- assert(result.second);
- return result.first->second;
+ derivedInfo.GenericEnv};
+
+ auto inserted = ConstantOverrideTypes.insert({{derived, base}, result});
+ assert(inserted.second);
+ return *result;
}
namespace {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 3955625..73d54ed 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -2719,7 +2719,7 @@
// Suggest '@nonobjc' to suppress this error, and not try to
// infer @objc for anything.
- tc.diagnose(decl, diag::optional_req_near_match_nonobjc, true)
+ tc.diagnose(decl, diag::req_near_match_nonobjc, true)
.fixItInsert(decl->getAttributeInsertionLoc(false), "@nonobjc ");
break;
}
@@ -8170,6 +8170,14 @@
return;
}
+ // If the nominal type has a generic signature that we didn't otherwise
+ // handle yet, use it directly.
+ if (auto genericSig = nominal->getGenericSignature()) {
+ auto genericEnv = genericSig->createGenericEnvironment();
+ ext->setGenericEnvironment(genericEnv);
+ return;
+ }
+
assert(extendedType->is<NominalType>());
}
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index dc6ba29..e86a809 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -2063,6 +2063,7 @@
llvm::SmallVector<ConformanceChecker, 4> AllUsedCheckers;
llvm::SmallVector<NormalProtocolConformance*, 4> AllConformances;
llvm::SetVector<ValueDecl*> MissingWitnesses;
+ llvm::SmallPtrSet<ValueDecl *, 8> CoveredMembers;
/// Check one conformance.
ProtocolConformance * checkIndividualConformance(
@@ -2083,6 +2084,11 @@
return llvm::makeArrayRef(UnsatisfiedReqs);
}
+ /// Whether this member is "covered" by one of the conformances.
+ bool isCoveredMember(ValueDecl *member) const {
+ return CoveredMembers.count(member) > 0;
+ }
+
/// Check all conformances and emit diagnosis globally.
void checkAllConformances();
};
@@ -2092,11 +2098,24 @@
if (conformance->isInvalid()) return false;
if (isa<TypeDecl>(req)) return false;
+ auto witness = conformance->hasWitness(req)
+ ? conformance->getWitness(req, nullptr).getDecl()
+ : nullptr;
+
// An optional requirement might not have a witness...
- if (!conformance->hasWitness(req) ||
- !conformance->getWitness(req, nullptr).getDecl())
+ if (!witness)
return req->getAttrs().hasAttribute<OptionalAttr>();
+ // If the witness lands within the declaration context of the conformance,
+ // record it as a "covered" member.
+ if (witness->getDeclContext() == conformance->getDeclContext())
+ CoveredMembers.insert(witness);
+
+ // The witness might come from a protocol or protocol extension.
+ if (witness->getDeclContext()
+ ->getAsProtocolOrProtocolExtensionContext())
+ return true;
+
return false;
}
@@ -5535,7 +5554,7 @@
// If the requirement is optional, @nonobjc suppresses the
// diagnostic.
if (isOptional) {
- TC.diagnose(witness, diag::optional_req_near_match_nonobjc, false)
+ TC.diagnose(witness, diag::req_near_match_nonobjc, false)
.fixItInsert(witness->getAttributeInsertionLoc(false),
"@nonobjc ");
}
@@ -6213,11 +6232,14 @@
DeclName reqName = req->getFullName();
DeclName witnessName = witness->getFullName();
- // Apply the omit-needless-words heuristics to both names.
- if (auto adjustedReqName = ::omitNeedlessWords(tc, req))
- reqName = *adjustedReqName;
- if (auto adjustedWitnessName = ::omitNeedlessWords(tc, witness))
- witnessName = *adjustedWitnessName;
+ // For @objc protocols, apply the omit-needless-words heuristics to
+ // both names.
+ if (cast<ProtocolDecl>(req->getDeclContext())->isObjC()) {
+ if (auto adjustedReqName = ::omitNeedlessWords(tc, req))
+ reqName = *adjustedReqName;
+ if (auto adjustedWitnessName = ::omitNeedlessWords(tc, witness))
+ witnessName = *adjustedWitnessName;
+ }
return scorePotentiallyMatchingNames(reqName, witnessName, isa<FuncDecl>(req),
limit);
@@ -6317,19 +6339,40 @@
return length;
}
+/// Determine whether a particular declaration is generic.
+static bool isGeneric(ValueDecl *decl) {
+ if (auto func = dyn_cast<AbstractFunctionDecl>(decl))
+ return func->isGeneric();
+ if (auto subscript = dyn_cast<SubscriptDecl>(decl))
+ return subscript->isGeneric();
+ return false;
+}
+
/// Determine whether we should warn about the given witness being a close
/// match for the given optional requirement.
-static bool shouldWarnAboutPotentialWitness(ValueDecl *req,
- ValueDecl *witness,
- AccessLevel access,
- unsigned score) {
+static bool shouldWarnAboutPotentialWitness(
+ MultiConformanceChecker &groupChecker,
+ ValueDecl *req,
+ ValueDecl *witness,
+ AccessLevel access,
+ unsigned score) {
+ // If the witness is covered, don't warn about it.
+ if (groupChecker.isCoveredMember(witness))
+ return false;
+
// If the warning couldn't be suppressed, don't warn.
if (!canSuppressPotentialWitnessWarningWithMovement(req, witness) &&
!canSuppressPotentialWitnessWarningWithNonObjC(req, witness))
return false;
- // If the potential witness is already marked @nonobjc, don't warn.
- if (witness->getAttrs().hasAttribute<NonObjCAttr>())
+ // If the potential witness for an @objc requirement is already
+ // marked @nonobjc, don't warn.
+ if (req->isObjC() && witness->getAttrs().hasAttribute<NonObjCAttr>())
+ return false;
+
+ // If the witness is generic and requirement is not, or vice-versa,
+ // don't warn.
+ if (isGeneric(req) != isGeneric(witness))
return false;
// Don't warn if the potential witness has been explicitly given less
@@ -6360,9 +6403,10 @@
auto proto = cast<ProtocolDecl>(req->getDeclContext());
// Primary warning.
- tc.diagnose(witness, diag::optional_req_near_match,
+ tc.diagnose(witness, diag::req_near_match,
witness->getDescriptiveKind(),
witness->getFullName(),
+ req->getAttrs().hasAttribute<OptionalAttr>(),
req->getFullName(),
proto->getFullName());
@@ -6385,21 +6429,21 @@
// If moving the declaration can help, suggest that.
if (auto move
= canSuppressPotentialWitnessWarningWithMovement(req, witness)) {
- tc.diagnose(witness, diag::optional_req_near_match_move,
+ tc.diagnose(witness, diag::req_near_match_move,
witness->getFullName(), static_cast<unsigned>(*move));
}
// If adding 'private', 'fileprivate', or 'internal' can help, suggest that.
if (access > AccessLevel::FilePrivate &&
!witness->getAttrs().hasAttribute<AccessControlAttr>()) {
- tc.diagnose(witness, diag::optional_req_near_match_access,
+ tc.diagnose(witness, diag::req_near_match_access,
witness->getFullName(), access)
.fixItInsert(witness->getAttributeInsertionLoc(true), "private ");
}
// If adding @nonobjc can help, suggest that.
if (canSuppressPotentialWitnessWarningWithNonObjC(req, witness)) {
- tc.diagnose(witness, diag::optional_req_near_match_nonobjc, false)
+ tc.diagnose(witness, diag::req_near_match_nonobjc, false)
.fixItInsert(witness->getAttributeInsertionLoc(false), "@nonobjc ");
}
@@ -6647,8 +6691,8 @@
bool valueIsType = isa<TypeDecl>(value);
for (auto requirement
- : diag.Protocol->lookupDirect(value->getFullName(),
- /*ignoreNewExtensions=*/true)) {
+ : diag.Protocol->lookupDirect(value->getFullName(),
+ /*ignoreNewExtensions=*/true)) {
auto requirementIsType = isa<TypeDecl>(requirement);
if (valueIsType != requirementIsType)
continue;
@@ -6742,8 +6786,8 @@
bestOptionalReqs.begin(),
bestOptionalReqs.end(),
[&](ValueDecl *req) {
- return !shouldWarnAboutPotentialWitness(req, value, defaultAccess,
- bestScore);
+ return !shouldWarnAboutPotentialWitness(groupChecker, req, value,
+ defaultAccess, bestScore);
}),
bestOptionalReqs.end());
}
@@ -6764,7 +6808,7 @@
assert(diagnosed && "Failed to find conformance to diagnose?");
(void)diagnosed;
- // Remove this optional requirement from the list. We don't want to
+ // Remove this requirement from the list. We don't want to
// complain about it twice.
unsatisfiedReqs.erase(std::find(unsatisfiedReqs.begin(),
unsatisfiedReqs.end(),
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 77750af..e40ef87 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -760,6 +760,10 @@
break;
}
+ // Don't create empty generic parameter lists.
+ if (params.empty())
+ return nullptr;
+
auto paramList = GenericParamList::create(getContext(), SourceLoc(),
params, SourceLoc(), { },
SourceLoc());
diff --git a/stdlib/public/core/RangeReplaceableCollection.swift.gyb b/stdlib/public/core/RangeReplaceableCollection.swift.gyb
index eda9d20..fd539dd 100644
--- a/stdlib/public/core/RangeReplaceableCollection.swift.gyb
+++ b/stdlib/public/core/RangeReplaceableCollection.swift.gyb
@@ -354,6 +354,9 @@
mutating func removeAll(keepingCapacity keepCapacity: Bool /*= false*/)
// FIXME(ABI): Associated type inference requires this.
+ subscript(bounds: Index) -> Element { get }
+
+ // FIXME(ABI): Associated type inference requires this.
subscript(bounds: Range<Index>) -> SubSequence { get }
}
diff --git a/stdlib/public/core/Shims.swift b/stdlib/public/core/Shims.swift
index 4596d47..3b453a1 100644
--- a/stdlib/public/core/Shims.swift
+++ b/stdlib/public/core/Shims.swift
@@ -29,6 +29,7 @@
/// A dummy value to be used as the target for `mutationsPtr` in fast
/// enumeration implementations.
@_versioned // FIXME(sil-serialize-all)
+@_fixed_layout
internal var _fastEnumerationStorageMutationsTarget: CUnsignedLong = 0
/// A dummy pointer to be used as `mutationsPtr` in fast enumeration
@@ -36,6 +37,8 @@
@_inlineable // FIXME(sil-serialize-all)
public // SPI(Foundation)
var _fastEnumerationStorageMutationsPtr: UnsafeMutablePointer<CUnsignedLong> {
+ // Note that either _fastEnumerationStorageMutationsPtr should be
+ // @_fixed_layout, or this function should not be @_inlineable.
return UnsafeMutablePointer(
Builtin.addressof(&_fastEnumerationStorageMutationsTarget))
}
diff --git a/test/Generics/requirement_inference.swift b/test/Generics/requirement_inference.swift
index ca0b3b6..bf6bfa2 100644
--- a/test/Generics/requirement_inference.swift
+++ b/test/Generics/requirement_inference.swift
@@ -295,8 +295,8 @@
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P22>
// CHECK: Protocol requirement signature:
// CHECK: .P22@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : P20, Self.A == X20<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : P20, τ_0_0.A == X20<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X20<Self.B>, Self.B : P20>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X20<τ_0_0.B>, τ_0_0.B : P20>
protocol P22 {
associatedtype A
associatedtype B where A == X20<B>
@@ -306,8 +306,8 @@
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P23>
// CHECK: Protocol requirement signature:
// CHECK: .P23@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : P20, Self.A == X20<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : P20, τ_0_0.A == X20<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X20<Self.B>, Self.B : P20>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X20<τ_0_0.B>, τ_0_0.B : P20>
protocol P23 {
associatedtype A
associatedtype B: P20
@@ -323,16 +323,16 @@
}
// CHECK-LABEL: .P25a@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : P20, Self.A == X24<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : P20, τ_0_0.A == X24<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X24<Self.B>, Self.B : P20>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X24<τ_0_0.B>, τ_0_0.B : P20>
protocol P25a {
associatedtype A: P24 // expected-warning{{redundant conformance constraint 'Self.A': 'P24'}}
associatedtype B where A == X24<B> // expected-note{{conformance constraint 'Self.A': 'P24' implied here}}
}
// CHECK-LABEL: .P25b@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : P20, Self.A == X24<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : P20, τ_0_0.A == X24<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X24<Self.B>, Self.B : P20>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X24<τ_0_0.B>, τ_0_0.B : P20>
protocol P25b {
associatedtype A
associatedtype B where A == X24<B>
@@ -353,16 +353,16 @@
}
// CHECK-LABEL: .P27a@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : X3, Self.A == X26<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : X3, τ_0_0.A == X26<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X26<Self.B>, Self.B : X3>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X26<τ_0_0.B>, τ_0_0.B : X3>
protocol P27a {
associatedtype A: P26 // expected-warning{{redundant conformance constraint 'Self.A': 'P26'}}
associatedtype B where A == X26<B> // expected-note{{conformance constraint 'Self.A': 'P26' implied here}}
}
// CHECK-LABEL: .P27b@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : X3, Self.A == X26<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : X3, τ_0_0.A == X26<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X26<Self.B>, Self.B : X3>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X26<τ_0_0.B>, τ_0_0.B : X3>
protocol P27b {
associatedtype A
associatedtype B where A == X26<B>
diff --git a/test/IRGen/unexploded-calls.swift b/test/IRGen/unexploded-calls.swift
index 1146ded..e9046f4 100644
--- a/test/IRGen/unexploded-calls.swift
+++ b/test/IRGen/unexploded-calls.swift
@@ -2,6 +2,8 @@
// RUN: %swift -target thumbv7-unknown-linux-gnueabihf -parse-stdlib -parse-as-library -I %S/Inputs/usr/include -module-name Swift -S -emit-ir -o - %s | %FileCheck %s
// RUN: %swift -target thumbv7-unknown-linux-gnueabi -Xcc -mfloat-abi=hard -parse-stdlib -parse-as-library -I %S/Inputs/usr/include -module-name Swift -S -emit-ir -o - %s | %FileCheck %s
+// REQUIRES: CODEGENERATOR=ARM
+
struct Float {
let _value: Builtin.FPIEEE32
}
diff --git a/test/Index/roles.swift b/test/Index/roles.swift
index 76fe95a..8c8acaf 100644
--- a/test/Index/roles.swift
+++ b/test/Index/roles.swift
@@ -313,6 +313,12 @@
func foo() -> Int { return 1 }
}
+protocol ExtendMe {}
+protocol Whatever {}
+// CHECK: [[@LINE-1]]:10 | protocol/Swift | Whatever | [[Whatever_USR:.*]] | Def | rel: 0
+extension ExtendMe where Self: Whatever {}
+// CHECK: [[@LINE-1]]:32 | protocol/Swift | Whatever | [[Whatever_USR]] | Ref | rel: 0
+
var anInstance = AClass(x: 1)
// CHECK: [[@LINE-1]]:18 | class/Swift | AClass | s:14swift_ide_test6AClassC | Ref | rel: 0
// CHECK: [[@LINE-2]]:18 | constructor/Swift | init(x:) | s:14swift_ide_test6AClassCACSi1x_tcfc | Ref,Call | rel: 0
diff --git a/test/Parse/errors.swift b/test/Parse/errors.swift
index 8fb0ecf..628ae9d 100644
--- a/test/Parse/errors.swift
+++ b/test/Parse/errors.swift
@@ -4,8 +4,8 @@
case Foo, Bar, Baz
case CarriesInt(Int)
- var domain: String { return "" }
- var code: Int { return 0 }
+ var _domain: String { return "" }
+ var _code: Int { return 0 }
}
func opaque_error() -> Error { return MSV.Foo }
diff --git a/test/SILOptimizer/bridged_casts_folding.swift b/test/SILOptimizer/bridged_casts_folding.swift
index 25f5f12..ccd0ab6 100644
--- a/test/SILOptimizer/bridged_casts_folding.swift
+++ b/test/SILOptimizer/bridged_casts_folding.swift
@@ -2,9 +2,6 @@
// REQUIRES: objc_interop
-// FIXME: https://bugs.swift.org/browse/SR-2808
-// XFAIL: resilient_stdlib
-
// Check that casts between bridged types are replaced by more
// efficient code sequences.
//
diff --git a/test/SILOptimizer/cast_folding_no_bridging.sil b/test/SILOptimizer/cast_folding_no_bridging.sil
index 47dffe2..88c00cf 100644
--- a/test/SILOptimizer/cast_folding_no_bridging.sil
+++ b/test/SILOptimizer/cast_folding_no_bridging.sil
@@ -1,9 +1,6 @@
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -O -emit-sil %s | %FileCheck %s
// REQUIRES: objc_interop
-// FIXME: https://bugs.swift.org/browse/SR-2808
-// XFAIL: resilient_stdlib
-
// We want to check that casts between two types which are both Swift types or
// both are ObjC types are not optimized by the cast optimizer into casts
// to/from ObjC.
diff --git a/test/SILOptimizer/prespecialize.swift b/test/SILOptimizer/prespecialize.swift
index b8d0c00..bddb2b9 100644
--- a/test/SILOptimizer/prespecialize.swift
+++ b/test/SILOptimizer/prespecialize.swift
@@ -2,9 +2,6 @@
// REQUIRES: optimized_stdlib
-// FIXME: https://bugs.swift.org/browse/SR-2808
-// XFAIL: resilient_stdlib
-
// Check that pre-specialization works at -Onone.
// This test requires the standard library to be compiled with pre-specializations!
diff --git a/test/SourceKit/DocSupport/doc_swift_module.swift.response b/test/SourceKit/DocSupport/doc_swift_module.swift.response
index ea22b0d..4683135 100644
--- a/test/SourceKit/DocSupport/doc_swift_module.swift.response
+++ b/test/SourceKit/DocSupport/doc_swift_module.swift.response
@@ -1039,7 +1039,7 @@
key.length: 4
},
{
- key.kind: source.lang.swift.syntaxtype.identifier,
+ key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 1207,
key.length: 7
},
diff --git a/test/decl/ext/protocol.swift b/test/decl/ext/protocol.swift
index 73e3ac4..117a0b5 100644
--- a/test/decl/ext/protocol.swift
+++ b/test/decl/ext/protocol.swift
@@ -510,7 +510,7 @@
protocol PConforms8 {
associatedtype Assoc
- func method() -> Assoc
+ func method() -> Assoc // expected-note{{requirement 'method()' declared here}}
var property: Assoc { get }
subscript (i: Assoc) -> Assoc { get }
}
@@ -535,7 +535,10 @@
}
struct SConforms8c : PConforms8 {
- func method() -> String { return "" }
+ func method() -> String { return "" } // expected-warning{{instance method 'method()' nearly matches defaulted requirement 'method()' of protocol 'PConforms8'}}
+ // expected-note@-1{{candidate has non-matching type '() -> String' [with Assoc = Int]}}
+ // expected-note@-2{{move 'method()' to an extension to silence this warning}}
+ // expected-note@-3{{make 'method()' private to silence this warning}}
}
func testSConforms8c() {
diff --git a/test/stdlib/RangeTraps.swift b/test/stdlib/RangeTraps.swift
index 865f940..51bde98 100644
--- a/test/stdlib/RangeTraps.swift
+++ b/test/stdlib/RangeTraps.swift
@@ -16,8 +16,6 @@
// RUN: %target-run %t/a.out_Debug
// RUN: %target-run %t/a.out_Release
// REQUIRES: executable_test
-// CountablePartialRangeFrom fails in resilient mode. <rdar://problem/31909976>
-// XFAIL: resilient_stdlib
import StdlibUnittest
diff --git a/test/stmt/errors.swift b/test/stmt/errors.swift
index 02051ce..688f15e 100644
--- a/test/stmt/errors.swift
+++ b/test/stmt/errors.swift
@@ -2,8 +2,8 @@
enum MSV : Error {
case Foo, Bar, Baz
- var domain: String { return "" }
- var code: Int { return 0 }
+ var _domain: String { return "" }
+ var _code: Int { return 0 }
}
func a() {}
diff --git a/validation-test/Sema/type_checker_perf/slow/rdar35213699.swift b/validation-test/Sema/type_checker_perf/slow/rdar35213699.swift
new file mode 100644
index 0000000..3f40370
--- /dev/null
+++ b/validation-test/Sema/type_checker_perf/slow/rdar35213699.swift
@@ -0,0 +1,8 @@
+// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1
+// REQUIRES: tools-release,no_asserts
+
+func test() {
+ let x: UInt = 1 * 2 + 3 * 4 + 5 * 6 + 7 * 8 + 9 * 10 + 11 * 12 + 13 * 14
+ // expected-error@-1 {{expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions}}
+}
+
diff --git a/validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift b/validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift
index e0d33be..967d912 100644
--- a/validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift
+++ b/validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift
@@ -1,5 +1,5 @@
// RUN: %target-swift-frontend %s -typecheck
-// FIXME: %target-swift-frontend %s -emit-ir -- see https://github.com/apple/swift/pull/7414
+// RUN: %target-swift-frontend %s -emit-ir -o /dev/null
protocol P {
associatedtype A
diff --git a/validation-test/compiler_crashers/28803-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/28803-swift-typebase-getdesugaredtype.swift
similarity index 87%
rename from validation-test/compiler_crashers/28803-swift-typebase-getdesugaredtype.swift
rename to validation-test/compiler_crashers_fixed/28803-swift-typebase-getdesugaredtype.swift
index 4511df4..4ae3193 100644
--- a/validation-test/compiler_crashers/28803-swift-typebase-getdesugaredtype.swift
+++ b/validation-test/compiler_crashers_fixed/28803-swift-typebase-getdesugaredtype.swift
@@ -5,6 +5,6 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{typealias a:Collection
typealias a=(t:Self.a
diff --git a/validation-test/compiler_crashers/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift b/validation-test/compiler_crashers_fixed/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
similarity index 87%
rename from validation-test/compiler_crashers/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
rename to validation-test/compiler_crashers_fixed/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
index 2b015fa..9d62d8f 100644
--- a/validation-test/compiler_crashers/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
+++ b/validation-test/compiler_crashers_fixed/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
@@ -5,5 +5,5 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
class a<a{protocol b}extension a.b
diff --git a/validation-test/compiler_crashers/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift b/validation-test/compiler_crashers_fixed/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
similarity index 87%
rename from validation-test/compiler_crashers/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
rename to validation-test/compiler_crashers_fixed/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
index aad1964..a9fbd25 100644
--- a/validation-test/compiler_crashers/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
+++ b/validation-test/compiler_crashers_fixed/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
@@ -5,5 +5,5 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{protocol a:P}extension P.a.a
diff --git a/validation-test/compiler_crashers/28846-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/28846-swift-typebase-getdesugaredtype.swift
similarity index 87%
rename from validation-test/compiler_crashers/28846-swift-typebase-getdesugaredtype.swift
rename to validation-test/compiler_crashers_fixed/28846-swift-typebase-getdesugaredtype.swift
index 56eb011..c70c62f 100644
--- a/validation-test/compiler_crashers/28846-swift-typebase-getdesugaredtype.swift
+++ b/validation-test/compiler_crashers_fixed/28846-swift-typebase-getdesugaredtype.swift
@@ -5,5 +5,5 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol A{typealias a:A=a{}typealias a=Self.a
diff --git a/validation-test/compiler_crashers/28848-iscanonicaltypeincontext-result-builder.swift b/validation-test/compiler_crashers_fixed/28848-iscanonicaltypeincontext-result-builder.swift
similarity index 88%
rename from validation-test/compiler_crashers/28848-iscanonicaltypeincontext-result-builder.swift
rename to validation-test/compiler_crashers_fixed/28848-iscanonicaltypeincontext-result-builder.swift
index 72c53f2..504f8d5 100644
--- a/validation-test/compiler_crashers/28848-iscanonicaltypeincontext-result-builder.swift
+++ b/validation-test/compiler_crashers_fixed/28848-iscanonicaltypeincontext-result-builder.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{typealias a{}func a:a.a{}class a{{}protocol 0
diff --git a/validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift b/validation-test/compiler_crashers_fixed/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
similarity index 88%
rename from validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
rename to validation-test/compiler_crashers_fixed/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
index 0e26155..350c824 100644
--- a/validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
+++ b/validation-test/compiler_crashers_fixed/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
@@ -6,5 +6,5 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol A:a{{}typealias a=a{}func a{}typealias a}class a:A{func a
diff --git a/validation-test/compiler_crashers/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift b/validation-test/compiler_crashers_fixed/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
similarity index 88%
rename from validation-test/compiler_crashers/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
rename to validation-test/compiler_crashers_fixed/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
index ea97cf1..40f673d 100644
--- a/validation-test/compiler_crashers/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
+++ b/validation-test/compiler_crashers_fixed/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
@@ -6,6 +6,6 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
protocol P{class a}protocol A:P
extension P.a:A