Skip to content

Commit b183ae1

Browse files
authored
Merge pull request #41812 from CodaFi/imap
Stabilize VarDecl::isLet for ParamDecls
2 parents b09b5c4 + 0d2b2f2 commit b183ae1

14 files changed

+65
-38
lines changed

include/swift/AST/Decl.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5060,6 +5060,13 @@ class VarDecl : public AbstractStorageDecl {
50605060
SourceLoc nameLoc, Identifier name, DeclContext *dc,
50615061
StorageIsMutable_t supportsMutation);
50625062

5063+
protected:
5064+
// Only \c ParamDecl::setSpecifier is allowed to flip this - and it's also
5065+
// on the way out of that business.
5066+
void setIntroducer(Introducer value) {
5067+
Bits.VarDecl.Introducer = uint8_t(value);
5068+
}
5069+
50635070
public:
50645071
VarDecl(bool isStatic, Introducer introducer,
50655072
SourceLoc nameLoc, Identifier name, DeclContext *dc)
@@ -5241,9 +5248,8 @@ class VarDecl : public AbstractStorageDecl {
52415248

52425249
/// Is this an immutable 'let' property?
52435250
///
5244-
/// If this is a ParamDecl, isLet() is true iff
5245-
/// getSpecifier() == Specifier::Default.
5246-
bool isLet() const { return getIntroducer() == Introducer::Let; }
5251+
/// For \c ParamDecl instances, using \c isImmutable is preferred.
5252+
bool isLet() const;
52475253

52485254
/// Is this an "async let" property?
52495255
bool isAsyncLet() const;
@@ -5263,10 +5269,6 @@ class VarDecl : public AbstractStorageDecl {
52635269
return Introducer(Bits.VarDecl.Introducer);
52645270
}
52655271

5266-
void setIntroducer(Introducer value) {
5267-
Bits.VarDecl.Introducer = uint8_t(value);
5268-
}
5269-
52705272
CaptureListExpr *getParentCaptureList() const {
52715273
if (!Parent)
52725274
return nullptr;

lib/AST/Decl.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6373,6 +6373,19 @@ bool VarDecl::isMemberwiseInitialized(bool preferDeclaredProperties) const {
63736373
return true;
63746374
}
63756375

6376+
bool VarDecl::isLet() const {
6377+
// An awful hack that stabilizes the value of 'isLet' for ParamDecl instances.
6378+
//
6379+
// All of the callers in SIL are actually looking for the semantic
6380+
// "is immutable" predicate (present on ParamDecl) and should be migrated to
6381+
// a high-level request. Once this is done, all callers of the introducer and
6382+
// specifier setters can be removed.
6383+
if (auto *PD = dyn_cast<ParamDecl>(this)) {
6384+
return PD->isImmutable();
6385+
}
6386+
return getIntroducer() == Introducer::Let;
6387+
}
6388+
63766389
bool VarDecl::isAsyncLet() const {
63776390
return getAttrs().hasAttribute<AsyncAttr>();
63786391
}

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ static VarDecl *addImplicitDistributedActorIDProperty(
7373
C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
7474
nominal);
7575

76-
propDecl->setIntroducer(VarDecl::Introducer::Let);
77-
7876
// mark as nonisolated, allowing access to it from everywhere
7977
propDecl->getAttrs().add(
8078
new (C) NonisolatedAttr(/*IsImplicit=*/true));

lib/Sema/DerivedConformanceActor.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ static ValueDecl *deriveActor_unownedExecutor(DerivedConformance &derived) {
138138
}
139139
Type executorType = executorDecl->getDeclaredInterfaceType();
140140

141-
auto propertyPair =
142-
derived.declareDerivedProperty(ctx.Id_unownedExecutor,
143-
executorType, executorType,
144-
/*static*/ false, /*final*/ false);
141+
auto propertyPair = derived.declareDerivedProperty(
142+
DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_unownedExecutor,
143+
executorType, executorType,
144+
/*static*/ false, /*final*/ false);
145145
auto property = propertyPair.first;
146146
property->setSynthesized(true);
147147
property->getAttrs().add(new (ctx) SemanticsAttr(SEMANTICS_DEFAULT_ACTOR,

lib/Sema/DerivedConformanceAdditiveArithmetic.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ static ValueDecl *deriveAdditiveArithmetic_zero(DerivedConformance &derived) {
302302
VarDecl *propDecl;
303303
PatternBindingDecl *pbDecl;
304304
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
305-
C.Id_zero, returnInterfaceTy, returnTy, /*isStatic*/ true,
305+
DerivedConformance::SynthesizedIntroducer::Var, C.Id_zero,
306+
returnInterfaceTy, returnTy, /*isStatic*/ true,
306307
/*isFinal*/ true);
307308

308309
// Create property getter.

lib/Sema/DerivedConformanceCaseIterable.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ ValueDecl *DerivedConformance::deriveCaseIterable(ValueDecl *requirement) {
9898

9999
VarDecl *propDecl;
100100
PatternBindingDecl *pbDecl;
101-
std::tie(propDecl, pbDecl) =
102-
declareDerivedProperty(Context.Id_allCases, returnTy, returnTy,
103-
/*isStatic=*/true, /*isFinal=*/true);
101+
std::tie(propDecl, pbDecl) = declareDerivedProperty(
102+
SynthesizedIntroducer::Var, Context.Id_allCases, returnTy, returnTy,
103+
/*isStatic=*/true, /*isFinal=*/true);
104104

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

lib/Sema/DerivedConformanceCodingKey.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ static ValueDecl *deriveProperty(DerivedConformance &derived, Type type,
160160
// Define the property.
161161
VarDecl *propDecl;
162162
PatternBindingDecl *pbDecl;
163-
std::tie(propDecl, pbDecl) =
164-
derived.declareDerivedProperty(name, type, type,
165-
/*isStatic=*/false, /*isFinal=*/false);
163+
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
164+
DerivedConformance::SynthesizedIntroducer::Var, name, type, type,
165+
/*isStatic=*/false, /*isFinal=*/false);
166166

167167
// Define the getter.
168168
auto *getterDecl = derived.addGetterToReadOnlyDerivedProperty(

lib/Sema/DerivedConformanceDistributedActor.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,10 @@ static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
112112
VarDecl *propDecl;
113113
PatternBindingDecl *pbDecl;
114114
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
115-
C.Id_id,
116-
propertyType, propertyType,
115+
DerivedConformance::SynthesizedIntroducer::Let, C.Id_id, propertyType,
116+
propertyType,
117117
/*isStatic=*/false, /*isFinal=*/true);
118118

119-
propDecl->setIntroducer(VarDecl::Introducer::Let);
120-
121119
// mark as nonisolated, allowing access to it from everywhere
122120
propDecl->getAttrs().add(
123121
new (C) NonisolatedAttr(/*IsImplicit=*/true));
@@ -143,12 +141,10 @@ static ValueDecl *deriveDistributedActor_actorSystem(
143141
VarDecl *propDecl;
144142
PatternBindingDecl *pbDecl;
145143
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
146-
C.Id_actorSystem,
144+
DerivedConformance::SynthesizedIntroducer::Let, C.Id_actorSystem,
147145
propertyType, propertyType,
148146
/*isStatic=*/false, /*isFinal=*/true);
149147

150-
propDecl->setIntroducer(VarDecl::Introducer::Let);
151-
152148
// mark as nonisolated, allowing access to it from everywhere
153149
propDecl->getAttrs().add(
154150
new (C) NonisolatedAttr(/*IsImplicit=*/true));

lib/Sema/DerivedConformanceError.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ deriveBridgedNSError_enum_nsErrorDomain(
9797
VarDecl *propDecl;
9898
PatternBindingDecl *pbDecl;
9999
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
100+
DerivedConformance::SynthesizedIntroducer::Var,
100101
derived.Context.Id_nsErrorDomain, stringTy, stringTy, /*isStatic=*/true,
101102
/*isFinal=*/true);
102103

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ static VarDecl *deriveRawRepresentable_raw(DerivedConformance &derived) {
165165
VarDecl *propDecl;
166166
PatternBindingDecl *pbDecl;
167167
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
168-
C.Id_rawValue, rawInterfaceType, rawType, /*isStatic=*/false,
168+
DerivedConformance::SynthesizedIntroducer::Var, C.Id_rawValue,
169+
rawInterfaceType, rawType, /*isStatic=*/false,
169170
/*isFinal=*/false);
170171

171172
// Define the getter.

lib/Sema/DerivedConformances.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -498,16 +498,27 @@ DerivedConformance::declareDerivedPropertyGetter(VarDecl *property,
498498
return getterDecl;
499499
}
500500

501+
static VarDecl::Introducer
502+
mapIntroducer(DerivedConformance::SynthesizedIntroducer intro) {
503+
switch (intro) {
504+
case DerivedConformance::SynthesizedIntroducer::Let:
505+
return VarDecl::Introducer::Let;
506+
case DerivedConformance::SynthesizedIntroducer::Var:
507+
return VarDecl::Introducer::Var;
508+
}
509+
llvm_unreachable("Invalid synthesized introducer!");
510+
}
511+
501512
std::pair<VarDecl *, PatternBindingDecl *>
502-
DerivedConformance::declareDerivedProperty(Identifier name,
513+
DerivedConformance::declareDerivedProperty(SynthesizedIntroducer intro,
514+
Identifier name,
503515
Type propertyInterfaceType,
504516
Type propertyContextType,
505517
bool isStatic, bool isFinal) {
506518
auto parentDC = getConformanceContext();
507519

508-
VarDecl *propDecl = new (Context)
509-
VarDecl(/*IsStatic*/ isStatic, VarDecl::Introducer::Var,
510-
SourceLoc(), name, parentDC);
520+
VarDecl *propDecl = new (Context) VarDecl(
521+
/*IsStatic*/ isStatic, mapIntroducer(intro), SourceLoc(), name, parentDC);
511522
propDecl->setImplicit();
512523
propDecl->setSynthesized();
513524
propDecl->copyFormalAccessFrom(Nominal, /*sourceIsParentContext*/ true);

lib/Sema/DerivedConformances.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class ValueDecl;
4949
class VarDecl;
5050

5151
class DerivedConformance {
52+
public:
53+
enum class SynthesizedIntroducer : bool { Let, Var };
54+
5255
public:
5356
ASTContext &Context;
5457
Decl *ConformanceDecl;
@@ -335,8 +338,9 @@ class DerivedConformance {
335338

336339
/// Declare a read-only property.
337340
std::pair<VarDecl *, PatternBindingDecl *>
338-
declareDerivedProperty(Identifier name, Type propertyInterfaceType,
339-
Type propertyContextType, bool isStatic, bool isFinal);
341+
declareDerivedProperty(SynthesizedIntroducer intro, Identifier name,
342+
Type propertyInterfaceType, Type propertyContextType,
343+
bool isStatic, bool isFinal);
340344

341345
/// Add a getter to a derived property. The property becomes read-only.
342346
static AccessorDecl *

test/DebugInfo/debug_value_addr.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func use<T>(_ t : T) {}
2828
// CHECK-SIL: sil hidden @$s16debug_value_addr11GenericSelfV1xACyxGx_tcfC : $@convention(method) <T> (@in T, @thin GenericSelf<T>.Type) -> GenericSelf<T> {
2929
// CHECK-SIL: bb0(%0 : $*T, %1 : $@thin GenericSelf<T>.Type):
3030
//
31-
// CHECK-SIL-NEXT: alloc_stack [lexical] $GenericSelf<T>, {{var|let}}, name "self", implicit, loc {{.*}}
31+
// CHECK-SIL-NEXT: alloc_stack [lexical] $GenericSelf<T>, var, name "self", implicit, loc {{.*}}
3232
// CHECK-SIL-NEXT: debug_value %0 : $*T, let, name "x", argno 1, expr op_deref, loc {{.*}}
3333
struct GenericSelf<T> {
3434
init(x: T) {

test/SILOptimizer/move_function_kills_copyable_values.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,10 @@ public struct Pair {
227227
// have invalidated a part of pair. We can be less restrictive in the future.
228228
//
229229
// TODO: Why are we emitting two uses here.
230-
public func performMoveOnOneEltOfPair(_ p: __owned Pair) {
230+
public func performMoveOnOneEltOfPair(_ p: __owned Pair) { // expected-error {{'p' used after being moved}}
231231
let _ = p.z
232-
let _ = _move(p.x) // expected-error {{_move applied to value that the compiler does not support checking}}
233-
nonConsumingUse(p.y)
232+
let _ = _move(p.x) // expected-note {{move here}}
233+
nonConsumingUse(p.y) // expected-note 2 {{use here}}
234234
}
235235

236236
public class KlassPair {

0 commit comments

Comments
 (0)