Merge pull request #7844 from slavapestov/one-last-cleanup
SILOptimizer: Use the SubstitutionMap form of substGenericArgs()
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 626e2e6..42e442f 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -164,6 +164,9 @@
ERROR(cannot_match_expr_pattern_with_value,none,
"expression pattern of type %0 cannot match values of type %1",
(Type, Type))
+ERROR(cannot_match_unresolved_expr_pattern_with_value,none,
+ "pattern cannot match values of type %0",
+ (Type))
ERROR(cannot_reference_compare_types,none,
"cannot check reference equality of functions; operands here have types "
diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h
index 3c561ce..5100365 100644
--- a/include/swift/AST/Pattern.h
+++ b/include/swift/AST/Pattern.h
@@ -492,7 +492,7 @@
SourceLoc DotLoc;
SourceLoc NameLoc;
Identifier Name;
- EnumElementDecl *ElementDecl;
+ PointerUnion<EnumElementDecl *, Expr*> ElementDeclOrUnresolvedOriginalExpr;
Pattern /*nullable*/ *SubPattern;
public:
@@ -501,10 +501,25 @@
Pattern *SubPattern, Optional<bool> Implicit = None)
: Pattern(PatternKind::EnumElement),
ParentType(ParentType), DotLoc(DotLoc), NameLoc(NameLoc), Name(Name),
- ElementDecl(Element), SubPattern(SubPattern) {
+ ElementDeclOrUnresolvedOriginalExpr(Element),
+ SubPattern(SubPattern) {
if (Implicit.hasValue() && *Implicit)
setImplicit();
}
+
+ /// Create an unresolved EnumElementPattern for a `.foo` pattern relying on
+ /// contextual type.
+ EnumElementPattern(SourceLoc DotLoc,
+ SourceLoc NameLoc,
+ Identifier Name,
+ Pattern *SubPattern,
+ Expr *UnresolvedOriginalExpr)
+ : Pattern(PatternKind::EnumElement),
+ ParentType(), DotLoc(DotLoc), NameLoc(NameLoc), Name(Name),
+ ElementDeclOrUnresolvedOriginalExpr(UnresolvedOriginalExpr),
+ SubPattern(SubPattern) {
+
+ }
bool hasSubPattern() const { return SubPattern; }
@@ -524,8 +539,19 @@
Identifier getName() const { return Name; }
- EnumElementDecl *getElementDecl() const { return ElementDecl; }
- void setElementDecl(EnumElementDecl *d) { ElementDecl = d; }
+ EnumElementDecl *getElementDecl() const {
+ return ElementDeclOrUnresolvedOriginalExpr.dyn_cast<EnumElementDecl*>();
+ }
+ void setElementDecl(EnumElementDecl *d) {
+ ElementDeclOrUnresolvedOriginalExpr = d;
+ }
+
+ Expr *getUnresolvedOriginalExpr() const {
+ return ElementDeclOrUnresolvedOriginalExpr.get<Expr*>();
+ }
+ bool hasUnresolvedOriginalExpr() const {
+ return ElementDeclOrUnresolvedOriginalExpr.is<Expr*>();
+ }
SourceLoc getNameLoc() const { return NameLoc; }
SourceLoc getLoc() const { return NameLoc; }
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index 9e6b638..82a1cee 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -29,6 +29,20 @@
#include <vector>
namespace swift {
+
+ /// Kind of implicit platform conditions.
+ enum class PlatformConditionKind {
+ /// The active os target (OSX, iOS, Linux, etc.)
+ OS,
+ /// The active arch target (x86_64, i386, arm, arm64, etc.)
+ Arch,
+ /// The active endianness target (big or little)
+ Endianness,
+ /// Runtime support (_ObjC or _Native)
+ Runtime,
+ };
+ enum { NumPlatformConditionKind = 4 };
+
/// \brief A collection of options that affect the language dialect and
/// provide compiler debugging facilities.
class LangOptions {
@@ -202,14 +216,9 @@
}
/// Sets an implicit platform condition.
- ///
- /// There are currently three supported platform conditions:
- /// - os: The active os target (OSX or iOS)
- /// - arch: The active arch target (x86_64, i386, arm, arm64)
- /// - _runtime: Runtime support (_ObjC or _Native)
- void addPlatformConditionValue(StringRef Name, StringRef Value) {
- assert(!Name.empty() && !Value.empty());
- PlatformConditionValues.emplace_back(Name, Value);
+ void addPlatformConditionValue(PlatformConditionKind Kind, StringRef Value) {
+ assert(!Value.empty());
+ PlatformConditionValues.emplace_back(Kind, Value);
}
/// Removes all values added with addPlatformConditionValue.
@@ -218,7 +227,7 @@
}
/// Returns the value for the given platform condition or an empty string.
- StringRef getPlatformConditionValue(StringRef Name) const;
+ StringRef getPlatformConditionValue(PlatformConditionKind Kind) const;
/// Explicit conditional compilation flags, initialized via the '-D'
/// compiler flag.
@@ -230,7 +239,7 @@
/// Determines if a given conditional compilation flag has been set.
bool isCustomConditionalCompilationFlagSet(StringRef Name) const;
- ArrayRef<std::pair<std::string, std::string>>
+ ArrayRef<std::pair<PlatformConditionKind, std::string>>
getPlatformConditionValues() const {
return PlatformConditionValues;
}
@@ -244,35 +253,18 @@
return EffectiveLanguageVersion.isVersion3();
}
- /// Returns true if the 'os' platform condition argument represents
+ /// Returns true if the given platform condition argument represents
/// a supported target operating system.
///
- /// Note that this also canonicalizes the OS name if the check returns
- /// true.
- ///
/// \param suggestions Populated with suggested replacements
/// if a match is not found.
- static bool checkPlatformConditionOS(
- StringRef &OSName, std::vector<StringRef> &suggestions);
-
- /// Returns true if the 'arch' platform condition argument represents
- /// a supported target architecture.
- ///
- /// \param suggestions Populated with suggested replacements
- /// if a match is not found.
- static bool isPlatformConditionArchSupported(
- StringRef ArchName, std::vector<StringRef> &suggestions);
-
- /// Returns true if the 'endian' platform condition argument represents
- /// a supported target endianness.
- ///
- /// \param suggestions Populated with suggested replacements
- /// if a match is not found.
- static bool isPlatformConditionEndiannessSupported(
- StringRef endianness, std::vector<StringRef> &suggestions);
+ static bool checkPlatformConditionSupported(
+ PlatformConditionKind Kind, StringRef Value,
+ std::vector<StringRef> &suggestions);
private:
- llvm::SmallVector<std::pair<std::string, std::string>, 3>
+ llvm::SmallVector<std::pair<PlatformConditionKind, std::string>,
+ NumPlatformConditionKind>
PlatformConditionValues;
llvm::SmallVector<std::string, 2> CustomConditionalCompilationFlags;
};
diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp
index 19efc63..93ec8a9 100644
--- a/lib/Basic/LangOptions.cpp
+++ b/lib/Basic/LangOptions.cpp
@@ -52,6 +52,11 @@
"big"
};
+static const StringRef SupportedConditionalCompilationRuntimes[] = {
+ "_ObjC",
+ "_Native",
+};
+
template <size_t N>
bool contains(const StringRef (&Array)[N], const StringRef &V,
std::vector<StringRef> &suggestions) {
@@ -75,36 +80,31 @@
return false;
}
-bool LangOptions::checkPlatformConditionOS(
- StringRef &OSName, std::vector<StringRef> &suggestions) {
- if (OSName == "macOS")
- OSName = "OSX";
- return contains(SupportedConditionalCompilationOSs,
- OSName,
- suggestions);
-}
-
-bool
-LangOptions::isPlatformConditionArchSupported(
- StringRef ArchName, std::vector<StringRef> &suggestions) {
- return contains(SupportedConditionalCompilationArches,
- ArchName,
- suggestions);
-}
-
-bool
-LangOptions::isPlatformConditionEndiannessSupported(
- StringRef Endianness, std::vector<StringRef> &suggestions) {
- return contains(SupportedConditionalCompilationEndianness,
- Endianness,
- suggestions);
+bool LangOptions::
+checkPlatformConditionSupported(PlatformConditionKind Kind, StringRef Value,
+ std::vector<StringRef> &suggestions) {
+ switch (Kind) {
+ case PlatformConditionKind::OS:
+ return contains(SupportedConditionalCompilationOSs, Value,
+ suggestions);
+ case PlatformConditionKind::Arch:
+ return contains(SupportedConditionalCompilationArches, Value,
+ suggestions);
+ case PlatformConditionKind::Endianness:
+ return contains(SupportedConditionalCompilationEndianness, Value,
+ suggestions);
+ case PlatformConditionKind::Runtime:
+ return contains(SupportedConditionalCompilationRuntimes, Value,
+ suggestions);
+ }
+ llvm_unreachable("Unhandled enum value");
}
StringRef
-LangOptions::getPlatformConditionValue(StringRef Name) const {
+LangOptions::getPlatformConditionValue(PlatformConditionKind Kind) const {
// Last one wins.
for (auto &Opt : reversed(PlatformConditionValues)) {
- if (Opt.first == Name)
+ if (Opt.first == Kind)
return Opt.second;
}
return StringRef();
@@ -141,23 +141,23 @@
// Set the "os" platform condition.
if (Target.isMacOSX())
- addPlatformConditionValue("os", "OSX");
+ addPlatformConditionValue(PlatformConditionKind::OS, "OSX");
else if (triple.isTvOS())
- addPlatformConditionValue("os", "tvOS");
+ addPlatformConditionValue(PlatformConditionKind::OS, "tvOS");
else if (triple.isWatchOS())
- addPlatformConditionValue("os", "watchOS");
+ addPlatformConditionValue(PlatformConditionKind::OS, "watchOS");
else if (triple.isiOS())
- addPlatformConditionValue("os", "iOS");
+ addPlatformConditionValue(PlatformConditionKind::OS, "iOS");
else if (triple.isAndroid())
- addPlatformConditionValue("os", "Android");
+ addPlatformConditionValue(PlatformConditionKind::OS, "Android");
else if (triple.isOSLinux())
- addPlatformConditionValue("os", "Linux");
+ addPlatformConditionValue(PlatformConditionKind::OS, "Linux");
else if (triple.isOSFreeBSD())
- addPlatformConditionValue("os", "FreeBSD");
+ addPlatformConditionValue(PlatformConditionKind::OS, "FreeBSD");
else if (triple.isOSWindows())
- addPlatformConditionValue("os", "Windows");
+ addPlatformConditionValue(PlatformConditionKind::OS, "Windows");
else if (triple.isPS4())
- addPlatformConditionValue("os", "PS4");
+ addPlatformConditionValue(PlatformConditionKind::OS, "PS4");
else
UnsupportedOS = true;
@@ -167,25 +167,25 @@
switch (Target.getArch()) {
case llvm::Triple::ArchType::arm:
case llvm::Triple::ArchType::thumb:
- addPlatformConditionValue("arch", "arm");
+ addPlatformConditionValue(PlatformConditionKind::Arch, "arm");
break;
case llvm::Triple::ArchType::aarch64:
- addPlatformConditionValue("arch", "arm64");
+ addPlatformConditionValue(PlatformConditionKind::Arch, "arm64");
break;
case llvm::Triple::ArchType::ppc64:
- addPlatformConditionValue("arch", "powerpc64");
+ addPlatformConditionValue(PlatformConditionKind::Arch, "powerpc64");
break;
case llvm::Triple::ArchType::ppc64le:
- addPlatformConditionValue("arch", "powerpc64le");
+ addPlatformConditionValue(PlatformConditionKind::Arch, "powerpc64le");
break;
case llvm::Triple::ArchType::x86:
- addPlatformConditionValue("arch", "i386");
+ addPlatformConditionValue(PlatformConditionKind::Arch, "i386");
break;
case llvm::Triple::ArchType::x86_64:
- addPlatformConditionValue("arch", "x86_64");
+ addPlatformConditionValue(PlatformConditionKind::Arch, "x86_64");
break;
case llvm::Triple::ArchType::systemz:
- addPlatformConditionValue("arch", "s390x");
+ addPlatformConditionValue(PlatformConditionKind::Arch, "s390x");
break;
default:
UnsupportedArch = true;
@@ -198,25 +198,25 @@
switch (Target.getArch()) {
case llvm::Triple::ArchType::arm:
case llvm::Triple::ArchType::thumb:
- addPlatformConditionValue("_endian", "little");
+ addPlatformConditionValue(PlatformConditionKind::Endianness, "little");
break;
case llvm::Triple::ArchType::aarch64:
- addPlatformConditionValue("_endian", "little");
+ addPlatformConditionValue(PlatformConditionKind::Endianness, "little");
break;
case llvm::Triple::ArchType::ppc64:
- addPlatformConditionValue("_endian", "big");
+ addPlatformConditionValue(PlatformConditionKind::Endianness, "big");
break;
case llvm::Triple::ArchType::ppc64le:
- addPlatformConditionValue("_endian", "little");
+ addPlatformConditionValue(PlatformConditionKind::Endianness, "little");
break;
case llvm::Triple::ArchType::x86:
- addPlatformConditionValue("_endian", "little");
+ addPlatformConditionValue(PlatformConditionKind::Endianness, "little");
break;
case llvm::Triple::ArchType::x86_64:
- addPlatformConditionValue("_endian", "little");
+ addPlatformConditionValue(PlatformConditionKind::Endianness, "little");
break;
case llvm::Triple::ArchType::systemz:
- addPlatformConditionValue("_endian", "big");
+ addPlatformConditionValue(PlatformConditionKind::Endianness, "big");
break;
default:
llvm_unreachable("undefined architecture endianness");
@@ -224,9 +224,9 @@
// Set the "runtime" platform condition.
if (EnableObjCInterop)
- addPlatformConditionValue("_runtime", "_ObjC");
+ addPlatformConditionValue(PlatformConditionKind::Runtime, "_ObjC");
else
- addPlatformConditionValue("_runtime", "_Native");
+ addPlatformConditionValue(PlatformConditionKind::Runtime, "_Native");
// If you add anything to this list, change the default size of
// PlatformConditionValues to not require an extra allocation
diff --git a/lib/Parse/ParseIfConfig.cpp b/lib/Parse/ParseIfConfig.cpp
index a106f48..f6c064d 100644
--- a/lib/Parse/ParseIfConfig.cpp
+++ b/lib/Parse/ParseIfConfig.cpp
@@ -16,8 +16,10 @@
#include "swift/Parse/Parser.h"
#include "swift/Basic/Defer.h"
+#include "swift/Basic/LangOptions.h"
#include "swift/Basic/Version.h"
#include "swift/Parse/Lexer.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -356,51 +358,46 @@
// tolerate extra parens).
auto argumentIdent = UDRE->getName().getBaseName();
auto argument = argumentIdent.str();
-
- // Error for values that don't make sense if there's a clear definition
- // of the possible values (as there is for _runtime).
- if (fnName.equals("_runtime") &&
- !argument.equals("_ObjC") && !argument.equals("_Native")) {
- D.diagnose(CE->getLoc(),
- diag::unsupported_platform_runtime_condition_argument);
- return ConditionalCompilationExprState::error();
- }
-
- std::vector<StringRef> suggestions;
- SWIFT_DEFER {
- for (const StringRef& suggestion : suggestions) {
- D.diagnose(UDRE->getLoc(), diag::note_typo_candidate,
- suggestion)
- .fixItReplace(UDRE->getSourceRange(), suggestion);
- }
- };
- if (fnName == "os") {
- if (!LangOptions::checkPlatformConditionOS(argument,
- suggestions)) {
- D.diagnose(UDRE->getLoc(), diag::unknown_platform_condition_argument,
- "operating system", fnName);
- return ConditionalCompilationExprState::error();
- }
- } else if (fnName == "arch") {
- if (!LangOptions::isPlatformConditionArchSupported(argument,
- suggestions)) {
- D.diagnose(UDRE->getLoc(), diag::unknown_platform_condition_argument,
- "architecture", fnName);
- return ConditionalCompilationExprState::error();
- }
- } else if (fnName == "_endian") {
- if (!LangOptions::isPlatformConditionEndiannessSupported(argument,
- suggestions)) {
- D.diagnose(UDRE->getLoc(), diag::unknown_platform_condition_argument,
- "endianness", fnName);
- }
- }
+ PlatformConditionKind Kind =
+ llvm::StringSwitch<PlatformConditionKind>(fnName)
+ .Case("os", PlatformConditionKind::OS)
+ .Case("arch", PlatformConditionKind::Arch)
+ .Case("_endian", PlatformConditionKind::Endianness)
+ .Case("_runtime", PlatformConditionKind::Runtime);
// FIXME: Perform the replacement macOS -> OSX elsewhere.
- if (fnName == "os" && argument == "macOS")
+ if (Kind == PlatformConditionKind::OS && argument == "macOS")
argument = "OSX";
- auto target = Context.LangOpts.getPlatformConditionValue(fnName);
+ std::vector<StringRef> suggestions;
+ if (!LangOptions::checkPlatformConditionSupported(Kind, argument,
+ suggestions)) {
+ if (Kind == PlatformConditionKind::Runtime) {
+ // Error for _runtime()
+ D.diagnose(UDRE->getLoc(),
+ diag::unsupported_platform_runtime_condition_argument);
+ return ConditionalCompilationExprState::error();
+ }
+ StringRef DiagName;
+ switch (Kind) {
+ case PlatformConditionKind::OS:
+ DiagName = "operating system"; break;
+ case PlatformConditionKind::Arch:
+ DiagName = "architecture"; break;
+ case PlatformConditionKind::Endianness:
+ DiagName = "endianness"; break;
+ case PlatformConditionKind::Runtime:
+ llvm_unreachable("handled above");
+ }
+ D.diagnose(UDRE->getLoc(), diag::unknown_platform_condition_argument,
+ DiagName, fnName);
+ for (const StringRef &suggestion : suggestions) {
+ D.diagnose(UDRE->getLoc(), diag::note_typo_candidate, suggestion)
+ .fixItReplace(UDRE->getSourceRange(), suggestion);
+ }
+ }
+
+ auto target = Context.LangOpts.getPlatformConditionValue(Kind);
return {target == argument, ConditionalCompilationExprKind::DeclRef};
} else {
D.diagnose(CE->getLoc(), diag::unsupported_platform_condition_argument,
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index de33fab..4f27b76 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -3495,11 +3495,13 @@
Expr *visitUnresolvedPatternExpr(UnresolvedPatternExpr *expr) {
// If we end up here, we should have diagnosed somewhere else
// already.
- if (!SuppressDiagnostics) {
- cs.TC.diagnose(expr->getLoc(), diag::pattern_in_expr,
+ Expr *simplified = simplifyExprType(expr);
+ if (!SuppressDiagnostics
+ && !simplified->getType()->is<UnresolvedType>()) {
+ cs.TC.diagnose(simplified->getLoc(), diag::pattern_in_expr,
expr->getSubPattern()->getKind());
}
- return expr;
+ return simplified;
}
Expr *visitBindOptionalExpr(BindOptionalExpr *expr) {
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index ba8e396..1730ae3 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -6077,9 +6077,13 @@
if (callExpr->isImplicit() && overloadName == "~=") {
// This binop was synthesized when typechecking an expression pattern.
- auto diag = diagnose(lhsExpr->getLoc(),
- diag::cannot_match_expr_pattern_with_value,
- lhsType, rhsType);
+ auto diag = lhsType->is<UnresolvedType>()
+ ? diagnose(lhsExpr->getLoc(),
+ diag::cannot_match_unresolved_expr_pattern_with_value,
+ rhsType)
+ : diagnose(lhsExpr->getLoc(),
+ diag::cannot_match_expr_pattern_with_value,
+ lhsType, rhsType);
diag.highlight(lhsExpr->getSourceRange());
diag.highlight(rhsExpr->getSourceRange());
if (auto optUnwrappedType = rhsType->getOptionalObjectType()) {
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index f50c194..f84b7dd 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -2670,8 +2670,13 @@
Type visitUnresolvedPatternExpr(UnresolvedPatternExpr *expr) {
// If there are UnresolvedPatterns floating around after name binding,
- // they are pattern productions in invalid positions.
- return ErrorType::get(CS.getASTContext());
+ // they are pattern productions in invalid positions. However, we will
+ // diagnose that condition elsewhere; to avoid unnecessary noise errors,
+ // just plop an open type variable here.
+
+ auto locator = CS.getConstraintLocator(expr);
+ auto typeVar = CS.createTypeVariable(locator, TVO_CanBindToLValue);
+ return typeVar;
}
/// Get the type T?
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 0a3131e..b2fa7ec 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -394,7 +394,7 @@
// Unresolved member syntax '.Element' forms an EnumElement pattern. The
// element will be resolved when we type-check the pattern.
Pattern *visitUnresolvedMemberExpr(UnresolvedMemberExpr *ume) {
- // We the unresolved member has an argument, turn it into a subpattern.
+ // If the unresolved member has an argument, turn it into a subpattern.
Pattern *subPattern = nullptr;
if (auto arg = ume->getArgument()) {
subPattern = getSubExprPattern(arg);
@@ -402,11 +402,11 @@
// FIXME: Compound names.
return new (TC.Context) EnumElementPattern(
- TypeLoc(), ume->getDotLoc(),
+ ume->getDotLoc(),
ume->getNameLoc().getBaseNameLoc(),
ume->getName().getBaseName(),
- nullptr,
- subPattern);
+ subPattern,
+ ume);
}
// Member syntax 'T.Element' forms a pattern if 'T' is an enum and the
@@ -1004,6 +1004,7 @@
TypeResolutionOptions options,
GenericTypeResolver *resolver,
TypeLoc tyLoc) {
+recur:
if (tyLoc.isNull()) {
tyLoc = TypeLoc::withoutLoc(type);
}
@@ -1377,6 +1378,14 @@
return true;
}
+
+ // If we have the original expression parse tree, try reinterpreting
+ // it as an expr-pattern if enum element lookup failed, since `.foo`
+ // could also refer to a static member of the context type.
+ } else if (EEP->hasUnresolvedOriginalExpr()) {
+ P = new (Context) ExprPattern(EEP->getUnresolvedOriginalExpr(),
+ nullptr, nullptr);
+ goto recur;
}
diagnose(EEP->getLoc(), diag::enum_element_pattern_member_not_found,
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index dc0d4ac..f193f73 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -96,7 +96,7 @@
// FIXME: Which name should we be using here? Do we care about CPU subtypes?
// FIXME: At the very least, don't hardcode "arch".
llvm::SmallString<16> archFile{
- ctx.LangOpts.getPlatformConditionValue("arch")};
+ ctx.LangOpts.getPlatformConditionValue(PlatformConditionKind::Arch)};
llvm::SmallString<16> archDocFile{archFile};
if (!archFile.empty()) {
archFile += '.';
diff --git a/test/Constraints/patterns.swift b/test/Constraints/patterns.swift
index 3b07ff8..1183a45 100644
--- a/test/Constraints/patterns.swift
+++ b/test/Constraints/patterns.swift
@@ -114,7 +114,8 @@
()
case Watch.Edition: // TODO: should warn that cast can't succeed with currently known conformances
()
-case .HairForceOne: // expected-error{{enum case 'HairForceOne' not found in type 'HairType'}}
+// TODO: Bad error message
+case .HairForceOne: // expected-error{{cannot convert}}
()
default:
break
@@ -254,3 +255,53 @@
if case let doesNotExist as SomeClass:AlsoDoesNotExist {}
// expected-error@-1 {{use of undeclared type 'AlsoDoesNotExist'}}
// expected-error@-2 {{variable binding in a condition requires an initializer}}
+
+// `.foo` and `.bar(...)` pattern syntax should also be able to match
+// static members as expr patterns
+
+struct StaticMembers: Equatable {
+ init() {}
+ init(_: Int) {}
+ init?(opt: Int) {}
+ static var prop = StaticMembers()
+ static var optProp: Optional = StaticMembers()
+
+ static func method(_: Int) -> StaticMembers { return prop }
+ static func method(withLabel: Int) -> StaticMembers { return prop }
+ static func optMethod(_: Int) -> StaticMembers? { return optProp }
+
+ static func ==(x: StaticMembers, y: StaticMembers) -> Bool { return true }
+}
+
+let staticMembers = StaticMembers()
+let optStaticMembers: Optional = StaticMembers()
+
+switch staticMembers {
+ case .init: break // expected-error{{cannot match values of type 'StaticMembers'}}
+ case .init(opt:): break // expected-error{{cannot match values of type 'StaticMembers'}}
+ case .init(): break
+
+ case .init(0): break
+ case .init(_): break // expected-error{{'_' can only appear in a pattern}}
+ case .init(let x): break // expected-error{{cannot appear in an expression}}
+ case .init(opt: 0): break // expected-error{{not unwrapped}}
+
+ case .prop: break
+ // TODO: repeated error message
+ case .optProp: break // expected-error* {{not unwrapped}}
+
+ case .method: break // expected-error{{cannot match}}
+ case .method(0): break
+ case .method(_): break // expected-error{{'_' can only appear in a pattern}}
+ case .method(let x): break // expected-error{{cannot appear in an expression}}
+
+ case .method(withLabel:): break // expected-error{{cannot match}}
+ case .method(withLabel: 0): break
+ case .method(withLabel: _): break // expected-error{{'_' can only appear in a pattern}}
+ case .method(withLabel: let x): break // expected-error{{cannot appear in an expression}}
+
+ case .optMethod: break // expected-error{{cannot match}}
+ case .optMethod(0): break // expected-error{{not unwrapped}}
+}
+
+_ = 0
diff --git a/test/Parse/matching_patterns.swift b/test/Parse/matching_patterns.swift
index d7766ec..57dd399 100644
--- a/test/Parse/matching_patterns.swift
+++ b/test/Parse/matching_patterns.swift
@@ -100,7 +100,7 @@
}
switch foo {
- case .Naught: // expected-error{{enum case 'Naught' not found in type 'Foo'}}
+ case .Naught: // expected-error{{pattern cannot match values of type 'Foo'}}
()
case .A, .B, .C:
()
@@ -137,7 +137,7 @@
var notAnEnum = 0
switch notAnEnum {
-case .Foo: // expected-error{{enum case 'Foo' not found in type 'Int'}}
+case .Foo: // expected-error{{pattern cannot match values of type 'Int'}}
()
}
@@ -264,10 +264,8 @@
// expected-error@-1{{'+++' is not a prefix unary operator}}
()
case (_, var e, 3) +++ (1, 2, 3):
-// expected-error@-1{{binary operator '+++' cannot be applied to operands of type '(_, <<error type>>, Int)' and '(Int, Int, Int)'}}
-// expected-note@-2{{expected an argument list of type '((Int, Int, Int), (Int, Int, Int))'}}
-// expected-error@-3{{'var' binding pattern cannot appear in an expression}}
-// expected-error@-4{{'var' binding pattern cannot appear in an expression}}
+// expected-error@-1{{'_' can only appear in a pattern}}
+// expected-error@-2{{'var' binding pattern cannot appear in an expression}}
()
}
diff --git a/test/Parse/switch.swift b/test/Parse/switch.swift
index 6741c3b..7e2b81ae 100644
--- a/test/Parse/switch.swift
+++ b/test/Parse/switch.swift
@@ -264,7 +264,7 @@
func enumElementSyntaxOnTuple() {
switch (1, 1) {
- case .Bar: // expected-error {{enum case 'Bar' not found in type '(Int, Int)'}}
+ case .Bar: // expected-error {{pattern cannot match values of type '(Int, Int)'}}
break
default:
break
diff --git a/test/stmt/statements.swift b/test/stmt/statements.swift
index b33944c..f927ee7 100644
--- a/test/stmt/statements.swift
+++ b/test/stmt/statements.swift
@@ -247,7 +247,7 @@
func brokenSwitch(_ x: Int) -> Int {
switch x {
- case .Blah(var rep): // expected-error{{enum case 'Blah' not found in type 'Int'}}
+ case .Blah(var rep): // expected-error{{pattern cannot match values of type 'Int'}}
return rep
}
}
diff --git a/validation-test/compiler_crashers_fixed/28445-gp-getouterparameters-proto-getdeclcontext-getgenericparamsofcontext-failed.swift b/validation-test/compiler_crashers_fixed/28445-gp-getouterparameters-proto-getdeclcontext-getgenericparamsofcontext-failed.swift
index 8b4bedd..18fddac 100644
--- a/validation-test/compiler_crashers_fixed/28445-gp-getouterparameters-proto-getdeclcontext-getgenericparamsofcontext-failed.swift
+++ b/validation-test/compiler_crashers_fixed/28445-gp-getouterparameters-proto-getdeclcontext-getgenericparamsofcontext-failed.swift
@@ -8,6 +8,7 @@
// RUN: not %target-swift-frontend %s -emit-ir
// FIXME(huonw): where clauses on associatedtypes broke this
// XFAIL: *
+// REQUIRES: asserts
class A{let f= <c
protocol A{
typealias e:A{}
diff --git a/validation-test/compiler_crashers_fixed/28547-env-dependent-type-in-non-generic-context.swift b/validation-test/compiler_crashers_fixed/28547-env-dependent-type-in-non-generic-context.swift
index 999e950..d8533f9 100644
--- a/validation-test/compiler_crashers_fixed/28547-env-dependent-type-in-non-generic-context.swift
+++ b/validation-test/compiler_crashers_fixed/28547-env-dependent-type-in-non-generic-context.swift
@@ -8,5 +8,6 @@
// RUN: not %target-swift-frontend %s -emit-ir
// FIXME(huonw): where clauses on associatedtypes broke this
// XFAIL: *
+// REQUIRES: asserts
class A:a
protocol a{typealias B:A.B