Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.

Commit 5633a9a

Browse files
committed
Merge branch 'master' of github.com:apple/swift into tensorflow-stage
* 'master' of github.com:apple/swift: [Docs] Update the documentation contents and index (swiftlang#34157) [SILGen] Don't use assign_by_wrapper for local property wrappers if there is an initial wrapped value. [Property Wrappers] Ban non-member property wrappers with observers, just like we do for regular non-member properties. [Test] Start to add SILGen tests for local property wrappers. [SILGen] Add a new CaptureEmission kind specifically for emitting captured local variables for the assign_by_wrapper setter. [Name Lookup] Remove property wrapper name lookup flags and generalize unqualified lookup of auxiliary decl names. [Property Wrappers] Generalize a few property wrapper decl context checks to check for type context instead of local context. [Property Wrappers] Add a VarDecl helper method for visiting synthesized property wrapper vars. [Property Wrappers] Allow property wrappers on local variables. [Property Wrappers] Make sure captures are computed for synthesized property wrapper accessors. [SILGen] Only use assign_by_wrapper for wrapped instance properties inside an initializer, and for wrapped local variables. [SILGen] Teach SIlGen to emit local property wrappers [NameLookup] Teach unqualified lookup to resolve backing property wrapper and projected value references [Parser] Don't resolve decl references in the parser if the declaration has a custom attribute.
2 parents 5078124 + ac06148 commit 5633a9a

21 files changed

+347
-56
lines changed

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ documentation, please create a thread on the Swift forums under the
113113
Describes how the "Omit Needless Words" algorithm works,
114114
making imported names more idiomatic.
115115
- Type-checking and inference:
116-
- [TypeChecker.rst](/docs/TypeChecker.rst):
116+
- [TypeChecker.md](/docs/TypeChecker.md):
117117
Provides an overview of how type-checking and inference work.
118118
- [RequestEvaluator.md](/docs/RequestEvaluator.md):
119119
Describes the request evaluator architecture, which is used for

docs/contents.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Contents
1212
Generics
1313
StoredAndComputedVariables
1414
SIL
15-
TypeChecker
1615
OptimizationTips
1716
ABI: TypeMetadata <ABI/TypeMetadata>
1817
ABI: TypeLayout <ABI/TypeLayout>

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4865,6 +4865,14 @@ class VarDecl : public AbstractStorageDecl {
48654865
/// property wrapper with a \c projectedValue .
48664866
VarDecl *getPropertyWrapperProjectionVar() const;
48674867

4868+
/// Visit all auxiliary declarations to this VarDecl.
4869+
///
4870+
/// An auxiliary declaration is a declaration synthesized by the compiler to support
4871+
/// this VarDecl, such as synthesized property wrapper variables.
4872+
///
4873+
/// \note this function only visits auxiliary decls that are not part of the AST.
4874+
void visitAuxiliaryDecls(llvm::function_ref<void(VarDecl *)>) const;
4875+
48684876
/// Retrieve the backing storage property for a lazy property.
48694877
VarDecl *getLazyStorageProperty() const;
48704878

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5275,8 +5275,6 @@ ERROR(property_wrapper_mutating_get_composed_to_get_only,none,
52755275
"property wrapper %0 with a mutating getter cannot be composed inside "
52765276
"get-only property wrapper %1", (TypeLoc, TypeLoc))
52775277

5278-
ERROR(property_wrapper_local,none,
5279-
"property wrappers are not yet supported on local properties", ())
52805278
ERROR(property_wrapper_top_level,none,
52815279
"property wrappers are not yet supported in top-level code", ())
52825280
ERROR(property_wrapper_let, none,

lib/AST/Decl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5888,6 +5888,17 @@ VarDecl *VarDecl::getPropertyWrapperProjectionVar() const {
58885888
return getPropertyWrapperBackingPropertyInfo().projectionVar;
58895889
}
58905890

5891+
void VarDecl::visitAuxiliaryDecls(llvm::function_ref<void(VarDecl *)> visit) const {
5892+
if (getDeclContext()->isTypeContext())
5893+
return;
5894+
5895+
if (auto *backingVar = getPropertyWrapperBackingProperty())
5896+
visit(backingVar);
5897+
5898+
if (auto *projectionVar = getPropertyWrapperProjectionVar())
5899+
visit(projectionVar);
5900+
}
5901+
58915902
VarDecl *VarDecl::getLazyStorageProperty() const {
58925903
auto &ctx = getASTContext();
58935904
auto mutableThis = const_cast<VarDecl *>(this);

lib/AST/UnqualifiedLookup.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/ModuleNameLookup.h"
2323
#include "swift/AST/NameLookup.h"
2424
#include "swift/AST/NameLookupRequests.h"
25+
#include "swift/AST/PropertyWrappers.h"
2526
#include "swift/Basic/Debug.h"
2627
#include "swift/Basic/STLExtras.h"
2728
#include "swift/Basic/SourceManager.h"
@@ -564,8 +565,22 @@ bool ASTScopeDeclConsumerForUnqualifiedLookup::consume(
564565
}
565566
}
566567

567-
if (!value->getName().matchesRef(factory.Name.getFullName()))
568-
continue;
568+
auto fullName = factory.Name.getFullName();
569+
if (!value->getName().matchesRef(fullName)) {
570+
bool foundMatch = false;
571+
if (auto *varDecl = dyn_cast<VarDecl>(value)) {
572+
// Check if the name matches any auxiliary decls not in the AST
573+
varDecl->visitAuxiliaryDecls([&](VarDecl *auxiliaryVar) {
574+
if (auxiliaryVar->ValueDecl::getName().matchesRef(fullName)) {
575+
value = auxiliaryVar;
576+
foundMatch = true;
577+
}
578+
});
579+
}
580+
581+
if (!foundMatch)
582+
continue;
583+
}
569584

570585
// In order to preserve the behavior of the existing context-based lookup,
571586
// which finds all results for non-local variables at the top level instead

lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2228,7 +2228,7 @@ Expr *Parser::parseExprIdentifier() {
22282228
}
22292229

22302230
Expr *E;
2231-
if (D == nullptr) {
2231+
if (D == nullptr || D->getAttrs().hasAttribute<CustomAttr>()) {
22322232
if (name.getBaseName().isEditorPlaceholder()) {
22332233
IDSyntaxContext.setCreateSyntax(SyntaxKind::EditorPlaceholderExpr);
22342234
return parseExprEditorPlaceholder(IdentTok, name.getBaseIdentifier());

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,8 @@ IsSerialized_t SILDeclRef::isSerialized() const {
487487

488488
// Stored property initializers are inlinable if the type is explicitly
489489
// marked as @frozen.
490-
if (isStoredPropertyInitializer() || isPropertyWrapperBackingInitializer()) {
490+
if (isStoredPropertyInitializer() || (isPropertyWrapperBackingInitializer() &&
491+
d->getDeclContext()->isTypeContext())) {
491492
auto *nominal = cast<NominalTypeDecl>(d->getDeclContext());
492493
auto scope =
493494
nominal->getFormalAccessScope(/*useDC=*/nullptr,

lib/SILGen/SILGenDecl.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/Module.h"
2323
#include "swift/AST/NameLookup.h"
2424
#include "swift/AST/ProtocolConformance.h"
25+
#include "swift/AST/PropertyWrappers.h"
2526
#include "swift/Basic/ProfileCounter.h"
2627
#include "swift/SIL/FormalLinkage.h"
2728
#include "swift/SIL/PrettyStackTrace.h"
@@ -1171,6 +1172,22 @@ void SILGenFunction::emitPatternBinding(PatternBindingDecl *PBD,
11711172
// the initialization. Otherwise, mark it uninitialized for DI to resolve.
11721173
if (auto *Init = PBD->getExecutableInit(idx)) {
11731174
FullExpr Scope(Cleanups, CleanupLocation(Init));
1175+
1176+
auto *var = PBD->getSingleVar();
1177+
if (var && var->getDeclContext()->isLocalContext()) {
1178+
if (auto *orig = var->getOriginalWrappedProperty()) {
1179+
auto wrapperInfo = orig->getPropertyWrapperBackingPropertyInfo();
1180+
Init = wrapperInfo.wrappedValuePlaceholder->getOriginalWrappedValue();
1181+
1182+
auto value = emitRValue(Init);
1183+
emitApplyOfPropertyWrapperBackingInitializer(SILLocation(PBD), orig,
1184+
getForwardingSubstitutionMap(),
1185+
std::move(value))
1186+
.forwardInto(*this, SILLocation(PBD), initialization.get());
1187+
return;
1188+
}
1189+
}
1190+
11741191
emitExprInto(Init, initialization.get(), SILLocation(PBD));
11751192
} else {
11761193
initialization->finishUninitialized(*this);
@@ -1189,6 +1206,18 @@ void SILGenFunction::visitPatternBindingDecl(PatternBindingDecl *PBD) {
11891206
void SILGenFunction::visitVarDecl(VarDecl *D) {
11901207
// We handle emitting the variable storage when we see the pattern binding.
11911208

1209+
// Emit the property wrapper backing initializer if necessary.
1210+
auto wrapperInfo = D->getPropertyWrapperBackingPropertyInfo();
1211+
if (wrapperInfo && wrapperInfo.initializeFromOriginal)
1212+
SGM.emitPropertyWrapperBackingInitializer(D);
1213+
1214+
D->visitAuxiliaryDecls([&](VarDecl *var) {
1215+
if (auto *patternBinding = var->getParentPatternBinding())
1216+
visitPatternBindingDecl(patternBinding);
1217+
1218+
visit(var);
1219+
});
1220+
11921221
// Emit the variable's accessors.
11931222
D->visitEmittedAccessors([&](AccessorDecl *accessor) {
11941223
SGM.emitFunction(accessor);

lib/SILGen/SILGenFunction.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,18 @@ void SILGenFunction::emitCaptures(SILLocation loc,
187187
// Partial applications take ownership of the context parameters, so we'll
188188
// need to pass ownership rather than merely guaranteeing parameters.
189189
bool canGuarantee;
190+
bool captureCanEscape = true;
190191
switch (purpose) {
191192
case CaptureEmission::PartialApplication:
192193
canGuarantee = false;
193194
break;
194195
case CaptureEmission::ImmediateApplication:
195196
canGuarantee = true;
196197
break;
198+
case CaptureEmission::AssignByWrapper:
199+
canGuarantee = false;
200+
captureCanEscape = false;
201+
break;
197202
}
198203

199204
auto expansion = getTypeExpansionContext();
@@ -381,7 +386,8 @@ void SILGenFunction::emitCaptures(SILLocation loc,
381386
} else {
382387
capturedArgs.push_back(emitManagedRetain(loc, Entry.box));
383388
}
384-
escapesToMark.push_back(entryValue);
389+
if (captureCanEscape)
390+
escapesToMark.push_back(entryValue);
385391
} else {
386392
// Address only 'let' values are passed by box. This isn't great, in
387393
// that a variable captured by multiple closures will be boxed for each

0 commit comments

Comments
 (0)