Merge pull request #12691 from DougGregor/gsb-restrict-infer-from-protocol-definitions
[GSB] Don't infer requirements from types in the definitions of protocols
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 8fa09bc..fcac408 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1543,7 +1543,7 @@
NOTE(associated_type_deduction_witness_failed,none,
"inferred type %1 (by matching requirement %0) is invalid: "
"does not %select{inherit from|conform to}3 %2",
- (DeclName, Type, DeclName, bool))
+ (DeclName, Type, Type, bool))
NOTE(ambiguous_associated_type_deduction,none,
"ambiguous inference of associated type %0: %1 vs. %2",
(DeclName, Type, Type))
@@ -3668,6 +3668,9 @@
ERROR(versioned_attr_in_protocol,none,
"'@_versioned' attribute cannot be used in protocols", ())
+ERROR(versioned_dynamic_not_supported,none,
+ "'@_versioned' attribute cannot be applied to 'dynamic' declarations", ())
+
#define FRAGILE_FUNC_KIND \
"%select{a '@_transparent' function|" \
"an '@inline(__always)' function|" \
@@ -3708,6 +3711,9 @@
ERROR(inlineable_stored_property,
none, "'@_inlineable' attribute cannot be applied to stored properties", ())
+ERROR(inlineable_dynamic_not_supported,
+ none, "'@_inlineable' attribute cannot be applied to 'dynamic' declarations", ())
+
ERROR(inlineable_decl_not_public,
none, "'@_inlineable' attribute can only be applied to public declarations, "
"but %0 is %select{private|fileprivate|internal|%error|%error}1",
diff --git a/lib/ClangImporter/CMakeLists.txt b/lib/ClangImporter/CMakeLists.txt
index 23be0e3..8fbeb0f 100644
--- a/lib/ClangImporter/CMakeLists.txt
+++ b/lib/ClangImporter/CMakeLists.txt
@@ -16,6 +16,7 @@
ImportName.cpp
ImportType.cpp
SwiftLookupTable.cpp
+ DEPENDS swift-syntax-generated-headers
LINK_LIBRARIES
swiftAST
swiftParse
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index 49635fc..c9d1c14 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -16,7 +16,7 @@
add_swift_library(swiftDriver STATIC
${swiftDriver_sources}
- DEPENDS SwiftOptions
+ DEPENDS swift-syntax-generated-headers SwiftOptions
LINK_LIBRARIES swiftAST swiftBasic swiftFrontend swiftOption)
# Generate the static-stdlib-args.lnk file used by -static-stdlib option
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index 6ffad24..95b2d58 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -219,10 +219,16 @@
addFields(Elements, LayoutStrategy::Universal);
}
- /// Adds an element layout.
- void addElement(const ElementLayout &Elt) {
+ /// Adds a layout of a tail-allocated element.
+ void addTailElement(const ElementLayout &Elt) {
Elements.push_back(Elt);
- addField(Elements.back(), LayoutStrategy::Universal);
+ if (!addField(Elements.back(), LayoutStrategy::Universal)) {
+ // For empty tail allocated elements we still add 1 padding byte.
+ assert(cast<FixedTypeInfo>(Elt.getType()).getFixedStride() == Size(1) &&
+ "empty elements should have stride 1");
+ StructFields.push_back(llvm::ArrayType::get(IGM.Int8Ty, 1));
+ CurSize += Size(1);
+ }
}
/// Return the element layouts.
@@ -443,7 +449,7 @@
// Add the tail elements.
for (SILType TailTy : tailTypes) {
const TypeInfo &tailTI = IGM.getTypeInfo(TailTy);
- builder.addElement(ElementLayout::getIncomplete(tailTI));
+ builder.addTailElement(ElementLayout::getIncomplete(tailTI));
}
// Create a name for the new llvm type.
diff --git a/lib/IRGen/StructLayout.h b/lib/IRGen/StructLayout.h
index c5f662a..70c1531 100644
--- a/lib/IRGen/StructLayout.h
+++ b/lib/IRGen/StructLayout.h
@@ -219,9 +219,9 @@
class StructLayoutBuilder {
protected:
IRGenModule &IGM;
-private:
SmallVector<llvm::Type*, 8> StructFields;
Size CurSize = Size(0);
+private:
Alignment CurAlignment = Alignment(1);
SpareBitVector CurSpareBits;
unsigned NextNonFixedOffsetIndex = 0;
diff --git a/lib/Immediate/CMakeLists.txt b/lib/Immediate/CMakeLists.txt
index f6919cd..d947f49 100644
--- a/lib/Immediate/CMakeLists.txt
+++ b/lib/Immediate/CMakeLists.txt
@@ -1,6 +1,7 @@
add_swift_library(swiftImmediate STATIC
Immediate.cpp
REPL.cpp
+ DEPENDS swift-syntax-generated-headers
LINK_LIBRARIES
swiftIDE
swiftFrontend
diff --git a/lib/ParseSIL/CMakeLists.txt b/lib/ParseSIL/CMakeLists.txt
index 5709107..54ba2ae 100644
--- a/lib/ParseSIL/CMakeLists.txt
+++ b/lib/ParseSIL/CMakeLists.txt
@@ -1,5 +1,6 @@
add_swift_library(swiftParseSIL STATIC
ParseSIL.cpp
+ DEPENDS swift-syntax-generated-headers
LINK_LIBRARIES
swiftParse
swiftSema
diff --git a/lib/PrintAsObjC/CMakeLists.txt b/lib/PrintAsObjC/CMakeLists.txt
index 33aae23..aa0667f 100644
--- a/lib/PrintAsObjC/CMakeLists.txt
+++ b/lib/PrintAsObjC/CMakeLists.txt
@@ -1,6 +1,7 @@
add_swift_library(swiftPrintAsObjC STATIC
PrintAsObjC.cpp
+ DEPENDS swift-syntax-generated-headers
LINK_LIBRARIES
swiftIDE
swiftFrontend
diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp
index 6f39a33..7de21a7 100644
--- a/lib/SILOptimizer/IPO/GlobalOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp
@@ -1031,19 +1031,6 @@
return false;
}
-/// Check if \p V is an empty tuple or empty struct.
-static bool isEmptyInitVal(SILValue V) {
- if (!isa<StructInst>(V) && !isa<TupleInst>(V))
- return false;
-
- // If any of the operands is not empty, the whole struct/tuple is not empty.
- for (Operand &Op : cast<SingleValueInstruction>(V)->getAllOperands()) {
- if (!isEmptyInitVal(Op.get()))
- return false;
- }
- return true;
-}
-
/// Check if a use of an object may prevent outlining the object.
///
/// If \p isCOWObject is true, then the object reference is wrapped into a
@@ -1134,11 +1121,6 @@
if (auto *SI = dyn_cast<StoreInst>(TailAddr)) {
if (!isValidInitVal(SI->getSrc()) || TailStores[TailIdx])
return false;
- // We don't optimize arrays with an empty element type. This would
- // generate a wrong initializer with zero-sized elements. But the stride
- // of zero sized types is (artificially) set to 1 in IRGen.
- if (isEmptyInitVal(SI->getSrc()))
- return false;
TailStores[TailIdx] = SI;
return true;
}
diff --git a/lib/SILOptimizer/Transforms/CSE.cpp b/lib/SILOptimizer/Transforms/CSE.cpp
index 0e140c6..dbd9e50 100644
--- a/lib/SILOptimizer/Transforms/CSE.cpp
+++ b/lib/SILOptimizer/Transforms/CSE.cpp
@@ -405,12 +405,28 @@
return false;
// Consider the types of two open_existential_ref instructions to be equal,
- // if the sets of protocols they conform to are equal.
+ // if the sets of protocols they conform to are equal ...
auto LHSArchetypeTy = LOpen->getType().castTo<ArchetypeType>();
- auto LHSConformsTo = LHSArchetypeTy->getConformsTo();
auto RHSArchetypeTy = ROpen->getType().castTo<ArchetypeType>();
+
+ auto LHSConformsTo = LHSArchetypeTy->getConformsTo();
auto RHSConformsTo = RHSArchetypeTy->getConformsTo();
- return LHSConformsTo == RHSConformsTo;
+ if (LHSConformsTo != RHSConformsTo)
+ return false;
+
+ // ... and other constraints are equal.
+ if (LHSArchetypeTy->requiresClass() != RHSArchetypeTy->requiresClass())
+ return false;
+
+ if (LHSArchetypeTy->getSuperclass().getPointer() !=
+ RHSArchetypeTy->getSuperclass().getPointer())
+ return false;
+
+ if (LHSArchetypeTy->getLayoutConstraint() !=
+ RHSArchetypeTy->getLayoutConstraint())
+ return false;
+
+ return true;
}
return LHSI->getKind() == RHSI->getKind() && LHSI->isIdenticalTo(RHSI);
}
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index a000b4e..ca96300 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -945,7 +945,6 @@
// Handle dynamic references.
if (isDynamic || member->getAttrs().hasAttribute<OptionalAttr>()) {
base = cs.coerceToRValue(base);
- if (!base) return nullptr;
Expr *ref = new (context) DynamicMemberRefExpr(base, dotLoc, memberRef,
memberLoc);
ref->setImplicit(Implicit);
@@ -2912,7 +2911,6 @@
Expr *visitDynamicTypeExpr(DynamicTypeExpr *expr) {
Expr *base = expr->getBase();
base = cs.coerceToRValue(base);
- if (!base) return nullptr;
expr->setBase(base);
return simplifyExprType(expr);
@@ -3016,9 +3014,7 @@
auto &tc = cs.getTypeChecker();
auto toType = simplifyType(expr->getCastTypeLoc().getType());
auto sub = cs.coerceToRValue(expr->getSubExpr());
- if (!sub)
- return nullptr;
-
+
checkForImportedUsedConformances(toType);
expr->setSubExpr(sub);
@@ -3344,10 +3340,8 @@
auto &tc = cs.getTypeChecker();
// Turn the subexpression into an rvalue.
- if (auto rvalueSub = cs.coerceToRValue(expr->getSubExpr()))
- expr->setSubExpr(rvalueSub);
- else
- return nullptr;
+ auto rvalueSub = cs.coerceToRValue(expr->getSubExpr());
+ expr->setSubExpr(rvalueSub);
// If we weren't explicitly told by the caller which disjunction choice,
// get it from the solution to determine whether we've picked a coercion
@@ -3414,8 +3408,6 @@
// The subexpression is always an rvalue.
auto &tc = cs.getTypeChecker();
auto sub = cs.coerceToRValue(expr->getSubExpr());
- if (!sub)
- return nullptr;
expr->setSubExpr(sub);
auto castContextKind =
@@ -3481,8 +3473,6 @@
// The subexpression is always an rvalue.
auto &tc = cs.getTypeChecker();
auto sub = cs.coerceToRValue(expr->getSubExpr());
- if (!sub)
- return nullptr;
expr->setSubExpr(sub);
@@ -6995,10 +6985,7 @@
// The function is always an rvalue.
fn = cs.coerceToRValue(fn);
- assert(fn && "Rvalue conversion failed?");
- if (!fn)
- return nullptr;
-
+
// Resolve applications of decls with special semantics.
if (auto declRef =
dyn_cast<DeclRefExpr>(getSemanticExprForDeclOrMemberRef(fn))) {
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index d64fb82..33f7ea3 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -98,13 +98,18 @@
// Enum cases are handled as part of their containing enum.
if (isa<EnumElementDecl>(D))
return false;
-
+
// Protocol requirements are not versioned because there's no
// global entry point.
if (isa<ProtocolDecl>(D->getDeclContext()) &&
D->isProtocolRequirement())
return false;
+ // Dynamic declarations are not versioned because there's no
+ // global entry point.
+ if (D->isDynamic())
+ return false;
+
// FIXME: Figure out what to do with typealiases
if (isa<TypeAliasDecl>(D))
return false;
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 6b74954..346d9c4 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -1892,6 +1892,15 @@
attr->setInvalid();
return;
}
+
+ // Symbols of dynamically-dispatched declarations are never referenced
+ // directly, so marking them as @_versioned does not make sense.
+ if (VD->isDynamic()) {
+ TC.diagnose(attr->getLocation(),
+ diag::versioned_dynamic_not_supported);
+ attr->setInvalid();
+ return;
+ }
}
void AttributeChecker::visitInlineableAttr(InlineableAttr *attr) {
@@ -1906,11 +1915,21 @@
diag::inlineable_stored_property)
.fixItRemove(attr->getRangeWithAt());
attr->setInvalid();
+ return;
}
}
auto *VD = cast<ValueDecl>(D);
+ // Calls to dynamically-dispatched declarations are never devirtualized,
+ // so marking them as @_inlinable does not make sense.
+ if (VD->isDynamic()) {
+ TC.diagnose(attr->getLocation(),
+ diag::inlineable_dynamic_not_supported);
+ attr->setInvalid();
+ return;
+ }
+
// @_inlineable can only be applied to public or @_versioned
// declarations.
auto access = VD->getFormalAccess(/*useDC=*/nullptr,
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 73d54ed..84131b3 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4252,7 +4252,6 @@
&resolver);
TypeResolutionOptions options;
options |= TR_SubscriptParameters;
- options |= TR_AllowIUO;
isInvalid |= TC.typeCheckParameterList(SD->getIndices(), SD,
options,
@@ -4792,8 +4791,8 @@
GenericTypeResolver &resolver) {
bool hadError = false;
for (auto paramList : fd->getParameterLists()) {
- hadError |=
- TC.typeCheckParameterList(paramList, fd, TR_AllowIUO, resolver);
+ hadError |= TC.typeCheckParameterList(paramList, fd,
+ TypeResolutionOptions(), resolver);
}
return hadError;
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 4fb3087..81211bb 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -457,7 +457,7 @@
// Check the parameter patterns.
for (auto params : func->getParameterLists()) {
// Check the pattern.
- if (tc.typeCheckParameterList(params, func, TR_AllowIUO,
+ if (tc.typeCheckParameterList(params, func, TypeResolutionOptions(),
resolver))
badType = true;
@@ -932,8 +932,7 @@
// Check the element type.
badType |= tc.validateType(subscript->getElementTypeLoc(), subscript,
- TypeResolutionOptions(),
- &resolver);
+ TR_AllowIUO, &resolver);
// Infer requirements from it.
if (genericParams && builder) {
@@ -951,7 +950,6 @@
TypeResolutionOptions options;
options |= TR_SubscriptParameters;
- options |= TR_AllowIUO;
badType |= tc.typeCheckParameterList(params, subscript,
options,
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 3a93cad..229243f 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -691,6 +691,9 @@
auto elementOptions = (options |
(decl->isVariadic() ? TR_VariadicFunctionInput
: TR_FunctionInput));
+ if (!decl->isVariadic())
+ elementOptions |= TR_AllowIUO;
+
bool hadError = false;
// We might have a null typeLoc if this is a closure parameter list,
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index e86a809..9f90a4b 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -1766,19 +1766,18 @@
///
/// This class evaluates true if an error occurred.
class CheckTypeWitnessResult {
- NominalTypeDecl *Nominal = nullptr;
+ Type Requirement;
public:
CheckTypeWitnessResult() { }
+ CheckTypeWitnessResult(Type reqt) : Requirement(reqt) {}
- CheckTypeWitnessResult(NominalTypeDecl *nominal) : Nominal(nominal) {
- assert(isa<ProtocolDecl>(nominal) || isa<ClassDecl>(nominal));
+ Type getRequirement() const { return Requirement; }
+ bool isConformanceRequirement() const {
+ return Requirement->isExistentialType();
}
- NominalTypeDecl *getProtocolOrClass() const { return Nominal; }
- bool isProtocol() const { return isa<ProtocolDecl>(Nominal); }
-
- explicit operator bool() const { return Nominal != nullptr; }
+ explicit operator bool() const { return !Requirement.isNull(); }
};
/// The set of associated types that have been inferred by matching
@@ -1814,8 +1813,8 @@
out.indent(indent + 2);
out << std::get<0>(inferred)->getName() << " := "
<< std::get<1>(inferred).getString();
- if (auto nominal = std::get<2>(inferred).getProtocolOrClass())
- out << " [failed constraint " << nominal->getName() << "]";
+ auto type = std::get<2>(inferred).getRequirement();
+ out << " [failed constraint " << type.getString() << "]";
}
out << ")";
@@ -3558,13 +3557,13 @@
if (auto superclass = genericSig->getSuperclassBound(depTy)) {
if (!superclass->isExactSuperclassOf(type))
- return superclass->getAnyNominal();
+ return superclass;
}
// Check protocol conformances.
for (auto reqProto : genericSig->getConformsTo(depTy)) {
if (!tc.conformsToProtocol(type, reqProto, dc, None))
- return reqProto;
+ return CheckTypeWitnessResult(reqProto->getDeclaredType());
// FIXME: Why is conformsToProtocol() not enough? The stdlib doesn't
// build unless we fail here while inferring an associated type
@@ -3580,10 +3579,16 @@
return t.subst(subMap, SubstFlags::UseErrorType)->hasError();
});
if (result)
- return reqProto;
+ return CheckTypeWitnessResult(reqProto->getDeclaredType());
}
}
+ if (genericSig->requiresClass(depTy)) {
+ if (!type->isObjCExistentialType() &&
+ !type->mayHaveSuperclass())
+ return CheckTypeWitnessResult(tc.Context.getAnyObjectType());
+ }
+
// Success!
return CheckTypeWitnessResult();
}
@@ -3616,7 +3621,7 @@
// Determine which of the candidates is viable.
SmallVector<std::pair<TypeDecl *, Type>, 2> viable;
- SmallVector<std::pair<TypeDecl *, NominalTypeDecl *>, 2> nonViable;
+ SmallVector<std::pair<TypeDecl *, CheckTypeWitnessResult>, 2> nonViable;
for (auto candidate : candidates) {
// Skip nested generic types.
if (auto *genericDecl = dyn_cast<GenericTypeDecl>(candidate.first))
@@ -3626,8 +3631,7 @@
// Check this type against the protocol requirements.
if (auto checkResult = checkTypeWitness(TC, DC, Proto, assocType,
candidate.second)) {
- auto reqProto = checkResult.getProtocolOrClass();
- nonViable.push_back({candidate.first, reqProto});
+ nonViable.push_back({candidate.first, checkResult});
} else {
viable.push_back(candidate);
}
@@ -3671,8 +3675,8 @@
candidate.first,
diag::protocol_witness_nonconform_type,
candidate.first->getDeclaredInterfaceType(),
- candidate.second->getDeclaredInterfaceType(),
- candidate.second->getDeclaredInterfaceType()->is<ProtocolType>());
+ candidate.second.getRequirement(),
+ candidate.second.isConformanceRequirement());
}
});
@@ -5077,9 +5081,8 @@
failedDefaultedWitness,
failedDefaultedAssocType->getFullName(),
proto->getDeclaredType(),
- failedDefaultedResult.getProtocolOrClass()
- ->getDeclaredType(),
- failedDefaultedResult.isProtocol());
+ failedDefaultedResult.getRequirement(),
+ failedDefaultedResult.isConformanceRequirement());
});
return;
}
@@ -5117,8 +5120,8 @@
diag::associated_type_deduction_witness_failed,
failed.Requirement->getFullName(),
failed.TypeWitness,
- failed.Result.getProtocolOrClass()->getFullName(),
- failed.Result.isProtocol());
+ failed.Result.getRequirement(),
+ failed.Result.isConformanceRequirement());
}
});
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 72005aa..22b48ca 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -501,6 +501,7 @@
options -= TR_FunctionInput;
options -= TR_TypeAliasUnderlyingType;
options -= TR_AllowUnavailableProtocol;
+ options -= TR_AllowIUO;
assert(genericArgs.size() == decl->getGenericParams()->size() &&
"invalid arguments, use applyGenericArguments for diagnostic emitting");
@@ -2774,17 +2775,18 @@
Type TypeResolver::resolveImplicitlyUnwrappedOptionalType(
ImplicitlyUnwrappedOptionalTypeRepr *repr,
TypeResolutionOptions options) {
- auto elementOptions = withoutContext(options, true);
- elementOptions |= TR_ImmediateOptionalTypeArgument;
// Swift version >= 5? Use the newer check for IUOs appearing in
// illegal positions.
- if (TC.Context.isSwiftVersionAtLeast(5) &&
- !elementOptions.contains(TR_AllowIUO)) {
+ if (TC.Context.isSwiftVersionAtLeast(5) && !options.contains(TR_AllowIUO)) {
TC.diagnose(repr->getStartLoc(), diag::iuo_in_illegal_position)
.fixItReplace(repr->getExclamationLoc(), "?");
+ return ErrorType::get(Context);
}
+ auto elementOptions = withoutContext(options, true);
+ elementOptions |= TR_ImmediateOptionalTypeArgument;
+
// The T in T! is a generic type argument and therefore always an AST type.
// FIXME: diagnose non-materializability of element type!
Type baseTy = resolveType(repr->getBase(), elementOptions);
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 7942dc3..bf862ae 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -557,6 +557,7 @@
options -= TR_VariadicFunctionInput;
options -= TR_EnumCase;
options -= TR_ImmediateOptionalTypeArgument;
+ options -= TR_AllowIUO;
if (!preserveSIL) options -= TR_SILType;
return options;
}
diff --git a/stdlib/public/core/Runtime.swift.gyb b/stdlib/public/core/Runtime.swift.gyb
index 1e680a7..587b17d 100644
--- a/stdlib/public/core/Runtime.swift.gyb
+++ b/stdlib/public/core/Runtime.swift.gyb
@@ -613,21 +613,19 @@
@_versioned // FIXME(sil-serialize-all)
@objc
internal init() {}
+
@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
deinit {}
+
// Use 'dynamic' to force Objective-C dispatch, which uses the
// return-autoreleased call sequence.
- @_inlineable // FIXME(sil-serialize-all)
- @_versioned // FIXME(sil-serialize-all)
@objc
internal dynamic func returnsAutoreleased(_ x: AnyObject) -> AnyObject {
return x
}
// Use 'dynamic' to prevent this call to be duplicated into other modules.
- @_inlineable // FIXME(sil-serialize-all)
- @_versioned // FIXME(sil-serialize-all)
@objc
internal dynamic func initializeReturnAutoreleased() {
// On x86_64 it is sufficient to perform one cycle of return-autoreleased
diff --git a/stdlib/public/core/SwiftNativeNSArray.swift b/stdlib/public/core/SwiftNativeNSArray.swift
index 27794d4..4e5cf43 100644
--- a/stdlib/public/core/SwiftNativeNSArray.swift
+++ b/stdlib/public/core/SwiftNativeNSArray.swift
@@ -67,14 +67,10 @@
// Implement the APIs required by NSArray
extension _SwiftNativeNSArrayWithContiguousStorage : _NSArrayCore {
- @_inlineable
- @_versioned
@objc internal var count: Int {
return withUnsafeBufferOfObjects { $0.count }
}
- @_inlineable
- @_versioned
@objc(objectAtIndex:)
internal func objectAt(_ index: Int) -> AnyObject {
return withUnsafeBufferOfObjects {
@@ -86,8 +82,6 @@
}
}
- @_inlineable
- @_versioned
@objc internal func getObjects(
_ aBuffer: UnsafeMutablePointer<AnyObject>, range: _SwiftNSRange
) {
@@ -113,8 +107,6 @@
}
}
- @_inlineable
- @_versioned
@objc(countByEnumeratingWithState:objects:count:)
internal func countByEnumerating(
with state: UnsafeMutablePointer<_SwiftNSFastEnumerationState>,
@@ -137,8 +129,6 @@
}
}
- @_inlineable
- @_versioned
@objc(copyWithZone:)
internal func copy(with _: _SwiftNSZone?) -> AnyObject {
return self
@@ -258,8 +248,6 @@
///
/// This override allows the count to be read without triggering
/// bridging of array elements.
- @_inlineable
- @_versioned
@objc
internal override var count: Int {
if let bridgedStorage = _heapBufferBridged {
diff --git a/test/IRGen/static_initializer.sil b/test/IRGen/static_initializer.sil
index 32a1c56..f9cb836 100644
--- a/test/IRGen/static_initializer.sil
+++ b/test/IRGen/static_initializer.sil
@@ -26,6 +26,7 @@
// CHECK: %T18static_initializer16TestArrayStorageC_tailelems0 = type <{ %swift.refcounted, %Ts5Int32V, [4 x i8], %Ts5Int64V, %Ts5Int64V }>
// CHECK: %T18static_initializer16TestArrayStorageC_tailelems1c = type { [2 x i64], %T18static_initializer16TestArrayStorageC_tailelems1 }
// CHECK: %T18static_initializer16TestArrayStorageC_tailelems1 = type <{ %swift.refcounted, %Ts5Int32V, [12 x i8], %Ts7Float80V }>
+// CHECK: %T18static_initializer16TestArrayStorageC_tailelems3 = type <{ %swift.refcounted, %Ts5Int32V, [1 x i8], [1 x i8] }>
sil_global @_T02ch1xSiv : $Int32 = {
%1 = integer_literal $Builtin.Int32, 2
@@ -92,6 +93,16 @@
}
// CHECK: @static_class_with_empty_field = {{(protected )?}}global %T18static_initializer19ClassWithEmptyFieldC_tailelems2c { [1 x i64] zeroinitializer, %T18static_initializer19ClassWithEmptyFieldC_tailelems2 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }> }> }, align 8
+struct Empty { }
+
+sil_global @static_array_with_empty_element : $TestArrayStorage = {
+ %0 = struct $Empty () // users: %7, %7
+ %1 = integer_literal $Builtin.Int32, 2
+ %2 = struct $Int32 (%1 : $Builtin.Int32)
+ %initval = object $TestArrayStorage (%2 : $Int32, [tail_elems] %0 : $Empty, %0 : $Empty)
+}
+// CHECK: @static_array_with_empty_element = {{(protected )?}}global %T18static_initializer16TestArrayStorageC_tailelems3c { [1 x i64] zeroinitializer, %T18static_initializer16TestArrayStorageC_tailelems3 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }>, [1 x i8] undef, [1 x i8] undef }> }, align 8
+
// CHECK-LABEL: define{{( protected)?}} swiftcc i8* @_TF2cha1xSi() {{.*}} {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret i8* bitcast (%Ts5Int32V* @_T02ch1xSiv to i8*)
diff --git a/test/SILOptimizer/cse.sil b/test/SILOptimizer/cse.sil
index 0cac78b..378d4e6 100644
--- a/test/SILOptimizer/cse.sil
+++ b/test/SILOptimizer/cse.sil
@@ -1250,3 +1250,20 @@
return %20 : $()
}
+// Check that we don't CSE open_existential_ref if they are not compeltely equal.
+// CHECK-LABEL: sil @dont_cse_open_existential_ref
+// CHECK: open_existential_ref
+// CHECK: open_existential_ref
+// CHECK: return
+sil @dont_cse_open_existential_ref : $@convention(thin) (@guaranteed Proto & Ping) -> @owned Ping {
+bb0(%0 : $Proto & Ping):
+ %4 = open_existential_ref %0 : $Proto & Ping to $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto
+ %5 = witness_method $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto, #Proto.doThis!1, %4 : $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto : $@convention(witness_method) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
+ %6 = apply %5<@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto>(%4) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
+ %9 = open_existential_ref %0 : $Proto & Ping to $@opened("3C038746-BE69-11E7-A5C1-685B35C48C83") Proto & Ping
+ %10 = upcast %9 : $@opened("3C038746-BE69-11E7-A5C1-685B35C48C83") Proto & Ping to $Ping
+ %11 = class_method %10 : $Ping, #Ping.ping!1 : (Ping) -> () -> Ping, $@convention(method) (@guaranteed Ping) -> @owned Ping
+ %12 = apply %11(%10) : $@convention(method) (@guaranteed Ping) -> @owned Ping
+ return %12 : $Ping
+}
+
diff --git a/test/SILOptimizer/static_arrays.swift b/test/SILOptimizer/static_arrays.swift
index 89571a2..1fedaa8 100644
--- a/test/SILOptimizer/static_arrays.swift
+++ b/test/SILOptimizer/static_arrays.swift
@@ -136,7 +136,7 @@
// CHECK-LABEL: sil {{.*}}arrayWithEmptyElements{{.*}} : $@convention(thin) () -> @owned Array<Empty> {
func arrayWithEmptyElements() -> [Empty] {
- // CHECK: alloc_ref
+ // CHECK: global_value @{{.*}}arrayWithEmptyElements{{.*}}
// CHECK: return
return [Empty()]
}
diff --git a/test/Sema/diag_erroneous_iuo.swift b/test/Sema/diag_erroneous_iuo.swift
index b2df2c2..33c7fbc 100644
--- a/test/Sema/diag_erroneous_iuo.swift
+++ b/test/Sema/diag_erroneous_iuo.swift
@@ -1,22 +1,72 @@
// RUN: %target-typecheck-verify-swift -swift-version 5
+// These are all legal uses of '!'.
+struct Fine {
+ var value: Int!
+
+ func m(_ unnamed: Int!, named: Int!) -> Int! { return unnamed }
+ static func s(_ unnamed: Int!, named: Int!) -> Int! { return named }
+
+ init(_ value: Int) { self.value = value }
+ init!() { return nil }
+
+ subscript (
+ index: Int!
+ ) -> Int! {
+ return index
+ }
+
+ subscript<T> (
+ index: T!
+ ) -> T! {
+ return index
+ }
+}
+
let _: ImplicitlyUnwrappedOptional<Int> = 1 // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{8-36=}}{{39-39=!}}{{39-40=}}
let _: ImplicitlyUnwrappedOptional = 1 // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' in unsupported; use an explicit type followed by '!'}}
extension ImplicitlyUnwrappedOptional {} // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
-func function(
+func functionSpelling(
_: ImplicitlyUnwrappedOptional<Int> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{6-34=}}{{37-37=!}}{{37-38=}}
) -> ImplicitlyUnwrappedOptional<Int> { // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{6-34=}}{{37-37=!}}{{37-38=}}
return 1
}
+// Okay, like in the method case.
+func functionSigil(
+ _: Int!
+) -> Int! {
+ return 1
+}
+
+// Not okay because '!' is not at the top level of the type.
+func functionSigilArray(
+ _: [Int!] // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+) -> [Int!] { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+ return [1]
+}
+
func genericFunction<T>(
iuo: ImplicitlyUnwrappedOptional<T> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{8-36=}}{{37-37=!}}{{37-38=}}
) -> ImplicitlyUnwrappedOptional<T> { // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{6-34=}}{{35-35=!}}{{35-36=}}
return iuo
}
+// Okay, like in the non-generic case.
+func genericFunctionSigil<T>(
+ iuo: T!
+) -> T! {
+ return iuo
+}
+
+func genericFunctionSigilArray<T>(
+ iuo: [T!] // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+) -> [T!] { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+ return iuo
+}
+
protocol P {
associatedtype T
associatedtype U
@@ -26,11 +76,23 @@
typealias T = ImplicitlyUnwrappedOptional<Int> // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
typealias U = Optional<ImplicitlyUnwrappedOptional<Int>> // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+ typealias V = Int! // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+ typealias W = Int!? // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+
+ var x: V
+ var y: W
+
subscript (
index: ImplicitlyUnwrappedOptional<Int> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{43-43=!}}{{43-44=}}
) -> ImplicitlyUnwrappedOptional<Int> { // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{43-43=!}}{{43-44=}}
return index
}
+
+ subscript<T> (
+ index: ImplicitlyUnwrappedOptional<T> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{41-41=!}}{{41-42=}}
+ ) -> ImplicitlyUnwrappedOptional<T> { // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{41-41=!}}{{41-42=}}
+ return index
+ }
}
func generic<T : P>(_: T) where T.T == ImplicitlyUnwrappedOptional<Int> { } // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
@@ -45,16 +107,33 @@
}
_ = Array<Int!>() // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+let _: Array<Int!> = [1] // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
_ = [Int!]() // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+let _: [Int!] = [1] // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
_ = Optional<Int!>(nil) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+let _: Optional<Int!> = nil // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
_ = Int!?(0) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+let _: Int!? = 0 // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
_ = (
Int!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
- Float!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
- String! // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+ Float!,
+ String!
)(1, 2.0, "3")
+let _: (
+ Int!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+ Float!,
+ String!
+) = (1, 2.0, "3")
-struct Generic<T, U, C> {}
+struct Generic<T, U, C> {
+ init(_ t: T, _ u: U, _ c: C) {}
+}
_ = Generic<Int!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
- Float!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
- String!>() // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+ Float!,
+ String!>(1, 2.0, "3")
+let _: Generic<Int!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+ Float!,
+ String!> = Generic(1, 2.0, "3")
+
+func vararg(_ first: Int, more: Int!...) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+}
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index 3f34263..0e10d29 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -2282,3 +2282,12 @@
}
}
}
+
+// 'dynamic' methods cannot be @_inlineable or @_versioned
+class BadClass {
+ @_inlineable @objc dynamic func badMethod1() {}
+ // expected-error@-1 {{'@_inlineable' attribute cannot be applied to 'dynamic' declarations}}
+
+ @_versioned @objc dynamic func badMethod2() {}
+ // expected-error@-1 {{'@_versioned' attribute cannot be applied to 'dynamic' declarations}}
+}
diff --git a/test/decl/protocol/conforms/associated_type.swift b/test/decl/protocol/conforms/associated_type.swift
index 92a5a79..6e8d744 100644
--- a/test/decl/protocol/conforms/associated_type.swift
+++ b/test/decl/protocol/conforms/associated_type.swift
@@ -5,10 +5,12 @@
protocol P {
associatedtype AssocP : C // expected-note{{protocol requires nested type 'AssocP'; do you want to add it?}}
+ associatedtype AssocA : AnyObject // expected-note{{protocol requires nested type 'AssocA'; do you want to add it?}}
}
struct X : P { // expected-error{{type 'X' does not conform to protocol 'P'}}
typealias AssocP = Int // expected-note{{possibly intended match 'X.AssocP' (aka 'Int') does not inherit from 'C'}}
+ typealias AssocA = Int // expected-note{{possibly intended match 'X.AssocA' (aka 'Int') does not conform to 'AnyObject'}}
}
// SR-5166
diff --git a/test/decl/protocol/req/associated_type_default.swift b/test/decl/protocol/req/associated_type_default.swift
index 60f691f..0d8e685 100644
--- a/test/decl/protocol/req/associated_type_default.swift
+++ b/test/decl/protocol/req/associated_type_default.swift
@@ -28,3 +28,9 @@
extension X : P3 { } // okay
struct X2 : P3 { } // expected-error{{type 'X2' does not conform to protocol 'P3'}}
+
+protocol P4 {
+ associatedtype AssocType4 : AnyObject = Int // expected-note{{default type 'Int' for associated type 'AssocType4' (from protocol 'P4') does not conform to 'AnyObject'}}
+}
+
+struct X4 : P4 {} // expected-error{{type 'X4' does not conform to protocol 'P4'}}
diff --git a/test/lit.cfg b/test/lit.cfg
index 492a54d..b1a8f93 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -940,12 +940,6 @@
if run_ptrsize != "32":
runtime_libs['tsan'] = 'tsan_runtime'
-# TODO: remove these lines once sanitizers start working on Linux again:
-# Tracked in https://bugs.swift.org/browse/SR-6257.
-if config.target_sdk_name == "linux":
- runtime_libs.pop('asan')
- runtime_libs.pop('tsan')
-
check_runtime_libs(runtime_libs)
if not getattr(config, 'target_run_simple_swift', None):