Merge pull request #17561 from jckarter/silfunctiontype-pseudogeneric-iff-generic
SIL: Assert that SILFunctionTypes are only @pseudogeneric when they have generic arguments.
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index d36b026..fdbc7be 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -2279,7 +2279,6 @@
StoredProperty,
GettableProperty,
SettableProperty,
- External,
OptionalChain,
OptionalForce,
OptionalWrap,
@@ -2298,7 +2297,6 @@
enum PackedKind: unsigned {
PackedStored,
PackedComputed,
- PackedExternal,
Unpacked,
};
@@ -2311,8 +2309,6 @@
case Kind::GettableProperty:
case Kind::SettableProperty:
return PackedComputed;
- case Kind::External:
- return PackedExternal;
case Kind::OptionalChain:
case Kind::OptionalForce:
case Kind::OptionalWrap:
@@ -2323,23 +2319,18 @@
// Value is the VarDecl* for StoredProperty, the SILFunction* of the
// Getter for computed properties, or the Kind for other kinds
llvm::PointerIntPair<void *, KindPackingBits, unsigned> ValueAndKind;
- union {
- // Valid if Kind == GettableProperty || Kind == SettableProperty
- struct {
- llvm::PointerIntPair<SILFunction *, 2,
- ComputedPropertyId::KindType> SetterAndIdKind;
- ComputedPropertyId::ValueType IdValue;
- } Computed;
- // Valid if Kind == External
- SubstitutionMap ExternalSubstitutions;
- };
+ llvm::PointerIntPair<SILFunction *, 2,
+ ComputedPropertyId::KindType> SetterAndIdKind;
+ ComputedPropertyId::ValueType IdValue;
ArrayRef<Index> Indices;
struct {
SILFunction *Equal;
SILFunction *Hash;
} IndexEquality;
CanType ComponentType;
-
+ AbstractStorageDecl *ExternalStorage;
+ SubstitutionMap ExternalSubstitutions;
+
/// Constructor for stored components
KeyPathPatternComponent(VarDecl *storedProp,
CanType ComponentType)
@@ -2353,26 +2344,18 @@
ArrayRef<Index> indices,
SILFunction *indicesEqual,
SILFunction *indicesHash,
+ AbstractStorageDecl *externalStorage,
+ SubstitutionMap externalSubstitutions,
CanType ComponentType)
: ValueAndKind(getter, PackedComputed),
- Computed{{setter, id.Kind}, {id.Value}},
+ SetterAndIdKind{setter, id.Kind},
+ IdValue{id.Value},
Indices(indices),
IndexEquality{indicesEqual, indicesHash},
- ComponentType(ComponentType) {
- }
-
- /// Constructor for external components
- KeyPathPatternComponent(AbstractStorageDecl *externalStorage,
- SubstitutionMap substitutions,
- ArrayRef<Index> indices,
- SILFunction *indicesEqual,
- SILFunction *indicesHash,
- CanType componentType)
- : ValueAndKind(externalStorage, PackedExternal),
- ExternalSubstitutions(substitutions),
- Indices(indices),
- IndexEquality{indicesEqual, indicesHash},
- ComponentType(componentType) {
+ ComponentType(ComponentType),
+ ExternalStorage(externalStorage),
+ ExternalSubstitutions(externalSubstitutions)
+ {
}
/// Constructor for optional components.
@@ -2396,10 +2379,8 @@
case PackedStored:
return Kind::StoredProperty;
case PackedComputed:
- return Computed.SetterAndIdKind.getPointer()
+ return SetterAndIdKind.getPointer()
? Kind::SettableProperty : Kind::GettableProperty;
- case PackedExternal:
- return Kind::External;
case Unpacked:
return (Kind)((uintptr_t)ValueAndKind.getPointer() >> KindPackingBits);
}
@@ -2418,7 +2399,6 @@
case Kind::OptionalChain:
case Kind::OptionalForce:
case Kind::OptionalWrap:
- case Kind::External:
llvm_unreachable("not a stored property");
}
llvm_unreachable("unhandled kind");
@@ -2430,12 +2410,11 @@
case Kind::OptionalChain:
case Kind::OptionalForce:
case Kind::OptionalWrap:
- case Kind::External:
llvm_unreachable("not a computed property");
case Kind::GettableProperty:
case Kind::SettableProperty:
- return ComputedPropertyId(Computed.IdValue,
- Computed.SetterAndIdKind.getInt());
+ return ComputedPropertyId(IdValue,
+ SetterAndIdKind.getInt());
}
llvm_unreachable("unhandled kind");
}
@@ -2446,7 +2425,6 @@
case Kind::OptionalChain:
case Kind::OptionalForce:
case Kind::OptionalWrap:
- case Kind::External:
llvm_unreachable("not a computed property");
case Kind::GettableProperty:
case Kind::SettableProperty:
@@ -2462,10 +2440,9 @@
case Kind::OptionalChain:
case Kind::OptionalForce:
case Kind::OptionalWrap:
- case Kind::External:
llvm_unreachable("not a settable computed property");
case Kind::SettableProperty:
- return Computed.SetterAndIdKind.getPointer();
+ return SetterAndIdKind.getPointer();
}
llvm_unreachable("unhandled kind");
}
@@ -2479,7 +2456,6 @@
return {};
case Kind::GettableProperty:
case Kind::SettableProperty:
- case Kind::External:
return Indices;
}
}
@@ -2491,7 +2467,6 @@
case Kind::OptionalForce:
case Kind::OptionalWrap:
llvm_unreachable("not a computed property");
- case Kind::External:
case Kind::GettableProperty:
case Kind::SettableProperty:
return IndexEquality.Equal;
@@ -2504,7 +2479,6 @@
case Kind::OptionalForce:
case Kind::OptionalWrap:
llvm_unreachable("not a computed property");
- case Kind::External:
case Kind::GettableProperty:
case Kind::SettableProperty:
return IndexEquality.Hash;
@@ -2519,15 +2493,29 @@
}
AbstractStorageDecl *getExternalDecl() const {
- assert(getKind() == Kind::External
- && "not an external property");
- return (AbstractStorageDecl*)ValueAndKind.getPointer();
+ switch (getKind()) {
+ case Kind::StoredProperty:
+ case Kind::OptionalChain:
+ case Kind::OptionalForce:
+ case Kind::OptionalWrap:
+ llvm_unreachable("not a computed property");
+ case Kind::GettableProperty:
+ case Kind::SettableProperty:
+ return ExternalStorage;
+ }
}
SubstitutionMap getExternalSubstitutions() const {
- assert(getKind() == Kind::External
- && "not an external property");
- return ExternalSubstitutions;
+ switch (getKind()) {
+ case Kind::StoredProperty:
+ case Kind::OptionalChain:
+ case Kind::OptionalForce:
+ case Kind::OptionalWrap:
+ llvm_unreachable("not a computed property");
+ case Kind::GettableProperty:
+ case Kind::SettableProperty:
+ return ExternalSubstitutions;
+ }
}
static KeyPathPatternComponent
@@ -2536,10 +2524,14 @@
ArrayRef<Index> indices,
SILFunction *indicesEquals,
SILFunction *indicesHash,
+ AbstractStorageDecl *externalDecl,
+ SubstitutionMap externalSubs,
CanType ty) {
return KeyPathPatternComponent(identifier,
getter, nullptr, indices,
- indicesEquals, indicesHash, ty);
+ indicesEquals, indicesHash,
+ externalDecl, externalSubs,
+ ty);
}
static KeyPathPatternComponent
@@ -2549,10 +2541,14 @@
ArrayRef<Index> indices,
SILFunction *indicesEquals,
SILFunction *indicesHash,
+ AbstractStorageDecl *externalDecl,
+ SubstitutionMap externalSubs,
CanType ty) {
return KeyPathPatternComponent(identifier,
getter, setter, indices,
- indicesEquals, indicesHash, ty);
+ indicesEquals, indicesHash,
+ externalDecl, externalSubs,
+ ty);
}
static KeyPathPatternComponent
@@ -2568,23 +2564,11 @@
case Kind::StoredProperty:
case Kind::GettableProperty:
case Kind::SettableProperty:
- case Kind::External:
llvm_unreachable("not an optional kind");
}
return KeyPathPatternComponent(kind, ty);
}
- static KeyPathPatternComponent
- forExternal(AbstractStorageDecl *externalDecl,
- SubstitutionMap substitutions,
- ArrayRef<Index> indices,
- SILFunction *indicesEquals,
- SILFunction *indicesHash,
- CanType ty) {
- return KeyPathPatternComponent(externalDecl, substitutions,
- indices, indicesEquals, indicesHash, ty);
- }
-
void incrementRefCounts() const;
void decrementRefCounts() const;
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index 9e194af..4b29be7 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -55,7 +55,7 @@
/// 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 = 425; // Last change: access impls
+const uint16_t VERSION_MINOR = 426; // SIL key path external components with local attempts
using DeclIDField = BCFixed<31>;
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index ebd675b..10913bf 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -623,8 +623,7 @@
// External components don't need to store the key path environment (and
// can't), since they need to already have enough information to function
// independently of any context using the component.
- if (genericEnv &&
- component.getKind() != KeyPathPatternComponent::Kind::External) {
+ if (genericEnv) {
auto destGenericEnv = dest;
if (!component.getSubscriptIndices().empty()) {
auto genericEnvAlignMask = llvm::ConstantInt::get(IGM.SizeTy,
@@ -703,28 +702,6 @@
});
};
-static llvm::Function *
-emitWitnessTableGeneratorForKeyPath(IRGenModule &IGM,
- CanType type,
- ProtocolConformanceRef conformance,
- GenericEnvironment *genericEnv,
- ArrayRef<GenericRequirement> requirements) {
- // TODO: Use the standard conformance accessor when there are no arguments
- // and the conformance accessor is defined.
- return emitGeneratorForKeyPath(IGM, "keypath_get_witness_table", type,
- IGM.WitnessTablePtrTy,
- genericEnv, requirements,
- [&](IRGenFunction &IGF, CanType substType) {
- if (type->hasTypeParameter())
- conformance = conformance.subst(type,
- QueryInterfaceTypeSubstitutions(genericEnv),
- LookUpConformanceInSignature(*genericEnv->getGenericSignature()));
- auto ret = emitWitnessTableRef(IGF, substType, conformance);
- IGF.Builder.CreateRet(ret);
- });
-}
-
-
static void
emitKeyPathComponent(IRGenModule &IGM,
ConstantStructBuilder &fields,
@@ -745,75 +722,6 @@
loweredBaseTy = IGM.getLoweredType(AbstractionPattern::getOpaque(),
baseTy->getWithoutSpecifierType());
switch (auto kind = component.getKind()) {
- case KeyPathPatternComponent::Kind::External: {
- fields.addInt32(KeyPathComponentHeader::forExternalComponent().getData());
- // Emit accessors for all of the external declaration's necessary
- // bindings.
- SmallVector<llvm::Constant*, 4> descriptorArgs;
- auto componentSig = component.getExternalDecl()->getInnermostDeclContext()
- ->getGenericSignatureOfContext();
- auto subs = component.getExternalSubstitutions();
- enumerateGenericSignatureRequirements(
- componentSig->getCanonicalSignature(),
- [&](GenericRequirement reqt) {
- auto substType = reqt.TypeParameter.subst(subs)
- ->getCanonicalType();
- if (!reqt.Protocol) {
- // Type requirement.
- descriptorArgs.push_back(
- emitMetadataGeneratorForKeyPath(IGM, substType,
- genericEnv, requirements));
- } else {
- // Protocol requirement.
- auto conformance = subs.lookupConformance(
- reqt.TypeParameter->getCanonicalType(), reqt.Protocol);
- descriptorArgs.push_back(
- emitWitnessTableGeneratorForKeyPath(IGM, substType,
- *conformance,
- genericEnv, requirements));
- }
- });
- // If instantiable in-place, pad out the argument count here to ensure
- // there's room enough to instantiate a settable computed property
- // with two captured words in-place. The runtime instantiation of the
- // external component will ignore the padding, and this will make in-place
- // instantiation more likely to avoid needing an allocation.
- unsigned argSize = descriptorArgs.size();
- if (isInstantiableInPlace) {
- argSize = std::max(argSize, 3u);
- }
-
- fields.addInt32(argSize);
- fields.add(IGM.getAddrOfPropertyDescriptor(component.getExternalDecl()));
-
- // Add an initializer function that copies generic arguments out of the
- // pattern argument buffer into the instantiated object, along with the
- // index equality/hash operations we have from our perspective, or null
- // if there are no arguments.
- if (component.getSubscriptIndices().empty()) {
- fields.addInt(IGM.IntPtrTy, 0);
- fields.addInt(IGM.IntPtrTy, 0);
- fields.addInt(IGM.IntPtrTy, 0);
- } else {
- fields.add(getInitializerForComputedComponent(IGM, component,
- operands,
- genericEnv,
- requirements));
- fields.add(IGM.getAddrOfSILFunction(component.getSubscriptIndexEquals(),
- NotForDefinition));
- fields.add(IGM.getAddrOfSILFunction(component.getSubscriptIndexHash(),
- NotForDefinition));
- }
-
- // Add the generic arguments for the external context.
- for (auto arg : descriptorArgs)
- fields.add(arg);
-
- // Add padding.
- for (unsigned i = descriptorArgs.size(); i < argSize; ++i)
- fields.addInt(IGM.IntPtrTy, 0);
- break;
- }
case KeyPathPatternComponent::Kind::StoredProperty: {
auto property = cast<VarDecl>(component.getStoredPropertyDecl());
@@ -1162,7 +1070,6 @@
switch (component.getKind()) {
case KeyPathPatternComponent::Kind::GettableProperty:
case KeyPathPatternComponent::Kind::SettableProperty:
- case KeyPathPatternComponent::Kind::External:
for (auto &index : component.getSubscriptIndices()) {
operands[index.Operand].LoweredType = index.LoweredType;
operands[index.Operand].LastUser = &component;
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 1dfbe44..bbf8e21 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -1943,79 +1943,6 @@
component =
KeyPathPatternComponent::forStoredProperty(cast<VarDecl>(prop), ty);
return false;
- } else if (componentKind.str() == "external") {
- ValueDecl *externalDecl;
- SmallVector<ParsedSubstitution, 4> parsedSubs;
- SmallVector<KeyPathPatternComponent::Index, 4> indexes;
- CanType ty;
-
- if (parseSILDottedPath(externalDecl)
- || parseSubstitutions(parsedSubs, patternEnv))
- return true;
-
- if (P.consumeIf(tok::l_square)) {
- if (parseComponentIndices(indexes))
- return true;
- }
-
- if (P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":")
- || P.parseToken(tok::sil_dollar,
- diag::expected_tok_in_sil_instr, "$")
- || parseASTType(ty, patternEnv))
- return true;
-
- SILFunction *equals = nullptr;
- SILFunction *hash = nullptr;
-
- while (P.consumeIf(tok::comma)) {
- Identifier subKind;
- SourceLoc subKindLoc;
- if (parseSILIdentifier(subKind, subKindLoc,
- diag::sil_keypath_expected_component_kind))
- return true;
-
- if (subKind.str() == "indices_equals") {
- if (parseSILFunctionRef(InstLoc, equals))
- return true;
- } else if (subKind.str() == "indices_hash") {
- if (parseSILFunctionRef(InstLoc, hash))
- return true;
- } else {
- P.diagnose(subKindLoc, diag::sil_keypath_unknown_component_kind,
- subKind);
- return true;
- }
- }
-
- if (!indexes.empty() != (equals && hash)) {
- P.diagnose(componentLoc,
- diag::sil_keypath_external_missing_part);
- return true;
- }
-
- SubstitutionMap subsMap;
- if (!parsedSubs.empty()) {
- auto genericEnv = externalDecl->getInnermostDeclContext()
- ->getGenericEnvironmentOfContext();
- if (!genericEnv) {
- P.diagnose(P.Tok,
- diag::sil_substitutions_on_non_polymorphic_type);
- return true;
- }
- subsMap = getApplySubstitutionsFromParsed(*this, genericEnv, parsedSubs);
- if (!subsMap) return true;
-
- // Map the substitutions out of the pattern context so that they
- // use interface types.
- subsMap = subsMap.mapReplacementTypesOutOfContext().getCanonical();
- }
-
- auto indexesCopy = P.Context.AllocateCopy(indexes);
-
- component = KeyPathPatternComponent::forExternal(
- cast<AbstractStorageDecl>(externalDecl),
- subsMap, indexesCopy, equals, hash, ty);
- return false;
} else if (componentKind.str() == "gettable_property"
|| componentKind.str() == "settable_property") {
bool isSettable = componentKind.str()[0] == 's';
@@ -2033,6 +1960,8 @@
SILFunction *setter = nullptr;
SILFunction *equals = nullptr;
SILFunction *hash = nullptr;
+ AbstractStorageDecl *externalDecl = nullptr;
+ SubstitutionMap externalSubs;
SmallVector<KeyPathPatternComponent::Index, 4> indexes;
while (true) {
Identifier subKind;
@@ -2078,6 +2007,34 @@
} else if (subKind.str() == "indices_hash") {
if (parseSILFunctionRef(InstLoc, hash))
return true;
+ } else if (subKind.str() == "external") {
+ ValueDecl *parsedExternalDecl;
+ SmallVector<ParsedSubstitution, 4> parsedSubs;
+
+ if (parseSILDottedPath(parsedExternalDecl)
+ || parseSubstitutions(parsedSubs, patternEnv))
+ return true;
+
+ externalDecl = cast<AbstractStorageDecl>(parsedExternalDecl);
+
+ if (!parsedSubs.empty()) {
+ auto genericEnv = externalDecl->getInnermostDeclContext()
+ ->getGenericEnvironmentOfContext();
+ if (!genericEnv) {
+ P.diagnose(P.Tok,
+ diag::sil_substitutions_on_non_polymorphic_type);
+ return true;
+ }
+ externalSubs = getApplySubstitutionsFromParsed(*this, genericEnv,
+ parsedSubs);
+ if (!externalSubs) return true;
+
+ // Map the substitutions out of the pattern context so that they
+ // use interface types.
+ externalSubs =
+ externalSubs.mapReplacementTypesOutOfContext().getCanonical();
+ }
+
} else {
P.diagnose(subKindLoc, diag::sil_keypath_unknown_component_kind,
subKind);
@@ -2126,11 +2083,13 @@
if (isSettable) {
component = KeyPathPatternComponent::forComputedSettableProperty(
id, getter, setter,
- indexesCopy, equals, hash, componentTy);
+ indexesCopy, equals, hash,
+ externalDecl, externalSubs, componentTy);
} else {
component = KeyPathPatternComponent::forComputedGettableProperty(
id, getter,
- indexesCopy, equals, hash, componentTy);
+ indexesCopy, equals, hash,
+ externalDecl, externalSubs, componentTy);
}
return false;
} else if (componentKind.str() == "optional_wrap"
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 3724703..4baaa31 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -2041,7 +2041,6 @@
case Kind::OptionalChain:
case Kind::OptionalWrap:
case Kind::OptionalForce:
- case Kind::External:
llvm_unreachable("not a settable computed property");
case Kind::SettableProperty: {
auto setter = getComputedPropertySetter();
@@ -2059,7 +2058,6 @@
case KeyPathPatternComponent::Kind::OptionalChain:
case KeyPathPatternComponent::Kind::OptionalWrap:
case KeyPathPatternComponent::Kind::OptionalForce:
- case KeyPathPatternComponent::Kind::External:
return;
case KeyPathPatternComponent::Kind::SettableProperty:
forFunction(component.getComputedPropertySetter());
@@ -2118,7 +2116,6 @@
case KeyPathPatternComponent::Kind::OptionalForce:
break;
- case KeyPathPatternComponent::Kind::External:
case KeyPathPatternComponent::Kind::GettableProperty:
case KeyPathPatternComponent::Kind::SettableProperty:
for (auto &index : component.getSubscriptIndices()) {
@@ -2196,14 +2193,7 @@
case KeyPathPatternComponent::Kind::StoredProperty:
ID.AddPointer(component.getStoredPropertyDecl());
break;
-
- case KeyPathPatternComponent::Kind::External: {
- ID.AddPointer(component.getExternalDecl());
- component.getExternalSubstitutions().profile(ID);
- profileIndices(component.getSubscriptIndices());
- break;
- }
-
+
case KeyPathPatternComponent::Kind::SettableProperty:
ID.AddPointer(component.getComputedPropertySetter());
LLVM_FALLTHROUGH;
@@ -2233,6 +2223,8 @@
}
}
profileIndices(component.getSubscriptIndices());
+ ID.AddPointer(component.getExternalDecl());
+ component.getExternalSubstitutions().profile(ID);
break;
}
}
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index 7b33dad..30ddd56 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -2132,6 +2132,16 @@
*this << " : "
<< component.getSubscriptIndexHash()->getLoweredType();
}
+
+ if (auto external = component.getExternalDecl()) {
+ *this << ", external #";
+ printValueDecl(external, PrintState.OS);
+ auto subs = component.getExternalSubstitutions();
+ if (!subs.empty()) {
+ printSubstitutions(subs);
+ }
+ }
+
break;
}
case KeyPathPatternComponent::Kind::OptionalWrap:
@@ -2153,30 +2163,6 @@
*this << component.getComponentType();
break;
}
- case KeyPathPatternComponent::Kind::External: {
- *this << "external #";
- printValueDecl(component.getExternalDecl(), PrintState.OS);
- if (!component.getExternalSubstitutions().empty()) {
- printSubstitutions(component.getExternalSubstitutions());
- }
-
- if (!component.getSubscriptIndices().empty()) {
- printComponentIndices(component.getSubscriptIndices());
- }
-
- *this << " : $" << component.getComponentType();
-
- if (!component.getSubscriptIndices().empty()) {
- *this << ", indices_equals ";
- component.getSubscriptIndexEquals()->printName(PrintState.OS);
- *this << " : "
- << component.getSubscriptIndexEquals()->getLoweredType();
- *this << ", indices_hash ";
- component.getSubscriptIndexHash()->printName(PrintState.OS);
- *this << " : "
- << component.getSubscriptIndexHash()->getLoweredType();
- }
- }
}
}
};
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index ab1eff6..84519b1 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -344,54 +344,6 @@
break;
}
- case KeyPathPatternComponent::Kind::External: {
- // The component type should match the substituted type of the
- // referenced property.
- auto decl = component.getExternalDecl();
- auto sig = decl->getInnermostDeclContext()
- ->getGenericSignatureOfContext();
- SubstitutionMap subs;
- CanGenericSignature canSig = nullptr;
- if (sig) {
- canSig = sig->getCanonicalSignature();
- subs = component.getExternalSubstitutions();
- }
- auto substType = component.getExternalDecl()->getStorageInterfaceType()
- .subst(subs);
- require(substType->isEqual(component.getComponentType()),
- "component type should match storage type of referenced "
- "declaration");
-
- // Index types should match the lowered index types expected by the
- // external declaration.
- if (auto sub = dyn_cast<SubscriptDecl>(decl)) {
- auto indexParams = sub->getIndices();
- require(indexParams->size() == component.getSubscriptIndices().size(),
- "number of subscript indices should match referenced decl");
- for (unsigned i : indices(*indexParams)) {
- auto param = (*indexParams)[i];
- auto &index = component.getSubscriptIndices()[i];
- auto paramTy = param->getInterfaceType()->getCanonicalType();
- auto substParamTy = paramTy.subst(subs);
- auto loweredTy = M.Types.getLoweredType(
- AbstractionPattern(canSig, paramTy), substParamTy);
- require(index.LoweredType == loweredTy,
- "index lowered types should match referenced decl");
- require(index.FormalType == substParamTy->getCanonicalType(),
- "index formal types should match referenced decl");
- }
-
- checkIndexEqualsAndHash();
- } else {
- require(component.getSubscriptIndices().empty(),
- "external var reference should not apply indices");
- require(!component.getSubscriptIndexEquals()
- && !component.getSubscriptIndexHash(),
- "external var reference should not apply hash");
- }
-
- break;
- }
case KeyPathPatternComponent::Kind::OptionalChain: {
require(baseTy->getOptionalObjectType()->isEqual(componentTy),
"chaining component should unwrap optional");
@@ -4222,14 +4174,6 @@
for (auto &component : pattern->getComponents()) {
bool hasIndices;
switch (component.getKind()) {
- case KeyPathPatternComponent::Kind::External:
- if (auto subscript =
- dyn_cast<SubscriptDecl>(component.getExternalDecl()))
- hasIndices = subscript->getIndices()->size() != 0;
- else
- hasIndices = false;
- break;
-
case KeyPathPatternComponent::Kind::GettableProperty:
case KeyPathPatternComponent::Kind::SettableProperty:
hasIndices = !component.getSubscriptIndices().empty();
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 03453e1..cdefc3b 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -3637,10 +3637,38 @@
ArrayRef<ProtocolConformanceRef> indexHashables,
CanType baseTy,
bool forPropertyDescriptor) {
+ /// Returns true if a key path component for the given property or
+ /// subscript should be externally referenced.
+ auto shouldUseExternalKeyPathComponent =
+ [&]() -> bool {
+ return getASTContext().LangOpts.EnableKeyPathResilience
+ && !forPropertyDescriptor
+ && storage->getModuleContext() != SwiftModule;
+ };
+
auto strategy = storage->getAccessStrategy(AccessSemantics::Ordinary,
storage->supportsMutation()
? AccessKind::ReadWrite
- : AccessKind::Read);
+ : AccessKind::Read,
+ M.getSwiftModule());
+
+ AbstractStorageDecl *externalDecl = nullptr;
+ SubstitutionMap externalSubs;
+
+ if (shouldUseExternalKeyPathComponent()) {
+ externalDecl = storage;
+ // Map the substitutions out of context.
+ if (!subs.empty()) {
+ externalSubs = subs;
+ // If any of the substitutions involve local archetypes, then the
+ // key path pattern needs to capture the generic context, and we need
+ // to map the pattern substitutions out of this context.
+ if (externalSubs.hasArchetypes()) {
+ needsGenericContext = true;
+ externalSubs = externalSubs.mapReplacementTypesOutOfContext();
+ }
+ }
+ }
if (auto var = dyn_cast<VarDecl>(storage)) {
CanType componentTy;
@@ -3698,10 +3726,12 @@
{},
baseTy, componentTy);
return KeyPathPatternComponent::forComputedSettableProperty(id,
- getter, setter, {}, nullptr, nullptr, componentTy);
+ getter, setter, {}, nullptr, nullptr,
+ externalDecl, externalSubs, componentTy);
} else {
return KeyPathPatternComponent::forComputedGettableProperty(id,
- getter, {}, nullptr, nullptr, componentTy);
+ getter, {}, nullptr, nullptr,
+ externalDecl, externalSubs, componentTy);
}
}
}
@@ -3754,6 +3784,8 @@
indexPatternsCopy,
indexEquals,
indexHash,
+ externalDecl,
+ externalSubs,
componentTy);
} else {
return KeyPathPatternComponent::forComputedGettableProperty(id,
@@ -3761,6 +3793,8 @@
indexPatternsCopy,
indexEquals,
indexHash,
+ externalDecl,
+ externalSubs,
componentTy);
}
}
@@ -3810,87 +3844,28 @@
}
};
- /// Returns true if a key path component for the given property or
- /// subscript should be externally referenced.
- auto shouldUseExternalKeyPathComponent =
- [&](AbstractStorageDecl *storage) -> bool {
- return SGF.getASTContext().LangOpts.EnableKeyPathResilience
- && storage->getModuleContext() != SGF.SGM.SwiftModule;
- };
-
- /// Build an external key path component referencing a property or subscript
- /// from another module.
- auto makeExternalKeyPathComponent =
- [&](const KeyPathExpr::Component &component) -> KeyPathPatternComponent {
- SmallVector<KeyPathPatternComponent::Index, 4> indices;
- SubstitutionMap subMap = component.getDeclRef().getSubstitutions();
- auto decl = cast<AbstractStorageDecl>(component.getDeclRef().getDecl());
- auto ty = decl->getStorageInterfaceType();
- // Map the substitutions out of context.
- if (!subMap.empty()) {
- // If any of the substitutions involve local archetypes, then the
- // key path pattern needs to capture the generic context, and we need
- // to map the pattern substitutions out of this context.
- if (subMap.hasArchetypes()) {
- needsGenericContext = true;
- subMap = subMap.mapReplacementTypesOutOfContext();
- }
- ty = ty.subst(subMap);
- }
-
- SILFunction *indexEquals = nullptr, *indexHash = nullptr;
- if (component.getKind() == KeyPathExpr::Component::Kind::Subscript) {
- unsigned numOperands = operands.size();
- SmallVector<IndexTypePair, 4> indexTypes;
- auto sub = cast<SubscriptDecl>(component.getDeclRef().getDecl());
- lowerKeyPathSubscriptIndexTypes(
- SGF.SGM, indexTypes, sub,
- component.getDeclRef().getSubstitutions(),
- needsGenericContext);
- lowerKeyPathSubscriptIndexPatterns(indices, indexTypes,
- component.getSubscriptIndexHashableConformances(),
- numOperands);
-
- lowerSubscriptOperands(component);
-
- assert(numOperands == operands.size()
- && "operand count out of sync");
- getOrCreateKeyPathEqualsAndHash(SGF.SGM, SILLocation(E),
- needsGenericContext ? SGF.F.getGenericEnvironment() : nullptr,
- indices,
- indexEquals, indexHash);
- }
- return KeyPathPatternComponent::forExternal(
- decl, subMap, SGF.getASTContext().AllocateCopy(indices),
- indexEquals, indexHash,
- ty->getCanonicalType());
- };
-
+
for (auto &component : E->getComponents()) {
switch (auto kind = component.getKind()) {
case KeyPathExpr::Component::Kind::Property:
case KeyPathExpr::Component::Kind::Subscript: {
auto decl = cast<AbstractStorageDecl>(component.getDeclRef().getDecl());
- if (shouldUseExternalKeyPathComponent(decl)) {
- loweredComponents.push_back(makeExternalKeyPathComponent(component));
- } else {
- unsigned numOperands = operands.size();
- loweredComponents.push_back(
- SGF.SGM.emitKeyPathComponentForDecl(SILLocation(E),
- SGF.F.getGenericEnvironment(),
- numOperands,
- needsGenericContext,
- component.getDeclRef().getSubstitutions(),
- decl,
- component.getSubscriptIndexHashableConformances(),
- baseTy,
- /*for descriptor*/ false));
- lowerSubscriptOperands(component);
-
- assert(numOperands == operands.size()
- && "operand count out of sync");
- }
+ unsigned numOperands = operands.size();
+ loweredComponents.push_back(
+ SGF.SGM.emitKeyPathComponentForDecl(SILLocation(E),
+ SGF.F.getGenericEnvironment(),
+ numOperands,
+ needsGenericContext,
+ component.getDeclRef().getSubstitutions(),
+ decl,
+ component.getSubscriptIndexHashableConformances(),
+ baseTy,
+ /*for descriptor*/ false));
+ lowerSubscriptOperands(component);
+
+ assert(numOperands == operands.size()
+ && "operand count out of sync");
baseTy = loweredComponents.back().getComponentType();
break;
diff --git a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
index 1989c32..59ccf91 100644
--- a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
+++ b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
@@ -234,7 +234,6 @@
case KeyPathPatternComponent::Kind::OptionalChain:
case KeyPathPatternComponent::Kind::OptionalForce:
case KeyPathPatternComponent::Kind::OptionalWrap:
- case KeyPathPatternComponent::Kind::External:
break;
}
}
diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementWMO.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementWMO.cpp
index 3440a83..8c8d8b5 100644
--- a/lib/SILOptimizer/Transforms/AccessEnforcementWMO.cpp
+++ b/lib/SILOptimizer/Transforms/AccessEnforcementWMO.cpp
@@ -184,7 +184,6 @@
break;
case KeyPathPatternComponent::Kind::GettableProperty:
case KeyPathPatternComponent::Kind::SettableProperty:
- case KeyPathPatternComponent::Kind::External:
case KeyPathPatternComponent::Kind::OptionalChain:
case KeyPathPatternComponent::Kind::OptionalForce:
case KeyPathPatternComponent::Kind::OptionalWrap:
diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp
index 2e3ffd6..32d393e 100644
--- a/lib/Sema/TypeCheckSwitchStmt.cpp
+++ b/lib/Sema/TypeCheckSwitchStmt.cpp
@@ -319,38 +319,6 @@
return TypeAndVal.getInt();
}
- // Defines a "usefulness" metric that returns whether the given space
- // contributes meaningfully to the exhaustiveness of a pattern.
- bool isUseful() const {
- auto subspacesUseful = [](const Space &space) {
- for (auto &subspace : space.getSpaces()) {
- if (!subspace.isUseful()) {
- return false;
- }
- }
- return true;
- };
-
- switch (getKind()) {
- case SpaceKind::Empty:
- return false;
- case SpaceKind::Type:
- case SpaceKind::BooleanConstant:
- case SpaceKind::UnknownCase:
- return true;
- case SpaceKind::Disjunct:
- if (getSpaces().empty()) {
- return false;
- }
- return subspacesUseful(*this);
- case SpaceKind::Constructor:
- if (getSpaces().empty()) {
- return true;
- }
- return subspacesUseful(*this);
- }
- }
-
// An optimization that computes if the difference of this space and
// another space is empty.
bool isSubspace(const Space &other, TypeChecker &TC,
@@ -1178,13 +1146,14 @@
Space projection = projectPattern(TC, caseItem.getPattern(),
sawDowngradablePattern);
- if (projection.isUseful()
- && projection.isSubspace(Space::forDisjunct(spaces), TC, DC)) {
+ if (!projection.isEmpty() &&
+ projection.isSubspace(Space::forDisjunct(spaces), TC, DC)) {
sawRedundantPattern |= true;
TC.diagnose(caseItem.getStartLoc(),
diag::redundant_particular_case)
.highlight(caseItem.getSourceRange());
+ continue;
} else {
Expr *cachedExpr = nullptr;
if (checkRedundantLiteral(caseItem.getPattern(), cachedExpr)) {
@@ -1195,6 +1164,7 @@
TC.diagnose(cachedExpr->getLoc(),
diag::redundant_particular_literal_case_here)
.highlight(cachedExpr->getSourceRange());
+ continue;
}
}
spaces.push_back(projection);
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 7a689f2..1b6a62f 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -838,8 +838,15 @@
ArrayRef<KeyPathPatternComponent::Index> indices;
SILFunction *indicesEquals = nullptr;
SILFunction *indicesHash = nullptr;
+ AbstractStorageDecl *externalDecl = nullptr;
+ SubstitutionMap externalSubs;
- auto handleComputedIndices = [&] {
+ auto handleComputedExternalReferenceAndIndices = [&] {
+ auto externalDeclID = ListOfValues[nextValue++];
+ externalDecl =
+ cast_or_null<AbstractStorageDecl>(MF->getDecl(externalDeclID));
+ externalSubs = MF->getSubstitutionMap(ListOfValues[nextValue++]);
+
SmallVector<KeyPathPatternComponent::Index, 4> indicesBuf;
auto numIndexes = ListOfValues[nextValue++];
indicesBuf.reserve(numIndexes);
@@ -874,9 +881,10 @@
auto id = handleComputedId();
auto getterName = MF->getIdentifier(ListOfValues[nextValue++]);
auto getter = getFuncForReference(getterName.str());
- handleComputedIndices();
+ handleComputedExternalReferenceAndIndices();
return KeyPathPatternComponent::forComputedGettableProperty(
- id, getter, indices, indicesEquals, indicesHash, type);
+ id, getter, indices, indicesEquals, indicesHash,
+ externalDecl, externalSubs, type);
}
case KeyPathComponentKindEncoding::SettableProperty: {
auto id = handleComputedId();
@@ -884,9 +892,10 @@
auto getter = getFuncForReference(getterName.str());
auto setterName = MF->getIdentifier(ListOfValues[nextValue++]);
auto setter = getFuncForReference(setterName.str());
- handleComputedIndices();
+ handleComputedExternalReferenceAndIndices();
return KeyPathPatternComponent::forComputedSettableProperty(
- id, getter, setter, indices, indicesEquals, indicesHash, type);
+ id, getter, setter, indices, indicesEquals, indicesHash,
+ externalDecl, externalSubs, type);
break;
}
case KeyPathComponentKindEncoding::OptionalChain:
@@ -898,15 +907,6 @@
case KeyPathComponentKindEncoding::OptionalWrap:
return KeyPathPatternComponent::forOptional(
KeyPathPatternComponent::Kind::OptionalWrap, type);
- case KeyPathComponentKindEncoding::External: {
- auto declID = ListOfValues[nextValue++];
- auto decl = cast<AbstractStorageDecl>(MF->getDecl(declID));
- auto subMap = MF->getSubstitutionMap(ListOfValues[nextValue++]);
- handleComputedIndices();
- return KeyPathPatternComponent::forExternal(decl, subMap, indices,
- indicesEquals, indicesHash,
- type);
- }
case KeyPathComponentKindEncoding::Trivial:
llvm_unreachable("handled above");
}
diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h
index 7f5f9ce..537c242 100644
--- a/lib/Serialization/SILFormat.h
+++ b/lib/Serialization/SILFormat.h
@@ -84,7 +84,6 @@
OptionalChain,
OptionalForce,
OptionalWrap,
- External,
Trivial,
};
enum class KeyPathComputedComponentIdKindEncoding : uint8_t {
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index e61b3f9..c238d3b 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -624,8 +624,12 @@
break;
}
};
- auto handleComputedIndices
+ auto handleComputedExternalReferenceAndIndices
= [&](const KeyPathPatternComponent &component) {
+ ListOfValues.push_back(S.addDeclRef(component.getExternalDecl()));
+ ListOfValues.push_back(
+ S.addSubstitutionMapRef(component.getExternalSubstitutions()));
+
auto indices = component.getSubscriptIndices();
ListOfValues.push_back(indices.size());
for (auto &index : indices) {
@@ -654,7 +658,7 @@
handleComputedId(component.getComputedPropertyId());
ListOfValues.push_back(
addSILFunctionRef(component.getComputedPropertyGetter()));
- handleComputedIndices(component);
+ handleComputedExternalReferenceAndIndices(component);
break;
case KeyPathPatternComponent::Kind::SettableProperty:
handleComponentCommon(KeyPathComponentKindEncoding::SettableProperty);
@@ -663,7 +667,7 @@
addSILFunctionRef(component.getComputedPropertyGetter()));
ListOfValues.push_back(
addSILFunctionRef(component.getComputedPropertySetter()));
- handleComputedIndices(component);
+ handleComputedExternalReferenceAndIndices(component);
break;
case KeyPathPatternComponent::Kind::OptionalChain:
handleComponentCommon(KeyPathComponentKindEncoding::OptionalChain);
@@ -674,13 +678,6 @@
case KeyPathPatternComponent::Kind::OptionalWrap:
handleComponentCommon(KeyPathComponentKindEncoding::OptionalWrap);
break;
- case KeyPathPatternComponent::Kind::External:
- handleComponentCommon(KeyPathComponentKindEncoding::External);
- ListOfValues.push_back(S.addDeclRef(component.getExternalDecl()));
- ListOfValues.push_back(
- S.addSubstitutionMapRef(component.getExternalSubstitutions()));
- handleComputedIndices(component);
- break;
}
}
diff --git a/test/Constraints/tuple-arguments-supported.swift b/test/Constraints/tuple-arguments-supported.swift
new file mode 100644
index 0000000..42da669
--- /dev/null
+++ b/test/Constraints/tuple-arguments-supported.swift
@@ -0,0 +1,48 @@
+// RUN: %target-typecheck-verify-swift
+
+func test1(_: ()) {}
+test1(())
+func test2() {}
+test2()
+
+func test4(_: (Int, Int) -> ()) {}
+test4({ (x,y) in })
+func test5(_: (Int, Int, Int) -> ()) {}
+test5({ (x,y,z) in })
+
+func test6(_: ((Int, Int)) -> ()) {}
+test6({ (x,y) in })
+func test7(_: ((Int, Int, Int)) -> ()) {}
+test7({ (x,y,z) in })
+test6({ (_ x, _ y) in })
+test6({ (_, _) in })
+test6({ (x:Int, y:Int) in })
+test6({ (_, _) ->() in })
+
+func test8(_: ((Int, Int)) -> Int) {}
+test8 { (_, _) -> Int in 2 }
+test8 { (x, y) in x }
+
+func isEven(_ x: Int) -> Bool { return x % 2 == 0 }
+let items = Array(zip(0..<10, 0..<10))
+_ = items.filter { (_, x) in isEven(x) }
+_ = items.filter { _ in true }
+
+func toString(indexes: Int?...) -> String {
+ let _ = indexes.enumerated().map({ (i: Int, index: Int?) -> String? in
+ let _: Int = i
+ if index != nil {}
+ return ""
+ })
+ let _ = [(1, 2)].contains { $0 != $1 }
+ _ = ["Hello" : 2].map { ($0, ($1)) }
+}
+
+extension Dictionary {
+ public mutating func merge(with dictionary: Dictionary) {
+ dictionary.forEach { updateValue($1, forKey: $0) }
+ }
+}
+
+let dictionary: [String: String] = [:]
+_ = dictionary.first { (column, value) in true }!.value
diff --git a/test/Constraints/tuple-arguments-unsupported.swift b/test/Constraints/tuple-arguments-unsupported.swift
new file mode 100644
index 0000000..5994829
--- /dev/null
+++ b/test/Constraints/tuple-arguments-unsupported.swift
@@ -0,0 +1,25 @@
+// RUN: %target-typecheck-verify-swift
+
+func test1(_: ()) {} // expected-note {{'test1' declared here}}
+test1() // expected-error {{missing argument for parameter #1 in call}}
+
+enum Result<T> {
+ case success(T) // expected-note {{'success' declared here}}
+}
+func test3(_: Result<()>) {}
+test3(.success()) // expected-error {{missing argument for parameter #1 in call}}
+
+func toString(indexes: Int?...) -> String {
+ let _ = indexes.reduce(0) { print($0); return $0.0 + ($0.1 ?? 0)}
+ // expected-error@-1 {{contextual closure type '(_, Int?) throws -> _' expects 2 arguments, but 1 was used in closure body}}
+ let _ = indexes.reduce(0) { (true ? $0 : (1, 2)).0 + ($0.1 ?? 0) }
+ // expected-error@-1 {{contextual closure type '(_, Int?) throws -> _' expects 2 arguments, but 1 was used in closure body}}
+ _ = ["Hello", "Foo"].sorted { print($0); return $0.0.count > ($0).1.count }
+ // expected-error@-1 {{argument passed to call that takes no arguments}}
+}
+
+func doit(_ x: Int) -> Bool { return x > 0 }
+let _: ((String, Int)) -> [String:Bool] = { [$0: doit($1)] }
+// expected-error@-1 {{closure tuple parameter '(String, Int)' does not support destructuring with implicit parameters}}
+func returnClosure() -> ((Int, Int)) -> Bool { return {$1 > $0} }
+// expected-error@-1 {{closure tuple parameter '(Int, Int)' does not support destructuring with implicit parameters}}
diff --git a/test/IDE/complete_func_reference.swift b/test/IDE/complete_func_reference.swift
index 94fdfa6..9d0005d 100644
--- a/test/IDE/complete_func_reference.swift
+++ b/test/IDE/complete_func_reference.swift
@@ -1,24 +1,24 @@
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=VOID_VOID_0 | %FileCheck %s -check-prefix=VOID_VOID
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=VOID_VOID_1 | %FileCheck %s -check-prefix=VOID_VOID
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=VOID_VOID_2 | %FileCheck %s -check-prefix=VOID_VOID
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=VOID_VOID_3 | %FileCheck %s -check-prefix=VOID_VOID
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=VOID_VOID_4 | %FileCheck %s -check-prefix=VOID_VOID
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=ANY_INT_0 | %FileCheck %s -check-prefix=ANY_INT
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=ANY_INT_1 | %FileCheck %s -check-prefix=ANY_INT
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=ANY_INT_2 > %t.results
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_VOID_0 | %FileCheck %s -check-prefix=VOID_VOID
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_VOID_1 | %FileCheck %s -check-prefix=VOID_VOID
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_VOID_2 | %FileCheck %s -check-prefix=VOID_VOID
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_VOID_3 | %FileCheck %s -check-prefix=VOID_VOID
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_VOID_4 | %FileCheck %s -check-prefix=VOID_VOID
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_0 | %FileCheck %s -check-prefix=ANY_INT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_1 | %FileCheck %s -check-prefix=ANY_INT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_2 > %t.results
// RUN:%FileCheck %s -check-prefix=ANY_INT < %t.results
// RUN:%FileCheck %s -check-prefix=ANY_INT_STATIC_CURRY < %t.results
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=ANY_INT_3 | %FileCheck %s -check-prefix=ANY_INT
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=ANY_INT_4 | %FileCheck %s -check-prefix=ANY_INT
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=INT_ANY_0 | %FileCheck %s -check-prefix=INT_ANY
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=INT_ANY_1 | %FileCheck %s -check-prefix=INT_ANY
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=INT_ANY_2 > %t.results
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_3 | %FileCheck %s -check-prefix=ANY_INT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_4 | %FileCheck %s -check-prefix=ANY_INT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INT_ANY_0 | %FileCheck %s -check-prefix=INT_ANY
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INT_ANY_1 | %FileCheck %s -check-prefix=INT_ANY
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INT_ANY_2 > %t.results
// RUN: %FileCheck %s -check-prefix=INT_ANY < %t.results
// RUN: %FileCheck %s -check-prefix=INT_ANY_STATIC_CURRY < %t.results
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=INT_ANY_3 > %t.results
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_0 | %FileCheck %s -check-prefix=VOID_INT_INT
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_1 | %FileCheck %s -check-prefix=VOID_INT_INT
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_2 | %FileCheck %s -check-prefix=VOID_INT_INT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INT_ANY_3 > %t.results
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_0 | %FileCheck %s -check-prefix=VOID_INT_INT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_1 | %FileCheck %s -check-prefix=VOID_INT_INT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_2 | %FileCheck %s -check-prefix=VOID_INT_INT
func voidToVoid() {}
func voidToInt() -> Int {}
@@ -122,7 +122,7 @@
}
// ANY_INT: Begin completions
-// ANY_INT-DAG: Decl{{.*}}/TypeRelation[Convertible]: anyToInt(a:);
+// ANY_INT-DAG: Decl{{.*}}: anyToInt({#a: Any#})[#Int#]; name=anyToInt(a: Any)
// ANY_INT-DAG: Decl{{.*}}/NotRecommended/TypeRelation[Invalid]: intToVoid({#a: Int#})[#Void#];
// ANY_INT-DAG: Decl{{.*}}/NotRecommended/TypeRelation[Invalid]: anyToVoid({#a: Any#})[#Void#];
// ANY_INT-DAG: Decl{{.*}}/NotRecommended/TypeRelation[Invalid]: voidToVoid()[#Void#];
@@ -135,7 +135,7 @@
// ANY_INT: End completions
// ANY_INT_STATIC_CURRY: Begin completions
-// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: anyToInt({#self: S0#})[#(a: Any) -> Int#];
+// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: anyToInt({#self: S0#})[#(a: Any) -> Int#]; name=anyToInt(S0)
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: voidToVoid({#self: S0#})[#() -> Void#];
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: intToVoid({#self: S0#})[#(a: Int) -> Void#];
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: anyToVoid({#self: S0#})[#(a: Any) -> Void#];
@@ -153,12 +153,12 @@
}
// INT_ANY: Begin completions
-// INT_ANY-DAG: Decl{{.*}}/TypeRelation[Convertible]: intToAny(a:);
-// INT_ANY-DAG: Decl{{.*}}/TypeRelation[Convertible]: intToInt(a:);
-// INT_ANY-DAG: Decl{{.*}}/TypeRelation[Convertible]: intToVoid(a:);
-// INT_ANY-DAG: Decl{{.*}}/TypeRelation[Convertible]: anyToAny(a:);
-// INT_ANY-DAG: Decl{{.*}}/TypeRelation[Convertible]: anyToInt(a:);
-// INT_ANY-DAG: Decl{{.*}}/TypeRelation[Convertible]: anyToVoid(a:);
+// INT_ANY-DAG: Decl{{.*}}: intToAny({#a: Int#})[#Any#]; name=intToAny(a: Int)
+// INT_ANY-DAG: Decl{{.*}}: intToInt({#a: Int#})[#Int#]; name=intToInt(a: Int)
+// INT_ANY-DAG: Decl{{.*}}: intToVoid({#a: Int#})[#Void#]; name=intToVoid(a: Int)
+// INT_ANY-DAG: Decl{{.*}}: anyToAny({#a: Any#})[#Any#]; name=anyToAny(a: Any)
+// INT_ANY-DAG: Decl{{.*}}: anyToInt({#a: Any#})[#Int#]; name=anyToInt(a: Any)
+// INT_ANY-DAG: Decl{{.*}}: anyToVoid({#a: Any#})[#Void#]; name=anyToVoid(a: Any)
// INT_ANY-DAG: Decl{{.*}}/TypeRelation[Convertible]: returnsIntToInt()[#(Int) -> Int#];
// INT_ANY-DAG: Decl{{.*}}/NotRecommended/TypeRelation[Invalid]: voidToVoid()[#Void#];
// INT_ANY-DAG: Decl{{.*}}: voidToInt()[#Int#];
@@ -166,12 +166,12 @@
// INT_ANY: End completions
// INT_ANY_STATIC_CURRY: Begin completions
-// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: intToInt({#self: S0#})[#(a: Int) -> Int#];
-// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: intToVoid({#self: S0#})[#(a: Int) -> Void#];
-// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: anyToAny({#self: S0#})[#(a: Any) -> Any#];
-// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: anyToVoid({#self: S0#})[#(a: Any) -> Void#];
-// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: intToAny({#self: S0#})[#(a: Int) -> Any#];
-// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: anyToInt({#self: S0#})[#(a: Any) -> Int#];
+// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: intToInt({#self: S0#})[#(a: Int) -> Int#]; name=intToInt(S0)
+// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: intToVoid({#self: S0#})[#(a: Int) -> Void#]; name=intToVoid(S0)
+// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: anyToAny({#self: S0#})[#(a: Any) -> Any#]; name=anyToAny(S0)
+// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: anyToVoid({#self: S0#})[#(a: Any) -> Void#]; name=anyToVoid(S0)
+// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: intToAny({#self: S0#})[#(a: Int) -> Any#]; name=intToAny(S0)
+// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: anyToInt({#self: S0#})[#(a: Any) -> Int#]; name=anyToInt(S0)
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: returnsIntToInt({#self: S0#})[#() -> (Int) -> Int#];
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: voidToAny({#self: S0#})[#() -> Any#];
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: voidToInt({#self: S0#})[#() -> Int#];
diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil
index c35019c..dc0260f 100644
--- a/test/IRGen/keypaths.sil
+++ b/test/IRGen/keypaths.sil
@@ -410,33 +410,6 @@
return undef : $()
}
-sil @generic_external : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B) -> () {
-entry(%0 : $*A, %1 : $*B, %2 : $*A, %3 : $*B, %4 : $*A, %5 : $*B):
- %t = keypath $KeyPath<G<B>, B>, <Z> (
- root $G<Z>;
- external #G.x<Z> : $Z
- ) <B>
-
- %u = keypath $KeyPath<G<A>, A>, <X: Hashable, Y: Hashable> (
- root $G<Y>;
- external #G.subscript<Y, X> [%$0 : $X : $*X] : $Y,
- indices_equals @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
- indices_hash @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int
- ) <B, A> (%1)
-
- %v = keypath $KeyPath<G<G<B>>, B>, <X: Hashable, Y: Hashable> (
- root $G<G<X>>;
- external #G.subscript<G<X>, Y> [%$1 : $Y : $*Y] : $G<X>,
- indices_equals @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
- indices_hash @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int;
- external #G.subscript<X, X> [%$0 : $X : $*X] : $X,
- indices_equals @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
- indices_hash @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int
- ) <B, A> (%3, %4)
-
- return undef : $()
-}
-
sil @s_get : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed A, UnsafeRawPointer) -> @out B
sil @s_set : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed B, @in_guaranteed A, UnsafeRawPointer) -> ()
sil @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
diff --git a/test/IRGen/type_layout_reference_storage.swift b/test/IRGen/type_layout_reference_storage.swift
index 2305cdf..ef53e24 100644
--- a/test/IRGen/type_layout_reference_storage.swift
+++ b/test/IRGen/type_layout_reference_storage.swift
@@ -41,43 +41,43 @@
// CHECK-native-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_[[REF_XI]]_bt, i32 0, i32 0)
// CHECK-objc-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_7fffffff, i32 0, i32 0)
// CHECK-native-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[REF_XI]]_bt, i32 0, i32 0)
- // CHECK-objc-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_7fffffff, i32 0, i32 0)
+ // CHECK-objc-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_8_4_[[REF_XI32:[0-9a-f]+]], i32 0, i32 0)
unowned(safe) var ps: P
// CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_7fffffff, i32 0, i32 0)
- // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_7fffffff, i32 0, i32 0)
+ // CHECK-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_8_4_[[REF_XI32_2:[0-9a-f]+]], i32 0, i32 0)
weak var pwo: P?
// CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_7fffffff, i32 0, i32 0)
- // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_7fffffff, i32 0, i32 0)
+ // CHECK-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_8_4_[[REF_XI32_2]], i32 0, i32 0)
weak var pwi: P!
// CHECK-native-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_[[REF_XI]]_bt, i32 0, i32 0)
// CHECK-objc-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_7fffffff, i32 0, i32 0)
// CHECK-native-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_[[REF_XI]]_bt, i32 0, i32 0)
- // CHECK-objc-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_7fffffff, i32 0, i32 0)
+ // CHECK-objc-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_12_4_[[REF_XI32]], i32 0, i32 0)
unowned(safe) var pqs: P & Q
// CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_[[REF_XI]]_pod, i32 0, i32 0)
// CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_[[REF_XI]]_pod, i32 0, i32 0)
unowned(unsafe) var pqu: P & Q
// CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_7fffffff, i32 0, i32 0)
- // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_7fffffff, i32 0, i32 0)
+ // CHECK-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_12_4_[[REF_XI32_2]], i32 0, i32 0)
weak var pqwo: (P & Q)?
// CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_7fffffff, i32 0, i32 0)
- // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_7fffffff, i32 0, i32 0)
+ // CHECK-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_12_4_[[REF_XI32_2]], i32 0, i32 0)
weak var pqwi: (P & Q)!
// CHECK-native-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_[[REF_XI]]_bt, i32 0, i32 0)
// CHECK-objc-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_7fffffff_bt, i32 0, i32 0)
// CHECK-native-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_[[REF_XI]]_bt, i32 0, i32 0)
- // CHECK-objc-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_7fffffff_bt, i32 0, i32 0)
+ // CHECK-objc-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_12_4_[[REF_XI32]]_bt, i32 0, i32 0)
unowned(safe) var pqcs: P & Q & C
// CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_[[REF_XI]]_pod, i32 0, i32 0)
- // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_[[REF_XI]]_pod, i32 0, i32 0)
+ // CHECK-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_12_4_[[REF_XI]]_pod, i32 0, i32 0)
unowned(unsafe) var pqcu: P & Q & C
// CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_7fffffff, i32 0, i32 0)
- // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_7fffffff, i32 0, i32 0)
+ // CHECK-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_12_4_[[REF_XI32_2]], i32 0, i32 0)
weak var pqcwo: (P & Q & C)?
// CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_7fffffff, i32 0, i32 0)
- // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_7fffffff, i32 0, i32 0)
+ // CHECK-32: store i8** getelementptr inbounds ([{{(3|4)}} x i8*], [{{(3|4)}} x i8*]* @type_layout_12_4_[[REF_XI32_2]], i32 0, i32 0)
weak var pqcwi: (P & Q & C)!
// -- Unknown-refcounted existential without witness tables.
diff --git a/test/Interpreter/currying_generics.swift b/test/Interpreter/currying_generics.swift
index 850856b..a38aec3 100644
--- a/test/Interpreter/currying_generics.swift
+++ b/test/Interpreter/currying_generics.swift
@@ -1,4 +1,4 @@
-// RUN: %target-run-simple-swift-swift3 | %FileCheck %s
+// RUN: %target-run-simple-swift | %FileCheck %s
// REQUIRES: executable_test
func curry<T, U, V>(_ f: @escaping (T, U) -> V) -> (T) -> (U) -> V {
@@ -120,8 +120,8 @@
let a : Int? = 23
let b : Int? = 42
-print((b <+> pair)(a!)) // CHECK-NEXT: (42, 23)
-print((b <+> pair_)(a!)) // CHECK-NEXT: (42, 23)
+print((b <+> pair)(a!) as Any) // CHECK-NEXT: (42, 23)
+print((b <+> pair_)(a!) as Any) // CHECK-NEXT: (42, 23)
//
// rdar://problem/20475584
@@ -172,12 +172,12 @@
return { x in { y in over(lens)(const(x))(y) } }
}
-func _1<A, B, C, D>(_ f: @escaping (A) -> C) -> (A, B) -> (@escaping (@escaping (A) -> (A, B)) -> (C) -> D) -> D {
- return { (x, y) in { fmap in fmap({ ($0, y) })(f(x)) } }
+func _1<A, B, C, D>(_ f: @escaping (A) -> C) -> ((A, B)) -> (@escaping (@escaping (A) -> (A, B)) -> (C) -> D) -> D {
+ return { pair in { fmap in fmap({ ($0, pair.1) })(f(pair.0)) } }
}
-func _2<A, B, C, D>(_ f: @escaping (B) -> C) -> (A, B) -> (@escaping (@escaping (B) -> (A, B)) -> (C) -> D) -> D {
- return { (x, y) in { fmap in fmap({ (x, $0) })(f(y)) } }
+func _2<A, B, C, D>(_ f: @escaping (B) -> C) -> ((A, B)) -> (@escaping (@escaping (B) -> (A, B)) -> (C) -> D) -> D {
+ return { pair in { fmap in fmap({ (pair.0, $0) })(f(pair.1)) } }
}
@@ -199,6 +199,6 @@
print(pt2) // CHECK-NEXT: (4, 2)
let pt3 = set(_1)(3)((1, 2))
print(pt3) // CHECK-NEXT: (3, 2)
-let pt4 = view(_2)("hello", 5)
+let pt4 = view(_2)(("hello", 5))
print(pt4) // CHECK-NEXT: 5
diff --git a/test/Migrator/Inputs/ignore_type_placeholder.swift b/test/Migrator/Inputs/ignore_type_placeholder.swift
deleted file mode 100644
index 26908f3..0000000
--- a/test/Migrator/Inputs/ignore_type_placeholder.swift
+++ /dev/null
@@ -1,3 +0,0 @@
-func foo(f: (Void) -> ()) {
- f()
-}
diff --git a/test/Migrator/fixit_void.swift b/test/Migrator/fixit_void.swift
deleted file mode 100644
index 31aaec9..0000000
--- a/test/Migrator/fixit_void.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %target-swift-frontend -typecheck %s -swift-version 3
-// RUN: %target-swift-frontend -typecheck -update-code -primary-file %s -emit-migrated-file-path %t.result -swift-version 3
-// RUN: diff -u %s.expected %t.result
-// RUN: %target-swift-frontend -typecheck %s.expected -swift-version 4
-
-func takesNothing(_ f: () -> ()) {
- f()
- f(())
-}
-
-func takesVoidFunction(_ f: (Void) -> ()) {
- f()
- f(())
-}
-
-takesNothing { print("Hello") }
-takesVoidFunction { print("Hello") }
diff --git a/test/Migrator/fixit_void.swift.expected b/test/Migrator/fixit_void.swift.expected
deleted file mode 100644
index 4c978d6..0000000
--- a/test/Migrator/fixit_void.swift.expected
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %target-swift-frontend -typecheck %s -swift-version 3
-// RUN: %target-swift-frontend -typecheck -update-code -primary-file %s -emit-migrated-file-path %t.result -swift-version 3
-// RUN: diff -u %s.expected %t.result
-// RUN: %target-swift-frontend -typecheck %s.expected -swift-version 4
-
-func takesNothing(_ f: () -> ()) {
- f()
- f()
-}
-
-func takesVoidFunction(_ f: () -> ()) {
- f()
- f()
-}
-
-takesNothing { print("Hello") }
-takesVoidFunction { print("Hello") }
diff --git a/test/Migrator/ignore_type_placeholder.swift b/test/Migrator/ignore_type_placeholder.swift
deleted file mode 100644
index e6c06cd..0000000
--- a/test/Migrator/ignore_type_placeholder.swift
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: %empty-directory(%t) && %target-swift-frontend -c -primary-file %S/Inputs/ignore_type_placeholder.swift -emit-migrated-file-path %t/ignore_type_placeholder.swift.result -emit-remap-file-path %t/ignore_type_placeholder.swift.remap -swift-version 3
-// RUN: %FileCheck %s < %t/ignore_type_placeholder.swift.result
-// CHECK-NOT: f(<#Void#>)
diff --git a/test/Migrator/tuple-arguments.swift b/test/Migrator/tuple-arguments.swift
deleted file mode 100644
index 4684b7c..0000000
--- a/test/Migrator/tuple-arguments.swift
+++ /dev/null
@@ -1,65 +0,0 @@
-// RUN: %target-swift-frontend -typecheck %s -swift-version 3
-// RUN: %target-swift-frontend -typecheck -update-code -primary-file %s -emit-migrated-file-path %t.result -disable-migrator-fixits -swift-version 3
-// RUN: diff -u %s.expected %t.result
-// RUN: %target-swift-frontend -typecheck %s.expected -swift-version 4
-
-func test1(_: ()) {}
-test1(())
-test1()
-func test2() {}
-test2()
-
-enum Result<T> {
- case success(T)
-}
-func test3(_: Result<()>) {}
-test3(.success())
-
-func test4(_: (Int, Int) -> ()) {}
-test4({ (x,y) in })
-func test5(_: (Int, Int, Int) -> ()) {}
-test5({ (x,y,z) in })
-
-func test6(_: ((Int, Int)) -> ()) {}
-test6({ (x,y) in })
-func test7(_: ((Int, Int, Int)) -> ()) {}
-test7({ (x,y,z) in })
-test6({ (_ x, _ y) in })
-test6({ (_, _) in })
-test6({ (x:Int, y:Int) in })
-test6({ (_, _) ->() in })
-
-func test8(_: ((Int, Int)) -> Int) {}
-test8 { (_, _) -> Int in 2 }
-test8 { (x, y) in x }
-
-func isEven(_ x: Int) -> Bool { return x % 2 == 0 }
-let items = Array(zip(0..<10, 0..<10))
-_ = items.filter { (_, x) in isEven(x) }
-_ = items.filter { _ in true }
-
-func toString(indexes: Int?...) -> String {
- let _ = indexes.enumerated().map({ (i: Int, index: Int?) -> String? in
- let _: Int = i
- if index != nil {}
- return ""
- })
- let _ = indexes.reduce(0) { print($0); return $0.0 + ($0.1 ?? 0)}
- let _ = indexes.reduce(0) { (true ? $0 : (1, 2)).0 + ($0.1 ?? 0) }
- let _ = [(1, 2)].contains { $0 != $1 }
- _ = ["Hello", "Foo"].sorted { print($0); return $0.0.count > ($0).1.count }
- _ = ["Hello" : 2].map { ($0, ($1)) }
-}
-
-extension Dictionary {
- public mutating func merge(with dictionary: Dictionary) {
- dictionary.forEach { updateValue($1, forKey: $0) }
- }
-}
-
-let dictionary: [String: String] = [:]
-_ = dictionary.first { (column, value) in true }!.value
-
-func doit(_ x: Int) -> Bool { return x > 0 }
-let _: ((String, Int)) -> [String:Bool] = { [$0: doit($1)] }
-func returnClosure() -> ((Int, Int)) -> Bool { return {$1 > $0} }
diff --git a/test/Migrator/tuple-arguments.swift.expected b/test/Migrator/tuple-arguments.swift.expected
deleted file mode 100644
index 800d990..0000000
--- a/test/Migrator/tuple-arguments.swift.expected
+++ /dev/null
@@ -1,65 +0,0 @@
-// RUN: %target-swift-frontend -typecheck %s -swift-version 3
-// RUN: %target-swift-frontend -typecheck -update-code -primary-file %s -emit-migrated-file-path %t.result -disable-migrator-fixits -swift-version 3
-// RUN: diff -u %s.expected %t.result
-// RUN: %target-swift-frontend -typecheck %s.expected -swift-version 4
-
-func test1(_: ()) {}
-test1(())
-test1(())
-func test2() {}
-test2()
-
-enum Result<T> {
- case success(T)
-}
-func test3(_: Result<()>) {}
-test3(.success(()))
-
-func test4(_: (Int, Int) -> ()) {}
-test4({ (x,y) in })
-func test5(_: (Int, Int, Int) -> ()) {}
-test5({ (x,y,z) in })
-
-func test6(_: ((Int, Int)) -> ()) {}
-test6({ (x,y) in })
-func test7(_: ((Int, Int, Int)) -> ()) {}
-test7({ (x,y,z) in })
-test6({ (_ x, _ y) in })
-test6({ (_, _) in })
-test6({ (x:Int, y:Int) in })
-test6({ (_, _) ->() in })
-
-func test8(_: ((Int, Int)) -> Int) {}
-test8 { (_, _) -> Int in 2 }
-test8 { (x, y) in x }
-
-func isEven(_ x: Int) -> Bool { return x % 2 == 0 }
-let items = Array(zip(0..<10, 0..<10))
-_ = items.filter { (_, x) in isEven(x) }
-_ = items.filter { _ in true }
-
-func toString(indexes: Int?...) -> String {
- let _ = indexes.enumerated().map({ (i: Int, index: Int?) -> String? in
- let _: Int = i
- if index != nil {}
- return ""
- })
- let _ = indexes.reduce(0) { print(($0, $1)); return $0 + ($1 ?? 0)}
- let _ = indexes.reduce(0) { (true ? ($0, $1) : (1, 2)).0 + ($1 ?? 0) }
- let _ = [(1, 2)].contains { $0 != $1 }
- _ = ["Hello", "Foo"].sorted { print(($0, $1)); return $0.count > $1.count }
- _ = ["Hello" : 2].map { ($0, ($1)) }
-}
-
-extension Dictionary {
- public mutating func merge(with dictionary: Dictionary) {
- dictionary.forEach { updateValue($1, forKey: $0) }
- }
-}
-
-let dictionary: [String: String] = [:]
-_ = dictionary.first { (column, value) in true }!.value
-
-func doit(_ x: Int) -> Bool { return x > 0 }
-let _: ((String, Int)) -> [String:Bool] = { [$0.0: doit($0.1)] }
-func returnClosure() -> ((Int, Int)) -> Bool { return {$0.1 > $0.0} }
diff --git a/test/Prototypes/Result.swift b/test/Prototypes/Result.swift
index 0eb320b..320e1ee 100644
--- a/test/Prototypes/Result.swift
+++ b/test/Prototypes/Result.swift
@@ -9,7 +9,7 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
-// RUN: %target-run-stdlib-swift-swift3
+// RUN: %target-run-stdlib-swift
// REQUIRES: executable_test
public enum Result<Value> {
@@ -138,8 +138,8 @@
print(catchResult { try mayFail(true) })
print(catchResult { try mayFail(false) })
-print(catchResult { _ in 1 }.flatMap { _ in Result(success: 4) }.flatMap { _ in Result<String>(error: Icky.Poor) })
-print(catchResult { _ in 1 }.map { _ in three }.flatMap {$0} )
+print(catchResult { 1 }.flatMap { _ in Result(success: 4) }.flatMap { _ in Result<String>(error: Icky.Poor) })
+print(catchResult { 1 }.map { _ in three }.flatMap {$0} )
let results = [three, nasty, four]
print(results.flatMap { $0.success })
diff --git a/test/SIL/Parser/keypath.sil b/test/SIL/Parser/keypath.sil
index 4f6981f..3642187 100644
--- a/test/SIL/Parser/keypath.sil
+++ b/test/SIL/Parser/keypath.sil
@@ -144,28 +144,10 @@
}
// CHECK-LABEL: sil @external
-sil @external : $@convention(thin) <A, B: Hashable> (@in_guaranteed B) -> () {
-entry(%z : $*B):
- // CHECK: %1 = keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.ro<Int> : $Int)
- %a = keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.ro<Int> : $Int)
-
- // CHECK: %2 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1, τ_0_2> (root $External<τ_0_2>; external #External.ro<τ_0_2> : $τ_0_2) <A, A, A>
- %b = keypath $KeyPath<External<A>, A>, <C, D, E> (root $External<E>; external #External.ro <E> : $E) <A, A, A>
-
- // CHECK: %3 = keypath $KeyPath<External<Int>, Int>, <τ_0_0> (root $External<τ_0_0>; external #External.ro<τ_0_0> : $τ_0_0) <Int>
- %c = keypath $KeyPath<External<Int>, Int>, <F> (root $External<F>; external #External.ro <F> : $F) <Int>
-
- // CHECK: %4 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (
- // CHECK-SAME: root $External<τ_0_1>;
- // CHECK-SAME: external #External.subscript<τ_0_1, τ_0_0>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1,
- // CHECK-SAME: indices_equals @equals_external_subscript
- // CHECK-SAME: indices_hash @hash_external_subscript
- // CHECK-SAME: ) <B, A> (%0)
- %d = keypath $KeyPath<External<A>, A>, <G: Hashable, H> (
- root $External<H>;
- external #External.subscript <H, G> [%$0 : $G : $*G] : $H,
- indices_equals @equals_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
- indices_hash @hash_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer) -> Int) <B, A> (%z)
+sil @external : $@convention(thin) <D: P, E: Q, F: R> () -> () {
+entry:
+ // CHECK: keypath $KeyPath<Gen<D, E, F>, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) <D, E, F>
+ %a = keypath $KeyPath<Gen<D, E, F>, D>, <G: P, H: Q, I: R> (root $Gen<G, H, I>; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <X3: P, Y3: Q, Z3: R> (@in_guaranteed Gen<X3, Y3, Z3>) -> @out X3, setter @set_gen_a : $@convention(thin) <X4: P, Y4: Q, Z4: R> (@in_guaranteed X4, @in_guaranteed Gen<X4, Y4, Z4>) -> (), external #Gen.x<G, H, I>) <D, E, F>
return undef : $()
}
diff --git a/test/SIL/Serialization/keypath.sil b/test/SIL/Serialization/keypath.sil
index b5d011b..a5e1ed5 100644
--- a/test/SIL/Serialization/keypath.sil
+++ b/test/SIL/Serialization/keypath.sil
@@ -149,28 +149,10 @@
}
// CHECK-LABEL: sil shared [serialized] @external
-sil shared [serialized] @external : $@convention(thin) <A, B: Hashable> (@in_guaranteed B) -> () {
-entry(%z : $*B):
- // CHECK: %1 = keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.ro<Int> : $Int)
- %a = keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.ro<Int> : $Int)
-
- // CHECK: %2 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1, τ_0_2> (root $External<τ_0_2>; external #External.ro<τ_0_2> : $τ_0_2) <A, A, A>
- %b = keypath $KeyPath<External<A>, A>, <C, D, E> (root $External<E>; external #External.ro <E> : $E) <A, A, A>
-
- // CHECK: %3 = keypath $KeyPath<External<Int>, Int>, <τ_0_0> (root $External<τ_0_0>; external #External.ro<τ_0_0> : $τ_0_0) <Int>
- %c = keypath $KeyPath<External<Int>, Int>, <F> (root $External<F>; external #External.ro <F> : $F) <Int>
-
- // CHECK: %4 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (
- // CHECK-SAME: root $External<τ_0_1>;
- // CHECK-SAME: external #External.subscript<τ_0_1, τ_0_0>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1,
- // CHECK-SAME: indices_equals @equals_external_subscript
- // CHECK-SAME: indices_hash @hash_external_subscript
- // CHECK-SAME: ) <B, A> (%0)
- %d = keypath $KeyPath<External<A>, A>, <G: Hashable, H> (
- root $External<H>;
- external #External.subscript <H, G> [%$0 : $G : $*G] : $H,
- indices_equals @equals_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
- indices_hash @hash_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer) -> Int) <B, A> (%z)
+sil shared [serialized] @external : $@convention(thin) <D: P, E: Q, F: R> () -> () {
+entry:
+ // CHECK: keypath $KeyPath<Gen<D, E, F>, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) <D, E, F>
+ %a = keypath $KeyPath<Gen<D, E, F>, D>, <G: P, H: Q, I: R> (root $Gen<G, H, I>; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <X3: P, Y3: Q, Z3: R> (@in_guaranteed Gen<X3, Y3, Z3>) -> @out X3, setter @set_gen_a : $@convention(thin) <X4: P, Y4: Q, Z4: R> (@in_guaranteed X4, @in_guaranteed Gen<X4, Y4, Z4>) -> (), external #Gen.x<G, H, I>) <D, E, F>
return undef : $()
}
@@ -183,7 +165,7 @@
%3 = function_ref @computed_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> ()
%4 = function_ref @optional : $@convention(thin) () -> ()
%5 = function_ref @indexes : $@convention(thin) (S, C) -> ()
- %6 = function_ref @external : $@convention(thin) <A, B: Hashable> (@in_guaranteed B) -> ()
+ %6 = function_ref @external : $@convention(thin) <D: P, E: Q, F: R> () -> ()
unreachable
}
diff --git a/test/SILGen/external-keypath.swift b/test/SILGen/external-keypath.swift
index 0b81600..88c41d6 100644
--- a/test/SILGen/external-keypath.swift
+++ b/test/SILGen/external-keypath.swift
@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t/ExternalKeyPaths.swiftmodule -module-name ExternalKeyPaths %S/Inputs/ExternalKeyPaths.swift
+// RUN: %target-swift-frontend -enable-resilience -emit-module -o %t/ExternalKeyPaths.swiftmodule -module-name ExternalKeyPaths %S/Inputs/ExternalKeyPaths.swift
// RUN: %target-swift-emit-silgen -enable-key-path-resilience -I %t %s | %FileCheck %s
import ExternalKeyPaths
@@ -11,47 +11,47 @@
// CHECK-LABEL: sil hidden @{{.*}}16externalKeyPaths
func externalKeyPaths<T: Hashable, U>(_ x: T, _ y: U, _ z: Int) {
- // CHECK: keypath $WritableKeyPath<External<Int>, Int>, (root $External<Int>; external #External.property<Int> : $Int)
+ // CHECK: keypath $WritableKeyPath<External<Int>, Int>, (root $External<Int>; {{.*}} external #External.property<Int>)
_ = \External<Int>.property
- // CHECK: keypath $WritableKeyPath<External<Int>, Int>, (root $External<Int>; external #External.intProperty<Int> : $Int)
+ // CHECK: keypath $WritableKeyPath<External<Int>, Int>, (root $External<Int>; {{.*}} external #External.intProperty<Int>)
_ = \External<Int>.intProperty
- // CHECK: keypath $WritableKeyPath<External<T>, T>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_0>; external #External.property<T> : $τ_0_0) <T, U>
+ // CHECK: keypath $WritableKeyPath<External<T>, T>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_0>; {{.*}} external #External.property<T>) <T, U>
_ = \External<T>.property
- // CHECK: keypath $WritableKeyPath<External<T>, Int>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_0>; external #External.intProperty<T> : $Int) <T, U>
+ // CHECK: keypath $WritableKeyPath<External<T>, Int>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_0>; {{.*}} external #External.intProperty<T>) <T, U>
_ = \External<T>.intProperty
- // CHECK: keypath $WritableKeyPath<External<U>, U>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.property<U> : $τ_0_1) <T, U>
+ // CHECK: keypath $WritableKeyPath<External<U>, U>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; {{.*}} external #External.property<U>) <T, U>
_ = \External<U>.property
- // CHECK: keypath $WritableKeyPath<External<U>, Int>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.intProperty<U> : $Int) <T, U>
+ // CHECK: keypath $WritableKeyPath<External<U>, Int>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; {{.*}} external #External.intProperty<U>) <T, U>
_ = \External<U>.intProperty
- // CHECK: keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.subscript<Int, Int>[%$0 : $Int : $Int] : $Int, indices_equals @{{.*}}) (%2)
+ // CHECK: keypath $KeyPath<External<Int>, Int>, (root $External<Int>; {{.*}} external #External.subscript<Int, Int>) (%2)
_ = \External<Int>.[z]
- // CHECK: keypath $KeyPath<External<T>, T>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_0>; external #External.subscript<T, T>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_0, indices_equals @{{.*}}) <T, U> ({{.*}})
+ // CHECK: keypath $KeyPath<External<T>, T>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_0>; {{.*}} external #External.subscript<T, T>) <T, U> ({{.*}})
_ = \External<T>.[x]
- // CHECK: keypath $KeyPath<External<U>, U>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.subscript<U, T>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1, indices_equals @{{.*}}) <T, U> ({{.*}})
+ // CHECK: keypath $KeyPath<External<U>, U>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; {{.*}} external #External.subscript<U, T>) <T, U> ({{.*}})
_ = \External<U>.[x]
// CHECK: keypath $KeyPath<External<Local>, Int>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (
// CHECK-SAME: root $External<Local>;
- // CHECK-SAME: external #External.subscript<Local, T>[%$0 : $τ_0_0 : $*τ_0_0] : $Local, indices_equals @{{.*}};
+ // CHECK-SAME: external #External.subscript<Local, T>
// CHECK-SAME: stored_property #Local.x : $Int) <T, U> ({{.*}})
_ = \External<Local>.[x].x
// CHECK: keypath $KeyPath<External<Local>, String>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (
// CHECK-SAME: root $External<Local>;
- // CHECK-SAME: external #External.subscript<Local, T>[%$0 : $τ_0_0 : $*τ_0_0] : $Local, indices_equals @{{.*}};
+ // CHECK-SAME: external #External.subscript<Local, T>
// CHECK-SAME: stored_property #Local.y : $String) <T, U> ({{.*}})
_ = \External<Local>.[x].y
// CHECK: keypath $KeyPath<ExternalEmptySubscript, Int>, (
// CHECK-SAME: root $ExternalEmptySubscript;
- // CHECK-SAME: external #ExternalEmptySubscript.subscript : $Int)
+ // CHECK-SAME: external #ExternalEmptySubscript.subscript
_ = \ExternalEmptySubscript.[]
}
diff --git a/test/stdlib/Inputs/DictionaryKeyValueTypesObjC.swift b/test/stdlib/Inputs/DictionaryKeyValueTypesObjC.swift
index c9d1b7a..9e3797e 100644
--- a/test/stdlib/Inputs/DictionaryKeyValueTypesObjC.swift
+++ b/test/stdlib/Inputs/DictionaryKeyValueTypesObjC.swift
@@ -874,7 +874,8 @@
for i in 0..<3 {
var actualContents = [ExpectedDictionaryElement]()
let sink: (AnyObjectTuple2) -> Void = {
- (key, value) in
+ pair in
+ let (key, value) = pair
actualContents.append(ExpectedDictionaryElement(
key: convertKey(key),
value: convertValue(value),
diff --git a/utils/dev-scripts/csvcolumn_to_scurve.py b/utils/dev-scripts/csvcolumn_to_scurve.py
new file mode 100755
index 0000000..621c7a9
--- /dev/null
+++ b/utils/dev-scripts/csvcolumn_to_scurve.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+# This is a simple script that reads in a csv file, selects a column, and then
+# forms an "s-curve" graph of that column.
+
+import argparse
+import csv
+import sys
+
+
+def get_data(input_file, before_column, after_column):
+
+ def get_selected_csv_rows(input_file, before_column, after_column):
+ for row in csv.DictReader(input_file):
+ before = float(row[before_column])
+ after = float(row[after_column])
+ delta = after / before
+ yield delta
+
+ def f(input_data):
+ result = list(enumerate(sorted(input_data)))
+ count = float(len(result) - 1)
+ return [(x[0] / count, x[1]) for x in result]
+
+ return f(get_selected_csv_rows(input_file, before_column, after_column))
+
+
+def main():
+ p = argparse.ArgumentParser(description="""
+
+ A script that reads in a csv file, splices out selected before/after
+ column, and then outputs a new csv file with that data in s-curve form. An
+ s-curve is a graph where one sorts the output %-change and graphs the %-n
+ vs %-change.
+
+ NOTE: We assume that the csv has a csv header that maps to the before and
+ after column names passed in.
+ """)
+
+ p.add_argument('input_file', type=argparse.FileType('r'))
+ p.add_argument('before_column_name', type=str)
+ p.add_argument('after_column_name', type=str)
+
+ args = p.parse_args()
+
+ data = get_data(args.input_file, args.before_column_name,
+ args.after_column_name)
+ w = csv.DictWriter(sys.stdout, fieldnames=['N/total', 'New/Old'])
+ w.writeheader()
+ for d in data:
+ w.writerow({'N/total': d[0], 'New/Old': d[1]})
+
+
+if __name__ == "__main__":
+ main()
diff --git a/utils/dev-scripts/scurve_printer.py b/utils/dev-scripts/scurve_printer.py
new file mode 100755
index 0000000..2fea673
--- /dev/null
+++ b/utils/dev-scripts/scurve_printer.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+
+# This is a simple script that takes in an scurve file produced by
+# csvcolumn_to_scurve and produces a png graph of the scurve.
+
+import argparse
+import csv
+
+import matplotlib.pyplot as plt
+
+import numpy as np
+
+FIELDS = ['N/total', 'New/Old']
+
+
+def get_data(input_file):
+ global FIELDS
+ for row in csv.DictReader(input_file):
+ yield (float(row[FIELDS[0]]), float(row[FIELDS[1]]))
+
+
+def main():
+ p = argparse.ArgumentParser()
+ p.add_argument('input_csv_file', type=argparse.FileType('r'))
+ p.add_argument('output_file', type=str)
+ p.add_argument('-y-axis-num-tick-marks', type=int,
+ help='The number of y tick marks to use above/below zero.')
+ p.add_argument('-y-axis-min', type=float,
+ help='Override the min y axis that we use')
+ p.add_argument('-y-axis-max', type=float,
+ help='Override the min y axis that we use')
+ p.add_argument('-title', type=str,
+ help='Title of the graph')
+ p.add_argument('-x-axis-title', type=str,
+ help='The title to use on the x-axis of the graph')
+ p.add_argument('-y-axis-title', type=str,
+ help='The title to use on the x-axis of the graph')
+
+ args = p.parse_args()
+
+ data = np.array(list(get_data(args.input_csv_file)))
+ assert np.all(data >= 0)
+
+ x = data[:, 0]
+ y = data[:, 1]
+
+ x_axis_title = args.x_axis_title or FIELDS[0]
+ y_axis_title = args.y_axis_title or FIELDS[1]
+ title = args.title or "{} vs {}".format(x_axis_title, y_axis_title)
+
+ fig, ax = plt.subplots()
+ fig.set_size_inches(18.5, 18.5)
+
+ fig.suptitle(title, fontsize=20)
+ ax.set_xlabel(x_axis_title, fontsize=20)
+ ax.set_ylabel(y_axis_title, fontsize=20)
+ ax.plot(x, y)
+ ax.scatter(x, y)
+
+ # To get good bounds, we:
+ #
+ # 1. Re-center our data at 0 by subtracting 1. This will give us the %
+ # difference in between new and old (i.e. (new - old)/old)
+ #
+ # 2. Then we take the maximum absolute delta from zero and round to a
+ # multiple of 5 away from zero. Lets call this value limit.
+ #
+ # 3. We set [min_y, max_y] = [1.0 - limit, 1.0 + limit]
+ recentered_data = y - 1.0
+ max_magnitude = int(np.max(np.abs(recentered_data)) * 100.0)
+ y_limit = float(((max_magnitude // 5) + 1) * 5) * 0.01
+
+ ax.set_xlim(0.0, 1.0)
+ y_min = args.y_axis_min or 1.0 - y_limit
+ y_max = args.y_axis_max or 1.0 + y_limit
+ assert(y_min <= y_max)
+ ax.set_ylim(y_min, y_max)
+ ax.grid(True)
+ ax.xaxis.set_ticks(np.arange(0.0, 1.0, 0.05))
+ if args.y_axis_num_tick_marks:
+ y_delta = y_max - y_min
+ y_tickmark_frequency = y_delta / float(args.y_axis_num_tick_marks)
+ ax.yaxis.set_ticks(np.arange(y_min, y_max, y_tickmark_frequency))
+ plt.savefig(args.output_file)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift b/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
index 64c07ba..2181e69 100644
--- a/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
+++ b/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
@@ -1,6 +1,6 @@
// This source file is part of the Swift.org open source project
//
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
diff --git a/validation-test/stdlib/Dictionary.swift b/validation-test/stdlib/Dictionary.swift
index fae87a1..f802af7 100644
--- a/validation-test/stdlib/Dictionary.swift
+++ b/validation-test/stdlib/Dictionary.swift
@@ -3,9 +3,9 @@
// RUN: %gyb %s -o %t/main.swift
// RUN: if [ %target-runtime == "objc" ]; then \
// RUN: %target-clang -fobjc-arc %S/Inputs/SlurpFastEnumeration/SlurpFastEnumeration.m -c -o %t/SlurpFastEnumeration.o; \
-// RUN: %line-directive %t/main.swift -- %target-build-swift %S/Inputs/DictionaryKeyValueTypes.swift %S/Inputs/DictionaryKeyValueTypesObjC.swift %t/main.swift -I %S/Inputs/SlurpFastEnumeration/ -Xlinker %t/SlurpFastEnumeration.o -o %t/Dictionary -Xfrontend -disable-access-control -swift-version 3; \
+// RUN: %line-directive %t/main.swift -- %target-build-swift %S/Inputs/DictionaryKeyValueTypes.swift %S/Inputs/DictionaryKeyValueTypesObjC.swift %t/main.swift -I %S/Inputs/SlurpFastEnumeration/ -Xlinker %t/SlurpFastEnumeration.o -o %t/Dictionary -Xfrontend -disable-access-control ; \
// RUN: else \
-// RUN: %line-directive %t/main.swift -- %target-build-swift %S/Inputs/DictionaryKeyValueTypes.swift %t/main.swift -o %t/Dictionary -Xfrontend -disable-access-control -swift-version 3; \
+// RUN: %line-directive %t/main.swift -- %target-build-swift %S/Inputs/DictionaryKeyValueTypes.swift %t/main.swift -o %t/Dictionary -Xfrontend -disable-access-control ; \
// RUN: fi
//
// RUN: %line-directive %t/main.swift -- %target-run %t/Dictionary
@@ -1671,10 +1671,10 @@
struct TE: Error {}
do {
// No duplicate keys, so no error thrown.
- var d1 = try Dictionary([(10, 1), (20, 2), (30, 3)]) { _ in throw TE() }
+ var d1 = try Dictionary([(10, 1), (20, 2), (30, 3)]) { _, _ in throw TE() }
expectEqual(d1.count, 3)
// Duplicate keys, should throw error.
- var d2 = try Dictionary([(10, 1), (10, 2)]) { _ in throw TE() }
+ var d2 = try Dictionary([(10, 1), (10, 2)]) { _, _ in throw TE() }
assertionFailure()
} catch {
assert(error is TE)
@@ -1762,7 +1762,7 @@
// Fill up to the limit, no reallocation.
d1.merge(stride(from: 50, through: 240, by: 10).lazy.map { ($0, 1000 + $0) },
- uniquingKeysWith: { _ in fatalError() })
+ uniquingKeysWith: { _, _ in fatalError() })
expectEqual(24, d1.count)
expectEqual(24, d1.capacity)
d1[250] = 1250
@@ -4297,28 +4297,28 @@
var ObjCThunks = TestSuite("ObjCThunks")
class ObjCThunksHelper : NSObject {
- dynamic func acceptArrayBridgedVerbatim(_ array: [TestObjCValueTy]) {
+ @objc dynamic func acceptArrayBridgedVerbatim(_ array: [TestObjCValueTy]) {
expectEqual(10, array[0].value)
expectEqual(20, array[1].value)
expectEqual(30, array[2].value)
}
- dynamic func acceptArrayBridgedNonverbatim(_ array: [TestBridgedValueTy]) {
+ @objc dynamic func acceptArrayBridgedNonverbatim(_ array: [TestBridgedValueTy]) {
// Cannot check elements because doing so would bridge them.
expectEqual(3, array.count)
}
- dynamic func returnArrayBridgedVerbatim() -> [TestObjCValueTy] {
+ @objc dynamic func returnArrayBridgedVerbatim() -> [TestObjCValueTy] {
return [ TestObjCValueTy(10), TestObjCValueTy(20),
TestObjCValueTy(30) ]
}
- dynamic func returnArrayBridgedNonverbatim() -> [TestBridgedValueTy] {
+ @objc dynamic func returnArrayBridgedNonverbatim() -> [TestBridgedValueTy] {
return [ TestBridgedValueTy(10), TestBridgedValueTy(20),
TestBridgedValueTy(30) ]
}
- dynamic func acceptDictionaryBridgedVerbatim(
+ @objc dynamic func acceptDictionaryBridgedVerbatim(
_ d: [TestObjCKeyTy : TestObjCValueTy]) {
expectEqual(3, d.count)
expectEqual(1010, d[TestObjCKeyTy(10)]!.value)
@@ -4326,13 +4326,13 @@
expectEqual(1030, d[TestObjCKeyTy(30)]!.value)
}
- dynamic func acceptDictionaryBridgedNonverbatim(
+ @objc dynamic func acceptDictionaryBridgedNonverbatim(
_ d: [TestBridgedKeyTy : TestBridgedValueTy]) {
expectEqual(3, d.count)
// Cannot check elements because doing so would bridge them.
}
- dynamic func returnDictionaryBridgedVerbatim() ->
+ @objc dynamic func returnDictionaryBridgedVerbatim() ->
[TestObjCKeyTy : TestObjCValueTy] {
return [
TestObjCKeyTy(10): TestObjCValueTy(1010),
@@ -4341,7 +4341,7 @@
]
}
- dynamic func returnDictionaryBridgedNonverbatim() ->
+ @objc dynamic func returnDictionaryBridgedNonverbatim() ->
[TestBridgedKeyTy : TestBridgedValueTy] {
return [
TestBridgedKeyTy(10): TestBridgedValueTy(1010),