Skip to content

Commit 94d8fac

Browse files
authored
Merge pull request #65348 from hamishknight/platypus-party-5.9
2 parents 5afa437 + 7611705 commit 94d8fac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+963
-466
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ ERROR(cannot_match_expr_tuple_pattern_with_nontuple_value,none,
197197
ERROR(cannot_match_unresolved_expr_pattern_with_value,none,
198198
"pattern cannot match values of type %0",
199199
(Type))
200+
ERROR(cannot_match_value_with_pattern,none,
201+
"pattern of type %1 cannot match %0",
202+
(Type, Type))
200203

201204
ERROR(cannot_reference_compare_types,none,
202205
"cannot check reference equality of functions; operands here have types "

include/swift/AST/Types.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,14 @@ class RecursiveTypeProperties {
173173
/// This type contains an ElementArchetype.
174174
HasElementArchetype = 0x4000,
175175

176+
/// Whether the type is allocated in the constraint solver arena. This can
177+
/// differ from \c HasTypeVariable for types such as placeholders, which do
178+
/// not have type variables, but we still want to allocate in the solver if
179+
/// they have a type variable originator.
180+
SolverAllocated = 0x8000,
181+
176182
/// This type contains a concrete pack.
177-
HasConcretePack = 0x8000,
183+
HasConcretePack = 0x10000,
178184

179185
Last_Property = HasConcretePack
180186
};
@@ -227,6 +233,12 @@ class RecursiveTypeProperties {
227233
/// opened element archetype?
228234
bool hasElementArchetype() const { return Bits & HasElementArchetype; }
229235

236+
/// Whether the type is allocated in the constraint solver arena. This can
237+
/// differ from \c hasTypeVariable() for types such as placeholders, which
238+
/// do not have type variables, but we still want to allocate in the solver if
239+
/// they have a type variable originator.
240+
bool isSolverAllocated() const { return Bits & SolverAllocated; }
241+
230242
/// Does a type with these properties structurally contain a local
231243
/// archetype?
232244
bool hasLocalArchetype() const {
@@ -405,12 +417,12 @@ class alignas(1 << TypeAlignInBits) TypeBase
405417
NumProtocols : 16
406418
);
407419

408-
SWIFT_INLINE_BITFIELD_FULL(TypeVariableType, TypeBase, 7+31,
420+
SWIFT_INLINE_BITFIELD_FULL(TypeVariableType, TypeBase, 7+30,
409421
/// Type variable options.
410422
Options : 7,
411423
: NumPadBits,
412424
/// The unique number assigned to this type variable.
413-
ID : 31
425+
ID : 30
414426
);
415427

416428
SWIFT_INLINE_BITFIELD(SILFunctionType, TypeBase, NumSILExtInfoBits+1+4+1+2+1+1,
@@ -506,6 +518,8 @@ class alignas(1 << TypeAlignInBits) TypeBase
506518
}
507519

508520
void setRecursiveProperties(RecursiveTypeProperties properties) {
521+
assert(!(properties.hasTypeVariable() && !properties.isSolverAllocated()) &&
522+
"type variables must be solver allocated!");
509523
Bits.TypeBase.Properties = properties.getBits();
510524
assert(Bits.TypeBase.Properties == properties.getBits() && "Bits dropped!");
511525
}
@@ -6733,8 +6747,9 @@ TypeVariableType : public TypeBase {
67336747
// type is opaque.
67346748

67356749
TypeVariableType(const ASTContext &C, unsigned ID)
6736-
: TypeBase(TypeKind::TypeVariable, &C,
6737-
RecursiveTypeProperties::HasTypeVariable) {
6750+
: TypeBase(TypeKind::TypeVariable, &C,
6751+
RecursiveTypeProperties::HasTypeVariable |
6752+
RecursiveTypeProperties::SolverAllocated) {
67386753
// Note: the ID may overflow (current limit is 2^20 - 1).
67396754
Bits.TypeVariableType.ID = ID;
67406755
if (Bits.TypeVariableType.ID != ID) {
@@ -6793,6 +6808,8 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(TypeVariableType, Type)
67936808
/// because the expression is ambiguous. This type is only used by the
67946809
/// constraint solver and transformed into UnresolvedType to be used in AST.
67956810
class PlaceholderType : public TypeBase {
6811+
// NOTE: If you add a new Type-based originator, you'll need to update the
6812+
// recursive property logic in PlaceholderType::get.
67966813
using Originator =
67976814
llvm::PointerUnion<TypeVariableType *, DependentMemberType *, VarDecl *,
67986815
ErrorExpr *, PlaceholderTypeRepr *>;

include/swift/Sema/CSFix.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,9 @@ enum class FixKind : uint8_t {
401401
/// Produce a warning for a tuple label mismatch.
402402
AllowTupleLabelMismatch,
403403

404+
/// Allow an associated value mismatch for an enum element pattern.
405+
AllowAssociatedValueMismatch,
406+
404407
/// Produce an error for not getting a compile-time constant
405408
NotCompileTimeConst,
406409

@@ -3241,6 +3244,28 @@ class AllowTupleLabelMismatch final : public ContextualMismatch {
32413244
}
32423245
};
32433246

3247+
class AllowAssociatedValueMismatch final : public ContextualMismatch {
3248+
AllowAssociatedValueMismatch(ConstraintSystem &cs, Type fromType, Type toType,
3249+
ConstraintLocator *locator)
3250+
: ContextualMismatch(cs, FixKind::AllowAssociatedValueMismatch, fromType,
3251+
toType, locator) {}
3252+
3253+
public:
3254+
std::string getName() const override {
3255+
return "allow associated value mismatch";
3256+
}
3257+
3258+
bool diagnose(const Solution &solution, bool asNote = false) const override;
3259+
3260+
static AllowAssociatedValueMismatch *create(ConstraintSystem &cs,
3261+
Type fromType, Type toType,
3262+
ConstraintLocator *locator);
3263+
3264+
static bool classof(const ConstraintFix *fix) {
3265+
return fix->getKind() == FixKind::AllowAssociatedValueMismatch;
3266+
}
3267+
};
3268+
32443269
class AllowNonOptionalWeak final : public ConstraintFix {
32453270
AllowNonOptionalWeak(ConstraintSystem &cs, ConstraintLocator *locator)
32463271
: ConstraintFix(cs, FixKind::AllowNonOptionalWeak, locator) {}

include/swift/Sema/CompletionContextFinder.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
namespace swift {
2222

23+
namespace constraints {
24+
class SyntacticElementTarget;
25+
}
26+
2327
class CompletionContextFinder : public ASTWalker {
2428
enum class ContextKind {
2529
FallbackExpression,
@@ -53,12 +57,9 @@ class CompletionContextFinder : public ASTWalker {
5357
return MacroWalking::Arguments;
5458
}
5559

56-
/// Finder for completion contexts within the provided initial expression.
57-
CompletionContextFinder(ASTNode initialNode, DeclContext *DC)
58-
: InitialExpr(initialNode.dyn_cast<Expr *>()), InitialDC(DC) {
59-
assert(DC);
60-
initialNode.walk(*this);
61-
};
60+
/// Finder for completion contexts within the provided SyntacticElementTarget.
61+
CompletionContextFinder(constraints::SyntacticElementTarget target,
62+
DeclContext *DC);
6263

6364
/// Finder for completion contexts within the outermost non-closure context of
6465
/// the code completion expression's direct context.

include/swift/Sema/ConstraintLocator.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818
#ifndef SWIFT_SEMA_CONSTRAINTLOCATOR_H
1919
#define SWIFT_SEMA_CONSTRAINTLOCATOR_H
2020

21-
#include "swift/Basic/Debug.h"
22-
#include "swift/Basic/LLVM.h"
2321
#include "swift/AST/ASTNode.h"
2422
#include "swift/AST/Type.h"
2523
#include "swift/AST/Types.h"
24+
#include "swift/Basic/Debug.h"
25+
#include "swift/Basic/LLVM.h"
26+
#include "swift/Basic/NullablePtr.h"
2627
#include "llvm/ADT/ArrayRef.h"
2728
#include "llvm/ADT/FoldingSet.h"
2829
#include "llvm/ADT/PointerIntPair.h"
@@ -313,6 +314,13 @@ class ConstraintLocator : public llvm::FoldingSetNode {
313314
/// branch, and if so, the kind of branch.
314315
Optional<SingleValueStmtBranchKind> isForSingleValueStmtBranch() const;
315316

317+
/// If the locator in question is for a pattern match, returns the pattern,
318+
/// otherwise \c nullptr.
319+
NullablePtr<Pattern> getPatternMatch() const;
320+
321+
/// Whether the locator in question is for a pattern match.
322+
bool isForPatternMatch() const;
323+
316324
/// Returns true if \p locator is ending with either of the following
317325
/// - Member
318326
/// - Member -> KeyPathDynamicMember

include/swift/Sema/ConstraintLocatorPathElts.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ CUSTOM_LOCATOR_PATH_ELT(TernaryBranch)
225225
/// Performing a pattern patch.
226226
CUSTOM_LOCATOR_PATH_ELT(PatternMatch)
227227

228+
/// The constraint that models the allowed implicit casts for
229+
/// an EnumElementPattern.
230+
SIMPLE_LOCATOR_PATH_ELT(EnumPatternImplicitCastMatch)
231+
228232
/// Points to a particular attribute associated with one of
229233
/// the arguments e.g. `inout` or its type e.g. `@escaping`.
230234
///

include/swift/Sema/ConstraintSystem.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,10 @@ class Solution {
15001500
llvm::SmallMapVector<const CaseLabelItem *, CaseLabelItemInfo, 4>
15011501
caseLabelItems;
15021502

1503+
/// A map of expressions to the ExprPatterns that they are being solved as
1504+
/// a part of.
1505+
llvm::SmallMapVector<Expr *, ExprPattern *, 2> exprPatterns;
1506+
15031507
/// The set of parameters that have been inferred to be 'isolated'.
15041508
llvm::SmallVector<ParamDecl *, 2> isolatedParams;
15051509

@@ -1685,6 +1689,16 @@ class Solution {
16851689
: nullptr;
16861690
}
16871691

1692+
/// Retrieve the solved ExprPattern that corresponds to provided
1693+
/// sub-expression.
1694+
NullablePtr<ExprPattern> getExprPatternFor(Expr *E) const {
1695+
auto result = exprPatterns.find(E);
1696+
if (result == exprPatterns.end())
1697+
return nullptr;
1698+
1699+
return result->second;
1700+
}
1701+
16881702
/// This method implements functionality of `Expr::isTypeReference`
16891703
/// with data provided by a given solution.
16901704
bool isTypeReference(Expr *E) const;
@@ -2148,6 +2162,10 @@ class ConstraintSystem {
21482162
llvm::SmallMapVector<const CaseLabelItem *, CaseLabelItemInfo, 4>
21492163
caseLabelItems;
21502164

2165+
/// A map of expressions to the ExprPatterns that they are being solved as
2166+
/// a part of.
2167+
llvm::SmallMapVector<Expr *, ExprPattern *, 2> exprPatterns;
2168+
21512169
/// The set of parameters that have been inferred to be 'isolated'.
21522170
llvm::SmallSetVector<ParamDecl *, 2> isolatedParams;
21532171

@@ -2745,6 +2763,9 @@ class ConstraintSystem {
27452763
/// The length of \c caseLabelItems.
27462764
unsigned numCaseLabelItems;
27472765

2766+
/// The length of \c exprPatterns.
2767+
unsigned numExprPatterns;
2768+
27482769
/// The length of \c isolatedParams.
27492770
unsigned numIsolatedParams;
27502771

@@ -3166,6 +3187,15 @@ class ConstraintSystem {
31663187
caseLabelItems[item] = info;
31673188
}
31683189

3190+
/// Record a given ExprPattern as the parent of its sub-expression.
3191+
void setExprPatternFor(Expr *E, ExprPattern *EP) {
3192+
assert(E);
3193+
assert(EP);
3194+
auto inserted = exprPatterns.insert({E, EP}).second;
3195+
assert(inserted && "Mapping already defined?");
3196+
(void)inserted;
3197+
}
3198+
31693199
Optional<CaseLabelItemInfo> getCaseLabelItemInfo(
31703200
const CaseLabelItem *item) const {
31713201
auto known = caseLabelItems.find(item);
@@ -4315,6 +4345,11 @@ class ConstraintSystem {
43154345
/// \returns \c true if constraint generation failed, \c false otherwise
43164346
bool generateConstraints(SingleValueStmtExpr *E);
43174347

4348+
/// Generate constraints for an array of ExprPatterns, forming a conjunction
4349+
/// that solves each expression in turn.
4350+
void generateConstraints(ArrayRef<ExprPattern *> exprPatterns,
4351+
ConstraintLocatorBuilder locator);
4352+
43184353
/// Generate constraints for the given (unchecked) expression.
43194354
///
43204355
/// \returns a possibly-sanitized expression, or null if an error occurred.

lib/AST/ASTContext.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ struct ASTContext::Implementation {
432432
llvm::DenseMap<Type, InOutType*> InOutTypes;
433433
llvm::DenseMap<std::pair<Type, void*>, DependentMemberType *>
434434
DependentMemberTypes;
435+
llvm::DenseMap<void *, PlaceholderType *> PlaceholderTypes;
435436
llvm::DenseMap<Type, DynamicSelfType *> DynamicSelfTypes;
436437
llvm::DenseMap<std::pair<EnumDecl*, Type>, EnumType*> EnumTypes;
437438
llvm::DenseMap<std::pair<StructDecl*, Type>, StructType*> StructTypes;
@@ -1801,9 +1802,8 @@ bool ASTContext::hadError() const {
18011802

18021803
/// Retrieve the arena from which we should allocate storage for a type.
18031804
static AllocationArena getArena(RecursiveTypeProperties properties) {
1804-
bool hasTypeVariable = properties.hasTypeVariable();
1805-
return hasTypeVariable ? AllocationArena::ConstraintSolver
1806-
: AllocationArena::Permanent;
1805+
return properties.isSolverAllocated() ? AllocationArena::ConstraintSolver
1806+
: AllocationArena::Permanent;
18071807
}
18081808

18091809
void ASTContext::addSearchPath(StringRef searchPath, bool isFramework,
@@ -3119,15 +3119,43 @@ Type ErrorType::get(Type originalType) {
31193119
void *mem = ctx.Allocate(sizeof(ErrorType) + sizeof(Type),
31203120
alignof(ErrorType), arena);
31213121
RecursiveTypeProperties properties = RecursiveTypeProperties::HasError;
3122-
if (originalProperties.hasTypeVariable())
3123-
properties |= RecursiveTypeProperties::HasTypeVariable;
3122+
3123+
// We need to preserve the solver allocated bit, to ensure any wrapping
3124+
// types are solver allocated too.
3125+
if (originalProperties.isSolverAllocated())
3126+
properties |= RecursiveTypeProperties::SolverAllocated;
3127+
31243128
return entry = new (mem) ErrorType(ctx, originalType, properties);
31253129
}
31263130

31273131
Type PlaceholderType::get(ASTContext &ctx, Originator originator) {
31283132
assert(originator);
3129-
return new (ctx, AllocationArena::Permanent)
3130-
PlaceholderType(ctx, originator, RecursiveTypeProperties::HasPlaceholder);
3133+
3134+
auto originatorProps = [&]() -> RecursiveTypeProperties {
3135+
if (auto *tv = originator.dyn_cast<TypeVariableType *>())
3136+
return tv->getRecursiveProperties();
3137+
3138+
if (auto *depTy = originator.dyn_cast<DependentMemberType *>())
3139+
return depTy->getRecursiveProperties();
3140+
3141+
return RecursiveTypeProperties();
3142+
}();
3143+
auto arena = getArena(originatorProps);
3144+
3145+
auto &cache = ctx.getImpl().getArena(arena).PlaceholderTypes;
3146+
auto &entry = cache[originator.getOpaqueValue()];
3147+
if (entry)
3148+
return entry;
3149+
3150+
RecursiveTypeProperties properties = RecursiveTypeProperties::HasPlaceholder;
3151+
3152+
// We need to preserve the solver allocated bit, to ensure any wrapping
3153+
// types are solver allocated too.
3154+
if (originatorProps.isSolverAllocated())
3155+
properties |= RecursiveTypeProperties::SolverAllocated;
3156+
3157+
entry = new (ctx, arena) PlaceholderType(ctx, originator, properties);
3158+
return entry;
31313159
}
31323160

31333161
BuiltinIntegerType *BuiltinIntegerType::get(BuiltinIntegerWidth BitWidth,
@@ -3986,7 +4014,7 @@ isAnyFunctionTypeCanonical(ArrayRef<AnyFunctionType::Param> params,
39864014
static RecursiveTypeProperties
39874015
getGenericFunctionRecursiveProperties(ArrayRef<AnyFunctionType::Param> params,
39884016
Type result) {
3989-
static_assert(RecursiveTypeProperties::BitWidth == 16,
4017+
static_assert(RecursiveTypeProperties::BitWidth == 17,
39904018
"revisit this if you add new recursive type properties");
39914019
RecursiveTypeProperties properties;
39924020

@@ -4646,7 +4674,7 @@ CanSILFunctionType SILFunctionType::get(
46464674
void *mem = ctx.Allocate(bytes, alignof(SILFunctionType));
46474675

46484676
RecursiveTypeProperties properties;
4649-
static_assert(RecursiveTypeProperties::BitWidth == 16,
4677+
static_assert(RecursiveTypeProperties::BitWidth == 17,
46504678
"revisit this if you add new recursive type properties");
46514679
for (auto &param : params)
46524680
properties |= param.getInterfaceType()->getRecursiveProperties();

0 commit comments

Comments
 (0)