Skip to content

[Sema] Enforce PatternTypeRequest returns contextual type #75011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions lib/Sema/CodeSynthesisDistributedActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@ static VarDecl *addImplicitDistributedActorIDProperty(
propDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true);
propDecl->setInterfaceType(propertyType);

Pattern *propPat = NamedPattern::createImplicit(C, propDecl, propertyType);
propPat = TypedPattern::createImplicit(C, propPat, propertyType);
propPat->setType(propertyType);
auto propContextTy = nominal->mapTypeIntoContext(propertyType);

Pattern *propPat = NamedPattern::createImplicit(C, propDecl, propContextTy);
propPat = TypedPattern::createImplicit(C, propPat, propContextTy);

PatternBindingDecl *pbDecl = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
Expand Down Expand Up @@ -150,9 +151,10 @@ static VarDecl *addImplicitDistributedActorActorSystemProperty(
propDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true);
propDecl->setInterfaceType(propertyType);

Pattern *propPat = NamedPattern::createImplicit(C, propDecl, propertyType);
propPat = TypedPattern::createImplicit(C, propPat, propertyType);
propPat->setType(propertyType);
auto propContextTy = nominal->mapTypeIntoContext(propertyType);

Pattern *propPat = NamedPattern::createImplicit(C, propDecl, propContextTy);
propPat = TypedPattern::createImplicit(C, propPat, propContextTy);

PatternBindingDecl *pbDecl = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
Expand Down
6 changes: 2 additions & 4 deletions lib/Sema/DerivedConformanceActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ static ValueDecl *deriveActor_unownedExecutor(DerivedConformance &derived) {

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

auto getter =
derived.addGetterToReadOnlyDerivedProperty(property, executorType);
auto getter = derived.addGetterToReadOnlyDerivedProperty(property);
getter->setBodySynthesizer(deriveBodyActor_unownedExecutor);

derived.addMembersToConformanceContext(
Expand Down
9 changes: 3 additions & 6 deletions lib/Sema/DerivedConformanceAdditiveArithmetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,22 +292,19 @@ deriveBodyAdditiveArithmetic_zero(AbstractFunctionDecl *funcDecl, void *) {
static ValueDecl *deriveAdditiveArithmetic_zero(DerivedConformance &derived) {
auto &C = derived.Context;
auto *nominal = derived.Nominal;
auto *parentDC = derived.getConformanceContext();

auto returnInterfaceTy = nominal->getDeclaredInterfaceType();
auto returnTy = parentDC->mapTypeIntoContext(returnInterfaceTy);

// Create property declaration.
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, C.Id_zero,
returnInterfaceTy, returnTy, /*isStatic*/ true,
/*isFinal*/ true);
returnInterfaceTy,
/*isStatic*/ true, /*isFinal*/ true);

// Create property getter.
auto *getterDecl =
derived.addGetterToReadOnlyDerivedProperty(propDecl, returnTy);
auto *getterDecl = derived.addGetterToReadOnlyDerivedProperty(propDecl);
getterDecl->setBodySynthesizer(deriveBodyAdditiveArithmetic_zero, nullptr);

derived.addMembersToConformanceContext({propDecl, pbDecl});
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/DerivedConformanceCaseIterable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ ValueDecl *DerivedConformance::deriveCaseIterable(ValueDecl *requirement) {
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = declareDerivedProperty(
SynthesizedIntroducer::Var, Context.Id_allCases, returnTy, returnTy,
SynthesizedIntroducer::Var, Context.Id_allCases, returnTy,
/*isStatic=*/true, /*isFinal=*/true);

propDecl->getAttrs().add(
new (C) NonisolatedAttr(/*unsafe=*/false, /*implicit=*/true));

// Define the getter.
auto *getterDecl = addGetterToReadOnlyDerivedProperty(propDecl, returnTy);
auto *getterDecl = addGetterToReadOnlyDerivedProperty(propDecl);

getterDecl->setBodySynthesizer(&deriveCaseIterable_enum_getter);

Expand Down
5 changes: 2 additions & 3 deletions lib/Sema/DerivedConformanceCodingKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,11 @@ static ValueDecl *deriveProperty(DerivedConformance &derived, Type type,
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, name, type, type,
DerivedConformance::SynthesizedIntroducer::Var, name, type,
/*isStatic=*/false, /*isFinal=*/false);

// Define the getter.
auto *getterDecl = derived.addGetterToReadOnlyDerivedProperty(
propDecl, type);
auto *getterDecl = derived.addGetterToReadOnlyDerivedProperty(propDecl);

// Synthesize the body.
synthesizer(getterDecl);
Expand Down
12 changes: 7 additions & 5 deletions lib/Sema/DerivedConformanceDifferentiable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,14 +413,16 @@ getOrSynthesizeTangentVectorStruct(DerivedConformance &derived, Identifier id) {
// causes the type checker to not guarantee the order of these members.
auto memberContextualType =
parentDC->mapTypeIntoContext(member->getValueInterfaceType());
auto memberTanType =
auto memberTanInterfaceType =
getTangentVectorInterfaceType(memberContextualType, parentDC);
tangentProperty->setInterfaceType(memberTanType);
tangentProperty->setInterfaceType(memberTanInterfaceType);
auto memberTanContextType =
parentDC->mapTypeIntoContext(memberTanInterfaceType);
Pattern *memberPattern =
NamedPattern::createImplicit(C, tangentProperty, memberTanType);
NamedPattern::createImplicit(C, tangentProperty, memberTanContextType);
memberPattern =
TypedPattern::createImplicit(C, memberPattern, memberTanType);
memberPattern->setType(memberTanType);
TypedPattern::createImplicit(C, memberPattern, memberTanContextType);

auto *memberBinding = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, memberPattern, /*initExpr*/ nullptr,
structDecl);
Expand Down
10 changes: 3 additions & 7 deletions lib/Sema/DerivedConformanceDistributedActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,6 @@ static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Let, C.Id_id, propertyType,
propertyType,
/*isStatic=*/false, /*isFinal=*/true);

// mark as nonisolated, allowing access to it from everywhere
Expand Down Expand Up @@ -488,8 +487,7 @@ static ValueDecl *deriveDistributedActor_actorSystem(
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Let, C.Id_actorSystem,
propertyType, propertyType,
/*isStatic=*/false, /*isFinal=*/true);
propertyType, /*isStatic=*/false, /*isFinal=*/true);

// mark as nonisolated, allowing access to it from everywhere
propDecl->getAttrs().add(
Expand Down Expand Up @@ -791,8 +789,7 @@ static ValueDecl *deriveDistributedActor_unownedExecutor(DerivedConformance &der

auto propertyPair = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_unownedExecutor,
executorType, executorType,
/*static*/ false, /*final*/ false);
executorType, /*static*/ false, /*final*/ false);
auto property = propertyPair.first;
property->setSynthesized(true);
property->getAttrs().add(new (ctx) SemanticsAttr(SEMANTICS_DEFAULT_ACTOR,
Expand All @@ -815,8 +812,7 @@ static ValueDecl *deriveDistributedActor_unownedExecutor(DerivedConformance &der
AvailabilityInference::applyInferredAvailableAttrs(
property, asAvailableAs, ctx);

auto getter =
derived.addGetterToReadOnlyDerivedProperty(property, executorType);
auto getter = derived.addGetterToReadOnlyDerivedProperty(property);
getter->setBodySynthesizer(deriveBodyDistributedActor_unownedExecutor);

// IMPORTANT: MUST BE AFTER [id, actorSystem].
Expand Down
1 change: 0 additions & 1 deletion lib/Sema/DerivedConformanceEquatableHashable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,6 @@ static ValueDecl *deriveHashable_hashValue(DerivedConformance &derived) {
Pattern *hashValuePat =
NamedPattern::createImplicit(C, hashValueDecl, intType);
hashValuePat = TypedPattern::createImplicit(C, hashValuePat, intType);
hashValuePat->setType(intType);

auto *patDecl = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, hashValuePat, /*InitExpr*/ nullptr,
Expand Down
5 changes: 2 additions & 3 deletions lib/Sema/DerivedConformanceError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,12 @@ deriveBridgedNSError_enum_nsErrorDomain(
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var,
derived.Context.Id_nsErrorDomain, stringTy, stringTy, /*isStatic=*/true,
derived.Context.Id_nsErrorDomain, stringTy, /*isStatic=*/true,
/*isFinal=*/true);
addNonIsolatedToSynthesized(derived.Nominal, propDecl);

// Define the getter.
auto getterDecl = derived.addGetterToReadOnlyDerivedProperty(
propDecl, stringTy);
auto getterDecl = derived.addGetterToReadOnlyDerivedProperty(propDecl);
getterDecl->setBodySynthesizer(synthesizer);

derived.addMembersToConformanceContext({propDecl, pbDecl});
Expand Down
9 changes: 3 additions & 6 deletions lib/Sema/DerivedConformanceRawRepresentable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,22 +160,19 @@ static VarDecl *deriveRawRepresentable_raw(DerivedConformance &derived) {
ASTContext &C = derived.Context;

auto enumDecl = cast<EnumDecl>(derived.Nominal);
auto parentDC = derived.getConformanceContext();
auto rawInterfaceType = enumDecl->getRawType();
auto rawType = parentDC->mapTypeIntoContext(rawInterfaceType);

// Define the property.
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
DerivedConformance::SynthesizedIntroducer::Var, C.Id_rawValue,
rawInterfaceType, rawType, /*isStatic=*/false,
/*isFinal=*/false);
rawInterfaceType, /*isStatic=*/false, /*isFinal=*/false);
addNonIsolatedToSynthesized(enumDecl, propDecl);

// Define the getter.
auto getterDecl = DerivedConformance::addGetterToReadOnlyDerivedProperty(
propDecl, rawType);
auto getterDecl =
DerivedConformance::addGetterToReadOnlyDerivedProperty(propDecl);
getterDecl->setBodySynthesizer(&deriveBodyRawRepresentable_raw);

// If the containing module is not resilient, make sure clients can get at
Expand Down
18 changes: 8 additions & 10 deletions lib/Sema/DerivedConformances.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,9 @@ CallExpr *DerivedConformance::createDiagnoseUnavailableCodeReachedCallExpr(
return callExpr;
}

AccessorDecl *DerivedConformance::
addGetterToReadOnlyDerivedProperty(VarDecl *property,
Type propertyContextType) {
auto getter =
declareDerivedPropertyGetter(property, propertyContextType);
AccessorDecl *
DerivedConformance::addGetterToReadOnlyDerivedProperty(VarDecl *property) {
auto getter = declareDerivedPropertyGetter(property);

property->setImplInfo(StorageImplInfo::getImmutableComputed());
property->setAccessors(SourceLoc(), {getter}, SourceLoc());
Expand All @@ -523,8 +521,7 @@ addGetterToReadOnlyDerivedProperty(VarDecl *property,
}

AccessorDecl *
DerivedConformance::declareDerivedPropertyGetter(VarDecl *property,
Type propertyContextType) {
DerivedConformance::declareDerivedPropertyGetter(VarDecl *property) {
auto &C = property->getASTContext();
auto parentDC = property->getDeclContext();
ParameterList *params = ParameterList::createEmpty(C);
Expand Down Expand Up @@ -558,7 +555,6 @@ std::pair<VarDecl *, PatternBindingDecl *>
DerivedConformance::declareDerivedProperty(SynthesizedIntroducer intro,
Identifier name,
Type propertyInterfaceType,
Type propertyContextType,
bool isStatic, bool isFinal) {
auto parentDC = getConformanceContext();

Expand All @@ -569,11 +565,13 @@ DerivedConformance::declareDerivedProperty(SynthesizedIntroducer intro,
propDecl->copyFormalAccessFrom(Nominal, /*sourceIsParentContext*/ true);
propDecl->setInterfaceType(propertyInterfaceType);

auto propertyContextType =
getConformanceContext()->mapTypeIntoContext(propertyInterfaceType);

Pattern *propPat =
NamedPattern::createImplicit(Context, propDecl, propertyContextType);

propPat = TypedPattern::createImplicit(Context, propPat, propertyContextType);
propPat->setType(propertyContextType);

auto *pbDecl = PatternBindingDecl::createImplicit(
Context, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
Expand Down Expand Up @@ -770,7 +768,7 @@ DeclRefExpr *DerivedConformance::convertEnumToIndex(SmallVectorImpl<ASTNode> &st
// generate: var indexVar
Pattern *indexPat = NamedPattern::createImplicit(C, indexVar, intType);
indexPat = TypedPattern::createImplicit(C, indexPat, intType);
indexPat->setType(intType);

auto *indexBind = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, indexPat, /*InitExpr*/ nullptr, funcDecl);

Expand Down
10 changes: 3 additions & 7 deletions lib/Sema/DerivedConformances.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,18 +368,14 @@ class DerivedConformance {
/// Declare a read-only property.
std::pair<VarDecl *, PatternBindingDecl *>
declareDerivedProperty(SynthesizedIntroducer intro, Identifier name,
Type propertyInterfaceType, Type propertyContextType,
bool isStatic, bool isFinal);
Type propertyContextType, bool isStatic, bool isFinal);

/// Add a getter to a derived property. The property becomes read-only.
static AccessorDecl *
addGetterToReadOnlyDerivedProperty(VarDecl *property,
Type propertyContextType);
static AccessorDecl *addGetterToReadOnlyDerivedProperty(VarDecl *property);

/// Declare a getter for a derived property.
/// The getter will not be added to the property yet.
static AccessorDecl *declareDerivedPropertyGetter(VarDecl *property,
Type propertyContextType);
static AccessorDecl *declareDerivedPropertyGetter(VarDecl *property);

/// Build a reference to the 'self' decl of a derived function.
static DeclRefExpr *createSelfDeclRef(AbstractFunctionDecl *fn);
Expand Down
2 changes: 2 additions & 0 deletions lib/Sema/TypeCheckPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,8 @@ Type TypeChecker::typeCheckPattern(ContextualPattern pattern) {
ASTContext &ctx = dc->getASTContext();
if (auto type = evaluateOrDefault(ctx.evaluator, PatternTypeRequest{pattern},
Type())) {
ASSERT(!type->hasTypeParameter() &&
"pattern should have a contextual type");
return type;
}

Expand Down