@@ -942,64 +942,72 @@ void repairTupleOrAssociatedValuePatternIfApplicable(
942
942
Type enumPayloadType,
943
943
const EnumElementDecl *enumCase) {
944
944
auto &DE = Ctx.Diags ;
945
- bool addDeclNote = false ;
946
- if (auto *tupleType = dyn_cast<TupleType>(enumPayloadType.getPointer ())) {
947
- if (tupleType->getNumElements () >= 2
948
- && enumElementInnerPat->getKind () == PatternKind::Paren) {
949
- auto *semantic = enumElementInnerPat->getSemanticsProvidingPattern ();
950
- if (auto *tuplePattern = dyn_cast<TuplePattern>(semantic)) {
951
- if (tuplePattern->getNumElements () >= 2 ) {
952
- auto diag = DE.diagnose (tuplePattern->getLoc (),
953
- diag::converting_tuple_into_several_associated_values,
954
- enumCase->getNameStr (), tupleType->getNumElements ());
955
- auto subPattern =
956
- dyn_cast<ParenPattern>(enumElementInnerPat)->getSubPattern ();
957
-
958
- // We might also have code like
959
- //
960
- // enum Upair { case upair(Int, Int) }
961
- // func f(u: Upair) { switch u { case .upair(let (x, y)): () } }
962
- //
963
- // This needs a more complex rearrangement to fix the code. So only
964
- // apply the fix-it if we have a tuple immediately inside.
965
- if (subPattern->getKind () == PatternKind::Tuple) {
966
- auto leadingParen = SourceRange (enumElementInnerPat->getStartLoc ());
967
- auto trailingParen = SourceRange (enumElementInnerPat->getEndLoc ());
968
- diag.fixItRemove (leadingParen)
969
- .fixItRemove (trailingParen);
970
- }
971
-
972
- addDeclNote = true ;
973
- enumElementInnerPat = semantic;
974
- }
975
- } else {
976
- DE.diagnose (enumElementInnerPat->getLoc (),
977
- diag::found_one_pattern_for_several_associated_values,
978
- enumCase->getNameStr (),
979
- tupleType->getNumElements ());
980
- addDeclNote = true ;
981
- }
982
- }
983
- } else if (auto *tupleType = enumPayloadType->getAs <TupleType>()) {
984
- if (tupleType->getNumElements () >= 2 ) {
985
- if (auto *tuplePattern = dyn_cast<TuplePattern>(enumElementInnerPat)) {
986
- DE.diagnose (enumElementInnerPat->getLoc (),
987
- diag::converting_several_associated_values_into_tuple,
988
- enumCase->getNameStr (),
989
- tupleType->getNumElements ())
990
- .fixItInsert (enumElementInnerPat->getStartLoc (), " (" )
991
- .fixItInsertAfter (enumElementInnerPat->getEndLoc (), " )" );
992
- addDeclNote = true ;
993
- enumElementInnerPat =
994
- new (Ctx) ParenPattern (enumElementInnerPat->getStartLoc (),
995
- enumElementInnerPat,
996
- enumElementInnerPat->getEndLoc ());
945
+ auto addDeclNote = [&]() {
946
+ DE.diagnose (enumCase->getStartLoc (), diag::decl_declared_here, enumCase);
947
+ };
948
+ auto payloadParams = enumCase->getCaseConstructorParams ();
949
+
950
+ // First check to see whether we need to untuple a pattern.
951
+ if (payloadParams.size () >= 2 ) {
952
+ if (enumElementInnerPat->getKind () != PatternKind::Paren)
953
+ return ;
954
+
955
+ auto *semantic = enumElementInnerPat->getSemanticsProvidingPattern ();
956
+ if (auto *tuplePattern = dyn_cast<TuplePattern>(semantic)) {
957
+ if (tuplePattern->getNumElements () < 2 )
958
+ return ;
959
+
960
+ auto diag =
961
+ DE.diagnose (tuplePattern->getLoc (),
962
+ diag::converting_tuple_into_several_associated_values,
963
+ enumCase->getNameStr (), payloadParams.size ());
964
+ auto subPattern =
965
+ dyn_cast<ParenPattern>(enumElementInnerPat)->getSubPattern ();
966
+
967
+ // We might also have code like
968
+ //
969
+ // enum Upair { case upair(Int, Int) }
970
+ // func f(u: Upair) { switch u { case .upair(let (x, y)): () } }
971
+ //
972
+ // This needs a more complex rearrangement to fix the code. So only
973
+ // apply the fix-it if we have a tuple immediately inside.
974
+ if (subPattern->getKind () == PatternKind::Tuple) {
975
+ auto leadingParen = SourceRange (enumElementInnerPat->getStartLoc ());
976
+ auto trailingParen = SourceRange (enumElementInnerPat->getEndLoc ());
977
+ diag.fixItRemove (leadingParen).fixItRemove (trailingParen);
997
978
}
979
+ diag.flush ();
980
+ addDeclNote ();
981
+ enumElementInnerPat = semantic;
982
+ } else {
983
+ DE.diagnose (enumElementInnerPat->getLoc (),
984
+ diag::found_one_pattern_for_several_associated_values,
985
+ enumCase->getNameStr (), payloadParams.size ());
986
+ addDeclNote ();
998
987
}
988
+ return ;
999
989
}
1000
990
1001
- if (addDeclNote)
1002
- DE.diagnose (enumCase->getStartLoc (), diag::decl_declared_here, enumCase);
991
+ // Then check to see whether we need to tuple a pattern.
992
+ if (payloadParams.size () == 1 && !payloadParams[0 ].hasLabel ()) {
993
+ auto *tupleType = enumPayloadType->getAs <TupleType>();
994
+ if (!tupleType || tupleType->getNumElements () < 2 )
995
+ return ;
996
+
997
+ auto *tuplePattern = dyn_cast<TuplePattern>(enumElementInnerPat);
998
+ if (!tuplePattern)
999
+ return ;
1000
+
1001
+ DE.diagnose (enumElementInnerPat->getLoc (),
1002
+ diag::converting_several_associated_values_into_tuple,
1003
+ enumCase->getNameStr (), tupleType->getNumElements ())
1004
+ .fixItInsert (enumElementInnerPat->getStartLoc (), " (" )
1005
+ .fixItInsertAfter (enumElementInnerPat->getEndLoc (), " )" );
1006
+ addDeclNote ();
1007
+ enumElementInnerPat = new (Ctx)
1008
+ ParenPattern (enumElementInnerPat->getStartLoc (), enumElementInnerPat,
1009
+ enumElementInnerPat->getEndLoc ());
1010
+ }
1003
1011
}
1004
1012
1005
1013
NullablePtr<Pattern> TypeChecker::trySimplifyExprPattern (ExprPattern *EP,
0 commit comments