Skip to content

Commit d5731c5

Browse files
authored
Merge pull request #33619 from slavapestov/fix-generic-requirements-in-inherited-inits
AST: Try harder to preserve type sugar in AbstractGenericSignatureRequest
2 parents 68dcbca + 995eb66 commit d5731c5

15 files changed

+83
-121
lines changed

include/swift/AST/Attr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1427,7 +1427,7 @@ class SpecializeAttr : public DeclAttribute {
14271427

14281428
TrailingWhereClause *getTrailingWhereClause() const;
14291429

1430-
GenericSignature getSpecializedSgnature() const {
1430+
GenericSignature getSpecializedSignature() const {
14311431
return specializedSignature;
14321432
}
14331433

include/swift/AST/GenericEnvironment.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,6 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
149149
std::pair<Type, ProtocolConformanceRef>
150150
mapConformanceRefIntoContext(Type conformingType,
151151
ProtocolConformanceRef conformance) const;
152-
153-
/// Get the sugared form of a generic parameter type.
154-
GenericTypeParamType *getSugaredType(GenericTypeParamType *type) const;
155-
156-
/// Get the sugared form of a type by substituting any
157-
/// generic parameter types by their sugared form.
158-
Type getSugaredType(Type type) const;
159152

160153
SubstitutionMap getForwardingSubstitutionMap() const;
161154

include/swift/AST/GenericSignature.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,11 +397,18 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
397397
/// <t_0_0, t_0_1, t_1_0>
398398
/// then this will return 0 for t_0_0, 1 for t_0_1, and 2 for t_1_0.
399399
unsigned getGenericParamOrdinal(GenericTypeParamType *param) const;
400-
400+
401401
/// Get a substitution map that maps all of the generic signature's
402402
/// generic parameters to themselves.
403403
SubstitutionMap getIdentitySubstitutionMap() const;
404404

405+
/// Get the sugared form of a generic parameter type.
406+
GenericTypeParamType *getSugaredType(GenericTypeParamType *type) const;
407+
408+
/// Get the sugared form of a type by substituting any
409+
/// generic parameter types by their sugared form.
410+
Type getSugaredType(Type type) const;
411+
405412
/// Whether this generic signature involves a type variable.
406413
bool hasTypeVariable() const;
407414

include/swift/AST/PrintOptions.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
namespace swift {
2626
class ASTPrinter;
27-
class GenericEnvironment;
27+
class GenericSignatureImpl;
2828
class CanType;
2929
class Decl;
3030
class Pattern;
@@ -423,8 +423,8 @@ struct PrintOptions {
423423
/// Replaces the name of private and internal properties of types with '_'.
424424
bool OmitNameOfInaccessibleProperties = false;
425425

426-
/// Print dependent types as references into this generic environment.
427-
GenericEnvironment *GenericEnv = nullptr;
426+
/// Use this signature to re-sugar dependent types.
427+
const GenericSignatureImpl *GenericSig = nullptr;
428428

429429
/// Print types with alternative names from their canonical names.
430430
llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr;

lib/AST/ASTPrinter.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "swift/AST/Decl.h"
2525
#include "swift/AST/Expr.h"
2626
#include "swift/AST/FileUnit.h"
27-
#include "swift/AST/GenericEnvironment.h"
27+
#include "swift/AST/GenericSignature.h"
2828
#include "swift/AST/Module.h"
2929
#include "swift/AST/NameLookup.h"
3030
#include "swift/AST/ParameterList.h"
@@ -2488,14 +2488,14 @@ void PrintAST::visitTypeAliasDecl(TypeAliasDecl *decl) {
24882488
Printer << " = ";
24892489
// FIXME: An inferred associated type witness type alias may reference
24902490
// an opaque type, but OpaqueTypeArchetypes are always canonicalized
2491-
// so lose type sugar for generic params. Bind the generic environment so
2492-
// we can map params back into the generic environment and print them
2491+
// so lose type sugar for generic params. Bind the generic signature so
2492+
// we can map params back into the generic signature and print them
24932493
// correctly.
24942494
//
24952495
// Remove this when we have a way to represent non-canonical archetypes
24962496
// preserving sugar.
2497-
llvm::SaveAndRestore<GenericEnvironment*> setGenericEnv(Options.GenericEnv,
2498-
decl->getGenericEnvironment());
2497+
llvm::SaveAndRestore<const GenericSignatureImpl *> setGenericSig(
2498+
Options.GenericSig, decl->getGenericSignature().getPointer());
24992499
printTypeLoc(TypeLoc(decl->getUnderlyingTypeRepr(), Ty));
25002500
printDeclGenericRequirements(decl);
25012501
}
@@ -4319,7 +4319,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
43194319
Optional<TypePrinter> subBuffer;
43204320
PrintOptions subOptions = Options;
43214321
if (auto substitutions = T->getPatternSubstitutions()) {
4322-
subOptions.GenericEnv = nullptr;
4322+
subOptions.GenericSig = nullptr;
43234323
subBuffer.emplace(Printer, subOptions);
43244324
sub = &*subBuffer;
43254325

@@ -4411,7 +4411,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
44114411
// A box layout has its own independent generic environment. Don't try
44124412
// to print it with the environment's generic params.
44134413
PrintOptions subOptions = Options;
4414-
subOptions.GenericEnv = nullptr;
4414+
subOptions.GenericSig = nullptr;
44154415
TypePrinter sub(Printer, subOptions);
44164416

44174417
// Capture list used here to ensure we don't print anything using `this`
@@ -4594,10 +4594,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
45944594
}
45954595
}
45964596

4597-
// When printing SIL types, use a generic environment to map them from
4597+
// When printing SIL types, use a generic signature to map them from
45984598
// canonical types to sugared types.
4599-
if (Options.GenericEnv)
4600-
T = Options.GenericEnv->getSugaredType(T);
4599+
if (Options.GenericSig)
4600+
T = Options.GenericSig->getSugaredType(T);
46014601
}
46024602

46034603
auto Name = T->getName();

lib/AST/Attr.cpp

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -589,32 +589,11 @@ static void printDifferentiableAttrArguments(
589589
if (!isLeadingClause)
590590
stream << ' ';
591591
stream << "where ";
592-
std::function<Type(Type)> getInterfaceType;
593-
if (!original || !original->getGenericEnvironment()) {
594-
getInterfaceType = [](Type Ty) -> Type { return Ty; };
595-
} else {
596-
// Use GenericEnvironment to produce user-friendly
597-
// names instead of something like 't_0_0'.
598-
auto *genericEnv = original->getGenericEnvironment();
599-
assert(genericEnv);
600-
getInterfaceType = [=](Type Ty) -> Type {
601-
return genericEnv->getSugaredType(Ty);
602-
};
603-
}
604592
interleave(requirementsToPrint, [&](Requirement req) {
605593
if (const auto &originalGenSig = original->getGenericSignature())
606594
if (originalGenSig->isRequirementSatisfied(req))
607595
return;
608-
auto FirstTy = getInterfaceType(req.getFirstType());
609-
if (req.getKind() != RequirementKind::Layout) {
610-
auto SecondTy = getInterfaceType(req.getSecondType());
611-
Requirement ReqWithDecls(req.getKind(), FirstTy, SecondTy);
612-
ReqWithDecls.print(stream, Options);
613-
} else {
614-
Requirement ReqWithDecls(req.getKind(), FirstTy,
615-
req.getLayoutConstraint());
616-
ReqWithDecls.print(stream, Options);
617-
}
596+
req.print(stream, Options);
618597
}, [&] {
619598
stream << ", ";
620599
});
@@ -928,25 +907,16 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
928907
Printer << "kind: " << kind << ", ";
929908
SmallVector<Requirement, 4> requirementsScratch;
930909
ArrayRef<Requirement> requirements;
931-
if (auto sig = attr->getSpecializedSgnature())
910+
if (auto sig = attr->getSpecializedSignature())
932911
requirements = sig->getRequirements();
933912

934-
std::function<Type(Type)> GetInterfaceType;
935913
auto *FnDecl = dyn_cast_or_null<AbstractFunctionDecl>(D);
936-
if (!FnDecl || !FnDecl->getGenericEnvironment())
937-
GetInterfaceType = [](Type Ty) -> Type { return Ty; };
938-
else {
939-
// Use GenericEnvironment to produce user-friendly
940-
// names instead of something like t_0_0.
941-
auto *GenericEnv = FnDecl->getGenericEnvironment();
942-
assert(GenericEnv);
943-
GetInterfaceType = [=](Type Ty) -> Type {
944-
return GenericEnv->getSugaredType(Ty);
945-
};
946-
947-
if (auto sig = attr->getSpecializedSgnature()) {
914+
if (FnDecl && FnDecl->getGenericSignature()) {
915+
auto genericSig = FnDecl->getGenericSignature();
916+
917+
if (auto sig = attr->getSpecializedSignature()) {
948918
requirementsScratch = sig->requirementsNotSatisfiedBy(
949-
GenericEnv->getGenericSignature());
919+
genericSig);
950920
requirements = requirementsScratch;
951921
}
952922
}
@@ -957,16 +927,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
957927

958928
interleave(requirements,
959929
[&](Requirement req) {
960-
auto FirstTy = GetInterfaceType(req.getFirstType());
961-
if (req.getKind() != RequirementKind::Layout) {
962-
auto SecondTy = GetInterfaceType(req.getSecondType());
963-
Requirement ReqWithDecls(req.getKind(), FirstTy, SecondTy);
964-
ReqWithDecls.print(Printer, Options);
965-
} else {
966-
Requirement ReqWithDecls(req.getKind(), FirstTy,
967-
req.getLayoutConstraint());
968-
ReqWithDecls.print(Printer, Options);
969-
}
930+
req.print(Printer, Options);
970931
},
971932
[&] { Printer << ", "; });
972933

lib/AST/GenericEnvironment.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -171,27 +171,6 @@ Type GenericEnvironment::mapTypeIntoContext(GenericTypeParamType *type) const {
171171
return result;
172172
}
173173

174-
GenericTypeParamType *GenericEnvironment::getSugaredType(
175-
GenericTypeParamType *type) const {
176-
for (auto *sugaredType : getGenericParams())
177-
if (sugaredType->isEqual(type))
178-
return sugaredType;
179-
180-
llvm_unreachable("missing generic parameter");
181-
}
182-
183-
Type GenericEnvironment::getSugaredType(Type type) const {
184-
if (!type->hasTypeParameter())
185-
return type;
186-
187-
return type.transform([this](Type Ty) -> Type {
188-
if (auto GP = dyn_cast<GenericTypeParamType>(Ty.getPointer())) {
189-
return Type(getSugaredType(GP));
190-
}
191-
return Ty;
192-
});
193-
}
194-
195174
SubstitutionMap GenericEnvironment::getForwardingSubstitutionMap() const {
196175
auto genericSig = getGenericSignature();
197176
return SubstitutionMap::get(genericSig,

lib/AST/GenericSignature.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,10 +1037,27 @@ SubstitutionMap GenericSignatureImpl::getIdentitySubstitutionMap() const {
10371037
MakeAbstractConformanceForGenericType());
10381038
}
10391039

1040+
GenericTypeParamType *GenericSignatureImpl::getSugaredType(
1041+
GenericTypeParamType *type) const {
1042+
unsigned ordinal = getGenericParamOrdinal(type);
1043+
return getGenericParams()[ordinal];
1044+
}
1045+
1046+
Type GenericSignatureImpl::getSugaredType(Type type) const {
1047+
if (!type->hasTypeParameter())
1048+
return type;
1049+
1050+
return type.transform([this](Type Ty) -> Type {
1051+
if (auto GP = dyn_cast<GenericTypeParamType>(Ty.getPointer())) {
1052+
return Type(getSugaredType(GP));
1053+
}
1054+
return Ty;
1055+
});
1056+
}
1057+
10401058
unsigned GenericSignatureImpl::getGenericParamOrdinal(
10411059
GenericTypeParamType *param) const {
1042-
return GenericParamKey(param->getDepth(), param->getIndex())
1043-
.findIndexIn(getGenericParams());
1060+
return GenericParamKey(param).findIndexIn(getGenericParams());
10441061
}
10451062

10461063
bool GenericSignatureImpl::hasTypeVariable() const {

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7430,13 +7430,11 @@ AbstractGenericSignatureRequest::evaluate(
74307430
if (baseSignature)
74317431
canBaseSignature = baseSignature->getCanonicalSignature();
74327432

7433-
llvm::SmallDenseMap<GenericTypeParamType *, Type> mappedTypeParameters;
74347433
SmallVector<GenericTypeParamType *, 2> canAddedParameters;
74357434
canAddedParameters.reserve(addedParameters.size());
74367435
for (auto gp : addedParameters) {
74377436
auto canGP = gp->getCanonicalType()->castTo<GenericTypeParamType>();
74387437
canAddedParameters.push_back(canGP);
7439-
mappedTypeParameters[canGP] = Type(gp);
74407438
}
74417439

74427440
SmallVector<Requirement, 2> canAddedRequirements;
@@ -7453,10 +7451,8 @@ AbstractGenericSignatureRequest::evaluate(
74537451
if (!canSignatureResult || !*canSignatureResult)
74547452
return GenericSignature();
74557453

7456-
// Substitute in the original generic parameters to form a more-sugared
7457-
// result closer to what the original request wanted. Note that this
7458-
// loses sugar on concrete types, but for abstract signatures that
7459-
// shouldn't matter.
7454+
// Substitute in the original generic parameters to form the sugared
7455+
// result the original request wanted.
74607456
auto canSignature = *canSignatureResult;
74617457
SmallVector<GenericTypeParamType *, 2> resugaredParameters;
74627458
resugaredParameters.reserve(canSignature->getGenericParams().size());
@@ -7474,9 +7470,8 @@ AbstractGenericSignatureRequest::evaluate(
74747470
auto resugaredReq = req.subst(
74757471
[&](SubstitutableType *type) {
74767472
if (auto gp = dyn_cast<GenericTypeParamType>(type)) {
7477-
auto knownGP = mappedTypeParameters.find(gp);
7478-
if (knownGP != mappedTypeParameters.end())
7479-
return knownGP->second;
7473+
unsigned ordinal = canSignature->getGenericParamOrdinal(gp);
7474+
return Type(resugaredParameters[ordinal]);
74807475
}
74817476
return Type(type);
74827477
},

lib/PrintAsObjC/DeclAndTypePrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,7 @@ class DeclAndTypePrinter::Implementation
19091909
assert(extension->getGenericSignature().getCanonicalSignature() ==
19101910
extendedClass->getGenericSignature().getCanonicalSignature() &&
19111911
"constrained extensions or custom generic parameters?");
1912-
type = extendedClass->getGenericEnvironment()->getSugaredType(type);
1912+
type = extendedClass->getGenericSignature()->getSugaredType(type);
19131913
decl = type->getDecl();
19141914
}
19151915

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void SILFunctionBuilder::addFunctionAttributes(
5454
? SILSpecializeAttr::SpecializationKind::Full
5555
: SILSpecializeAttr::SpecializationKind::Partial;
5656
F->addSpecializeAttr(
57-
SILSpecializeAttr::create(M, SA->getSpecializedSgnature(),
57+
SILSpecializeAttr::create(M, SA->getSpecializedSignature(),
5858
SA->isExported(), kind));
5959
}
6060

0 commit comments

Comments
 (0)