Merge pull request #12766 from xedin/fix-tuple-type-metadata-reader
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index cd38cde..9e8b509 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -1744,6 +1744,9 @@
}
}
+/// Canonical ordering for dependent types.
+int compareDependentTypes(Type type1, Type type2);
+
} // end namespace swift
#endif
diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h
index b6b7171..96f2d3e 100644
--- a/include/swift/AST/Pattern.h
+++ b/include/swift/AST/Pattern.h
@@ -170,8 +170,9 @@
/// Return true if this pattern (or a subpattern) is refutable.
bool isRefutablePattern() const;
-
-
+
+ bool isNeverDefaultInitializable() const;
+
/// \brief Mark all vardecls in this pattern as having non-pattern initial
/// values bound into them.
void markHasNonPatternBindingInit() {
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 8a13c45..10ca863 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -1716,12 +1716,10 @@
ArrayRef<Type> getGenericArgs() const { return GenericArgs; }
void Profile(llvm::FoldingSetNodeID &ID) {
- RecursiveTypeProperties properties;
- Profile(ID, TheDecl, Parent, GenericArgs, properties);
+ Profile(ID, TheDecl, Parent, GenericArgs);
}
static void Profile(llvm::FoldingSetNodeID &ID, NominalTypeDecl *TheDecl,
- Type Parent, ArrayRef<Type> GenericArgs,
- RecursiveTypeProperties &properties);
+ Type Parent, ArrayRef<Type> GenericArgs);
// Implement isa/cast/dyncast/etc.
static bool classof(const TypeBase *T) {
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index f2a56bf..1ed4bcb 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -47,6 +47,8 @@
class SingleValueInstruction;
class MultipleValueInstruction;
class MultipleValueInstructionResult;
+class DestructureTupleInst;
+class DestructureStructInst;
class NonValueInstruction;
class SILBasicBlock;
class SILBuilder;
@@ -7274,6 +7276,11 @@
static bool classof(const SILNode *N) {
return N->getKind() == SILNodeKind::DestructureStructResult;
}
+
+ DestructureStructInst *getParent();
+ const DestructureStructInst *getParent() const {
+ return const_cast<DestructureStructResult *>(this)->getParent();
+ }
};
/// Instruction that takes in a struct value and splits the struct into the
@@ -7300,6 +7307,12 @@
}
};
+// Out of line to work around forward declaration issues.
+inline DestructureStructInst *DestructureStructResult::getParent() {
+ auto *Parent = MultipleValueInstructionResult::getParent();
+ return cast<DestructureStructInst>(Parent);
+}
+
/// A result for the destructure_tuple instruction. See documentation for
/// destructure_tuple for more information.
class DestructureTupleResult final : public MultipleValueInstructionResult {
@@ -7312,6 +7325,11 @@
static bool classof(const SILNode *N) {
return N->getKind() == SILNodeKind::DestructureTupleResult;
}
+
+ DestructureTupleInst *getParent();
+ const DestructureTupleInst *getParent() const {
+ return const_cast<DestructureTupleResult *>(this)->getParent();
+ }
};
/// Instruction that takes in a tuple value and splits the tuple into the
@@ -7338,6 +7356,12 @@
}
};
+// Out of line to work around forward declaration issues.
+inline DestructureTupleInst *DestructureTupleResult::getParent() {
+ auto *Parent = MultipleValueInstructionResult::getParent();
+ return cast<DestructureTupleInst>(Parent);
+}
+
} // end swift namespace
//===----------------------------------------------------------------------===//
diff --git a/include/swift/Syntax/SyntaxParsingContext.h b/include/swift/Syntax/SyntaxParsingContext.h
index 3f8580d..002f9b0 100644
--- a/include/swift/Syntax/SyntaxParsingContext.h
+++ b/include/swift/Syntax/SyntaxParsingContext.h
@@ -13,7 +13,8 @@
#ifndef SWIFT_SYNTAX_PARSING_CONTEXT_H
#define SWIFT_SYNTAX_PARSING_CONTEXT_H
- #include "swift/Syntax/Syntax.h"
+#include "swift/Basic/SourceLoc.h"
+#include "swift/Syntax/Syntax.h"
namespace swift {
class SourceLoc;
@@ -25,19 +26,28 @@
struct RawSyntax;
enum class SyntaxKind;
+enum class SyntaxContextKind: uint8_t{
+ Expr,
+ Decl,
+ Stmt,
+};
+
/// The handler for parser to generate libSyntax entities.
struct RawSyntaxInfo {
- /// Start location of this syntax node.
- SourceLoc StartLoc;
-
- /// The number of tokens belong to the syntax node.
- unsigned TokCount;
+ /// Start and end location of this syntax node.
+ SourceRange SyntaxRange;
/// The raw node.
RC<RawSyntax> RawNode;
+ RawSyntaxInfo(RC<RawSyntax> RawNode): RawNode(RawNode) {}
RawSyntaxInfo(SourceLoc StartLoc, RC<RawSyntax> RawNode):
- RawSyntaxInfo(StartLoc, 1, RawNode) {}
- RawSyntaxInfo(SourceLoc StartLoc, unsigned TokCount, RC<RawSyntax> RawNode);
+ SyntaxRange(StartLoc), RawNode(RawNode) {}
+ RawSyntaxInfo(SourceRange SyntaxRange, RC<RawSyntax> RawNode):
+ SyntaxRange(SyntaxRange), RawNode(RawNode) {}
+
+ bool isImplicit() const { return SyntaxRange.isInvalid(); }
+ SourceLoc getStartLoc() const { return SyntaxRange.Start; }
+ SourceLoc getEndLoc() const { return SyntaxRange.End; }
template <typename SyntaxNode>
SyntaxNode makeSyntax() const { return make<SyntaxNode>(RawNode); }
@@ -46,6 +56,7 @@
RC<RawSyntaxNode> getRaw() const {
return RC<RawSyntaxNode>(cast<RawSyntaxNode>(RawNode));
}
+ void brigeWithContext(SyntaxContextKind Kind);
};
enum class SyntaxParsingContextKind: uint8_t {
@@ -96,11 +107,6 @@
};
};
-enum class SyntaxContextKind: uint8_t{
- Expr,
- Decl,
-};
-
// The base class for contexts that are created from a parent context.
// The stack instance will set the context holder when the context
// is firstly created and reset the context holder to the parent when
@@ -108,10 +114,21 @@
class SyntaxParsingContextChild: public SyntaxParsingContext {
SyntaxParsingContext *Parent;
SyntaxParsingContext *&ContextHolder;
- const SyntaxContextKind Kind;
+ Optional<SyntaxContextKind> Kind;
+ Optional<SyntaxKind> KnownSyntax;
+ void makeNodeWhole(SyntaxKind Kind);
+ SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
+ Optional<SyntaxContextKind> Kind,
+ Optional<SyntaxKind> KnownSyntax);
public:
SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
- SyntaxContextKind Kind);
+ SyntaxContextKind Kind): SyntaxParsingContextChild(ContextHolder,
+ Kind, None) {}
+
+ SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
+ SyntaxKind KnownSyntax): SyntaxParsingContextChild(ContextHolder,
+ None, KnownSyntax) {};
+
~SyntaxParsingContextChild();
void makeNode(SyntaxKind Kind) override;
void addTokenSyntax(SourceLoc Loc) override;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 256fbb2..314321f 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3190,15 +3190,12 @@
void BoundGenericType::Profile(llvm::FoldingSetNodeID &ID,
NominalTypeDecl *TheDecl, Type Parent,
- ArrayRef<Type> GenericArgs,
- RecursiveTypeProperties &properties) {
+ ArrayRef<Type> GenericArgs) {
ID.AddPointer(TheDecl);
ID.AddPointer(Parent.getPointer());
- if (Parent) properties |= Parent->getRecursiveProperties();
ID.AddInteger(GenericArgs.size());
for (Type Arg : GenericArgs) {
ID.AddPointer(Arg.getPointer());
- properties |= Arg->getRecursiveProperties();
}
}
@@ -3224,8 +3221,12 @@
ASTContext &C = TheDecl->getDeclContext()->getASTContext();
llvm::FoldingSetNodeID ID;
+ BoundGenericType::Profile(ID, TheDecl, Parent, GenericArgs);
RecursiveTypeProperties properties;
- BoundGenericType::Profile(ID, TheDecl, Parent, GenericArgs, properties);
+ if (Parent) properties |= Parent->getRecursiveProperties();
+ for (Type Arg : GenericArgs) {
+ properties |= Arg->getRecursiveProperties();
+ }
auto arena = getArena(properties);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 8bcf7c1..d276857 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1187,10 +1187,10 @@
// @NSManaged properties never get default initialized, nor do debugger
// variables and immutable properties.
-bool isNeverDefaultInitializable(const Pattern *p) {
+bool Pattern::isNeverDefaultInitializable() const {
bool result = false;
- p->forEachVariable([&](const VarDecl *var) {
+ forEachVariable([&](const VarDecl *var) {
if (var->getAttrs().hasAttribute<NSManagedAttr>())
return;
@@ -1209,7 +1209,7 @@
if (entry.getInit())
return true;
- if (isNeverDefaultInitializable(entry.getPattern()))
+ if (entry.getPattern()->isNeverDefaultInitializable())
return false;
// If the pattern is typed as optional (or tuples thereof), it is
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index df269f0..4aada77 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -193,18 +193,6 @@
}
#pragma mark GraphViz visualization
-static int compareDependentTypes(PotentialArchetype * const* pa,
- PotentialArchetype * const* pb,
- bool outermost);
-
-static int compareDependentTypes(PotentialArchetype * const* pa,
- PotentialArchetype * const* pb) {
- return compareDependentTypes(pa, pb, /*outermost=*/true);
-}
-
-static int compareDependentTypes(Type type1, Type type2,
- bool outermost = true);
-
namespace {
/// A node in the equivalence class, used for visualization.
struct EquivalenceClassVizNode {
@@ -1967,13 +1955,14 @@
// within that equivalence class.
llvm::SmallDenseMap<EquivalenceClass *, AssociatedTypeDecl *> nestedTypes;
- PotentialArchetype *bestGenericParam = nullptr;
+ Type bestGenericParam;
for (auto member : members) {
// If the member is a generic parameter, keep the best generic parameter.
if (member->isGenericParam()) {
+ Type genericParamType = member->getDependentType(genericParams);
if (!bestGenericParam ||
- compareDependentTypes(&member, &bestGenericParam) < 0)
- bestGenericParam = member;
+ compareDependentTypes(genericParamType, bestGenericParam) < 0)
+ bestGenericParam = genericParamType;
continue;
}
@@ -2003,7 +1992,7 @@
// If we found a generic parameter, return that.
if (bestGenericParam)
- return bestGenericParam->getDependentType(genericParams);
+ return bestGenericParam;
// Determine the best anchor among the parent equivalence classes.
Type bestParentAnchor;
@@ -2486,35 +2475,11 @@
return result;
}
-/// Whether there are any concrete type declarations in the potential archetype.
-static bool hasConcreteDecls(const PotentialArchetype *pa) {
- auto parent = pa->getParent();
- if (!parent) return false;
-
- if (pa->getConcreteTypeDecl())
- return true;
-
- return hasConcreteDecls(parent);
-}
-
/// Canonical ordering for dependent types.
-static int compareDependentTypes(Type type1, Type type2,
- bool outermost) {
+int swift::compareDependentTypes(Type type1, Type type2) {
// Fast-path check for equality.
if (type1->isEqual(type2)) return 0;
- if (outermost) {
- // If there are any unresolved dependent member types in a type,
- // it's an indication of a reference to a concrete, non-associated-type
- // declaration. We prefer the type without such declarations.
- bool hasConcreteDecls1 =
- static_cast<bool>(type1->findUnresolvedDependentMemberType());
- bool hasConcreteDecls2 =
- static_cast<bool>(type2->findUnresolvedDependentMemberType());
- if (hasConcreteDecls1 != hasConcreteDecls2)
- return hasConcreteDecls1 ? +1 : -1;
- }
-
// Ordering is as follows:
// - Generic params
auto gp1 = type1->getAs<GenericTypeParamType>();
@@ -2532,8 +2497,7 @@
// - by base, so t_0_n.`P.T` < t_1_m.`P.T`
if (int compareBases =
- compareDependentTypes(depMemTy1->getBase(), depMemTy2->getBase(),
- /*outermost=*/false))
+ compareDependentTypes(depMemTy1->getBase(), depMemTy2->getBase()))
return compareBases;
// - by name, so t_n_m.`P.T` < t_n_m.`P.U`
@@ -2558,86 +2522,6 @@
return 0;
}
-/// Canonical ordering for dependent types in generic signatures.
-static int compareDependentTypes(PotentialArchetype * const* pa,
- PotentialArchetype * const* pb,
- bool outermost) {
- auto a = *pa, b = *pb;
-
- // Fast-path check for equality.
- if (a == b)
- return 0;
-
- // If one has concrete declarations somewhere but the other does not,
- // prefer the one without concrete declarations.
- if (outermost) {
- bool aHasConcreteDecls = hasConcreteDecls(a);
- bool bHasConcreteDecls = hasConcreteDecls(b);
- if (aHasConcreteDecls != bHasConcreteDecls)
- return aHasConcreteDecls ? +1 : -1;
- }
-
- // Ordering is as follows:
- // - Generic params
- if (a->isGenericParam() && b->isGenericParam())
- return a->getGenericParamKey() < b->getGenericParamKey() ? -1 : +1;
-
- // A generic parameter is always ordered before a nested type.
- if (a->isGenericParam() != b->isGenericParam())
- return a->isGenericParam() ? -1 : +1;
-
- // - Dependent members
- auto ppa = a->getParent();
- auto ppb = b->getParent();
-
- // - by base, so t_0_n.`P.T` < t_1_m.`P.T`
- if (int compareBases = compareDependentTypes(&ppa, &ppb, /*outermost=*/false))
- return compareBases;
-
- // Types that are equivalent to concrete types follow types that are still
- // type parameters.
- if (a->isConcreteType() != b->isConcreteType())
- return a->isConcreteType() ? +1 : -1;
-
- // Concrete types must be ordered *after* everything else, to ensure they
- // don't become representatives in the case where a concrete type is equated
- // with an associated type.
- if (a->getParent() && b->getParent() &&
- !!a->getConcreteTypeDecl() != !!b->getConcreteTypeDecl())
- return a->getConcreteTypeDecl() ? +1 : -1;
-
- // - by name, so t_n_m.`P.T` < t_n_m.`P.U`
- if (int compareNames = a->getNestedName().str().compare(
- b->getNestedName().str()))
- return compareNames;
-
- if (auto *aa = a->getResolvedAssociatedType()) {
- if (auto *ab = b->getResolvedAssociatedType()) {
- if (int result = compareAssociatedTypes(aa, ab))
- return result;
- } else {
- // A resolved archetype is always ordered before an unresolved one.
- return -1;
- }
- } else {
- // A resolved archetype is always ordered before an unresolved one.
- if (b->getResolvedAssociatedType())
- return +1;
- }
-
- // Make sure concrete type declarations are properly ordered, to avoid
- // crashers.
- if (auto *aa = a->getConcreteTypeDecl()) {
- auto *ab = b->getConcreteTypeDecl();
- assert(ab != nullptr && "Should have handled this case above");
-
- if (int result = TypeDecl::compare(aa, ab))
- return result;
- }
-
- llvm_unreachable("potential archetype total order failure");
-}
-
namespace {
/// Function object used to suppress conflict diagnoses when we know we'll
/// see them again later.
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 25e4c19..aa7059c 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -22,12 +22,15 @@
#include "swift/Parse/Lexer.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Subsystems.h"
+#include "swift/Syntax/TokenSyntax.h"
+#include "swift/Syntax/SyntaxParsingContext.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SaveAndRestore.h"
using namespace swift;
+using namespace swift::syntax;
/// isStartOfStmt - Return true if the current token starts a statement.
///
@@ -223,7 +226,7 @@
ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
BraceItemListKind Kind,
BraceItemListKind ConditionalBlockKind) {
-
+ SyntaxParsingContextChild StmtListContext(SyntaxContext, SyntaxKind::StmtList);
bool IsTopLevel = (Kind == BraceItemListKind::TopLevelCode) ||
(Kind == BraceItemListKind::TopLevelLibrary);
bool isActiveConditionalBlock =
@@ -259,6 +262,7 @@
Tok.isNot(tok::kw_sil_default_witness_table) &&
(isConditionalBlock ||
!isTerminatorForBraceItemListKind(Kind, Entries))) {
+ SyntaxParsingContextChild StmtContext(SyntaxContext, SyntaxContextKind::Stmt);
if (Kind == BraceItemListKind::TopLevelLibrary &&
skipExtraTopLevelRBraces())
continue;
@@ -489,7 +493,7 @@
}
ParserResult<Stmt> Parser::parseStmt() {
-
+ SyntaxParsingContextChild LocalContext(SyntaxContext, SyntaxContextKind::Stmt);
// Note that we're parsing a statement.
StructureMarkerRAII ParsingStmt(*this, Tok.getLoc(),
StructureMarkerKind::Statement);
@@ -586,15 +590,19 @@
if (Tok.isNot(tok::l_brace))
return nullptr;
}
+ SyntaxParsingContextChild LocalContext(SyntaxContext, SyntaxKind::CodeBlock);
SourceLoc LBLoc = consumeToken(tok::l_brace);
+ LocalContext.addTokenSyntax(LBLoc);
SmallVector<ASTNode, 16> Entries;
SourceLoc RBLoc;
ParserStatus Status = parseBraceItems(Entries, BraceItemListKind::Brace,
BraceItemListKind::Brace);
- parseMatchingToken(tok::r_brace, RBLoc,
- diag::expected_rbrace_in_brace_stmt, LBLoc);
+ if (!parseMatchingToken(tok::r_brace, RBLoc,
+ diag::expected_rbrace_in_brace_stmt, LBLoc)) {
+ LocalContext.addTokenSyntax(RBLoc);
+ }
return makeParserResult(Status,
BraceStmt::create(Context, LBLoc, Entries, RBLoc));
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 2c906f8..a5d5c6d 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -68,7 +68,7 @@
SourceManager &SourceMgr = SF.getASTContext().SourceMgr;
unsigned BufferID = SourceMgr.findBufferContainingLoc(AFD->getLoc());
Parser TheParser(BufferID, SF, nullptr, &ParserState);
-
+ TheParser.SyntaxContext->disable();
std::unique_ptr<CodeCompletionCallbacks> CodeCompletion;
if (CodeCompletionFactory) {
CodeCompletion.reset(
@@ -102,6 +102,9 @@
SourceMgr.findBufferContainingLoc(ParserState.getDelayedDeclLoc());
Parser TheParser(BufferID, SF, nullptr, &ParserState);
+ // Disable libSyntax creation in the delayed parsing.
+ TheParser.SyntaxContext->disable();
+
std::unique_ptr<CodeCompletionCallbacks> CodeCompletion;
if (CodeCompletionFactory) {
CodeCompletion.reset(
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
index d85cf71..d610be8 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
@@ -446,14 +446,12 @@
}
/// Given an RValue of aggregate type, compute the values of the elements by
-/// emitting a series of tuple_element instructions.
+/// emitting a destructure.
static void getScalarizedElements(SILValue V,
SmallVectorImpl<SILValue> &ElementVals,
SILLocation Loc, SILBuilder &B) {
- TupleType *TT = V->getType().castTo<TupleType>();
- for (auto Index : indices(TT->getElements())) {
- ElementVals.push_back(B.emitTupleExtract(Loc, V, Index));
- }
+ auto *DTI = B.createDestructureTuple(Loc, V);
+ copy(DTI->getResults(), std::back_inserter(ElementVals));
}
/// Scalarize a load down to its subelements. If NewLoads is specified, this
@@ -562,6 +560,8 @@
void addElementUses(unsigned BaseEltNo, SILType UseTy, SILInstruction *User,
DIUseKind Kind);
void collectTupleElementUses(TupleElementAddrInst *TEAI, unsigned BaseEltNo);
+ void collectDestructureTupleResultUses(DestructureTupleResult *DTR,
+ unsigned BaseEltNo);
void collectStructElementUses(StructElementAddrInst *SEAI,
unsigned BaseEltNo);
};
@@ -611,6 +611,33 @@
collectUses(TEAI, BaseEltNo);
}
+/// Given a destructure_tuple, compute the new BaseEltNo implicit in the
+/// selected member, and recursively add uses of the instruction.
+void ElementUseCollector::collectDestructureTupleResultUses(
+ DestructureTupleResult *DTR, unsigned BaseEltNo) {
+
+ // If we're walking into a tuple within a struct or enum, don't adjust the
+ // BaseElt. The uses hanging off the tuple_element_addr are going to be
+ // counted as uses of the struct or enum itself.
+ if (InStructSubElement || InEnumSubElement)
+ return collectUses(DTR, BaseEltNo);
+
+ assert(!IsSelfOfNonDelegatingInitializer && "self doesn't have tuple type");
+
+ // tuple_element_addr P, 42 indexes into the current tuple element.
+ // Recursively process its uses with the adjusted element number.
+ unsigned FieldNo = DTR->getIndex();
+ auto T = DTR->getParent()->getOperand()->getType();
+ if (T.is<TupleType>()) {
+ for (unsigned i = 0; i != FieldNo; ++i) {
+ SILType EltTy = T.getTupleElementType(i);
+ BaseEltNo += getElementCountRec(Module, EltTy, false);
+ }
+ }
+
+ collectUses(DTR, BaseEltNo);
+}
+
void ElementUseCollector::collectStructElementUses(StructElementAddrInst *SEAI,
unsigned BaseEltNo) {
// Generally, we set the "InStructSubElement" flag and recursively process
@@ -1024,8 +1051,15 @@
// Now that we've scalarized some stuff, recurse down into the newly created
// element address computations to recursively process it. This can cause
// further scalarization.
- for (auto EltPtr : ElementAddrs)
- collectTupleElementUses(cast<TupleElementAddrInst>(EltPtr), BaseEltNo);
+ for (SILValue EltPtr : ElementAddrs) {
+ if (auto *TEAI = dyn_cast<TupleElementAddrInst>(EltPtr)) {
+ collectTupleElementUses(TEAI, BaseEltNo);
+ continue;
+ }
+
+ auto *DTRI = cast<DestructureTupleResult>(EltPtr);
+ collectDestructureTupleResultUses(DTRI, BaseEltNo);
+ }
}
}
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index f63bf23..55aa7a8 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4127,8 +4127,25 @@
TC.checkTypeModifyingDeclAttributes(var);
// Decide whether we should suppress default initialization.
- if (!PBD->isDefaultInitializable(i))
- continue;
+ //
+ // Note: Swift 4 had a bug where properties with a desugared optional
+ // type like Optional<Int> had a half-way behavior where sometimes
+ // they behave like they are default initialized, and sometimes not.
+ //
+ // In Swift 5 mode, use the right condition here, and only default
+ // initialize properties with a sugared Optional type.
+ //
+ // (The restriction to sugared types only comes because we don't have
+ // the iterative declaration checker yet; so in general, we cannot
+ // look at the type of a property at all, and can only look at the
+ // TypeRepr, because we haven't validated the property yet.)
+ if (TC.Context.isSwiftVersionAtLeast(5)) {
+ if (!PBD->isDefaultInitializable(i))
+ continue;
+ } else {
+ if (PBD->getPattern(i)->isNeverDefaultInitializable())
+ continue;
+ }
auto type = PBD->getPattern(i)->getType();
if (auto defaultInit = buildDefaultInitializer(TC, type)) {
@@ -8540,16 +8557,20 @@
// Bail out if we're validating one of our constructors already; we'll
// revisit the issue later.
- bool alreadyValidatingCtor = false;
- for (auto member : decl->getMembers()) {
- if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
- validateDecl(ctor);
- if (!ctor->hasValidSignature())
- alreadyValidatingCtor = true;
+ if (isa<ClassDecl>(decl)) {
+ bool alreadyValidatingCtor = false;
+ for (auto member : decl->getMembers()) {
+ if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
+ validateDecl(ctor);
+ if (!ctor->hasValidSignature())
+ alreadyValidatingCtor = true;
+ }
}
+ if (alreadyValidatingCtor)
+ return;
}
- if (alreadyValidatingCtor)
- return;
+
+ decl->setAddedImplicitInitializers();
// Check whether there is a user-declared constructor or an instance
// variable.
@@ -8558,7 +8579,6 @@
bool SuppressMemberwiseInitializer = false;
bool FoundSynthesizedInit = false;
bool FoundDesignatedInit = false;
- decl->setAddedImplicitInitializers();
// Before we look for constructors, we need to make sure that all synthesized
// initializers are properly synthesized.
@@ -8600,6 +8620,9 @@
FoundDesignatedInit = true;
}
+ if (isa<StructDecl>(decl))
+ continue;
+
if (!ctor->isInvalid())
initializerParamTypes.insert(getInitializerParamType(ctor));
@@ -8816,8 +8839,7 @@
if (auto ref = conformsToProtocol(targetType, protocol, target,
ConformanceCheckFlags::Used,
SourceLoc())) {
- if (auto *conformance =
- dyn_cast_or_null<NormalProtocolConformance>(ref->getConcrete())) {
+ if (auto *conformance = ref->getConcrete()->getRootNormalConformance()) {
if (conformance->isIncomplete()) {
// Check conformance, forcing synthesis.
//
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 9f90a4b..f53508b 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -3628,6 +3628,11 @@
if (genericDecl->getGenericParams())
continue;
+ // Skip typealiases with an unbound generic type as their underlying type.
+ if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(candidate.first))
+ if (typeAliasDecl->getDeclaredInterfaceType()->is<UnboundGenericType>())
+ continue;
+
// Check this type against the protocol requirements.
if (auto checkResult = checkTypeWitness(TC, DC, Proto, assocType,
candidate.second)) {
diff --git a/lib/Syntax/RawSyntax.cpp b/lib/Syntax/RawSyntax.cpp
index 6a6c2b3..1c80bee 100644
--- a/lib/Syntax/RawSyntax.cpp
+++ b/lib/Syntax/RawSyntax.cpp
@@ -29,6 +29,7 @@
case SyntaxKind::SourceFile:
case SyntaxKind::TopLevelCodeDecl:
case SyntaxKind::ExpressionStmt:
+ case SyntaxKind::DeclarationStmt:
return true;
default:
return false;
diff --git a/lib/Syntax/SyntaxParsingContext.cpp b/lib/Syntax/SyntaxParsingContext.cpp
index 236c1d5..eb8e495 100644
--- a/lib/Syntax/SyntaxParsingContext.cpp
+++ b/lib/Syntax/SyntaxParsingContext.cpp
@@ -43,17 +43,21 @@
return Scratch;
}
-static unsigned countTokens(ArrayRef<RawSyntaxInfo> AllNodes) {
- return std::accumulate(AllNodes.begin(), AllNodes.end(), 0,
- [](unsigned Sum, const RawSyntaxInfo &Info) { return Sum + Info.TokCount; });
+static SourceRange getNodesRange(ArrayRef<RawSyntaxInfo> RawNodes) {
+ SourceLoc StartLoc, EndLoc;
+ for (auto Info: RawNodes) {
+ if (Info.isImplicit())
+ continue;
+ if (StartLoc.isInvalid()) {
+ StartLoc = Info.getStartLoc();
+ }
+ EndLoc = Info.getEndLoc();
+ }
+ assert(StartLoc.isValid() == EndLoc.isValid());
+ return SourceRange(StartLoc, EndLoc);
}
} // End of anonymous namespace
-RawSyntaxInfo::RawSyntaxInfo(SourceLoc StartLoc, unsigned TokCount,
- RC<RawSyntax> RawNode): StartLoc(StartLoc), TokCount(TokCount), RawNode(RawNode) {
- assert(StartLoc.isValid());
-}
-
struct SyntaxParsingContext::ContextInfo {
bool Enabled;
private:
@@ -66,8 +70,8 @@
ArrayRef<RawSyntaxInfo>::const_iterator findTokenAt(SourceLoc Loc) {
for (auto It = Tokens.begin(); It != Tokens.end(); It ++) {
- assert(It->TokCount == 1);
- if (It->StartLoc == Loc)
+ assert(It->getStartLoc() == It->getEndLoc());
+ if (It->getStartLoc() == Loc)
return It;
}
llvm_unreachable("cannot find the token on the given location");
@@ -98,8 +102,9 @@
ArrayRef<RawSyntaxInfo> getPendingSyntax() const { return PendingSyntax; };
void addPendingSyntax(RawSyntaxInfo Info) {
- assert(PendingSyntax.empty() || PendingSyntax.back().StartLoc.
- getOpaquePointerValue() < Info.StartLoc.getOpaquePointerValue());
+ assert(Info.isImplicit() || PendingSyntax.empty() ||
+ PendingSyntax.back().getStartLoc().getOpaquePointerValue() <
+ Info.getStartLoc().getOpaquePointerValue());
PendingSyntax.push_back(Info);
}
@@ -139,16 +144,21 @@
// If no remaining syntax nodes, add the token.
Results.emplace_back(Tok);
It ++;
- } else if (CurSyntax->StartLoc == Tok.StartLoc) {
+ } else if (CurSyntax->isImplicit()) {
+ // Skip implicit syntax node.
+ CurSyntax ++;
+ } else if (CurSyntax->getStartLoc() == Tok.getStartLoc()) {
// Prefer syntax nodes to tokens.
Results.emplace_back(*CurSyntax);
- It += CurSyntax->TokCount;
+ while(It->getEndLoc() != CurSyntax->getEndLoc()) It++;
+ assert(It < Tokens.end() && It->getEndLoc() == CurSyntax->getEndLoc());
+ It ++;
CurSyntax ++;
} else {
// We have to add token in this case since the next syntax node has not
// started.
- assert(Tok.StartLoc.getOpaquePointerValue() <
- CurSyntax->StartLoc.getOpaquePointerValue());
+ assert(Tok.getStartLoc().getOpaquePointerValue() <
+ CurSyntax->getStartLoc().getOpaquePointerValue());
Results.push_back(Tok);
It ++;
}
@@ -178,8 +188,8 @@
Result.emplace(makeUnknownSyntax(SyntaxFactory::getUnknownKind(Kind),
SyntaxParts));
}
- RawSyntaxInfo NewSyntaxNode(Parts.front().StartLoc, countTokens(Parts),
- Result->getRaw());
+ RawSyntaxInfo NewSyntaxNode(getNodesRange(Parts), Result->getRaw());
+
// Remove the building bricks and re-append the result.
for (unsigned I = 0; I < N; I ++)
PendingSyntax.pop_back();
@@ -209,26 +219,9 @@
}
}
for (auto Info: ContextData.getPendingSyntax()) {
- std::vector<StmtSyntax> AllStmts;
- auto S = Info.makeSyntax<Syntax>();
- if (S.isDecl()) {
- AllStmts.push_back(SyntaxFactory::makeDeclarationStmt(
- S.getAs<DeclSyntax>().getValue(), None));
- } else if (S.isExpr()) {
- AllStmts.push_back(SyntaxFactory::makeExpressionStmt(
- S.getAs<ExprSyntax>().getValue(), None));
- } else if (S.isStmt()) {
- AllStmts.push_back(S.getAs<StmtSyntax>().getValue());
- } else {
- // If this is a standalone token, we create an unknown expression wrapper
- // for it.
- AllStmts.push_back(SyntaxFactory::makeExpressionStmt(
- *makeUnknownSyntax(SyntaxKind::UnknownExpr,
- { *S.getAs<TokenSyntax>() }).getAs<ExprSyntax>(),
- None));
- }
+ assert(Info.RawNode->Kind == SyntaxKind::StmtList);
AllTopLevel.push_back(SyntaxFactory::makeTopLevelCodeDecl(
- SyntaxFactory::makeStmtList(AllStmts)));
+ Info.makeSyntax<StmtListSyntax>()));
}
File.setSyntaxRoot(
@@ -248,14 +241,16 @@
SyntaxParsingContextChild::
SyntaxParsingContextChild(SyntaxParsingContext *&ContextHolder,
- SyntaxContextKind Kind):
+ Optional<SyntaxContextKind> Kind, Optional<SyntaxKind> KnownSyntax):
SyntaxParsingContext(*ContextHolder), Parent(ContextHolder),
- ContextHolder(ContextHolder), Kind(Kind) {
+ ContextHolder(ContextHolder), Kind(Kind), KnownSyntax(KnownSyntax) {
+ assert(Kind.hasValue() != KnownSyntax.hasValue());
ContextHolder = this;
if (ContextData.Enabled)
ContextData.setContextStart(Tok.getLoc());
}
+
void SyntaxParsingContextChild::addTokenSyntax(SourceLoc Loc) {
if (ContextData.Enabled)
ContextData.promoteTokenAt(Loc);
@@ -281,6 +276,53 @@
}
default:
+ llvm_unreachable("Unrecognized node kind.");
+ }
+}
+
+void SyntaxParsingContextChild::makeNodeWhole(SyntaxKind Kind) {
+ assert(ContextData.Enabled);
+ switch (Kind) {
+ case SyntaxKind::CodeBlock: {
+ ContextData.createFromBack(Kind);
+ break;
+ }
+ case SyntaxKind::StmtList: {
+ if (ContextData.getPendingSyntax().empty()) {
+ // Create an empty statement list if no statement is in the context.
+ ContextData.addPendingSyntax({SyntaxFactory::makeBlankStmtList().getRaw()});
+ } else {
+ ContextData.createFromBack(Kind);
+ }
+ break;
+ }
+ default:
+ llvm_unreachable("Unrecognized node kind.");
+ }
+}
+
+void RawSyntaxInfo::brigeWithContext(SyntaxContextKind Kind) {
+ switch (Kind) {
+ case SyntaxContextKind::Stmt: {
+ if (RawNode->isDecl()) {
+ // Wrap a declaration with a declaration statement
+ RawNode = SyntaxFactory::createSyntax(SyntaxKind::DeclarationStmt,
+ { makeSyntax<Syntax>() })->getRaw();
+ } else if (RawNode->isExpr()) {
+ // Wrap an expression with an expression statement
+ RawNode = SyntaxFactory::createSyntax(SyntaxKind::ExpressionStmt,
+ { makeSyntax<Syntax>() })->getRaw();
+ } else if (RawNode->isToken()) {
+ // Wrap a standalone token withn an expression statement
+ RawNode = SyntaxFactory::createSyntax(SyntaxKind::ExpressionStmt,
+ makeUnknownSyntax(SyntaxKind::UnknownExpr,
+ {make<Syntax>(RawNode)}))->getRaw();
+ }
+ assert(RawNode->isStmt());
+ break;
+ }
+ case SyntaxContextKind::Decl:
+ case SyntaxContextKind::Expr:
break;
}
}
@@ -295,32 +337,51 @@
// Set the end of the context.
ContextData.setContextEnd(Tok.getLoc());
+ if (KnownSyntax) {
+ // If the entire context should be created to a known syntax kind, create
+ // all pending syntax nodes into that node.
+ makeNodeWhole(*KnownSyntax);
+ assert(ContextData.getPendingSyntax().size() == 1);
+ auto AllNodes = ContextData.collectAllSyntax();
+ assert(AllNodes.size() == 1);
+ Parent->ContextData.addPendingSyntax(AllNodes.front());
+ return;
+ }
auto AllNodes = ContextData.collectAllSyntax();
- assert(countTokens(AllNodes) == ContextData.allTokens().size());
RC<RawSyntax> FinalResult;
if (AllNodes.empty())
return;
+ // Make sure we used all tokens.
+ assert(AllNodes.front().getStartLoc() == ContextData.allTokens().front().getStartLoc());
+ assert(AllNodes.back().getEndLoc() == ContextData.allTokens().back().getStartLoc());
+
if (AllNodes.size() == 1) {
- // FIXME: Check kind
- Parent->ContextData.addPendingSyntax(AllNodes.front());
+ // If we have only one syntax node remaining, we are done.
+ auto Result = AllNodes.front();
+ // Bridge the syntax node to the expected context kind.
+ Result.brigeWithContext(*Kind);
+ Parent->ContextData.addPendingSyntax(Result);
return;
}
llvm::SmallVector<Syntax, 8> Scratch;
auto SyntaxNodes = getSyntaxNodes(AllNodes, Scratch);
- SourceLoc Start = AllNodes.front().StartLoc;
- unsigned TokCount = countTokens(AllNodes);
+ SourceLoc Start = AllNodes.front().getStartLoc();
+ SourceLoc End = AllNodes.back().getEndLoc();
SyntaxKind UnknownKind;
- switch (Kind) {
+ switch (*Kind) {
case SyntaxContextKind::Expr:
UnknownKind = SyntaxKind::UnknownExpr;
break;
case SyntaxContextKind::Decl:
UnknownKind = SyntaxKind::UnknownDecl;
break;
+ case SyntaxContextKind::Stmt:
+ UnknownKind = SyntaxKind::UnknownStmt;
+ break;
}
// Create an unknown node and give it to the parent context.
- Parent->ContextData.addPendingSyntax({Start, TokCount,
+ Parent->ContextData.addPendingSyntax({SourceRange(Start, End),
makeUnknownSyntax(UnknownKind, SyntaxNodes).getRaw()});
}
diff --git a/test/Compatibility/default_init.swift b/test/Compatibility/default_init.swift
new file mode 100644
index 0000000..e6eebc4
--- /dev/null
+++ b/test/Compatibility/default_init.swift
@@ -0,0 +1,16 @@
+// RUN: %target-swift-frontend -typecheck -parse-as-library %s -verify -swift-version 4
+
+// Default initialization of variables -- totally broken Swift 4 behavior.
+
+class NotInitializableOptionalClass {
+ var opt: Optional<Int>
+}
+
+struct NotInitializableOptionalStruct { // expected-note {{'init(opt:)' declared here}}
+ var opt: Optional<Int>
+}
+
+func testBadDefaultInit() {
+ _ = NotInitializableOptionalStruct() // expected-error {{missing argument for parameter 'opt' in call}}
+ _ = NotInitializableOptionalClass()
+}
diff --git a/test/SILOptimizer/definite_init_scalarization_test.sil b/test/SILOptimizer/definite_init_scalarization_test.sil
new file mode 100644
index 0000000..d79d250
--- /dev/null
+++ b/test/SILOptimizer/definite_init_scalarization_test.sil
@@ -0,0 +1,228 @@
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init | %FileCheck %s
+//
+// Make sure that we properly scalarize tuples.
+//
+// TODO: This should be split out into its own pass /before/ DI rather than
+// running during DI. Even once that happens, it is important that we update
+// this test so that the test is in its post scalarization state so we can
+// verify that DI can properly look through destructures.
+
+sil_stage raw
+
+import Builtin
+
+struct Int {
+ var _value: Builtin.Int64
+}
+
+struct TripleInt {
+ var a, b, c: Int
+}
+
+struct ObjectValue {
+ var a : Builtin.NativeObject
+}
+
+// CHECK-LABEL: sil @test_store_trivial : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @trivial $TripleInt, [[ARG1:%.*]] : @trivial $TripleInt, [[ARG2:%.*]] : @trivial $TripleInt):
+// CHECK: [[BOX:%.*]] = alloc_box
+// CHECK: [[PB_BOX:%.*]] = project_box [[BOX]]
+// CHECK: [[ELT0:%.*]] = tuple_element_addr [[PB_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 0
+// CHECK: [[ELT1:%.*]] = tuple_element_addr [[PB_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 1
+// CHECK: [[ELT10:%.*]] = tuple_element_addr [[ELT1]] : $*(TripleInt, TripleInt), 0
+// CHECK: [[ELT11:%.*]] = tuple_element_addr [[ELT1]] : $*(TripleInt, TripleInt), 1
+// CHECK: [[RHS_TUP:%.*]] = tuple ([[ARG0]] : ${{.*}}, [[ARG1:%.*]] : ${{.*}})
+// CHECK: [[TUP:%.*]] = tuple ([[ARG2:%.*]] : ${{.*}}, [[RHS_TUP]] : ${{.*}})
+// CHECK: ([[DESTRUCTURE_TUP_LHS:%.*]], [[DESTRUCTURE_TUP_RHS:%.*]]) = destructure_tuple [[TUP]] : $(TripleInt, (TripleInt, TripleInt))
+// CHECK: store [[DESTRUCTURE_TUP_LHS]] to [trivial] [[ELT0]]
+// CHECK: ([[DESTRUCTURE_TUP_RHS_LHS:%.*]], [[DESTRUCTURE_TUP_RHS_RHS:%.*]]) = destructure_tuple [[DESTRUCTURE_TUP_RHS]] : $(TripleInt, TripleInt)
+// CHECK: store [[DESTRUCTURE_TUP_RHS_LHS]] to [trivial] [[ELT10]]
+// CHECK: store [[DESTRUCTURE_TUP_RHS_RHS]] to [trivial] [[ELT11]]
+// CHECK: destroy_value [[BOX]]
+// CHECK: } // end sil function 'test_store_trivial'
+sil @test_store_trivial : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+bb0(%0 : @trivial $TripleInt, %1 : @trivial $TripleInt, %1a : @trivial $TripleInt):
+ %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+ %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>, 0
+ %4 = mark_uninitialized [var] %3 : $*(TripleInt, (TripleInt, TripleInt))
+ %5 = tuple(%0 : $TripleInt, %1 : $TripleInt)
+ %6 = tuple(%1a : $TripleInt, %5 : $(TripleInt, TripleInt))
+ store %6 to [trivial] %4 : $*(TripleInt, (TripleInt, TripleInt))
+ destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_store_owned : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @owned $Builtin.NativeObject, [[ARG1:%.*]] : @owned $Builtin.NativeObject, [[ARG2:%.*]] : @owned $Builtin.NativeObject):
+// CHECK: [[BOX:%.*]] = alloc_box
+// CHECK: [[PB_BOX:%.*]] = project_box [[BOX]]
+// CHECK: [[ELT0:%.*]] = tuple_element_addr [[PB_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 0
+// CHECK: [[ELT1:%.*]] = tuple_element_addr [[PB_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 1
+// CHECK: [[ELT10:%.*]] = tuple_element_addr [[ELT1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 0
+// CHECK: [[ELT11:%.*]] = tuple_element_addr [[ELT1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK: [[RHS_TUP:%.*]] = tuple ([[ARG0]] : ${{.*}}, [[ARG1:%.*]] : ${{.*}})
+// CHECK: [[TUP:%.*]] = tuple ([[ARG2:%.*]] : ${{.*}}, [[RHS_TUP]] : ${{.*}})
+// CHECK: ([[DESTRUCTURE_TUP_LHS:%.*]], [[DESTRUCTURE_TUP_RHS:%.*]]) = destructure_tuple [[TUP]] : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+// CHECK: store [[DESTRUCTURE_TUP_LHS]] to [init] [[ELT0]]
+// CHECK: ([[DESTRUCTURE_TUP_RHS_LHS:%.*]], [[DESTRUCTURE_TUP_RHS_RHS:%.*]]) = destructure_tuple [[DESTRUCTURE_TUP_RHS]] : $(Builtin.NativeObject, Builtin.NativeObject)
+// CHECK: store [[DESTRUCTURE_TUP_RHS_LHS]] to [init] [[ELT10]]
+// CHECK: store [[DESTRUCTURE_TUP_RHS_RHS]] to [init] [[ELT11]]
+// CHECK: destroy_value [[BOX]]
+// CHECK: } // end sil function 'test_store_owned'
+sil @test_store_owned : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject, %1a : @owned $Builtin.NativeObject):
+ %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+ %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+ %4 = mark_uninitialized [var] %3 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+ %5 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
+ %6 = tuple(%1a : $Builtin.NativeObject, %5 : $(Builtin.NativeObject, Builtin.NativeObject))
+ store %6 to [init] %4 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+ destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_assign_trivial : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @trivial $TripleInt, [[ARG1:%.*]] : @trivial $TripleInt, [[ARG2:%.*]] : @trivial $TripleInt):
+// CHECK: [[BOX:%.*]] = alloc_box
+// CHECK: [[PB_BOX:%.*]] = project_box [[BOX]]
+// CHECK: [[ELT0:%.*]] = tuple_element_addr [[PB_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 0
+// CHECK: [[ELT1:%.*]] = tuple_element_addr [[PB_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 1
+// CHECK: [[ELT10:%.*]] = tuple_element_addr [[ELT1]] : $*(TripleInt, TripleInt), 0
+// CHECK: [[ELT11:%.*]] = tuple_element_addr [[ELT1]] : $*(TripleInt, TripleInt), 1
+// CHECK: [[RHS_TUP:%.*]] = tuple ([[ARG0]] : ${{.*}}, [[ARG1:%.*]] : ${{.*}})
+// CHECK: [[TUP:%.*]] = tuple ([[ARG2:%.*]] : ${{.*}}, [[RHS_TUP]] : ${{.*}})
+// CHECK: ([[DESTRUCTURE_TUP_LHS:%.*]], [[DESTRUCTURE_TUP_RHS:%.*]]) = destructure_tuple [[TUP]] : $(TripleInt, (TripleInt, TripleInt))
+// CHECK: store [[DESTRUCTURE_TUP_LHS]] to [trivial] [[ELT0]]
+// CHECK: ([[DESTRUCTURE_TUP_RHS_LHS:%.*]], [[DESTRUCTURE_TUP_RHS_RHS:%.*]]) = destructure_tuple [[DESTRUCTURE_TUP_RHS]] : $(TripleInt, TripleInt)
+// CHECK: store [[DESTRUCTURE_TUP_RHS_LHS]] to [trivial] [[ELT10]]
+// CHECK: store [[DESTRUCTURE_TUP_RHS_RHS]] to [trivial] [[ELT11]]
+// CHECK: destroy_value [[BOX]]
+// CHECK: } // end sil function 'test_assign_trivial'
+sil @test_assign_trivial : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+bb0(%0 : @trivial $TripleInt, %1 : @trivial $TripleInt, %1a : @trivial $TripleInt):
+ %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+ %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>, 0
+ %4 = mark_uninitialized [var] %3 : $*(TripleInt, (TripleInt, TripleInt))
+ %5 = tuple(%0 : $TripleInt, %1 : $TripleInt)
+ %6 = tuple(%1a : $TripleInt, %5 : $(TripleInt, TripleInt))
+ assign %6 to %4 : $*(TripleInt, (TripleInt, TripleInt))
+ destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_assign_trivial_2 : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @trivial $TripleInt, [[ARG1:%.*]] : @trivial $TripleInt, [[ARG2:%.*]] : @trivial $TripleInt):
+// CHECK: [[BOX:%.*]] = alloc_box $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+// CHECK: [[PROJ_BOX:%.*]] = project_box [[BOX]] : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>, 0
+// CHECK: [[PROJ_BOX_0:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 0
+// CHECK: [[PROJ_BOX_1:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(TripleInt, (TripleInt, TripleInt)), 1
+// CHECK: [[PROJ_BOX_10:%.*]] = tuple_element_addr %6 : $*(TripleInt, TripleInt), 0
+// CHECK: [[PROJ_BOX_11:%.*]] = tuple_element_addr %6 : $*(TripleInt, TripleInt), 1
+// CHECK: [[TUP11:%.*]] = tuple ([[ARG0]] : $TripleInt, [[ARG1]] : $TripleInt)
+// CHECK: [[TUP1:%.*]] = tuple ([[ARG2]] : $TripleInt, [[TUP11]] : $(TripleInt, TripleInt))
+// CHECK: [[TUP1_2nd:%.*]] = tuple ([[ARG2]] : $TripleInt, [[TUP11]] : $(TripleInt, TripleInt))
+// CHECK: ([[TUP1_D_0:%.*]], [[TUP1_D_1:%.*]]) = destructure_tuple [[TUP1]] : $(TripleInt, (TripleInt, TripleInt))
+// CHECK: store [[TUP1_D_0]] to [trivial] [[PROJ_BOX_0]] : $*TripleInt
+// CHECK: ([[TUP1_D_1_0:%.*]], [[TUP1_D_1_1:%.*]]) = destructure_tuple [[TUP1_D_1]] : $(TripleInt, TripleInt)
+// CHECK: store [[TUP1_D_1_0]] to [trivial] [[PROJ_BOX_10]] : $*TripleInt
+// CHECK: store [[TUP1_D_1_1]] to [trivial] [[PROJ_BOX_11]] : $*TripleInt
+// CHECK: ([[TUP1_2nd_0:%.*]], [[TUP1_2nd_1:%.*]]) = destructure_tuple [[TUP1_2nd]] : $(TripleInt, (TripleInt, TripleInt))
+// CHECK: store [[TUP1_2nd_0]] to [trivial] [[PROJ_BOX_0]] : $*TripleInt
+// CHECK: ([[TUP1_2nd_10:%.*]], [[TUP1_2nd_11:%.*]]) = destructure_tuple [[TUP1_2nd_1]] : $(TripleInt, TripleInt)
+// CHECK: store [[TUP1_2nd_10]] to [trivial] [[PROJ_BOX_10]] : $*TripleInt
+// CHECK: store [[TUP1_2nd_11]] to [trivial] [[PROJ_BOX_11]] : $*TripleInt
+// CHECK: destroy_value [[BOX]] : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+// CHECK: } // end sil function 'test_assign_trivial_2'
+sil @test_assign_trivial_2 : $@convention(thin) (TripleInt, TripleInt, TripleInt) -> () {
+bb0(%0 : @trivial $TripleInt, %1 : @trivial $TripleInt, %1a : @trivial $TripleInt):
+ %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+ %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>, 0
+ %4 = mark_uninitialized [var] %3 : $*(TripleInt, (TripleInt, TripleInt))
+ %5 = tuple(%0 : $TripleInt, %1 : $TripleInt)
+ %6 = tuple(%1a : $TripleInt, %5 : $(TripleInt, TripleInt))
+ %7 = tuple(%1a : $TripleInt, %5 : $(TripleInt, TripleInt))
+ assign %6 to %4 : $*(TripleInt, (TripleInt, TripleInt))
+ assign %7 to %4 : $*(TripleInt, (TripleInt, TripleInt))
+ destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(TripleInt, (TripleInt, TripleInt))>
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_assign_owned : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @owned $Builtin.NativeObject, [[ARG1:%.*]] : @owned $Builtin.NativeObject, [[ARG2:%.*]] : @owned $Builtin.NativeObject):
+// CHECK: [[BOX:%.*]] = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+// CHECK: [[PROJ_BOX:%.*]] = project_box [[BOX]] : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+// CHECK: [[PROJ_BOX_0:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 0
+// CHECK: [[PROJ_BOX_1:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 1
+// CHECK: [[PROJ_BOX_10:%.*]] = tuple_element_addr [[PROJ_BOX_1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 0
+// CHECK: [[PROJ_BOX_11:%.*]] = tuple_element_addr [[PROJ_BOX_1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK: [[TUP_1:%.*]] = tuple ([[ARG0]] : $Builtin.NativeObject, [[ARG1]] : $Builtin.NativeObject)
+// CHECK: [[TUP:%.*]] = tuple ([[ARG2]] : $Builtin.NativeObject, [[TUP_1]] : $(Builtin.NativeObject, Builtin.NativeObject))
+// CHECK: ([[TUP_D_0:%.*]], [[TUP_D_1:%.*]]) = destructure_tuple [[TUP]] : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+// CHECK: store [[TUP_D_0]] to [init] [[PROJ_BOX_0]] : $*Builtin.NativeObject
+// CHECK: ([[TUP_D_10:%.*]], [[TUP_D_11:%.*]]) = destructure_tuple [[TUP_D_1]] : $(Builtin.NativeObject, Builtin.NativeObject)
+// CHECK: store [[TUP_D_10]] to [init] [[PROJ_BOX_10]] : $*Builtin.NativeObject
+// CHECK: store [[TUP_D_11]] to [init] [[PROJ_BOX_11]] : $*Builtin.NativeObject
+// CHECK: destroy_value [[BOX]] : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+// CHECK: } // end sil function 'test_assign_owned'
+sil @test_assign_owned : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject, %1a : @owned $Builtin.NativeObject):
+ %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+ %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+ %4 = mark_uninitialized [var] %3 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+ %5 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
+ %6 = tuple(%1a : $Builtin.NativeObject, %5 : $(Builtin.NativeObject, Builtin.NativeObject))
+ assign %6 to %4 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+ destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_assigned_owned_2 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG0:%.*]] : @owned $Builtin.NativeObject, [[ARG1:%.*]] : @owned $Builtin.NativeObject, [[ARG2:%.*]] : @owned $Builtin.NativeObject):
+// CHECK: [[BOX:%.*]] = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+// CHECK: [[PROJ_BOX:%.*]] = project_box [[BOX]] : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+// CHECK: [[PROJ_BOX_0:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 0
+// CHECK: [[PROJ_BOX_1:%.*]] = tuple_element_addr [[PROJ_BOX]] : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject)), 1
+// CHECK: [[PROJ_BOX_10:%.*]] = tuple_element_addr [[PROJ_BOX_1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 0
+// CHECK: [[PROJ_BOX_11:%.*]] = tuple_element_addr [[PROJ_BOX_1]] : $*(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK: [[TUP_1:%.*]] = tuple ([[ARG0]] : $Builtin.NativeObject, [[ARG1]] : $Builtin.NativeObject)
+// CHECK: [[TUP:%.*]] = tuple ([[ARG2]] : $Builtin.NativeObject, [[TUP_1]] : $(Builtin.NativeObject, Builtin.NativeObject))
+// CHECK: [[TUP_COPY:%.*]] = copy_value [[TUP]]
+// CHECK: ([[TUP_D_0:%.*]], [[TUP_D_1:%.*]]) = destructure_tuple [[TUP]] : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+// CHECK: store [[TUP_D_0]] to [init] [[PROJ_BOX_0]] : $*Builtin.NativeObject
+// CHECK: ([[TUP_D_10:%.*]], [[TUP_D_11:%.*]]) = destructure_tuple [[TUP_D_1]] : $(Builtin.NativeObject, Builtin.NativeObject)
+// CHECK: store [[TUP_D_10]] to [init] [[PROJ_BOX_10]] : $*Builtin.NativeObject
+// CHECK: store [[TUP_D_11]] to [init] [[PROJ_BOX_11]] : $*Builtin.NativeObject
+
+// CHECK: ([[TUP_D_0:%.*]], [[TUP_D_1:%.*]]) = destructure_tuple [[TUP_COPY]] : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+// CHECK: [[OLD_VALUE:%.*]] = load [take] [[PROJ_BOX_0]]
+// CHECK: store [[TUP_D_0]] to [init] [[PROJ_BOX_0]] : $*Builtin.NativeObject
+// CHECK: destroy_value [[OLD_VALUE]]
+// CHECK: ([[TUP_D_10:%.*]], [[TUP_D_11:%.*]]) = destructure_tuple [[TUP_D_1]] : $(Builtin.NativeObject, Builtin.NativeObject)
+// CHECK: [[OLD_VALUE:%.*]] = load [take] [[PROJ_BOX_10]]
+// CHECK: store [[TUP_D_10]] to [init] [[PROJ_BOX_10]] : $*Builtin.NativeObject
+// CHECK: destroy_value [[OLD_VALUE]]
+// CHECK: [[OLD_VALUE:%.*]] = load [take] [[PROJ_BOX_11]]
+// CHECK: store [[TUP_D_11]] to [init] [[PROJ_BOX_11]] : $*Builtin.NativeObject
+// CHECK: destroy_value [[OLD_VALUE]]
+
+// CHECK: destroy_value [[BOX]] : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+// CHECK: } // end sil function 'test_assigned_owned_2'
+sil @test_assigned_owned_2 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject, %1a : @owned $Builtin.NativeObject):
+ %2 = alloc_box $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+ %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>, 0
+ %4 = mark_uninitialized [var] %3 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+ %5 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
+ %6 = tuple(%1a : $Builtin.NativeObject, %5 : $(Builtin.NativeObject, Builtin.NativeObject))
+ %7 = copy_value %6 : $(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+ assign %6 to %4 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+ assign %7 to %4 : $*(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))
+ destroy_value %2 : $<τ_0_0> { var τ_0_0 } <(Builtin.NativeObject, (Builtin.NativeObject, Builtin.NativeObject))>
+ %9999 = tuple()
+ return %9999 : $()
+}
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 04d5077..6c36768 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -1,12 +1,12 @@
-<DeclarationStmt><UnknownDecl>// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t
+<UnknownDecl>// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t
// RUN: diff -u %s %t
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen -print-node-kind > %t.withkinds
// RUN: diff -u %S/Outputs/round_trip_parse_gen.swift.withkinds %t.withkinds
class C {<UnknownDecl>
- func bar(_ a: Int) {}</UnknownDecl><UnknownDecl>
- func bar1(_ a: Float) -> Float { return <UnknownExpr><FloatLiteralExpr>-0.6 </FloatLiteralExpr>+ <FloatLiteralExpr>0.1 </FloatLiteralExpr>- <FloatLiteralExpr>0.3 </FloatLiteralExpr></UnknownExpr>}</UnknownDecl><UnknownDecl>
- func foo() {<UnknownDecl>
+ func bar(_ a: Int) <CodeBlock>{}</CodeBlock></UnknownDecl><UnknownDecl>
+ func bar1(_ a: Float) -> Float <CodeBlock>{ <UnknownStmt>return <UnknownExpr><FloatLiteralExpr>-0.6 </FloatLiteralExpr>+ <FloatLiteralExpr>0.1 </FloatLiteralExpr>- <FloatLiteralExpr>0.3 </FloatLiteralExpr></UnknownExpr></UnknownStmt>}</CodeBlock></UnknownDecl><UnknownDecl>
+ func foo() <CodeBlock>{<UnknownDecl>
var a = /*comment*/<StringLiteralExpr>"abc"/*comment*/</StringLiteralExpr></UnknownDecl><UnknownDecl>
var b = /*comment*/<IntegerLiteralExpr>+2/*comment*/</IntegerLiteralExpr></UnknownDecl><UnknownExpr>
bar(<IntegerLiteralExpr>1</IntegerLiteralExpr>)</UnknownExpr><UnknownExpr>
@@ -15,5 +15,5 @@
bar1(<FloatLiteralExpr>-1.1</FloatLiteralExpr>)</UnknownExpr><UnknownExpr>
bar1(<FloatLiteralExpr>1.1</FloatLiteralExpr>)</UnknownExpr><UnknownDecl>
var f = /*comments*/<FloatLiteralExpr>+0.1/*comments*/</FloatLiteralExpr></UnknownDecl>
- }</UnknownDecl>
-}</UnknownDecl></DeclarationStmt>
+ }</CodeBlock></UnknownDecl>
+}</UnknownDecl>
diff --git a/test/decl/protocol/conforms/failure.swift b/test/decl/protocol/conforms/failure.swift
index f61c257..a669f55 100644
--- a/test/decl/protocol/conforms/failure.swift
+++ b/test/decl/protocol/conforms/failure.swift
@@ -100,9 +100,10 @@
init() { } // expected-note 2{{candidate has non-matching type '()'}}
}
+// Type witness cannot have its own generic parameters
// FIXME: Crappy diagnostic
protocol PA {
- associatedtype A // expected-note 2 {{protocol requires nested type 'A'; do you want to add it?}}
+ associatedtype A // expected-note 3 {{protocol requires nested type 'A'; do you want to add it?}}
}
struct BadCase1 : PA { // expected-error {{type 'BadCase1' does not conform to protocol 'PA'}}
@@ -113,6 +114,13 @@
typealias A<T> = T
}
+// Variation on the above
+struct G<T> {}
+
+struct BadCase3 : PA { // expected-error {{type 'BadCase3' does not conform to protocol 'PA'}}
+ typealias A = G
+}
+
// rdar://problem/32215763
extension UInt32: ExpressibleByStringLiteral {}
// expected-error@-1 {{type 'UInt32' does not conform to protocol 'ExpressibleByStringLiteral'}}
diff --git a/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift b/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift
index a9f0963..4fee57d 100644
--- a/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift
+++ b/test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift
@@ -645,3 +645,7 @@
case value
}
}
+
+struct GenericCodableStruct<T : Codable> : Codable {}
+
+func foo(_: GenericCodableStruct<Int>.CodingKeys) // expected-error {{'CodingKeys' is inaccessible due to 'private' protection level}}
diff --git a/test/decl/var/default_init.swift b/test/decl/var/default_init.swift
index 0f28437..d21ee17 100644
--- a/test/decl/var/default_init.swift
+++ b/test/decl/var/default_init.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -typecheck -parse-as-library %s -verify
+// RUN: %target-swift-frontend -typecheck -parse-as-library %s -verify -swift-version 5
// Default initialization of variables.
@@ -38,3 +38,16 @@
var global: Int?
+class NotInitializableOptionalClass { // expected-error{{class 'NotInitializableOptionalClass' has no initializers}}
+ // Do not perform default initialization for properties with explicitly-spelled 'Optional'.
+ var opt: Optional<Int> // expected-note{{stored property 'opt' without initial value prevents synthesized initializers}}
+}
+
+struct NotInitializableOptionalStruct { // expected-note {{'init(opt:)' declared here}}
+ var opt: Optional<Int>
+}
+
+func testBadDefaultInit() {
+ _ = NotInitializableOptionalStruct() // expected-error {{missing argument for parameter 'opt' in call}}
+ _ = NotInitializableOptionalClass() // expected-error {{'NotInitializableOptionalClass' cannot be constructed because it has no accessible initializers}}
+}