Skip to content

Commit af1706e

Browse files
authored
Merge pull request #38606 from CodaFi/fly-by-require
2 parents 2d546b0 + e545d7f commit af1706e

20 files changed

+118
-173
lines changed

include/swift/AST/GenericSignature.h

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,18 @@ class GenericSignature {
201201
/// signature.
202202
GenericEnvironment *getGenericEnvironment() const;
203203

204+
/// Return the requirements of this generic signature that are not also
205+
/// satisfied by \c otherSig.
206+
///
207+
/// \param otherSig Another generic signature whose generic parameters are
208+
/// equivalent to or a subset of the generic parameters in this signature.
209+
SmallVector<Requirement, 4>
210+
requirementsNotSatisfiedBy(GenericSignature otherSig) const;
211+
212+
/// Return the canonical version of the given type under this generic
213+
/// signature.
214+
CanType getCanonicalTypeInContext(Type type) const;
215+
204216
/// Check invariants.
205217
void verify() const;
206218
};
@@ -373,18 +385,6 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
373385
bool isRequirementSatisfied(
374386
Requirement requirement, bool allowMissing = false) const;
375387

376-
/// Return the requirements of this generic signature that are not also
377-
/// satisfied by \c otherSig.
378-
///
379-
/// \param otherSig Another generic signature whose generic parameters are
380-
/// equivalent to or a subset of the generic parameters in this signature.
381-
SmallVector<Requirement, 4> requirementsNotSatisfiedBy(
382-
GenericSignature otherSig) const;
383-
384-
/// Return the canonical version of the given type under this generic
385-
/// signature.
386-
CanType getCanonicalTypeInContext(Type type) const;
387-
388388
bool isCanonicalTypeInContext(Type type) const;
389389
bool isCanonicalTypeInContext(Type type,
390390
GenericSignatureBuilder &builder) const;
@@ -462,6 +462,18 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
462462
/// (archetypes) that correspond to the interface types in this generic
463463
/// signature.
464464
GenericEnvironment *getGenericEnvironment() const;
465+
466+
/// Return the requirements of this generic signature that are not also
467+
/// satisfied by \c otherSig.
468+
///
469+
/// \param otherSig Another generic signature whose generic parameters are
470+
/// equivalent to or a subset of the generic parameters in this signature.
471+
SmallVector<Requirement, 4>
472+
requirementsNotSatisfiedBy(GenericSignature otherSig) const;
473+
474+
/// Return the canonical version of the given type under this generic
475+
/// signature.
476+
CanType getCanonicalTypeInContext(Type type) const;
465477
};
466478

467479
void simple_display(raw_ostream &out, GenericSignature sig);

include/swift/SIL/AbstractionPattern.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ class AbstractionPattern {
530530
OrigType = origType;
531531
GenericSig = CanGenericSignature();
532532
if (OrigType->hasTypeParameter()) {
533-
assert(OrigType == signature->getCanonicalTypeInContext(origType));
533+
assert(OrigType == signature.getCanonicalTypeInContext(origType));
534534
GenericSig = signature;
535535
}
536536
}

include/swift/SILOptimizer/Analysis/DifferentiableActivityAnalysis.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ class DifferentiableActivityInfo {
135135
bool hasTangentSpace(SILValue value) {
136136
auto type = value->getType().getASTType();
137137
// Remap archetypes in the derivative generic signature, if it exists.
138-
if (derivativeGenericSignature && type->hasArchetype()) {
139-
type = derivativeGenericSignature->getCanonicalTypeInContext(
138+
if (type->hasArchetype()) {
139+
type = derivativeGenericSignature.getCanonicalTypeInContext(
140140
type->mapTypeOutOfContext());
141141
}
142142
// Look up conformance in the current module.

lib/AST/ASTContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5159,9 +5159,9 @@ bool ASTContext::overrideGenericSignatureReqsSatisfied(
51595159

51605160
switch (direction) {
51615161
case OverrideGenericSignatureReqCheck::BaseReqSatisfiedByDerived:
5162-
return sig->requirementsNotSatisfiedBy(derivedSig).empty();
5162+
return sig.requirementsNotSatisfiedBy(derivedSig).empty();
51635163
case OverrideGenericSignatureReqCheck::DerivedReqSatisfiedByBase:
5164-
return derivedSig->requirementsNotSatisfiedBy(sig).empty();
5164+
return derivedSig.requirementsNotSatisfiedBy(sig).empty();
51655165
}
51665166
llvm_unreachable("Unhandled OverrideGenericSignatureReqCheck in switch");
51675167
}

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2645,7 +2645,7 @@ bool ASTMangler::appendGenericSignature(GenericSignature sig,
26452645
genericParams = canSig.getGenericParams();
26462646
requirements = canSig.getRequirements();
26472647
} else {
2648-
requirementsBuffer = canSig->requirementsNotSatisfiedBy(contextSig);
2648+
requirementsBuffer = canSig.requirementsNotSatisfiedBy(contextSig);
26492649
requirements = requirementsBuffer;
26502650
}
26512651
} else {

lib/AST/Attr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
991991
auto genericSig = FnDecl->getGenericSignature();
992992

993993
if (auto sig = attr->getSpecializedSignature()) {
994-
requirementsScratch = sig->requirementsNotSatisfiedBy(
995-
genericSig);
994+
requirementsScratch = sig.requirementsNotSatisfiedBy(genericSig);
996995
requirements = requirementsScratch;
997996
}
998997
}

lib/AST/GenericSignature.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,16 @@ bool GenericSignatureImpl::isRequirementSatisfied(
967967
return requirement.isSatisfied(conditionalRequirements, allowMissing);
968968
}
969969

970+
SmallVector<Requirement, 4>
971+
GenericSignature::requirementsNotSatisfiedBy(GenericSignature otherSig) const {
972+
// The null generic signature has no requirements, therefore all requirements
973+
// are satisfied by any signature.
974+
if (isNull()) {
975+
return {};
976+
}
977+
return getPointer()->requirementsNotSatisfiedBy(otherSig);
978+
}
979+
970980
SmallVector<Requirement, 4> GenericSignatureImpl::requirementsNotSatisfiedBy(
971981
GenericSignature otherSig) const {
972982
SmallVector<Requirement, 4> result;
@@ -1071,6 +1081,15 @@ bool GenericSignatureImpl::isCanonicalTypeInContext(
10711081
});
10721082
}
10731083

1084+
CanType GenericSignature::getCanonicalTypeInContext(Type type) const {
1085+
// The null generic signature has no requirements so cannot influence the
1086+
// structure of the can type computed here.
1087+
if (isNull()) {
1088+
return type->getCanonicalType();
1089+
}
1090+
return getPointer()->getCanonicalTypeInContext(type);
1091+
}
1092+
10741093
CanType GenericSignatureImpl::getCanonicalTypeInContext(Type type) const {
10751094
type = type->getCanonicalType();
10761095

lib/AST/ProtocolConformance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ ConditionalRequirementsRequest::evaluate(Evaluator &evaluator,
543543

544544
// Find the requirements in the extension that aren't proved by the original
545545
// type, these are the ones that make the conformance conditional.
546-
const auto unsatReqs = extensionSig->requirementsNotSatisfiedBy(typeSig);
546+
const auto unsatReqs = extensionSig.requirementsNotSatisfiedBy(typeSig);
547547
if (unsatReqs.empty())
548548
return {};
549549

lib/AST/SubstitutionMap.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ Type SubstitutionMap::lookupSubstitution(CanSubstitutableType type) const {
295295

296296
// The generic parameter may not be canonical. Retrieve the canonical
297297
// type, which will be dependent.
298-
CanType canonicalType = genericSig->getCanonicalTypeInContext(genericParam);
298+
CanType canonicalType = genericSig.getCanonicalTypeInContext(genericParam);
299299

300300
// If nothing changed, we don't have a replacement.
301301
if (canonicalType == type) return Type();

lib/AST/Type.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,10 +1450,7 @@ CanType TypeBase::computeCanonicalType() {
14501450
}
14511451

14521452
CanType TypeBase::getCanonicalType(GenericSignature sig) {
1453-
if (!sig)
1454-
return getCanonicalType();
1455-
1456-
return sig->getCanonicalTypeInContext(this);
1453+
return sig.getCanonicalTypeInContext(this);
14571454
}
14581455

14591456
TypeBase *TypeBase::reconstituteSugar(bool Recursive) {
@@ -1904,7 +1901,7 @@ class IsBindableVisitor
19041901

19051902
// Collect requirements from the conformance not satisfied by the
19061903
// original declaration.
1907-
for (auto reqt : conformanceSig->requirementsNotSatisfiedBy(genericSig)) {
1904+
for (auto reqt : conformanceSig.requirementsNotSatisfiedBy(genericSig)) {
19081905
LLVM_DEBUG(llvm::dbgs() << "\n- adds requirement\n";
19091906
reqt.dump(llvm::dbgs()));
19101907

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,9 @@ TypeConverter::getAbstractionPattern(AbstractStorageDecl *decl,
4747

4848
AbstractionPattern
4949
TypeConverter::getAbstractionPattern(SubscriptDecl *decl, bool isNonObjC) {
50-
auto type = decl->getElementInterfaceType()->getCanonicalType();
51-
CanGenericSignature genericSig;
52-
if (auto sig = decl->getGenericSignatureOfContext()) {
53-
genericSig = sig.getCanonicalSignature();
54-
type = sig->getCanonicalTypeInContext(type);
55-
}
56-
return AbstractionPattern(genericSig, type);
50+
auto sig = decl->getGenericSignatureOfContext().getCanonicalSignature();
51+
auto type = sig.getCanonicalTypeInContext(decl->getElementInterfaceType());
52+
return AbstractionPattern(sig, type);
5753
}
5854

5955
static const clang::Type *getClangType(const clang::Decl *decl) {
@@ -78,30 +74,27 @@ static Bridgeability getClangDeclBridgeability(const clang::Decl *decl) {
7874

7975
AbstractionPattern
8076
TypeConverter::getAbstractionPattern(VarDecl *var, bool isNonObjC) {
81-
CanType swiftType = var->getInterfaceType()
82-
->getCanonicalType();
83-
84-
CanGenericSignature genericSig;
85-
if (auto sig = var->getDeclContext()->getGenericSignatureOfContext()) {
86-
genericSig = sig.getCanonicalSignature();
87-
swiftType = genericSig->getCanonicalTypeInContext(swiftType);
88-
}
77+
auto sig = var->getDeclContext()
78+
->getGenericSignatureOfContext()
79+
.getCanonicalSignature();
80+
auto swiftType = sig.getCanonicalTypeInContext(var->getInterfaceType());
8981

9082
if (isNonObjC)
91-
return AbstractionPattern(genericSig, swiftType);
83+
return AbstractionPattern(sig, swiftType);
9284

9385
if (auto clangDecl = var->getClangDecl()) {
9486
auto clangType = getClangType(clangDecl);
9587
auto contextType = var->getDeclContext()->mapTypeIntoContext(swiftType);
96-
swiftType = getLoweredBridgedType(
97-
AbstractionPattern(genericSig, swiftType, clangType),
98-
contextType, getClangDeclBridgeability(clangDecl),
99-
SILFunctionTypeRepresentation::CFunctionPointer,
100-
TypeConverter::ForMemory)->getCanonicalType();
101-
return AbstractionPattern(genericSig, swiftType, clangType);
88+
swiftType =
89+
getLoweredBridgedType(AbstractionPattern(sig, swiftType, clangType),
90+
contextType, getClangDeclBridgeability(clangDecl),
91+
SILFunctionTypeRepresentation::CFunctionPointer,
92+
TypeConverter::ForMemory)
93+
->getCanonicalType();
94+
return AbstractionPattern(sig, swiftType, clangType);
10295
}
10396

104-
return AbstractionPattern(genericSig, swiftType);
97+
return AbstractionPattern(sig, swiftType);
10598
}
10699

107100
AbstractionPattern TypeConverter::getAbstractionPattern(EnumElementDecl *decl) {
@@ -113,15 +106,12 @@ AbstractionPattern TypeConverter::getAbstractionPattern(EnumElementDecl *decl) {
113106
"Optional.Some does not have a unique abstraction pattern because "
114107
"optionals are re-abstracted");
115108

116-
CanType type = decl->getArgumentInterfaceType()->getCanonicalType();
117-
118-
CanGenericSignature genericSig;
119-
if (auto sig = decl->getParentEnum()->getGenericSignatureOfContext()) {
120-
genericSig = sig.getCanonicalSignature();
121-
type = genericSig->getCanonicalTypeInContext(type);
122-
}
109+
auto sig = decl->getParentEnum()
110+
->getGenericSignatureOfContext()
111+
.getCanonicalSignature();
112+
auto type = sig.getCanonicalTypeInContext(decl->getArgumentInterfaceType());
123113

124-
return AbstractionPattern(genericSig, type);
114+
return AbstractionPattern(sig, type);
125115
}
126116

127117
AbstractionPattern::EncodedForeignInfo

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3542,21 +3542,18 @@ TypeConverter::getConstantOverrideInfo(TypeExpansionContext context,
35423542

35433543
assert(base.requiresNewVTableEntry() && "base must not be an override");
35443544

3545-
// Figure out the generic signature for the class method call. This is the
3546-
// signature of the derived class, with requirements transplanted from
3547-
// the base method. The derived method is allowed to have fewer
3548-
// requirements, in which case the thunk will translate the calling
3549-
// convention appropriately before calling the derived method.
3550-
bool hasGenericRequirementDifference = false;
35513545

35523546
auto derivedSig = derived.getDecl()->getAsGenericContext()
35533547
->getGenericSignature();
35543548
auto genericSig = Context.getOverrideGenericSignature(base.getDecl(),
35553549
derived.getDecl());
3556-
if (genericSig) {
3557-
hasGenericRequirementDifference =
3558-
!genericSig->requirementsNotSatisfiedBy(derivedSig).empty();
3559-
}
3550+
// Figure out the generic signature for the class method call. This is the
3551+
// signature of the derived class, with requirements transplanted from
3552+
// the base method. The derived method is allowed to have fewer
3553+
// requirements, in which case the thunk will translate the calling
3554+
// convention appropriately before calling the derived method.
3555+
bool hasGenericRequirementDifference =
3556+
!genericSig.requirementsNotSatisfiedBy(derivedSig).empty();
35603557

35613558
auto baseInfo = getConstantInfo(context, base);
35623559
auto derivedInfo = getConstantInfo(context, derived);

lib/SIL/IR/SILPrinter.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,17 +3706,8 @@ void SILSpecializeAttr::print(llvm::raw_ostream &OS) const {
37063706
if (genericEnv)
37073707
genericSig = genericEnv->getGenericSignature();
37083708

3709-
ArrayRef<Requirement> requirements;
3710-
SmallVector<Requirement, 4> requirementsScratch;
3711-
if (auto specializedSig = getSpecializedSignature()) {
3712-
if (genericSig) {
3713-
requirementsScratch = specializedSig->requirementsNotSatisfiedBy(
3714-
genericSig);
3715-
requirements = requirementsScratch;
3716-
} else {
3717-
requirements = specializedSig.getRequirements();
3718-
}
3719-
}
3709+
auto requirements =
3710+
getSpecializedSignature().requirementsNotSatisfiedBy(genericSig);
37203711
if (targetFunction) {
37213712
OS << "target: \"" << targetFunction->getName() << "\", ";
37223713
}

lib/SIL/IR/TypeLowering.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3402,11 +3402,11 @@ TypeConverter::getInterfaceBoxTypeForCapture(ValueDecl *captured,
34023402

34033403
// Instantiate the layout with identity substitutions.
34043404
auto subMap = SubstitutionMap::get(
3405-
signature,
3406-
[&](SubstitutableType *type) -> Type {
3407-
return signature->getCanonicalTypeInContext(type);
3408-
},
3409-
MakeAbstractConformanceForGenericType());
3405+
signature,
3406+
[&](SubstitutableType *type) -> Type {
3407+
return signature.getCanonicalTypeInContext(type);
3408+
},
3409+
MakeAbstractConformanceForGenericType());
34103410

34113411
auto boxTy = SILBoxType::get(C, layout, subMap);
34123412
#ifndef NDEBUG

lib/SILOptimizer/Differentiation/JVPCloner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ class JVPCloner::Implementation final
352352
/// Find the tangent space of a given canonical type.
353353
Optional<TangentSpace> getTangentSpace(CanType type) {
354354
// Use witness generic signature to remap types.
355-
if (auto witnessGenSig = witness->getDerivativeGenericSignature())
356-
type = witnessGenSig->getCanonicalTypeInContext(type);
355+
type = witness->getDerivativeGenericSignature().getCanonicalTypeInContext(
356+
type);
357357
return type->getAutoDiffTangentSpace(
358358
LookUpConformanceInModule(getModule().getSwiftModule()));
359359
}

lib/SILOptimizer/Differentiation/PullbackCloner.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,9 @@ class PullbackCloner::Implementation final
211211

212212
Optional<TangentSpace> getTangentSpace(CanType type) {
213213
// Use witness generic signature to remap types.
214-
if (auto witnessGenSig = getWitness()->getDerivativeGenericSignature())
215-
type = witnessGenSig->getCanonicalTypeInContext(type);
214+
type =
215+
getWitness()->getDerivativeGenericSignature().getCanonicalTypeInContext(
216+
type);
216217
return type->getAutoDiffTangentSpace(
217218
LookUpConformanceInModule(getModule().getSwiftModule()));
218219
}

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -802,23 +802,14 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF,
802802
auto CanSpecializedGenericSig = SpecializedGenericSig.getCanonicalSignature();
803803

804804
// First substitute concrete types into the existing function type.
805-
CanSILFunctionType FnTy;
806-
{
807-
FnTy = OrigF->getLoweredFunctionType()
808-
->substGenericArgs(M, SubstMap, getResilienceExpansion())
809-
->getUnsubstitutedType(M);
810-
// FIXME: Some of the added new requirements may not have been taken into
811-
// account by the substGenericArgs. So, canonicalize in the context of the
812-
// specialized signature.
813-
if (CanSpecializedGenericSig)
814-
FnTy = cast<SILFunctionType>(
815-
CanSpecializedGenericSig->getCanonicalTypeInContext(FnTy));
816-
else {
817-
FnTy = cast<SILFunctionType>(FnTy->getCanonicalType());
818-
assert(!FnTy->hasTypeParameter() && "Type parameters outside generic context?");
819-
}
820-
}
805+
CanSILFunctionType FnTy =
806+
cast<SILFunctionType>(CanSpecializedGenericSig.getCanonicalTypeInContext(
807+
OrigF->getLoweredFunctionType()
808+
->substGenericArgs(M, SubstMap, getResilienceExpansion())
809+
->getUnsubstitutedType(M)));
821810
assert(FnTy);
811+
assert((CanSpecializedGenericSig || !FnTy->hasTypeParameter()) &&
812+
"Type parameters outside generic context?");
822813

823814
// Use the new specialized generic signature.
824815
auto NewFnTy = SILFunctionType::get(
@@ -1439,8 +1430,7 @@ void FunctionSignaturePartialSpecializer::
14391430
createGenericParamsForCalleeGenericParams() {
14401431
for (auto GP : CalleeGenericSig.getGenericParams()) {
14411432
auto CanTy = GP->getCanonicalType();
1442-
auto CanTyInContext =
1443-
CalleeGenericSig->getCanonicalTypeInContext(CanTy);
1433+
auto CanTyInContext = CalleeGenericSig.getCanonicalTypeInContext(CanTy);
14441434
auto Replacement = CanTyInContext.subst(CalleeInterfaceToCallerArchetypeMap);
14451435
LLVM_DEBUG(llvm::dbgs() << "\n\nChecking callee generic parameter:\n";
14461436
CanTy->dump(llvm::dbgs()));

0 commit comments

Comments
 (0)