Skip to content

Commit a76965c

Browse files
committed
Improved out-of-place binding diagnostic and reflecting 'var' or 'let' binding pattern
Fixes Issue #63993
1 parent bbfc4bf commit a76965c

File tree

6 files changed

+80
-40
lines changed

6 files changed

+80
-40
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ namespace swift {
4545
class ValueDecl;
4646
class SourceFile;
4747

48-
enum class PatternKind : uint8_t;
48+
enum class DescriptivePatternKind : uint8_t;
4949
enum class SelfAccessKind : uint8_t;
5050
enum class ReferenceOwnership : uint8_t;
5151
enum class StaticSpellingKind : uint8_t;
@@ -112,7 +112,7 @@ namespace swift {
112112
Type,
113113
TypeRepr,
114114
FullyQualifiedType,
115-
PatternKind,
115+
DescriptivePatternKind,
116116
SelfAccessKind,
117117
ReferenceOwnership,
118118
StaticSpellingKind,
@@ -146,7 +146,7 @@ namespace swift {
146146
Type TypeVal;
147147
TypeRepr *TyR;
148148
FullyQualified<Type> FullyQualifiedTypeVal;
149-
PatternKind PatternKindVal;
149+
DescriptivePatternKind DescriptivePatternKindVal;
150150
SelfAccessKind SelfAccessKindVal;
151151
ReferenceOwnership ReferenceOwnershipVal;
152152
StaticSpellingKind StaticSpellingKindVal;
@@ -219,8 +219,9 @@ namespace swift {
219219
}
220220
}
221221

222-
DiagnosticArgument(PatternKind K)
223-
: Kind(DiagnosticArgumentKind::PatternKind), PatternKindVal(K) {}
222+
DiagnosticArgument(DescriptivePatternKind DPK)
223+
: Kind(DiagnosticArgumentKind::DescriptivePatternKind),
224+
DescriptivePatternKindVal(DPK) {}
224225

225226
DiagnosticArgument(ReferenceOwnership RO)
226227
: Kind(DiagnosticArgumentKind::ReferenceOwnership),
@@ -323,9 +324,9 @@ namespace swift {
323324
return FullyQualifiedTypeVal;
324325
}
325326

326-
PatternKind getAsPatternKind() const {
327-
assert(Kind == DiagnosticArgumentKind::PatternKind);
328-
return PatternKindVal;
327+
DescriptivePatternKind getAsDescriptivePatternKind() const {
328+
assert(Kind == DiagnosticArgumentKind::DescriptivePatternKind);
329+
return DescriptivePatternKindVal;
329330
}
330331

331332
ReferenceOwnership getAsReferenceOwnership() const {

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ ERROR(optional_chain_isnt_chaining,none,
12121212
"'?' must be followed by a call, member lookup, or subscript",
12131213
())
12141214
ERROR(pattern_in_expr,none,
1215-
"%0 cannot appear in an expression", (PatternKind))
1215+
"%0 cannot appear in an expression", (DescriptivePatternKind))
12161216
NOTE(note_call_to_operator,none,
12171217
"in call to operator %0", (DeclName))
12181218
NOTE(note_call_to_func,none,

include/swift/AST/Pattern.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,20 @@ enum class PatternKind : uint8_t {
4747
enum : unsigned { NumPatternKindBits =
4848
countBitsUsed(static_cast<unsigned>(PatternKind::Last_Pattern)) };
4949

50-
/// Diagnostic printing of PatternKinds.
51-
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, PatternKind kind);
50+
enum class DescriptivePatternKind : uint8_t {
51+
Paren,
52+
Tuple,
53+
Named,
54+
Any,
55+
Typed,
56+
Is,
57+
EnumElement,
58+
OptionalSome,
59+
Bool,
60+
Expr,
61+
Var,
62+
Let
63+
};
5264

5365
/// Pattern - Base class for all patterns in Swift.
5466
class alignas(8) Pattern : public ASTAllocated<Pattern> {
@@ -103,13 +115,20 @@ class alignas(8) Pattern : public ASTAllocated<Pattern> {
103115
public:
104116
PatternKind getKind() const { return PatternKind(Bits.Pattern.Kind); }
105117

118+
/// Retrieve the descriptive pattern kind for this pattern.
119+
DescriptivePatternKind getDescriptiveKind() const;
120+
106121
/// Retrieve the name of the given pattern kind.
107122
///
108123
/// This name should only be used for debugging dumps and other
109124
/// developer aids, and should never be part of a diagnostic or exposed
110125
/// to the user of the compiler in any way.
111126
static StringRef getKindName(PatternKind K);
112127

128+
/// Produce a name for the given descriptive pattern kind, which
129+
/// is suitable for use in diagnostics.
130+
static StringRef getDescriptivePatternKindName(DescriptivePatternKind K);
131+
113132
/// A pattern is implicit if it is compiler-generated and there
114133
/// exists no source code for it.
115134
bool isImplicit() const { return Bits.Pattern.isImplicit; }

lib/AST/DiagnosticEngine.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -759,9 +759,11 @@ static void formatDiagnosticArgument(StringRef Modifier,
759759
<< FormatOpts.ClosingQuotationMark;
760760
break;
761761

762-
case DiagnosticArgumentKind::PatternKind:
763-
assert(Modifier.empty() && "Improper modifier for PatternKind argument");
764-
Out << Arg.getAsPatternKind();
762+
case DiagnosticArgumentKind::DescriptivePatternKind:
763+
assert(Modifier.empty() &&
764+
"Improper modifier for DescriptivePatternKind argument");
765+
Out << Pattern::getDescriptivePatternKindName(
766+
Arg.getAsDescriptivePatternKind());
765767
break;
766768

767769
case DiagnosticArgumentKind::SelfAccessKind:

lib/AST/Pattern.cpp

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,29 @@ using namespace swift;
3131
"Patterns are BumpPtrAllocated; the d'tor is never called");
3232
#include "swift/AST/PatternNodes.def"
3333

34-
/// Diagnostic printing of PatternKinds.
35-
llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &OS, PatternKind kind) {
36-
switch (kind) {
37-
case PatternKind::Paren:
38-
return OS << "parenthesized pattern";
39-
case PatternKind::Tuple:
40-
return OS << "tuple pattern";
41-
case PatternKind::Named:
42-
return OS << "pattern variable binding";
43-
case PatternKind::Any:
44-
return OS << "'_' pattern";
45-
case PatternKind::Typed:
46-
return OS << "pattern type annotation";
47-
case PatternKind::Is:
48-
return OS << "prefix 'is' pattern";
49-
case PatternKind::Expr:
50-
return OS << "expression pattern";
34+
DescriptivePatternKind Pattern::getDescriptiveKind() const {
35+
#define TRIVIAL_PATTERN_KIND(Kind) \
36+
case PatternKind::Kind: \
37+
return DescriptivePatternKind::Kind
38+
39+
switch (getKind()) {
40+
TRIVIAL_PATTERN_KIND(Paren);
41+
TRIVIAL_PATTERN_KIND(Tuple);
42+
TRIVIAL_PATTERN_KIND(Named);
43+
TRIVIAL_PATTERN_KIND(Any);
44+
TRIVIAL_PATTERN_KIND(Typed);
45+
TRIVIAL_PATTERN_KIND(Is);
46+
TRIVIAL_PATTERN_KIND(EnumElement);
47+
TRIVIAL_PATTERN_KIND(OptionalSome);
48+
TRIVIAL_PATTERN_KIND(Bool);
49+
TRIVIAL_PATTERN_KIND(Expr);
50+
5151
case PatternKind::Binding:
52-
return OS << "'var' binding pattern";
53-
case PatternKind::EnumElement:
54-
return OS << "enum case matching pattern";
55-
case PatternKind::OptionalSome:
56-
return OS << "optional .Some matching pattern";
57-
case PatternKind::Bool:
58-
return OS << "bool matching pattern";
52+
return cast<BindingPattern>(this)->isLet() ? DescriptivePatternKind::Let
53+
: DescriptivePatternKind::Var;
5954
}
60-
llvm_unreachable("bad PatternKind");
55+
#undef TRIVIAL_PATTERN_KIND
56+
llvm_unreachable("bad DescriptivePatternKind");
6157
}
6258

6359
StringRef Pattern::getKindName(PatternKind K) {
@@ -68,6 +64,28 @@ StringRef Pattern::getKindName(PatternKind K) {
6864
llvm_unreachable("bad PatternKind");
6965
}
7066

67+
StringRef Pattern::getDescriptivePatternKindName(DescriptivePatternKind K) {
68+
#define ENTRY(Kind, String) \
69+
case DescriptivePatternKind::Kind: \
70+
return String
71+
switch (K) {
72+
ENTRY(Paren, "parenthesized pattern");
73+
ENTRY(Tuple, "tuple pattern");
74+
ENTRY(Named, "pattern variable binding");
75+
ENTRY(Any, "'_' pattern");
76+
ENTRY(Typed, "pattern type annotation");
77+
ENTRY(Is, "prefix 'is' pattern");
78+
ENTRY(EnumElement, "enum case matching pattern");
79+
ENTRY(OptionalSome, "optional pattern");
80+
ENTRY(Bool, "bool matching pattern");
81+
ENTRY(Expr, "expression pattern");
82+
ENTRY(Var, "'var' binding pattern");
83+
ENTRY(Let, "'let' binding pattern");
84+
}
85+
#undef Entry
86+
llvm_unreachable("bad DescriptivePatternKind");
87+
}
88+
7189
// Metaprogram to verify that every concrete class implements
7290
// a 'static bool classof(const Pattern*)'.
7391
template <bool fn(const Pattern*)> struct CheckClassOfPattern {

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4537,7 +4537,7 @@ namespace {
45374537
&& !cs.getType(simplified)->is<UnresolvedType>()) {
45384538
auto &de = cs.getASTContext().Diags;
45394539
de.diagnose(simplified->getLoc(), diag::pattern_in_expr,
4540-
expr->getSubPattern()->getKind());
4540+
expr->getSubPattern()->getDescriptiveKind());
45414541
}
45424542
return simplified;
45434543
}

0 commit comments

Comments
 (0)