Merge pull request #13945 from airspeedswift/array-protocol
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 6747434..7d96782 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -3079,6 +3079,11 @@
return result;
}
+ /// If this enum has a unique element, return it. A unique element can
+ /// either hold a value or not, and the existence of one unique element does
+ /// not imply the existence or non-existence of the opposite unique element.
+ EnumElementDecl *getUniqueElement(bool hasValue) const;
+
/// Return a range that iterates over all the cases of an enum.
CaseRange getAllCases() const {
return CaseRange(getMembers());
@@ -6522,6 +6527,20 @@
}
}
+inline EnumElementDecl *EnumDecl::getUniqueElement(bool hasValue) const {
+ EnumElementDecl *result = nullptr;
+ bool found = false;
+ for (auto elt : getAllElements()) {
+ if (elt->hasAssociatedValues() == hasValue) {
+ if (found)
+ return nullptr;
+ found = true;
+ result = elt;
+ }
+ }
+ return result;
+}
+
} // end namespace swift
#endif
diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def
index 16d2fd7..bb04564 100644
--- a/include/swift/AST/KnownIdentifiers.def
+++ b/include/swift/AST/KnownIdentifiers.def
@@ -72,7 +72,6 @@
IDENTIFIER(Iterator)
IDENTIFIER(load)
IDENTIFIER(next)
-IDENTIFIER(none)
IDENTIFIER_(nsErrorDomain)
IDENTIFIER(objectAtIndexedSubscript)
IDENTIFIER(objectForKeyedSubscript)
@@ -89,7 +88,6 @@
IDENTIFIER(Self)
IDENTIFIER(setObject)
IDENTIFIER(simd)
-IDENTIFIER(some)
IDENTIFIER(storage)
IDENTIFIER(stringValue)
IDENTIFIER(super)
diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h
index 185cbce..539f97a 100644
--- a/include/swift/SIL/SILDeclRef.h
+++ b/include/swift/SIL/SILDeclRef.h
@@ -114,10 +114,6 @@
/// accessor for the global VarDecl in loc.
GlobalAccessor,
- /// GlobalGetter - this constant references the lazy-initializing
- /// getter for the global VarDecl.
- GlobalGetter,
-
/// References the generator for a default argument of a function.
DefaultArgGenerator,
@@ -245,7 +241,7 @@
}
/// True if the SILDeclRef references a global variable accessor.
bool isGlobal() const {
- return kind == Kind::GlobalAccessor || kind == Kind::GlobalGetter;
+ return kind == Kind::GlobalAccessor;
}
/// True if the SILDeclRef references the generator for a default argument of
/// a function.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 585ce99..3bae3d0 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -651,14 +651,6 @@
llvm_unreachable("Unhandled OptionalTypeKind in switch.");
}
-static EnumElementDecl *findEnumElement(EnumDecl *e, Identifier name) {
- for (auto elt : e->getAllElements()) {
- if (elt->getName() == name)
- return elt;
- }
- return nullptr;
-}
-
EnumElementDecl *ASTContext::getOptionalSomeDecl(OptionalTypeKind kind) const {
switch (kind) {
case OTK_Optional:
@@ -685,27 +677,27 @@
EnumElementDecl *ASTContext::getOptionalSomeDecl() const {
if (!Impl.OptionalSomeDecl)
- Impl.OptionalSomeDecl = findEnumElement(getOptionalDecl(), Id_some);
+ Impl.OptionalSomeDecl = getOptionalDecl()->getUniqueElement(/*hasVal*/true);
return Impl.OptionalSomeDecl;
}
EnumElementDecl *ASTContext::getOptionalNoneDecl() const {
if (!Impl.OptionalNoneDecl)
- Impl.OptionalNoneDecl = findEnumElement(getOptionalDecl(), Id_none);
+ Impl.OptionalNoneDecl =getOptionalDecl()->getUniqueElement(/*hasVal*/false);
return Impl.OptionalNoneDecl;
}
EnumElementDecl *ASTContext::getImplicitlyUnwrappedOptionalSomeDecl() const {
if (!Impl.ImplicitlyUnwrappedOptionalSomeDecl)
Impl.ImplicitlyUnwrappedOptionalSomeDecl =
- findEnumElement(getImplicitlyUnwrappedOptionalDecl(), Id_some);
+ getImplicitlyUnwrappedOptionalDecl()->getUniqueElement(/*hasVal*/true);
return Impl.ImplicitlyUnwrappedOptionalSomeDecl;
}
EnumElementDecl *ASTContext::getImplicitlyUnwrappedOptionalNoneDecl() const {
if (!Impl.ImplicitlyUnwrappedOptionalNoneDecl)
Impl.ImplicitlyUnwrappedOptionalNoneDecl =
- findEnumElement(getImplicitlyUnwrappedOptionalDecl(), Id_none);
+ getImplicitlyUnwrappedOptionalDecl()->getUniqueElement(/*hasVal*/false);
return Impl.ImplicitlyUnwrappedOptionalNoneDecl;
}
diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp
index 8f02131..7151e6f 100644
--- a/lib/IRGen/GenObjC.cpp
+++ b/lib/IRGen/GenObjC.cpp
@@ -540,7 +540,6 @@
case SILDeclRef::Kind::StoredPropertyInitializer:
case SILDeclRef::Kind::EnumElement:
case SILDeclRef::Kind::GlobalAccessor:
- case SILDeclRef::Kind::GlobalGetter:
llvm_unreachable("Method does not have a selector");
case SILDeclRef::Kind::Destroyer:
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index e9b6750..eb02d5a 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -143,7 +143,7 @@
TheParser.setCodeCompletionCallbacks(CodeCompletion.get());
}
bool Parsed = false;
- if (auto accessor = dyn_cast<AccessorDecl>(AFD)) {
+ if (isa<AccessorDecl>(AFD)) {
TheParser.parseAccessorBodyDelayed(AFD);
Parsed = true;
}
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 50d7356..8507aa1 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -1310,9 +1310,6 @@
} else if (!ParseState && Id.str() == "globalaccessor") {
Kind = SILDeclRef::Kind::GlobalAccessor;
ParseState = 1;
- } else if (!ParseState && Id.str() == "globalgetter") {
- Kind = SILDeclRef::Kind::GlobalGetter;
- ParseState = 1;
} else if (!ParseState && Id.str() == "ivardestroyer") {
Kind = SILDeclRef::Kind::IVarDestroyer;
ParseState = 1;
diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp
index 10c12f5..a0da3fa 100644
--- a/lib/SIL/SILDeclRef.cpp
+++ b/lib/SIL/SILDeclRef.cpp
@@ -650,10 +650,6 @@
/*isStatic*/ false,
SKind);
- case SILDeclRef::Kind::GlobalGetter:
- assert(!isCurried);
- return mangler.mangleGlobalGetterEntity(getDecl(), SKind);
-
case SILDeclRef::Kind::DefaultArgGenerator:
assert(!isCurried);
return mangler.mangleDefaultArgumentEntity(
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 76ab8ef..9977c29 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -1267,7 +1267,6 @@
LLVM_FALLTHROUGH;
case SILDeclRef::Kind::Destroyer:
case SILDeclRef::Kind::GlobalAccessor:
- case SILDeclRef::Kind::GlobalGetter:
case SILDeclRef::Kind::DefaultArgGenerator:
case SILDeclRef::Kind::StoredPropertyInitializer:
case SILDeclRef::Kind::IVarInitializer:
@@ -1796,7 +1795,6 @@
case SILDeclRef::Kind::Destroyer:
case SILDeclRef::Kind::Deallocator:
case SILDeclRef::Kind::GlobalAccessor:
- case SILDeclRef::Kind::GlobalGetter:
case SILDeclRef::Kind::IVarDestroyer:
case SILDeclRef::Kind::DefaultArgGenerator:
case SILDeclRef::Kind::StoredPropertyInitializer:
@@ -2031,7 +2029,6 @@
switch (c.kind) {
case SILDeclRef::Kind::GlobalAccessor:
- case SILDeclRef::Kind::GlobalGetter:
case SILDeclRef::Kind::DefaultArgGenerator:
case SILDeclRef::Kind::StoredPropertyInitializer:
return SILFunctionTypeRepresentation::Thin;
@@ -2552,7 +2549,6 @@
case SILDeclRef::Kind::Destroyer:
case SILDeclRef::Kind::Deallocator:
case SILDeclRef::Kind::GlobalAccessor:
- case SILDeclRef::Kind::GlobalGetter:
case SILDeclRef::Kind::DefaultArgGenerator:
case SILDeclRef::Kind::StoredPropertyInitializer:
case SILDeclRef::Kind::IVarInitializer:
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index 6cd5e6c..3fcdc10 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -344,9 +344,6 @@
case SILDeclRef::Kind::GlobalAccessor:
OS << "!globalaccessor";
break;
- case SILDeclRef::Kind::GlobalGetter:
- OS << "!globalgetter";
- break;
case SILDeclRef::Kind::DefaultArgGenerator:
OS << "!defaultarg" << "." << defaultArgIndex;
break;
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index a4ff6b0..4e4cf70 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -1720,12 +1720,6 @@
return CanFunctionType::get(TupleType::getEmpty(C), C.TheRawPointerType);
}
-/// Get the type of a global variable getter function.
-static CanAnyFunctionType getGlobalGetterType(CanType varType) {
- ASTContext &C = varType->getASTContext();
- return CanFunctionType::get(TupleType::getEmpty(C), varType);
-}
-
/// Get the type of a default argument generator, () -> T.
static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
TypeConverter &TC,
@@ -1920,12 +1914,6 @@
"constant ref to computed global var");
return getGlobalAccessorType(var->getInterfaceType()->getCanonicalType());
}
- case SILDeclRef::Kind::GlobalGetter: {
- VarDecl *var = cast<VarDecl>(vd);
- assert(var->hasStorage() &&
- "constant ref to computed global var");
- return getGlobalGetterType(var->getInterfaceType()->getCanonicalType());
- }
case SILDeclRef::Kind::DefaultArgGenerator:
return getDefaultArgGeneratorInterfaceType(*this,
cast<AbstractFunctionDecl>(vd),
@@ -1977,9 +1965,7 @@
return getEffectiveGenericEnvironment(afd, captureInfo);
}
case SILDeclRef::Kind::GlobalAccessor:
- case SILDeclRef::Kind::GlobalGetter: {
return vd->getDeclContext()->getGenericEnvironmentOfContext();
- }
case SILDeclRef::Kind::IVarInitializer:
case SILDeclRef::Kind::IVarDestroyer:
return cast<ClassDecl>(vd)->getGenericEnvironmentOfContext();
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index 602badb..ceb7e22 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -1038,20 +1038,6 @@
});
}
-void SILGenModule::emitGlobalGetter(VarDecl *global,
- SILGlobalVariable *onceToken,
- SILFunction *onceFunc) {
- SILDeclRef accessor(global, SILDeclRef::Kind::GlobalGetter);
- emitOrDelayFunction(*this, accessor,
- [this,accessor,global,onceToken,onceFunc](SILFunction *f){
- preEmitFunction(accessor, global, f, global);
- PrettyStackTraceSILFunction X("silgen emitGlobalGetter", f);
- SILGenFunction(*this, *f)
- .emitGlobalGetter(global, onceToken, onceFunc);
- postEmitFunction(accessor, f);
- });
-}
-
void SILGenModule::emitDefaultArgGenerators(SILDeclRef::Loc decl,
ParameterList *paramList) {
unsigned index = 0;
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index d0a2001..71918f8 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -329,10 +329,6 @@
SILGlobalVariable *onceToken,
SILFunction *onceFunc);
- void emitGlobalGetter(VarDecl *global,
- SILGlobalVariable *onceToken,
- SILFunction *onceFunc);
-
/// True if the given function requires an entry point for ObjC method
/// dispatch.
bool requiresObjCMethodEntryPoint(FuncDecl *method);
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index 79ca9ff..ddcbe04 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -108,7 +108,6 @@
case SILDeclRef::Kind::Destroyer:
return getMagicFunctionName(cast<DestructorDecl>(ref.getDecl()));
case SILDeclRef::Kind::GlobalAccessor:
- case SILDeclRef::Kind::GlobalGetter:
return getMagicFunctionName(cast<VarDecl>(ref.getDecl())->getDeclContext());
case SILDeclRef::Kind::DefaultArgGenerator:
return getMagicFunctionName(cast<AbstractFunctionDecl>(ref.getDecl()));
@@ -432,8 +431,6 @@
CanType NSStringTy = SGM.Types.getNSStringType();
CanType OptNSStringTy
= OptionalType::get(NSStringTy)->getCanonicalType();
- CanType IUOptNSStringTy
- = ImplicitlyUnwrappedOptionalType::get(NSStringTy)->getCanonicalType();
// Look up UIApplicationMain.
// FIXME: Doing an AST lookup here is gross and not entirely sound;
@@ -499,21 +496,9 @@
assert(nameArgTy == fnConv.getSILArgumentType(2));
auto managedName = ManagedValue::forUnmanaged(optName);
SILValue nilValue;
- if (optName->getType() == nameArgTy) {
- nilValue = getOptionalNoneValue(mainClass,
- getTypeLowering(OptNSStringTy));
- } else {
- assert(nameArgTy.getSwiftRValueType() == IUOptNSStringTy);
- nilValue = getOptionalNoneValue(mainClass,
- getTypeLowering(IUOptNSStringTy));
- managedName = emitOptionalToOptional(
- mainClass, managedName,
- SILType::getPrimitiveObjectType(IUOptNSStringTy),
- [](SILGenFunction &, SILLocation, ManagedValue input, SILType,
- SGFContext) {
- return input;
- });
- }
+ assert(optName->getType() == nameArgTy);
+ nilValue = getOptionalNoneValue(mainClass,
+ getTypeLowering(OptNSStringTy));
// Fix up argv to have the right type.
auto argvTy = fnConv.getSILArgumentType(1);
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index 94536ba..679ad1b 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -542,10 +542,6 @@
SILGlobalVariable *onceToken,
SILFunction *onceFunc);
- void emitGlobalGetter(VarDecl *global,
- SILGlobalVariable *onceToken,
- SILFunction *onceFunc);
-
/// Generate a protocol witness entry point, invoking 'witness' at the
/// abstraction level of 'requirement'.
///
diff --git a/lib/SILGen/SILGenGlobalVariable.cpp b/lib/SILGen/SILGenGlobalVariable.cpp
index c373f0d..48f4c26 100644
--- a/lib/SILGen/SILGenGlobalVariable.cpp
+++ b/lib/SILGen/SILGenGlobalVariable.cpp
@@ -296,18 +296,3 @@
assert(ret->getDebugScope() && "instruction without scope");
}
-void SILGenFunction::emitGlobalGetter(VarDecl *global,
- SILGlobalVariable *onceToken,
- SILFunction *onceFunc) {
- emitOnceCall(*this, global, onceToken, onceFunc);
-
- auto *silG = SGM.getSILGlobalVariable(global, NotForDefinition);
- SILValue addr = B.createGlobalAddr(global, silG);
-
- auto refType = global->getInterfaceType()->getCanonicalType();
- ManagedValue value = emitLoad(global, addr, getTypeLowering(refType),
- SGFContext(), IsNotTake);
- SILValue result = value.forward(*this);
- B.createReturn(global, result);
-}
-
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index aaa3f30..38af939 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -2191,7 +2191,9 @@
}
// Before the memory allocation, store zero in the control variable.
- B.setInsertionPoint(&*std::next(TheMemory.MemoryInst->getIterator()));
+ auto *InsertPoint = &*std::next(TheMemory.MemoryInst->getIterator());
+ B.setInsertionPoint(InsertPoint);
+ B.setCurrentDebugScope(InsertPoint->getDebugScope());
SILValue ControlVariableAddr = ControlVariableBox;
auto Zero = B.createIntegerLiteral(Loc, IVType, 0);
B.createStore(Loc, Zero, ControlVariableAddr,
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 0c912c3..b150808 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -3900,8 +3900,11 @@
if (!choices[i].isDecl()) {
return SolutionKind::Error;
}
+ auto storage = dyn_cast<AbstractStorageDecl>(choices[i].getDecl());
+ if (!storage) {
+ return SolutionKind::Error;
+ }
- auto storage = cast<AbstractStorageDecl>(choices[i].getDecl());
if (!storage->isSettable(DC)) {
// A non-settable component makes the key path read-only, unless
// a reference-writable component shows up later.
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index 4f9db18..5571060 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -25,10 +25,10 @@
FragileFunctionKind TypeChecker::getFragileFunctionKind(const DeclContext *DC) {
for (; DC->isLocalContext(); DC = DC->getParent()) {
- if (auto *DAI = dyn_cast<DefaultArgumentInitializer>(DC))
+ if (isa<DefaultArgumentInitializer>(DC))
return FragileFunctionKind::DefaultArgument;
- if (auto *PBI = dyn_cast<PatternBindingInitializer>(DC))
+ if (isa<PatternBindingInitializer>(DC))
return FragileFunctionKind::PropertyInitializer;
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 662071b..799e27d 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -1231,10 +1231,11 @@
if (numExtraOptionals > 0) {
Pattern *sub = IP;
for (int i = 0; i < numExtraOptionals; ++i) {
+ auto some = Context.getOptionalDecl()->getUniqueElement(/*hasVal*/true);
sub = new (Context) EnumElementPattern(TypeLoc(),
IP->getStartLoc(),
IP->getEndLoc(),
- Context.Id_some,
+ some->getName(),
nullptr, sub,
/*Implicit=*/true);
}
diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil
index d7428cd..276046e 100644
--- a/test/SIL/Parser/basic.sil
+++ b/test/SIL/Parser/basic.sil
@@ -1,7 +1,4 @@
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=false %s | %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=false | %FileCheck %s
-//
-// FIXME: Enable sil-verify-all in both commands above:
-// SIL Parsing fails on vtables: <rdar://problem/24060338> Identify problems with textual SIL and fix them.
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=true %s | %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=true | %FileCheck %s
sil_stage raw // CHECK: sil_stage raw
@@ -1160,7 +1157,7 @@
init()
}
-sil @_TFC3tmp3Foog9subscriptFTVs5Int32S1__S1_ : $@convention(method) (Int32, Int32, Foo) -> Int32 {
+sil @Foo_subscript_getter : $@convention(method) (Int32, Int32, @guaranteed Foo) -> Int32 {
bb0(%0 : $Int32, %1 : $Int32, %2 : $Foo):
%3 = tuple ()
%4 = alloc_stack $Int32 // var x // users: %17, %6
@@ -1172,14 +1169,13 @@
%10 = metatype $@thin Int32.Type
%12 = integer_literal $Builtin.Int32, 0 // user: %13
%13 = struct $Int32 (%12 : $Builtin.Int32) // user: %18
- destroy_addr %8 : $*Foo
dealloc_stack %8 : $*Foo
dealloc_stack %5 : $*Int32
dealloc_stack %4 : $*Int32
return %13 : $Int32
}
-sil @_TFC3tmp3Foos9subscriptFTVs5Int32S1__S1_ : $@convention(method) (Int32, Int32, Int32, Foo) -> () {
+sil @Foo_subscript_setter : $@convention(method) (Int32, Int32, Int32, @guaranteed Foo) -> () {
bb0(%0 : $Int32, %1 : $Int32, %2 : $Int32, %3 : $Foo):
%4 = alloc_stack $Int32 // var value // users: %16, %5
store %0 to %4 : $*Int32
@@ -1189,7 +1185,6 @@
store %2 to %7 : $*Int32
%10 = alloc_stack $Foo // var self // users: %13, %12, %11
store %3 to %10 : $*Foo
- destroy_addr %10 : $*Foo
dealloc_stack %10 : $*Foo
dealloc_stack %7 : $*Int32
dealloc_stack %6 : $*Int32
@@ -1638,12 +1633,12 @@
}
// CHECK-LABEL: sil_vtable Foo {
-// CHECK: #Foo.subscript!getter.1: {{.*}} : hidden @_TFC3tmp3Foog9subscriptFTVs5Int32S1__S1_
-// CHECK: #Foo.subscript!setter.1: {{.*}} : @_TFC3tmp3Foos9subscriptFTVs5Int32S1__S1_
+// CHECK: #Foo.subscript!getter.1: {{.*}} : hidden @Foo_subscript_getter
+// CHECK: #Foo.subscript!setter.1: {{.*}} : @Foo_subscript_setter
// CHECK: }
sil_vtable Foo {
- // Override the linke to check if it is parsed correctly.
- #Foo.subscript!getter.1: hidden @_TFC3tmp3Foog9subscriptFTVs5Int32S1__S1_
+ // Override the linkage to check if it is parsed correctly.
+ #Foo.subscript!getter.1: hidden @Foo_subscript_getter
// The public linkage is the same as the function's linkage and should not be printed.
- #Foo.subscript!setter.1: public @_TFC3tmp3Foos9subscriptFTVs5Int32S1__S1_
+ #Foo.subscript!setter.1: public @Foo_subscript_setter
}
diff --git a/test/SILOptimizer/definite-init-wrong-scope2.swift b/test/SILOptimizer/definite-init-wrong-scope2.swift
new file mode 100644
index 0000000..4e05133
--- /dev/null
+++ b/test/SILOptimizer/definite-init-wrong-scope2.swift
@@ -0,0 +1,26 @@
+// RUN: %target-swift-frontend -emit-sil %s -Onone -Xllvm -sil-print-debuginfo \
+// RUN: -o /dev/null -Xllvm -sil-print-after=definite-init \
+// RUN: -Xllvm -sil-print-only-functions=$S8patatino4BearC6before7before26during5afterACSb_S3btKcfc \
+// RUN: 2>&1 | %FileCheck %s
+// REQUIRES: executable_test
+
+import StdlibUnittest
+
+func unwrap(_ b: Bool) throws -> Int {
+ return 0
+}
+class Bear {
+ let x: LifetimeTracked
+ init(n: Int, before: Bool) throws {
+ self.x = LifetimeTracked(0)
+ }
+ init(n: Int, after: Bool) throws {
+ self.x = LifetimeTracked(0)
+ }
+ convenience init(before: Bool, before2: Bool, during: Bool, after: Bool) throws {
+ try self.init(n: unwrap(before2), after: during)
+ }
+}
+
+// CHECK: %7 = integer_literal $Builtin.Int1, 0, loc {{.*}}:20:15, scope 1
+// CHECK-NEXT: store %7 to [trivial] %5 : $*Builtin.Int1, loc {{.*}}:20:15, scope 1
diff --git a/test/expr/unary/keypath/keypath.swift b/test/expr/unary/keypath/keypath.swift
index 2498292..e7e6f63 100644
--- a/test/expr/unary/keypath/keypath.swift
+++ b/test/expr/unary/keypath/keypath.swift
@@ -485,6 +485,20 @@
}
}
+// SR-6744
+func sr6744() {
+ struct ABC {
+ let value: Int
+ func value(adding i: Int) -> Int { return value + i }
+ }
+
+ let abc = ABC(value: 0)
+ func get<T>(for kp: KeyPath<ABC, T>) -> T {
+ return abc[keyPath: kp]
+ }
+ _ = get(for: \.value)
+}
+
func testSyntaxErrors() { // expected-note{{}}
_ = \. ; // expected-error{{expected member name following '.'}}
_ = \.a ;
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index 943ae43..d4fddf9 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -302,7 +302,8 @@
StringRef SuperclassUsr;
SDKNodeInitInfo(SDKContext &Ctx) : Ctx(Ctx) {}
SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD);
- SDKNodeInitInfo(SDKContext &Ctx, Type Ty);
+ SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
+ bool IsImplicitlyUnwrappedOptional =false);
SDKNode* createSDKNode(SDKNodeKind Kind);
};
@@ -1029,16 +1030,21 @@
SDKNodeDumpVisitor() {};
};
-static StringRef getPrintedName(SDKContext &Ctx, Type Ty) {
+static StringRef getPrintedName(SDKContext &Ctx, Type Ty,
+ bool IsImplicitlyUnwrappedOptional) {
std::string S;
llvm::raw_string_ostream OS(S);
PrintOptions PO;
PO.SkipAttributes = true;
+ if (IsImplicitlyUnwrappedOptional)
+ PO.PrintOptionalAsImplicitlyUnwrapped = true;
+
Ty.print(OS, PO);
return Ctx.buffer(OS.str());
}
-static StringRef getTypeName(SDKContext &Ctx, Type Ty) {
+static StringRef getTypeName(SDKContext &Ctx, Type Ty,
+ bool IsImplicitlyUnwrappedOptional) {
if (Ty->getKind() == TypeKind::Paren) {
return Ctx.buffer("Paren");
}
@@ -1049,6 +1055,10 @@
return NAT->getDecl()->getNameStr();
}
if (Ty->getAnyNominal()) {
+ if (IsImplicitlyUnwrappedOptional) {
+ assert(Ty->getAnyOptionalObjectType());
+ return StringRef("ImplicitlyUnwrappedOptional");
+ }
return Ty->getAnyNominal()->getNameStr();
}
#define TYPE(id, parent) \
@@ -1159,8 +1169,10 @@
return Ownership::Strong;
}
-SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty) :
- Ctx(Ctx), Name(getTypeName(Ctx, Ty)), PrintedName(getPrintedName(Ctx, Ty)) {
+SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
+ bool IsImplicitlyUnwrappedOptional) :
+ Ctx(Ctx), Name(getTypeName(Ctx, Ty, IsImplicitlyUnwrappedOptional)),
+ PrintedName(getPrintedName(Ctx, Ty, IsImplicitlyUnwrappedOptional)) {
if (isFunctionTypeNoEscape(Ty))
TypeAttrs.push_back(TypeAttrKind::TAK_noescape);
}
@@ -1196,8 +1208,10 @@
// Recursively construct a node that represents a type, for instance,
// representing the return value type of a function decl.
-static SDKNode *constructTypeNode(SDKContext &Ctx, Type T) {
- SDKNode* Root = SDKNodeInitInfo(Ctx, T).createSDKNode(SDKNodeKind::TypeNominal);
+static SDKNode *constructTypeNode(SDKContext &Ctx, Type T,
+ bool IsImplicitlyUnwrappedOptional =false) {
+ SDKNode* Root = SDKNodeInitInfo(Ctx, T, IsImplicitlyUnwrappedOptional)
+ .createSDKNode(SDKNodeKind::TypeNominal);
if (auto NAT = dyn_cast<NameAliasType>(T.getPointer())) {
SDKNode* Root = SDKNodeInitInfo(Ctx, T).createSDKNode(SDKNodeKind::TypeNameAlias);
@@ -1245,11 +1259,20 @@
static SDKNode *constructFunctionNode(SDKContext &Ctx, FuncDecl* FD,
SDKNodeKind Kind) {
auto Func = SDKNodeInitInfo(Ctx, FD).createSDKNode(Kind);
- Func->addChild(constructTypeNode(Ctx, FD->getResultInterfaceType()));
+ bool resultIsImplicitlyUnwrappedOptional = false;
+ if (FD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
+ resultIsImplicitlyUnwrappedOptional = true;
+ Func->addChild(constructTypeNode(Ctx, FD->getResultInterfaceType(),
+ resultIsImplicitlyUnwrappedOptional));
for (auto *paramList : FD->getParameterLists()) {
for (auto param : *paramList) {
+ bool paramIsImplicitlyUnwrappedOptional = false;
+ if (param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
+ paramIsImplicitlyUnwrappedOptional = true;
+
if (!param->isSelfParameter())
- Func->addChild(constructTypeNode(Ctx, param->getInterfaceType()));
+ Func->addChild(constructTypeNode(Ctx, param->getInterfaceType(),
+ paramIsImplicitlyUnwrappedOptional));
}
}
return Func;
@@ -1321,7 +1344,11 @@
static SDKNode *constructVarNode(SDKContext &Ctx, ValueDecl *VD) {
auto Var = SDKNodeInitInfo(Ctx, VD).createSDKNode(SDKNodeKind::Var);
- Var->addChild(constructTypeNode(Ctx, VD->getInterfaceType()));
+ auto isImplicitlyUnwrappedOptional = false;
+ if (VD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
+ isImplicitlyUnwrappedOptional = true;
+ Var->addChild(constructTypeNode(Ctx, VD->getInterfaceType(),
+ isImplicitlyUnwrappedOptional));
if (auto VAD = dyn_cast<AbstractStorageDecl>(VD)) {
if (auto Getter = VAD->getGetter())
Var->addChild(constructFunctionNode(Ctx, Getter, SDKNodeKind::Getter));
diff --git a/utils/rth b/utils/rth
index 287011a..87aabfe 100755
--- a/utils/rth
+++ b/utils/rth
@@ -70,9 +70,12 @@
for emit_flag in ['-emit-library', '-emit-module']:
output_obj = os.path.join(self.config_dir_map[config],
self.lib_obj_name)
- compiler_flags = [emit_flag, '-Xfrontend',
- '-enable-resilience', '-D', config, '-c',
- self.lib_src, '-o', output_obj]
+ compiler_flags = [emit_flag,
+ '-swift-version', '4',
+ '-Xfrontend', '-enable-resilience',
+ '-D', config,
+ '-c', self.lib_src,
+ '-o', output_obj]
command = self.target_build_swift + \
self.additional_compile_flags_library + compiler_flags
verbose_print_command(command)