Skip to content

Commit 38f1788

Browse files
committed
Sema: Extract resolveGenericArguments() from applyGenericArguments()
1 parent d2a03b4 commit 38f1788

File tree

1 file changed

+127
-104
lines changed

1 file changed

+127
-104
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 127 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,130 @@ namespace {
827827
};
828828
}
829829

830+
/// Returns true on error.
831+
static bool resolveGenericArguments(ValueDecl *decl,
832+
const GenericContext *genCtx,
833+
const TypeResolution &resolution,
834+
SILTypeResolutionContext *silContext,
835+
DeclRefTypeRepr *repr,
836+
SmallVectorImpl<Type> &args) {
837+
auto options = resolution.getOptions();
838+
auto &ctx = decl->getASTContext();
839+
840+
auto genericParams = genCtx->getGenericParams();
841+
auto hasParameterPack = llvm::any_of(*genericParams, [](auto *paramDecl) {
842+
return paramDecl->isParameterPack();
843+
});
844+
auto hasValueParam = llvm::any_of(*genericParams, [](auto *paramDecl) {
845+
return paramDecl->isValue();
846+
});
847+
848+
// If the type declares at least one parameter pack, allow pack expansions
849+
// anywhere in the argument list. We'll use the PackMatcher to ensure that
850+
// everything lines up. Otherwise, don't allow pack expansions to appear
851+
// at all.
852+
auto argOptions = options.withoutContext().withContext(
853+
hasParameterPack
854+
? TypeResolverContext::VariadicGenericArgument
855+
: TypeResolverContext::ScalarGenericArgument);
856+
if (hasValueParam)
857+
argOptions = argOptions.withContext(TypeResolverContext::ValueGenericArgument);
858+
auto genericResolution = resolution.withOptions(argOptions);
859+
860+
// In SIL mode, Optional<T> interprets T as a SIL type.
861+
if (options.contains(TypeResolutionFlags::SILType)) {
862+
if (auto nominal = dyn_cast<NominalTypeDecl>(genCtx)) {
863+
if (nominal->isOptionalDecl()) {
864+
genericResolution = resolution;
865+
}
866+
}
867+
}
868+
869+
auto genericArgs = repr->getGenericArgs();
870+
auto loc = repr->getNameLoc().getBaseNameLoc();
871+
872+
// Resolve the types of the generic arguments.
873+
for (auto tyR : genericArgs) {
874+
// Propagate failure.
875+
Type substTy = genericResolution.resolveType(tyR, silContext);
876+
if (!substTy || substTy->hasError())
877+
return true;
878+
879+
args.push_back(substTy);
880+
}
881+
882+
// Make sure we have the right number of generic arguments.
883+
if (!hasParameterPack) {
884+
// For generic types without type parameter packs, we require
885+
// the number of declared generic parameters match the number of
886+
// arguments.
887+
if (genericArgs.size() != genericParams->size()) {
888+
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
889+
diagnoseInvalidGenericArguments(
890+
loc, decl, genericArgs.size(), genericParams->size(),
891+
/*hasParameterPack=*/false, repr->getAngleBrackets());
892+
}
893+
return true;
894+
}
895+
896+
return false;
897+
}
898+
899+
// For generic types with type parameter packs, we only require
900+
// that the number of arguments is enough to saturate the number of
901+
// regular generic parameters. The parameter pack will absorb
902+
// zero or arguments.
903+
SmallVector<Type, 2> params;
904+
for (auto paramDecl : genericParams->getParams()) {
905+
auto paramType = paramDecl->getDeclaredInterfaceType();
906+
params.push_back(paramDecl->isParameterPack()
907+
? PackExpansionType::get(paramType, paramType)
908+
: paramType);
909+
}
910+
911+
PackMatcher matcher(params, args, ctx);
912+
if (matcher.match() || matcher.pairs.size() != params.size()) {
913+
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
914+
diagnoseInvalidGenericArguments(
915+
loc, decl, genericArgs.size(), genericParams->size(),
916+
/*hasParameterPack=*/true, repr->getAngleBrackets());
917+
}
918+
return true;
919+
}
920+
921+
args.clear();
922+
for (unsigned i : indices(params)) {
923+
auto found = std::find_if(matcher.pairs.begin(),
924+
matcher.pairs.end(),
925+
[&](const MatchedPair &pair) -> bool {
926+
return pair.lhsIdx == i;
927+
});
928+
assert(found != matcher.pairs.end());
929+
930+
auto arg = found->rhs;
931+
932+
// PackMatcher will always produce a PackExpansionType as the
933+
// arg for a pack parameter, if necessary by wrapping a PackType
934+
// in one. (It's a weird representation.) Look for that pattern
935+
// and unwrap the pack. Otherwise, we must have matched with a
936+
// single component which happened to be an expansion; wrap that
937+
// in a PackType. In either case, we always want arg to end up
938+
// a PackType.
939+
if (auto *expansionType = arg->getAs<PackExpansionType>()) {
940+
auto pattern = expansionType->getPatternType();
941+
if (auto pack = pattern->getAs<PackType>()) {
942+
arg = pack;
943+
} else {
944+
arg = PackType::get(ctx, {expansionType});
945+
}
946+
}
947+
948+
args.push_back(arg);
949+
}
950+
951+
return false;
952+
}
953+
830954
/// Apply generic arguments to the given type.
831955
///
832956
/// If the type is itself not generic, this does nothing.
@@ -1005,112 +1129,10 @@ static Type applyGenericArguments(Type type,
10051129
auto *unboundType = type->castTo<UnboundGenericType>();
10061130
auto *decl = unboundType->getDecl();
10071131

1008-
auto genericParams = decl->getGenericParams();
1009-
auto hasParameterPack = llvm::any_of(*genericParams, [](auto *paramDecl) {
1010-
return paramDecl->isParameterPack();
1011-
});
1012-
auto hasValueParam = llvm::any_of(*genericParams, [](auto *paramDecl) {
1013-
return paramDecl->isValue();
1014-
});
1015-
1016-
// If the type declares at least one parameter pack, allow pack expansions
1017-
// anywhere in the argument list. We'll use the PackMatcher to ensure that
1018-
// everything lines up. Otherwise, don't allow pack expansions to appear
1019-
// at all.
1020-
auto argOptions = options.withoutContext().withContext(
1021-
hasParameterPack
1022-
? TypeResolverContext::VariadicGenericArgument
1023-
: TypeResolverContext::ScalarGenericArgument);
1024-
if (hasValueParam)
1025-
argOptions = argOptions.withContext(TypeResolverContext::ValueGenericArgument);
1026-
auto genericResolution = resolution.withOptions(argOptions);
1027-
1028-
// In SIL mode, Optional<T> interprets T as a SIL type.
1029-
if (options.contains(TypeResolutionFlags::SILType)) {
1030-
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
1031-
if (nominal->isOptionalDecl()) {
1032-
genericResolution = resolution;
1033-
}
1034-
}
1035-
}
1036-
10371132
// Resolve the types of the generic arguments.
10381133
SmallVector<Type, 2> args;
1039-
for (auto tyR : genericArgs) {
1040-
// Propagate failure.
1041-
Type substTy = genericResolution.resolveType(tyR, silContext);
1042-
if (!substTy || substTy->hasError())
1043-
return ErrorType::get(ctx);
1044-
1045-
args.push_back(substTy);
1046-
}
1047-
1048-
// Make sure we have the right number of generic arguments.
1049-
if (!hasParameterPack) {
1050-
// For generic types without type parameter packs, we require
1051-
// the number of declared generic parameters match the number of
1052-
// arguments.
1053-
if (genericArgs.size() != genericParams->size()) {
1054-
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
1055-
diagnoseInvalidGenericArguments(
1056-
loc, decl, genericArgs.size(), genericParams->size(),
1057-
/*hasParameterPack=*/false, repr->getAngleBrackets());
1058-
}
1059-
return ErrorType::get(ctx);
1060-
}
1061-
} else {
1062-
// For generic types with type parameter packs, we only require
1063-
// that the number of arguments is enough to saturate the number of
1064-
// regular generic parameters. The parameter pack will absorb
1065-
// zero or arguments.
1066-
SmallVector<Type, 2> params;
1067-
for (auto paramDecl : genericParams->getParams()) {
1068-
auto paramType = paramDecl->getDeclaredInterfaceType();
1069-
params.push_back(paramDecl->isParameterPack()
1070-
? PackExpansionType::get(paramType, paramType)
1071-
: paramType);
1072-
}
1073-
1074-
PackMatcher matcher(params, args, ctx);
1075-
if (matcher.match() || matcher.pairs.size() != params.size()) {
1076-
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
1077-
diagnoseInvalidGenericArguments(
1078-
loc, decl, genericArgs.size(), genericParams->size(),
1079-
/*hasParameterPack=*/true, repr->getAngleBrackets());
1080-
}
1081-
return ErrorType::get(ctx);
1082-
}
1083-
1084-
args.clear();
1085-
for (unsigned i : indices(params)) {
1086-
auto found = std::find_if(matcher.pairs.begin(),
1087-
matcher.pairs.end(),
1088-
[&](const MatchedPair &pair) -> bool {
1089-
return pair.lhsIdx == i;
1090-
});
1091-
assert(found != matcher.pairs.end());
1092-
1093-
auto arg = found->rhs;
1094-
1095-
// PackMatcher will always produce a PackExpansionType as the
1096-
// arg for a pack parameter, if necessary by wrapping a PackType
1097-
// in one. (It's a weird representation.) Look for that pattern
1098-
// and unwrap the pack. Otherwise, we must have matched with a
1099-
// single component which happened to be an expansion; wrap that
1100-
// in a PackType. In either case, we always want arg to end up
1101-
// a PackType.
1102-
if (auto *expansionType = arg->getAs<PackExpansionType>()) {
1103-
auto pattern = expansionType->getPatternType();
1104-
if (auto pack = pattern->getAs<PackType>()) {
1105-
arg = pack;
1106-
} else {
1107-
arg = PackType::get(ctx, {expansionType});
1108-
}
1109-
}
1110-
1111-
args.push_back(arg);
1112-
}
1113-
}
1134+
if (resolveGenericArguments(decl, decl, resolution, silContext, repr, args))
1135+
return ErrorType::get(ctx);
11141136

11151137
// Construct the substituted type.
11161138
const auto result = resolution.applyUnboundGenericArguments(
@@ -1130,6 +1152,7 @@ static Type applyGenericArguments(Type type,
11301152
if (auto clangDecl = decl->getClangDecl()) {
11311153
if (auto classTemplateDecl =
11321154
dyn_cast<clang::ClassTemplateDecl>(clangDecl)) {
1155+
// FIXME: Why does this resolve the types twice?
11331156
SmallVector<Type, 2> typesOfGenericArgs;
11341157
for (auto typeRepr : genericArgs) {
11351158
typesOfGenericArgs.push_back(resolution.resolveType(typeRepr));

0 commit comments

Comments
 (0)