23
23
#include " swift/Basic/APIntMap.h"
24
24
#include < llvm/ADT/APFloat.h>
25
25
26
- #include < numeric>
27
26
#include < forward_list>
27
+ #include < iterator>
28
+ #include < numeric>
29
+ #include < utility>
28
30
29
31
using namespace swift ;
30
32
@@ -115,7 +117,7 @@ namespace {
115
117
116
118
// In type space, we reuse HEAD to help us print meaningful name, e.g.,
117
119
// tuple element name in fixits.
118
- Identifier Head;
120
+ DeclName Head;
119
121
std::forward_list<Space> Spaces;
120
122
121
123
size_t computeSize (TypeChecker &TC, const DeclContext *DC,
@@ -170,19 +172,18 @@ namespace {
170
172
llvm_unreachable (" unhandled kind" );
171
173
}
172
174
173
- explicit Space (Type T, Identifier NameForPrinting)
174
- : Kind (SpaceKind::Type), TypeAndVal (T),
175
- Head (NameForPrinting), Spaces ({}){}
175
+ explicit Space (Type T, DeclName NameForPrinting)
176
+ : Kind (SpaceKind::Type), TypeAndVal (T), Head (NameForPrinting ),
177
+ Spaces ({}) {}
176
178
explicit Space (UnknownCase_t, bool allowedButNotRequired)
177
179
: Kind (SpaceKind::UnknownCase),
178
180
TypeAndVal (Type (), allowedButNotRequired), Head (Identifier ()),
179
181
Spaces ({}) {}
180
- explicit Space (Type T, Identifier H, ArrayRef<Space> SP)
181
- : Kind (SpaceKind::Constructor), TypeAndVal (T), Head (H),
182
- Spaces (SP.begin (), SP.end ()) {}
183
- explicit Space (Type T, Identifier H, std::forward_list<Space> SP)
184
- : Kind (SpaceKind::Constructor), TypeAndVal (T), Head (H),
185
- Spaces (SP) {}
182
+ explicit Space (Type T, DeclName H, ArrayRef<Space> SP)
183
+ : Kind (SpaceKind::Constructor), TypeAndVal (T), Head (H),
184
+ Spaces (SP.begin (), SP.end ()) {}
185
+ explicit Space (Type T, DeclName H, std::forward_list<Space> SP)
186
+ : Kind (SpaceKind::Constructor), TypeAndVal (T), Head (H), Spaces (SP) {}
186
187
explicit Space (ArrayRef<Space> SP)
187
188
: Kind (SpaceKind::Disjunct), TypeAndVal (Type ()),
188
189
Head (Identifier ()), Spaces (SP.begin (), SP.end ()) {}
@@ -194,23 +195,23 @@ namespace {
194
195
: Kind (SpaceKind::Empty), TypeAndVal (Type ()), Head (Identifier ()),
195
196
Spaces ({}) {}
196
197
197
- static Space forType (Type T, Identifier NameForPrinting) {
198
+ static Space forType (Type T, DeclName NameForPrinting) {
198
199
if (T->isStructurallyUninhabited ())
199
200
return Space ();
200
201
return Space (T, NameForPrinting);
201
202
}
202
203
static Space forUnknown (bool allowedButNotRequired) {
203
204
return Space (UnknownCase, allowedButNotRequired);
204
205
}
205
- static Space forConstructor (Type T, Identifier H, ArrayRef<Space> SP) {
206
+ static Space forConstructor (Type T, DeclName H, ArrayRef<Space> SP) {
206
207
if (llvm::any_of (SP, std::mem_fn (&Space::isEmpty))) {
207
208
// A constructor with an unconstructible parameter can never actually
208
209
// be used.
209
210
return Space ();
210
211
}
211
212
return Space (T, H, SP);
212
213
}
213
- static Space forConstructor (Type T, Identifier H,
214
+ static Space forConstructor (Type T, DeclName H,
214
215
std::forward_list<Space> SP) {
215
216
// No need to filter SP here; this is only used to copy other
216
217
// Constructor spaces.
@@ -263,7 +264,7 @@ namespace {
263
264
return TypeAndVal.getPointer ();
264
265
}
265
266
266
- Identifier getHead () const {
267
+ DeclName getHead () const {
267
268
assert (getKind () == SpaceKind::Constructor
268
269
&& " Wrong kind of space tried to access head" );
269
270
return Head;
@@ -272,7 +273,7 @@ namespace {
272
273
Identifier getPrintingName () const {
273
274
assert (getKind () == SpaceKind::Type
274
275
&& " Wrong kind of space tried to access printing name" );
275
- return Head;
276
+ return Head. getBaseIdentifier () ;
276
277
}
277
278
278
279
const std::forward_list<Space> &getSpaces () const {
@@ -333,7 +334,7 @@ namespace {
333
334
return this ->isSubspace (or2Space, TC, DC);
334
335
}
335
336
336
- return true ;
337
+ return false ;
337
338
}
338
339
PAIRCASE (SpaceKind::Type, SpaceKind::Disjunct): {
339
340
// (_ : Ty1) <= (S1 | ... | Sn) iff (S1 <= S) || ... || (Sn <= S)
@@ -372,10 +373,11 @@ namespace {
372
373
PAIRCASE (SpaceKind::Constructor, SpaceKind::Constructor): {
373
374
// Optimization: If the constructor heads don't match, subspace is
374
375
// impossible.
376
+
375
377
if (this ->Head != other.Head ) {
376
378
return false ;
377
379
}
378
-
380
+
379
381
// Special Case: Short-circuit comparisons with payload-less
380
382
// constructors.
381
383
if (other.getSpaces ().empty ()) {
@@ -557,7 +559,8 @@ namespace {
557
559
PAIRCASE (SpaceKind::Constructor, SpaceKind::Constructor): {
558
560
// Optimization: If the heads of the constructors don't match then
559
561
// the two are disjoint and their difference is the first space.
560
- if (this ->Head != other.Head ) {
562
+ if (this ->Head .getBaseIdentifier () !=
563
+ other.Head .getBaseIdentifier ()) {
561
564
return *this ;
562
565
}
563
566
@@ -696,19 +699,40 @@ namespace {
696
699
buffer << (getBoolValue () ? " true" : " false" );
697
700
break ;
698
701
case SpaceKind::Constructor: {
699
- if (!Head.empty ()) {
702
+ if (!Head.getBaseIdentifier (). empty ()) {
700
703
buffer << " ." ;
701
- buffer << Head.str ();
704
+ buffer << Head.getBaseIdentifier (). str ();
702
705
}
703
706
704
707
if (Spaces.empty ()) {
705
708
return ;
706
709
}
707
710
711
+ auto args = Head.getArgumentNames ().begin ();
712
+ auto argEnd = Head.getArgumentNames ().end ();
713
+
714
+ // FIXME: Clean up code for performance
708
715
buffer << " (" ;
709
- interleave (Spaces, [&](const Space ¶m) {
710
- param.show (buffer, forDisplay);
711
- }, [&buffer]() { buffer << " , " ; });
716
+ llvm::SmallVector<std::pair<Identifier, Space>, 4 > labelSpaces;
717
+ for (auto param : Spaces) {
718
+ if (args != argEnd) {
719
+ labelSpaces.push_back (
720
+ std::pair<Identifier, Space>(*args, param));
721
+ args++;
722
+ } else
723
+ labelSpaces.push_back (
724
+ std::pair<Identifier, Space>(Identifier (), param));
725
+ }
726
+ interleave (
727
+ labelSpaces,
728
+ [&](const std::pair<Identifier, Space> ¶m) {
729
+ if (!param.first .empty ()) {
730
+ buffer << param.first ;
731
+ buffer << " : " ;
732
+ }
733
+ param.second .show (buffer, forDisplay);
734
+ },
735
+ [&buffer]() { buffer << " , " ; });
712
736
buffer << " )" ;
713
737
}
714
738
break ;
@@ -800,7 +824,7 @@ namespace {
800
824
Space::forType (TTy->getUnderlyingType (), Identifier ()));
801
825
}
802
826
}
803
- return Space::forConstructor (tp, eed->getName (),
827
+ return Space::forConstructor (tp, eed->getFullName (),
804
828
constElemSpaces);
805
829
});
806
830
@@ -961,7 +985,6 @@ namespace {
961
985
return ;
962
986
963
987
Space projection = projectPattern (TC, caseItem.getPattern ());
964
-
965
988
bool isRedundant = !projection.isEmpty () &&
966
989
llvm::any_of (spaces, [&](const Space &handled) {
967
990
return projection.isSubspace (handled, TC, DC);
@@ -1414,8 +1437,8 @@ namespace {
1414
1437
auto subSpace = projectPattern (TC, OSP->getSubPattern ());
1415
1438
// To match patterns like (_, _, ...)?, we must rewrite the underlying
1416
1439
// tuple pattern to .some(_, _, ...) first.
1417
- if (subSpace.getKind () == SpaceKind::Constructor
1418
- && subSpace.getHead ().empty ()) {
1440
+ if (subSpace.getKind () == SpaceKind::Constructor &&
1441
+ subSpace.getHead (). getBaseIdentifier ().empty ()) {
1419
1442
return Space::forConstructor (item->getType (), name,
1420
1443
std::move (subSpace.getSpaces ()));
1421
1444
}
0 commit comments