30
30
#include " swift/AST/ForeignErrorConvention.h"
31
31
#include " swift/AST/GenericEnvironment.h"
32
32
#include " swift/AST/NameLookup.h"
33
+ #include " swift/AST/PackExpansionMatcher.h"
33
34
#include " swift/AST/ParameterList.h"
34
35
#include " swift/AST/PrettyStackTrace.h"
35
36
#include " swift/AST/ProtocolConformance.h"
@@ -726,6 +727,8 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
726
727
auto &ctx = dc->getASTContext ();
727
728
auto &diags = ctx.Diags ;
728
729
730
+ auto genericArgs = generic->getGenericArgs ();
731
+
729
732
if (auto *protoType = type->getAs <ProtocolType>()) {
730
733
auto *protoDecl = protoType->getDecl ();
731
734
@@ -741,8 +744,6 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
741
744
return ErrorType::get (ctx);
742
745
}
743
746
744
- auto genericArgs = generic->getGenericArgs ();
745
-
746
747
if (genericArgs.size () != assocTypes.size ()) {
747
748
diags.diagnose (loc,
748
749
diag::parameterized_protocol_type_argument_count_mismatch,
@@ -809,68 +810,26 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
809
810
auto *decl = unboundType->getDecl ();
810
811
811
812
// Make sure we have the right number of generic arguments.
812
- //
813
- // For generic types without type parameter packs, we require
814
- // the number of declared generic parameters match the number of
815
- // arguments.
816
- //
817
- // For generic types with type parameter packs, we only require
818
- // that the number of arguments is enough to saturate the number of
819
- // regular generic parameters. The parameter pack will absorb
820
- // any excess parameters, or will have a substitution of `Void` if there
821
- // is nothing to bind. This Void-binding behavior of parameter packs
822
- // also explains the offset of one that isn't otherwise present in
823
- // the plain generic parameter case.
824
- //
825
- // struct Foo<Prefix, T..., Suffix> {}
826
- // typealias X = Foo<String, Int, Float, Double> // Prefix -> String, Suffix
827
- // -> Double, T... -> (Int, Float) typealias X = Foo<String, Int> // Prefix ->
828
- // String, Suffix -> Int, T... -> Void typealias Y = Foo<String> // error: Not
829
- // enough arguments to bind Suffix.
830
- //
831
- // FIXME: If we have fewer arguments than we need, that might be okay, if
832
- // we're allowed to deduce the remaining arguments from context. The
833
- // expression checker certainly only cares about the case where too many
834
- // arguments are given.
835
- auto genericArgs = generic->getGenericArgs ();
836
813
auto genericParams = decl->getGenericParams ();
837
814
auto hasParameterPack = llvm::any_of (
838
- *genericParams, [](const auto *GPT) { return GPT->isParameterPack (); });
839
- if ((!hasParameterPack && genericArgs.size () != genericParams->size ()) ||
840
- (hasParameterPack && genericArgs.size () < genericParams->size () - 1 )) {
841
- if (!options.contains (TypeResolutionFlags::SilenceErrors)) {
842
- diags
843
- .diagnose (loc, diag::type_parameter_count_mismatch, decl->getName (),
844
- genericParams->size () - (hasParameterPack ? 1 : 0 ),
845
- genericArgs.size (),
846
- genericArgs.size () < genericParams->size (), hasParameterPack)
847
- .highlight (generic->getAngleBrackets ());
848
- decl->diagnose (diag::kind_declname_declared_here,
849
- DescriptiveDeclKind::GenericType, decl->getName ());
850
- }
851
- return ErrorType::get (ctx);
852
- }
815
+ *genericParams, [](auto *paramDecl) {
816
+ return paramDecl->isParameterPack ();
817
+ });
818
+
819
+ // Resolve the types of the generic arguments.
820
+ auto argOptions = options.withoutContext ().withContext (
821
+ TypeResolverContext::GenericArgument);
822
+ auto genericResolution = resolution.withOptions (argOptions);
853
823
854
824
// In SIL mode, Optional<T> interprets T as a SIL type.
855
825
if (options.contains (TypeResolutionFlags::SILType)) {
856
826
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
857
827
if (nominal->isOptionalDecl ()) {
858
- // Validate the generic argument.
859
- Type objectType = resolution.resolveType (genericArgs[0 ], silParams);
860
- if (objectType->hasError ()) {
861
- return ErrorType::get (ctx);
862
- }
863
-
864
- return BoundGenericType::get (nominal, /* parent*/ Type (), objectType);
828
+ genericResolution = resolution;
865
829
}
866
- }
830
+ }
867
831
}
868
832
869
- // Resolve the types of the generic arguments.
870
- auto argOptions = options.withoutContext ().withContext (
871
- TypeResolverContext::GenericArgument);
872
- auto genericResolution = resolution.withOptions (argOptions);
873
-
874
833
SmallVector<Type, 2 > args;
875
834
for (auto tyR : genericArgs) {
876
835
// Propagate failure.
@@ -881,6 +840,69 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
881
840
args.push_back (substTy);
882
841
}
883
842
843
+ if (!hasParameterPack) {
844
+ // For generic types without type parameter packs, we require
845
+ // the number of declared generic parameters match the number of
846
+ // arguments.
847
+ if (genericArgs.size () != genericParams->size ()) {
848
+ if (!options.contains (TypeResolutionFlags::SilenceErrors)) {
849
+ diags
850
+ .diagnose (loc, diag::type_parameter_count_mismatch, decl->getName (),
851
+ genericParams->size (),
852
+ genericArgs.size (),
853
+ genericArgs.size () < genericParams->size (),
854
+ /* hasParameterPack=*/ 0 )
855
+ .highlight (generic->getAngleBrackets ());
856
+ decl->diagnose (diag::kind_declname_declared_here,
857
+ DescriptiveDeclKind::GenericType, decl->getName ());
858
+ }
859
+ return ErrorType::get (ctx);
860
+ }
861
+ } else {
862
+ // For generic types with type parameter packs, we only require
863
+ // that the number of arguments is enough to saturate the number of
864
+ // regular generic parameters. The parameter pack will absorb
865
+ // zero or arguments.
866
+ SmallVector<Type, 2 > params;
867
+ for (auto paramDecl : genericParams->getParams ()) {
868
+ auto paramType = paramDecl->getDeclaredInterfaceType ();
869
+ params.push_back (paramDecl->isParameterPack ()
870
+ ? PackExpansionType::get (paramType, paramType)
871
+ : paramType);
872
+ }
873
+
874
+ PackMatcher matcher (params, args, ctx);
875
+ if (matcher.match ()) {
876
+ if (!options.contains (TypeResolutionFlags::SilenceErrors)) {
877
+ diags
878
+ .diagnose (loc, diag::type_parameter_count_mismatch, decl->getName (),
879
+ genericParams->size () - 1 ,
880
+ genericArgs.size (),
881
+ genericArgs.size () < genericParams->size (),
882
+ /* hasParameterPack=*/ 1 )
883
+ .highlight (generic->getAngleBrackets ());
884
+ decl->diagnose (diag::kind_declname_declared_here,
885
+ DescriptiveDeclKind::GenericType, decl->getName ());
886
+ }
887
+ return ErrorType::get (ctx);
888
+ }
889
+
890
+ args.clear ();
891
+ for (unsigned i : indices (params)) {
892
+ auto found = std::find_if (matcher.pairs .begin (),
893
+ matcher.pairs .end (),
894
+ [&](const MatchedPair &pair) -> bool {
895
+ return pair.lhsIdx == i;
896
+ });
897
+ assert (found != matcher.pairs .end ());
898
+
899
+ auto arg = found->rhs ;
900
+ if (auto *expansionType = arg->getAs <PackExpansionType>())
901
+ arg = expansionType->getPatternType ();
902
+ args.push_back (arg);
903
+ }
904
+ }
905
+
884
906
const auto result = resolution.applyUnboundGenericArguments (
885
907
decl, unboundType->getParent (), loc, args);
886
908
@@ -941,15 +963,9 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
941
963
Type TypeResolution::applyUnboundGenericArguments (
942
964
GenericTypeDecl *decl, Type parentTy, SourceLoc loc,
943
965
ArrayRef<Type> genericArgs) const {
944
- const bool hasParameterPack =
945
- llvm::any_of (*decl->getGenericParams (),
946
- [](const auto *GPT) { return GPT->isParameterPack (); });
947
- assert (
948
- ((!hasParameterPack &&
949
- genericArgs.size () == decl->getGenericParams ()->size ()) ||
950
- (hasParameterPack &&
951
- genericArgs.size () >= decl->getGenericParams ()->size () - 1 )) &&
952
- " invalid arguments, use applyGenericArguments for diagnostic emitting" );
966
+ assert (genericArgs.size () == decl->getGenericParams ()->size () &&
967
+ " invalid arguments, use applyGenericArguments to emit diagnostics "
968
+ " and collect arguments to pack generic parameters" );
953
969
954
970
TypeSubstitutionMap subs;
955
971
@@ -986,6 +1002,10 @@ Type TypeResolution::applyUnboundGenericArguments(
986
1002
}
987
1003
988
1004
skipRequirementsCheck |= parentTy->hasTypeVariable ();
1005
+
1006
+ // Fill in substitutions for outer generic parameters if we have a local
1007
+ // type in generic context. This isn't actually supported all the way,
1008
+ // but we have to put something here so we don't crash.
989
1009
} else if (auto parentSig =
990
1010
decl->getDeclContext ()->getGenericSignatureOfContext ()) {
991
1011
for (auto gp : parentSig.getGenericParams ()) {
@@ -1000,58 +1020,13 @@ Type TypeResolution::applyUnboundGenericArguments(
1000
1020
auto origTy = innerParams[i]->getDeclaredInterfaceType ();
1001
1021
auto origGP = origTy->getCanonicalType ()->castTo <GenericTypeParamType>();
1002
1022
1003
- if (!origGP->isParameterPack ()) {
1004
- auto substTy = genericArgs[i];
1005
-
1006
- // Enter a substitution.
1007
- subs[origGP] = substTy;
1008
-
1009
- skipRequirementsCheck |=
1010
- substTy->hasTypeVariable () || substTy->hasUnboundGenericType ();
1023
+ auto substTy = genericArgs[i];
1011
1024
1012
- continue ;
1013
- }
1014
-
1015
- // Scan backwards to find the bounds of the longest run of
1016
- // types we can bind to this parameter pack.
1017
- unsigned tail;
1018
- for (tail = 1 ; tail <= innerParams.size (); ++tail) {
1019
- auto tailTy = innerParams[innerParams.size () - tail]
1020
- ->getDeclaredInterfaceType ();
1021
- auto tailGP = tailTy->getCanonicalType ()->castTo <GenericTypeParamType>();
1022
- if (tailGP->isParameterPack ()) {
1023
- assert (tailGP->isEqual (origGP) &&
1024
- " Found multiple type parameter packs!" );
1025
-
1026
- // Saturate the parameter pack. Take care that if the prefix and suffix
1027
- // have bound all available arguments that we bind the parameter
1028
- // pack to `Void`.
1029
- const size_t sequenceLength = tail + i <= genericArgs.size ()
1030
- ? genericArgs.size () - tail - i + 1
1031
- : 0 ;
1025
+ // Enter a substitution.
1026
+ subs[origGP] = substTy;
1032
1027
1033
- auto substTy = PackType::get (getASTContext (),
1034
- genericArgs.slice (i, sequenceLength));
1035
-
1036
- // Enter a substitution.
1037
- subs[origGP] = substTy;
1038
-
1039
- skipRequirementsCheck |=
1040
- substTy->hasTypeVariable () || substTy->hasUnboundGenericType ();
1041
-
1042
- break ;
1043
- }
1044
-
1045
- auto substTy = genericArgs[genericArgs.size () - tail];
1046
-
1047
- // Enter a substitution.
1048
- subs[tailGP] = substTy;
1049
-
1050
- skipRequirementsCheck |=
1051
- substTy->hasTypeVariable () || substTy->hasUnboundGenericType ();
1052
- }
1053
-
1054
- break ;
1028
+ skipRequirementsCheck |=
1029
+ substTy->hasTypeVariable () || substTy->hasUnboundGenericType ();
1055
1030
}
1056
1031
1057
1032
// Check the generic arguments against the requirements of the declaration's
0 commit comments