Merge pull request #75011 from hamishknight/context-is-key

[Sema] Enforce PatternTypeRequest returns contextual type
This commit is contained in:
Hamish Knight
2024-07-07 10:23:57 +01:00
committed by GitHub
13 changed files with 45 additions and 60 deletions

View File

@@ -100,9 +100,10 @@ static VarDecl *addImplicitDistributedActorIDProperty(
propDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true); propDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true);
propDecl->setInterfaceType(propertyType); propDecl->setInterfaceType(propertyType);
Pattern *propPat = NamedPattern::createImplicit(C, propDecl, propertyType); auto propContextTy = nominal->mapTypeIntoContext(propertyType);
propPat = TypedPattern::createImplicit(C, propPat, propertyType);
propPat->setType(propertyType); Pattern *propPat = NamedPattern::createImplicit(C, propDecl, propContextTy);
propPat = TypedPattern::createImplicit(C, propPat, propContextTy);
PatternBindingDecl *pbDecl = PatternBindingDecl::createImplicit( PatternBindingDecl *pbDecl = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr, C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
@@ -150,9 +151,10 @@ static VarDecl *addImplicitDistributedActorActorSystemProperty(
propDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true); propDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true);
propDecl->setInterfaceType(propertyType); propDecl->setInterfaceType(propertyType);
Pattern *propPat = NamedPattern::createImplicit(C, propDecl, propertyType); auto propContextTy = nominal->mapTypeIntoContext(propertyType);
propPat = TypedPattern::createImplicit(C, propPat, propertyType);
propPat->setType(propertyType); Pattern *propPat = NamedPattern::createImplicit(C, propDecl, propContextTy);
propPat = TypedPattern::createImplicit(C, propPat, propContextTy);
PatternBindingDecl *pbDecl = PatternBindingDecl::createImplicit( PatternBindingDecl *pbDecl = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr, C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,

View File

@@ -140,8 +140,7 @@ static ValueDecl *deriveActor_unownedExecutor(DerivedConformance &derived) {
auto propertyPair = derived.declareDerivedProperty( auto propertyPair = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_unownedExecutor, DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_unownedExecutor,
executorType, executorType, executorType, /*static*/ false, /*final*/ false);
/*static*/ false, /*final*/ false);
auto property = propertyPair.first; auto property = propertyPair.first;
property->setSynthesized(true); property->setSynthesized(true);
property->getAttrs().add(new (ctx) SemanticsAttr(SEMANTICS_DEFAULT_ACTOR, property->getAttrs().add(new (ctx) SemanticsAttr(SEMANTICS_DEFAULT_ACTOR,
@@ -164,8 +163,7 @@ static ValueDecl *deriveActor_unownedExecutor(DerivedConformance &derived) {
AvailabilityInference::applyInferredAvailableAttrs( AvailabilityInference::applyInferredAvailableAttrs(
property, asAvailableAs, ctx); property, asAvailableAs, ctx);
auto getter = auto getter = derived.addGetterToReadOnlyDerivedProperty(property);
derived.addGetterToReadOnlyDerivedProperty(property, executorType);
getter->setBodySynthesizer(deriveBodyActor_unownedExecutor); getter->setBodySynthesizer(deriveBodyActor_unownedExecutor);
derived.addMembersToConformanceContext( derived.addMembersToConformanceContext(

View File

@@ -292,22 +292,19 @@ deriveBodyAdditiveArithmetic_zero(AbstractFunctionDecl *funcDecl, void *) {
static ValueDecl *deriveAdditiveArithmetic_zero(DerivedConformance &derived) { static ValueDecl *deriveAdditiveArithmetic_zero(DerivedConformance &derived) {
auto &C = derived.Context; auto &C = derived.Context;
auto *nominal = derived.Nominal; auto *nominal = derived.Nominal;
auto *parentDC = derived.getConformanceContext();
auto returnInterfaceTy = nominal->getDeclaredInterfaceType(); auto returnInterfaceTy = nominal->getDeclaredInterfaceType();
auto returnTy = parentDC->mapTypeIntoContext(returnInterfaceTy);
// Create property declaration. // Create property declaration.
VarDecl *propDecl; VarDecl *propDecl;
PatternBindingDecl *pbDecl; PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty( std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, C.Id_zero, DerivedConformance::SynthesizedIntroducer::Var, C.Id_zero,
returnInterfaceTy, returnTy, /*isStatic*/ true, returnInterfaceTy,
/*isFinal*/ true); /*isStatic*/ true, /*isFinal*/ true);
// Create property getter. // Create property getter.
auto *getterDecl = auto *getterDecl = derived.addGetterToReadOnlyDerivedProperty(propDecl);
derived.addGetterToReadOnlyDerivedProperty(propDecl, returnTy);
getterDecl->setBodySynthesizer(deriveBodyAdditiveArithmetic_zero, nullptr); getterDecl->setBodySynthesizer(deriveBodyAdditiveArithmetic_zero, nullptr);
derived.addMembersToConformanceContext({propDecl, pbDecl}); derived.addMembersToConformanceContext({propDecl, pbDecl});

View File

@@ -101,14 +101,14 @@ ValueDecl *DerivedConformance::deriveCaseIterable(ValueDecl *requirement) {
VarDecl *propDecl; VarDecl *propDecl;
PatternBindingDecl *pbDecl; PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = declareDerivedProperty( std::tie(propDecl, pbDecl) = declareDerivedProperty(
SynthesizedIntroducer::Var, Context.Id_allCases, returnTy, returnTy, SynthesizedIntroducer::Var, Context.Id_allCases, returnTy,
/*isStatic=*/true, /*isFinal=*/true); /*isStatic=*/true, /*isFinal=*/true);
propDecl->getAttrs().add( propDecl->getAttrs().add(
new (C) NonisolatedAttr(/*unsafe=*/false, /*implicit=*/true)); new (C) NonisolatedAttr(/*unsafe=*/false, /*implicit=*/true));
// Define the getter. // Define the getter.
auto *getterDecl = addGetterToReadOnlyDerivedProperty(propDecl, returnTy); auto *getterDecl = addGetterToReadOnlyDerivedProperty(propDecl);
getterDecl->setBodySynthesizer(&deriveCaseIterable_enum_getter); getterDecl->setBodySynthesizer(&deriveCaseIterable_enum_getter);

View File

@@ -163,12 +163,11 @@ static ValueDecl *deriveProperty(DerivedConformance &derived, Type type,
VarDecl *propDecl; VarDecl *propDecl;
PatternBindingDecl *pbDecl; PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty( std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, name, type, type, DerivedConformance::SynthesizedIntroducer::Var, name, type,
/*isStatic=*/false, /*isFinal=*/false); /*isStatic=*/false, /*isFinal=*/false);
// Define the getter. // Define the getter.
auto *getterDecl = derived.addGetterToReadOnlyDerivedProperty( auto *getterDecl = derived.addGetterToReadOnlyDerivedProperty(propDecl);
propDecl, type);
// Synthesize the body. // Synthesize the body.
synthesizer(getterDecl); synthesizer(getterDecl);

View File

@@ -413,14 +413,16 @@ getOrSynthesizeTangentVectorStruct(DerivedConformance &derived, Identifier id) {
// causes the type checker to not guarantee the order of these members. // causes the type checker to not guarantee the order of these members.
auto memberContextualType = auto memberContextualType =
parentDC->mapTypeIntoContext(member->getValueInterfaceType()); parentDC->mapTypeIntoContext(member->getValueInterfaceType());
auto memberTanType = auto memberTanInterfaceType =
getTangentVectorInterfaceType(memberContextualType, parentDC); getTangentVectorInterfaceType(memberContextualType, parentDC);
tangentProperty->setInterfaceType(memberTanType); tangentProperty->setInterfaceType(memberTanInterfaceType);
auto memberTanContextType =
parentDC->mapTypeIntoContext(memberTanInterfaceType);
Pattern *memberPattern = Pattern *memberPattern =
NamedPattern::createImplicit(C, tangentProperty, memberTanType); NamedPattern::createImplicit(C, tangentProperty, memberTanContextType);
memberPattern = memberPattern =
TypedPattern::createImplicit(C, memberPattern, memberTanType); TypedPattern::createImplicit(C, memberPattern, memberTanContextType);
memberPattern->setType(memberTanType);
auto *memberBinding = PatternBindingDecl::createImplicit( auto *memberBinding = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, memberPattern, /*initExpr*/ nullptr, C, StaticSpellingKind::None, memberPattern, /*initExpr*/ nullptr,
structDecl); structDecl);

View File

@@ -456,7 +456,6 @@ static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
PatternBindingDecl *pbDecl; PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty( std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Let, C.Id_id, propertyType, DerivedConformance::SynthesizedIntroducer::Let, C.Id_id, propertyType,
propertyType,
/*isStatic=*/false, /*isFinal=*/true); /*isStatic=*/false, /*isFinal=*/true);
// mark as nonisolated, allowing access to it from everywhere // mark as nonisolated, allowing access to it from everywhere
@@ -488,8 +487,7 @@ static ValueDecl *deriveDistributedActor_actorSystem(
PatternBindingDecl *pbDecl; PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty( std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Let, C.Id_actorSystem, DerivedConformance::SynthesizedIntroducer::Let, C.Id_actorSystem,
propertyType, propertyType, propertyType, /*isStatic=*/false, /*isFinal=*/true);
/*isStatic=*/false, /*isFinal=*/true);
// mark as nonisolated, allowing access to it from everywhere // mark as nonisolated, allowing access to it from everywhere
propDecl->getAttrs().add( propDecl->getAttrs().add(
@@ -791,8 +789,7 @@ static ValueDecl *deriveDistributedActor_unownedExecutor(DerivedConformance &der
auto propertyPair = derived.declareDerivedProperty( auto propertyPair = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_unownedExecutor, DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_unownedExecutor,
executorType, executorType, executorType, /*static*/ false, /*final*/ false);
/*static*/ false, /*final*/ false);
auto property = propertyPair.first; auto property = propertyPair.first;
property->setSynthesized(true); property->setSynthesized(true);
property->getAttrs().add(new (ctx) SemanticsAttr(SEMANTICS_DEFAULT_ACTOR, property->getAttrs().add(new (ctx) SemanticsAttr(SEMANTICS_DEFAULT_ACTOR,
@@ -815,8 +812,7 @@ static ValueDecl *deriveDistributedActor_unownedExecutor(DerivedConformance &der
AvailabilityInference::applyInferredAvailableAttrs( AvailabilityInference::applyInferredAvailableAttrs(
property, asAvailableAs, ctx); property, asAvailableAs, ctx);
auto getter = auto getter = derived.addGetterToReadOnlyDerivedProperty(property);
derived.addGetterToReadOnlyDerivedProperty(property, executorType);
getter->setBodySynthesizer(deriveBodyDistributedActor_unownedExecutor); getter->setBodySynthesizer(deriveBodyDistributedActor_unownedExecutor);
// IMPORTANT: MUST BE AFTER [id, actorSystem]. // IMPORTANT: MUST BE AFTER [id, actorSystem].

View File

@@ -919,7 +919,6 @@ static ValueDecl *deriveHashable_hashValue(DerivedConformance &derived) {
Pattern *hashValuePat = Pattern *hashValuePat =
NamedPattern::createImplicit(C, hashValueDecl, intType); NamedPattern::createImplicit(C, hashValueDecl, intType);
hashValuePat = TypedPattern::createImplicit(C, hashValuePat, intType); hashValuePat = TypedPattern::createImplicit(C, hashValuePat, intType);
hashValuePat->setType(intType);
auto *patDecl = PatternBindingDecl::createImplicit( auto *patDecl = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, hashValuePat, /*InitExpr*/ nullptr, C, StaticSpellingKind::None, hashValuePat, /*InitExpr*/ nullptr,

View File

@@ -98,13 +98,12 @@ deriveBridgedNSError_enum_nsErrorDomain(
PatternBindingDecl *pbDecl; PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty( std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, DerivedConformance::SynthesizedIntroducer::Var,
derived.Context.Id_nsErrorDomain, stringTy, stringTy, /*isStatic=*/true, derived.Context.Id_nsErrorDomain, stringTy, /*isStatic=*/true,
/*isFinal=*/true); /*isFinal=*/true);
addNonIsolatedToSynthesized(derived.Nominal, propDecl); addNonIsolatedToSynthesized(derived.Nominal, propDecl);
// Define the getter. // Define the getter.
auto getterDecl = derived.addGetterToReadOnlyDerivedProperty( auto getterDecl = derived.addGetterToReadOnlyDerivedProperty(propDecl);
propDecl, stringTy);
getterDecl->setBodySynthesizer(synthesizer); getterDecl->setBodySynthesizer(synthesizer);
derived.addMembersToConformanceContext({propDecl, pbDecl}); derived.addMembersToConformanceContext({propDecl, pbDecl});

View File

@@ -157,22 +157,19 @@ static VarDecl *deriveRawRepresentable_raw(DerivedConformance &derived) {
ASTContext &C = derived.Context; ASTContext &C = derived.Context;
auto enumDecl = cast<EnumDecl>(derived.Nominal); auto enumDecl = cast<EnumDecl>(derived.Nominal);
auto parentDC = derived.getConformanceContext();
auto rawInterfaceType = enumDecl->getRawType(); auto rawInterfaceType = enumDecl->getRawType();
auto rawType = parentDC->mapTypeIntoContext(rawInterfaceType);
// Define the property. // Define the property.
VarDecl *propDecl; VarDecl *propDecl;
PatternBindingDecl *pbDecl; PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty( std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, C.Id_rawValue, DerivedConformance::SynthesizedIntroducer::Var, C.Id_rawValue,
rawInterfaceType, rawType, /*isStatic=*/false, rawInterfaceType, /*isStatic=*/false, /*isFinal=*/false);
/*isFinal=*/false);
addNonIsolatedToSynthesized(enumDecl, propDecl); addNonIsolatedToSynthesized(enumDecl, propDecl);
// Define the getter. // Define the getter.
auto getterDecl = DerivedConformance::addGetterToReadOnlyDerivedProperty( auto getterDecl =
propDecl, rawType); DerivedConformance::addGetterToReadOnlyDerivedProperty(propDecl);
getterDecl->setBodySynthesizer(&deriveBodyRawRepresentable_raw); getterDecl->setBodySynthesizer(&deriveBodyRawRepresentable_raw);
// If the containing module is not resilient, make sure clients can get at // If the containing module is not resilient, make sure clients can get at

View File

@@ -510,11 +510,9 @@ CallExpr *DerivedConformance::createDiagnoseUnavailableCodeReachedCallExpr(
return callExpr; return callExpr;
} }
AccessorDecl *DerivedConformance:: AccessorDecl *
addGetterToReadOnlyDerivedProperty(VarDecl *property, DerivedConformance::addGetterToReadOnlyDerivedProperty(VarDecl *property) {
Type propertyContextType) { auto getter = declareDerivedPropertyGetter(property);
auto getter =
declareDerivedPropertyGetter(property, propertyContextType);
property->setImplInfo(StorageImplInfo::getImmutableComputed()); property->setImplInfo(StorageImplInfo::getImmutableComputed());
property->setAccessors(SourceLoc(), {getter}, SourceLoc()); property->setAccessors(SourceLoc(), {getter}, SourceLoc());
@@ -523,8 +521,7 @@ addGetterToReadOnlyDerivedProperty(VarDecl *property,
} }
AccessorDecl * AccessorDecl *
DerivedConformance::declareDerivedPropertyGetter(VarDecl *property, DerivedConformance::declareDerivedPropertyGetter(VarDecl *property) {
Type propertyContextType) {
auto &C = property->getASTContext(); auto &C = property->getASTContext();
auto parentDC = property->getDeclContext(); auto parentDC = property->getDeclContext();
ParameterList *params = ParameterList::createEmpty(C); ParameterList *params = ParameterList::createEmpty(C);
@@ -558,7 +555,6 @@ std::pair<VarDecl *, PatternBindingDecl *>
DerivedConformance::declareDerivedProperty(SynthesizedIntroducer intro, DerivedConformance::declareDerivedProperty(SynthesizedIntroducer intro,
Identifier name, Identifier name,
Type propertyInterfaceType, Type propertyInterfaceType,
Type propertyContextType,
bool isStatic, bool isFinal) { bool isStatic, bool isFinal) {
auto parentDC = getConformanceContext(); auto parentDC = getConformanceContext();
@@ -569,11 +565,13 @@ DerivedConformance::declareDerivedProperty(SynthesizedIntroducer intro,
propDecl->copyFormalAccessFrom(Nominal, /*sourceIsParentContext*/ true); propDecl->copyFormalAccessFrom(Nominal, /*sourceIsParentContext*/ true);
propDecl->setInterfaceType(propertyInterfaceType); propDecl->setInterfaceType(propertyInterfaceType);
auto propertyContextType =
getConformanceContext()->mapTypeIntoContext(propertyInterfaceType);
Pattern *propPat = Pattern *propPat =
NamedPattern::createImplicit(Context, propDecl, propertyContextType); NamedPattern::createImplicit(Context, propDecl, propertyContextType);
propPat = TypedPattern::createImplicit(Context, propPat, propertyContextType); propPat = TypedPattern::createImplicit(Context, propPat, propertyContextType);
propPat->setType(propertyContextType);
auto *pbDecl = PatternBindingDecl::createImplicit( auto *pbDecl = PatternBindingDecl::createImplicit(
Context, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr, Context, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
@@ -770,7 +768,7 @@ DeclRefExpr *DerivedConformance::convertEnumToIndex(SmallVectorImpl<ASTNode> &st
// generate: var indexVar // generate: var indexVar
Pattern *indexPat = NamedPattern::createImplicit(C, indexVar, intType); Pattern *indexPat = NamedPattern::createImplicit(C, indexVar, intType);
indexPat = TypedPattern::createImplicit(C, indexPat, intType); indexPat = TypedPattern::createImplicit(C, indexPat, intType);
indexPat->setType(intType);
auto *indexBind = PatternBindingDecl::createImplicit( auto *indexBind = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, indexPat, /*InitExpr*/ nullptr, funcDecl); C, StaticSpellingKind::None, indexPat, /*InitExpr*/ nullptr, funcDecl);

View File

@@ -368,18 +368,14 @@ public:
/// Declare a read-only property. /// Declare a read-only property.
std::pair<VarDecl *, PatternBindingDecl *> std::pair<VarDecl *, PatternBindingDecl *>
declareDerivedProperty(SynthesizedIntroducer intro, Identifier name, declareDerivedProperty(SynthesizedIntroducer intro, Identifier name,
Type propertyInterfaceType, Type propertyContextType, Type propertyContextType, bool isStatic, bool isFinal);
bool isStatic, bool isFinal);
/// Add a getter to a derived property. The property becomes read-only. /// Add a getter to a derived property. The property becomes read-only.
static AccessorDecl * static AccessorDecl *addGetterToReadOnlyDerivedProperty(VarDecl *property);
addGetterToReadOnlyDerivedProperty(VarDecl *property,
Type propertyContextType);
/// Declare a getter for a derived property. /// Declare a getter for a derived property.
/// The getter will not be added to the property yet. /// The getter will not be added to the property yet.
static AccessorDecl *declareDerivedPropertyGetter(VarDecl *property, static AccessorDecl *declareDerivedPropertyGetter(VarDecl *property);
Type propertyContextType);
/// Build a reference to the 'self' decl of a derived function. /// Build a reference to the 'self' decl of a derived function.
static DeclRefExpr *createSelfDeclRef(AbstractFunctionDecl *fn); static DeclRefExpr *createSelfDeclRef(AbstractFunctionDecl *fn);

View File

@@ -754,6 +754,8 @@ Type TypeChecker::typeCheckPattern(ContextualPattern pattern) {
ASTContext &ctx = dc->getASTContext(); ASTContext &ctx = dc->getASTContext();
if (auto type = evaluateOrDefault(ctx.evaluator, PatternTypeRequest{pattern}, if (auto type = evaluateOrDefault(ctx.evaluator, PatternTypeRequest{pattern},
Type())) { Type())) {
ASSERT(!type->hasTypeParameter() &&
"pattern should have a contextual type");
return type; return type;
} }