Skip to content

Commit 354416f

Browse files
committed
AST: Kill Type::getAllGenericArgs()
This was almost identical to getMemberSubstitutions(), except protocol and protocol extension members are not properly supported. Now that this method is no longer used by the ASTPrinter, there are only two remaining usages, both trivially refactorable to use better APIs.
1 parent cfe9e6a commit 354416f

File tree

6 files changed

+26
-115
lines changed

6 files changed

+26
-115
lines changed

include/swift/AST/Types.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -554,12 +554,6 @@ class alignas(1 << TypeAlignInBits) TypeBase {
554554
/// specialized, but the type Vector is not.
555555
bool isSpecialized();
556556

557-
/// Retrieve the complete set of generic arguments for a specialized type.
558-
///
559-
/// \param scratch Scratch space to use when the complete list needs to be
560-
/// stitched together from multiple lists of generic arguments.
561-
ArrayRef<Type> getAllGenericArgs(SmallVectorImpl<Type> &scratch);
562-
563557
/// Gather all of the substitutions used to produce the given specialized type
564558
/// from its unspecialized type.
565559
///

lib/AST/Type.cpp

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -277,69 +277,6 @@ bool TypeBase::isSpecialized() {
277277
});
278278
}
279279

280-
ArrayRef<Type> TypeBase::getAllGenericArgs(SmallVectorImpl<Type> &scratch) {
281-
Type type(this);
282-
SmallVector<ArrayRef<Type>, 2> allGenericArgs;
283-
284-
while (type) {
285-
// Gather generic arguments from a bound generic type.
286-
if (auto bound = type->getAs<BoundGenericType>()) {
287-
allGenericArgs.push_back(bound->getGenericArgs());
288-
289-
// Continue up to the parent.
290-
type = bound->getParent();
291-
continue;
292-
}
293-
294-
// Use the generic type parameter types for an unbound generic type.
295-
if (auto unbound = type->getAs<UnboundGenericType>()) {
296-
auto genericSig = unbound->getDecl()->getGenericSignature();
297-
auto genericParams = genericSig->getInnermostGenericParams();
298-
allGenericArgs.push_back(
299-
llvm::makeArrayRef((const Type *)genericParams.data(),
300-
genericParams.size()));
301-
302-
// Continue up to the parent.
303-
type = unbound->getParent();
304-
continue;
305-
}
306-
307-
// For a protocol type, use its Self parameter.
308-
if (auto protoType = type->getAs<ProtocolType>()) {
309-
auto proto = protoType->getDecl();
310-
allGenericArgs.push_back(
311-
llvm::makeArrayRef(proto->getSelfInterfaceType()));
312-
313-
// Continue up to the parent.
314-
type = protoType->getParent();
315-
continue;
316-
}
317-
318-
// Look through non-generic nominal types.
319-
if (auto nominal = type->getAs<NominalType>()) {
320-
type = nominal->getParent();
321-
continue;
322-
}
323-
324-
break;
325-
}
326-
327-
// Trivial case: no generic arguments.
328-
if (allGenericArgs.empty())
329-
return { };
330-
331-
// Common case: a single set of generic arguments, for which we need no
332-
// allocation.
333-
if (allGenericArgs.size() == 1)
334-
return allGenericArgs.front();
335-
336-
// General case: concatenate all of the generic argument lists together.
337-
scratch.clear();
338-
for (auto args : reversed(allGenericArgs))
339-
scratch.append(args.begin(), args.end());
340-
return scratch;
341-
}
342-
343280
bool TypeBase::isUnspecializedGeneric() {
344281
CanType CT = getCanonicalType();
345282
if (CT.getPointer() != this)

lib/Sema/CSDiag.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4074,10 +4074,11 @@ bool FailureDiagnosis::diagnoseContextualConversionError() {
40744074

40754075
// When converting from T to [T] or UnsafePointer<T>, we can offer fixit to wrap
40764076
// the expr with brackets.
4077-
if (auto *contextDecl = contextualType->getAnyNominal()) {
4077+
auto *genericType = contextualType->getAs<BoundGenericType>();
4078+
if (genericType) {
4079+
auto *contextDecl = genericType->getDecl();
40784080
if (contextDecl == CS->TC.Context.getArrayDecl()) {
4079-
SmallVector<Type, 4> scratch;
4080-
for (Type arg : contextualType->getAllGenericArgs(scratch)) {
4081+
for (Type arg : genericType->getGenericArgs()) {
40814082
if (arg->isEqual(exprType)) {
40824083
diagnose(expr->getLoc(), diagID, exprType, contextualType).
40834084
fixItInsert(expr->getStartLoc(), "[").fixItInsert(
@@ -4090,8 +4091,7 @@ bool FailureDiagnosis::diagnoseContextualConversionError() {
40904091
contextDecl == CS->TC.Context.getUnsafeMutablePointerDecl() ||
40914092
contextDecl == CS->TC.Context.getUnsafeRawPointerDecl() ||
40924093
contextDecl == CS->TC.Context.getUnsafeMutableRawPointerDecl()) {
4093-
SmallVector<Type, 4> scratch;
4094-
for (Type arg : contextualType->getAllGenericArgs(scratch)) {
4094+
for (Type arg : genericType->getGenericArgs()) {
40954095
if (arg->isEqual(exprType) && expr->getType()->isLValueType()) {
40964096
diagnose(expr->getLoc(), diagID, exprType, contextualType).
40974097
fixItInsert(expr->getStartLoc(), "&");

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -980,32 +980,31 @@ void TypeChecker::revertGenericFuncSignature(AbstractFunctionDecl *func) {
980980
/// \param types The types that will be scanned for generic type parameters,
981981
/// which will be used in the resulting type.
982982
///
983-
/// \param genericParams The actual generic parameters, whose names will be used
983+
/// \param genericSig The actual generic parameters, whose names will be used
984984
/// in the resulting text.
985985
///
986986
/// \param substitutions The generic parameter -> generic argument substitutions
987987
/// that will have been applied to these types. These are used to produce the
988988
/// "parameter = argument" bindings in the test.
989989
static std::string gatherGenericParamBindingsText(
990990
ArrayRef<Type> types,
991-
ArrayRef<GenericTypeParamType *> genericParams,
992-
TypeSubstitutionMap &substitutions) {
991+
GenericSignature *genericSig,
992+
const TypeSubstitutionMap &substitutions) {
993993
llvm::SmallPtrSet<GenericTypeParamType *, 2> knownGenericParams;
994994
for (auto type : types) {
995-
type.findIf([&](Type type) -> bool {
995+
type.visit([&](Type type) {
996996
if (auto gp = type->getAs<GenericTypeParamType>()) {
997997
knownGenericParams.insert(gp->getCanonicalType()
998998
->castTo<GenericTypeParamType>());
999999
}
1000-
return false;
10011000
});
10021001
}
10031002

10041003
if (knownGenericParams.empty())
10051004
return "";
10061005

10071006
SmallString<128> result;
1008-
for (auto gp : genericParams) {
1007+
for (auto gp : genericSig->getGenericParams()) {
10091008
auto canonGP = gp->getCanonicalType()->castTo<GenericTypeParamType>();
10101009
if (!knownGenericParams.count(canonGP))
10111010
continue;
@@ -1016,7 +1015,12 @@ static std::string gatherGenericParamBindingsText(
10161015
result += ", ";
10171016
result += gp->getName().str();
10181017
result += " = ";
1019-
result += substitutions[canonGP].getString();
1018+
1019+
auto found = substitutions.find(canonGP);
1020+
if (found == substitutions.end())
1021+
return "";
1022+
1023+
result += found->second.getString();
10201024
}
10211025

10221026
result += "]";
@@ -1027,31 +1031,7 @@ bool TypeChecker::checkGenericArguments(DeclContext *dc, SourceLoc loc,
10271031
SourceLoc noteLoc,
10281032
Type owner,
10291033
GenericSignature *genericSig,
1030-
ArrayRef<Type> genericArgs) {
1031-
// Form the set of generic substitutions required
1032-
TypeSubstitutionMap substitutions;
1033-
1034-
auto genericParams = genericSig->getGenericParams();
1035-
1036-
unsigned count = 0;
1037-
1038-
// If the type is nested inside a generic function, skip
1039-
// substitutions from the outer context.
1040-
unsigned start = (genericParams.size() - genericArgs.size());
1041-
1042-
for (auto gp : genericParams) {
1043-
if (count >= start) {
1044-
auto gpTy = gp->getCanonicalType()->castTo<GenericTypeParamType>();
1045-
substitutions[gpTy] = genericArgs[count - start];
1046-
}
1047-
1048-
count++;
1049-
}
1050-
1051-
// The number of generic type arguments being bound must be equal to the
1052-
// total number of generic parameters in the current generic type context.
1053-
assert(count - start == genericArgs.size());
1054-
1034+
const TypeSubstitutionMap &substitutions) {
10551035
// Check each of the requirements.
10561036
Module *module = dc->getParentModule();
10571037
for (const auto &req : genericSig->getRequirements()) {
@@ -1099,7 +1079,7 @@ bool TypeChecker::checkGenericArguments(DeclContext *dc, SourceLoc loc,
10991079
req.getFirstType(), req.getSecondType(),
11001080
gatherGenericParamBindingsText(
11011081
{req.getFirstType(), req.getSecondType()},
1102-
genericParams, substitutions));
1082+
genericSig, substitutions));
11031083
return true;
11041084
}
11051085
continue;
@@ -1113,7 +1093,7 @@ bool TypeChecker::checkGenericArguments(DeclContext *dc, SourceLoc loc,
11131093
req.getFirstType(), req.getSecondType(),
11141094
gatherGenericParamBindingsText(
11151095
{req.getFirstType(), req.getSecondType()},
1116-
genericParams, substitutions));
1096+
genericSig, substitutions));
11171097
return true;
11181098
}
11191099
continue;

lib/Sema/TypeCheckType.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -582,19 +582,19 @@ Type TypeChecker::applyUnboundGenericArguments(
582582
// FIXME: Record that we're checking substitutions, so we can't end up
583583
// with infinite recursion.
584584

585-
// Collect the complete set of generic arguments.
586-
SmallVector<Type, 4> scratch;
587-
ArrayRef<Type> allGenericArgs = BGT->getAllGenericArgs(scratch);
588-
589585
// Check the generic arguments against the generic signature.
590586
auto genericSig = decl->getGenericSignature();
591587
if (!decl->hasType() || decl->isValidatingGenericSignature()) {
592588
diagnose(loc, diag::recursive_requirement_reference);
593589
return nullptr;
594590
}
591+
592+
// Collect the complete set of generic arguments.
595593
assert(genericSig != nullptr);
594+
auto substitutions = BGT->getMemberSubstitutions(BGT->getDecl());
595+
596596
if (checkGenericArguments(dc, loc, noteLoc, UGT, genericSig,
597-
allGenericArgs))
597+
substitutions))
598598
return nullptr;
599599

600600
useObjectiveCBridgeableConformancesOfArgs(dc, BGT);

lib/Sema/TypeChecker.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,14 +1088,14 @@ class TypeChecker final : public LazyResolver {
10881088
/// \param noteLoc The location at which any notes will be printed.
10891089
/// \param owner The type that owns the generic signature.
10901090
/// \param genericSig The actual generic signature.
1091-
/// \param genericArgs The generic arguments.
1091+
/// \param substitutions Substitutions from interface types of the signature.
10921092
///
10931093
/// \returns true if an error occurred, false otherwise.
10941094
bool checkGenericArguments(DeclContext *dc, SourceLoc loc,
10951095
SourceLoc noteLoc,
10961096
Type owner,
10971097
GenericSignature *genericSig,
1098-
ArrayRef<Type> genericArgs);
1098+
const TypeSubstitutionMap &substitutions);
10991099

11001100
/// Resolve the superclass of the given class.
11011101
void resolveSuperclass(ClassDecl *classDecl) override;

0 commit comments

Comments
 (0)