Skip to content

Commit d5e963b

Browse files
committed
[TypeChecker] NFC: Add a dedicated method to get outermost attached wrapper
The outermost wrapper is the one at index `0` in the wrapper list but it's easy for humans to make a reverse assumption since outermost is the back of the list. Let's add a dedicated method to reduce error probability of the property wrapper APIs. (cherry picked from commit 5ee5a22)
1 parent 3c39957 commit d5e963b

File tree

7 files changed

+23
-9
lines changed

7 files changed

+23
-9
lines changed

include/swift/AST/Decl.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5430,6 +5430,20 @@ class VarDecl : public AbstractStorageDecl {
54305430
/// is provided first.
54315431
llvm::TinyPtrVector<CustomAttr *> getAttachedPropertyWrappers() const;
54325432

5433+
/// Retrieve the outermost property wrapper attribute associated with
5434+
/// this declaration. For example:
5435+
///
5436+
/// \code
5437+
/// @A @B @C var <name>: Bool = ...
5438+
/// \endcode
5439+
///
5440+
/// The outermost attribute in this case is `@A` and it has
5441+
/// complete wrapper type `A<B<C<Bool>>>`.
5442+
CustomAttr *getOutermostAttachedPropertyWrapper() const {
5443+
auto wrappers = getAttachedPropertyWrappers();
5444+
return wrappers.empty() ? nullptr : wrappers.front();
5445+
}
5446+
54335447
/// Whether this property has any attached property wrappers.
54345448
bool hasAttachedPropertyWrapper() const;
54355449

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6532,7 +6532,7 @@ bool VarDecl::hasExternalPropertyWrapper() const {
65326532
return true;
65336533

65346534
// Wrappers with attribute arguments are always implementation-detail.
6535-
if (getAttachedPropertyWrappers().front()->hasArgs())
6535+
if (getOutermostAttachedPropertyWrapper()->hasArgs())
65366536
return false;
65376537

65386538
auto wrapperInfo = getAttachedPropertyWrapperTypeInfo(0);

lib/Sema/CSApply.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8564,8 +8564,8 @@ static Optional<SolutionApplicationTarget> applySolutionToInitialization(
85648564
wrappedVar, initType->mapTypeOutOfContext());
85658565

85668566
// Record the semantic initializer on the outermost property wrapper.
8567-
wrappedVar->getAttachedPropertyWrappers().front()
8568-
->setSemanticInit(initializer);
8567+
wrappedVar->getOutermostAttachedPropertyWrapper()->setSemanticInit(
8568+
initializer);
85698569

85708570
// If this is a wrapped parameter, we're done.
85718571
if (isa<ParamDecl>(wrappedVar))
@@ -8983,7 +8983,7 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
89838983
return target;
89848984
} else if (auto *wrappedVar = target.getAsUninitializedWrappedVar()) {
89858985
// Get the outermost wrapper type from the solution
8986-
auto outermostWrapper = wrappedVar->getAttachedPropertyWrappers().front();
8986+
auto outermostWrapper = wrappedVar->getOutermostAttachedPropertyWrapper();
89878987
auto backingType = solution.simplifyType(
89888988
solution.getType(outermostWrapper->getTypeExpr()));
89898989

lib/Sema/CSClosure.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class TypeVariableRefFinder : public ASTWalker {
9494

9595
if (auto *wrappedVar = var->getOriginalWrappedProperty()) {
9696
auto outermostWrapperAttr =
97-
wrappedVar->getAttachedPropertyWrappers().front();
97+
wrappedVar->getOutermostAttachedPropertyWrapper();
9898

9999
// If the attribute doesn't have a type it could only mean
100100
// that the declaration was incorrect.

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3568,7 +3568,7 @@ bool InvalidProjectedValueArgument::diagnoseAsError() {
35683568
if (!param->hasAttachedPropertyWrapper()) {
35693569
param->diagnose(diag::property_wrapper_param_no_wrapper, param->getName());
35703570
} else if (!param->hasImplicitPropertyWrapper() &&
3571-
param->getAttachedPropertyWrappers().front()->hasArgs()) {
3571+
param->getOutermostAttachedPropertyWrapper()->hasArgs()) {
35723572
param->diagnose(diag::property_wrapper_param_attr_arg);
35733573
} else {
35743574
Type backingType;

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9989,7 +9989,7 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
99899989
wrappedValueType = createTypeVariable(getConstraintLocator(paramDecl),
99909990
TVO_CanBindToHole | TVO_CanBindToLValue);
99919991
} else {
9992-
auto *wrapperAttr = paramDecl->getAttachedPropertyWrappers().front();
9992+
auto *wrapperAttr = paramDecl->getOutermostAttachedPropertyWrapper();
99939993
auto wrapperType = paramDecl->getAttachedPropertyWrapperType(0);
99949994
backingType = replaceInferableTypesWithTypeVars(
99959995
wrapperType, getConstraintLocator(wrapperAttr->getTypeRepr()));

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6327,9 +6327,9 @@ void ConstraintSystem::diagnoseFailureFor(SolutionApplicationTarget target) {
63276327
DE.diagnose(expr->getLoc(), diag::type_of_expression_is_ambiguous)
63286328
.highlight(expr->getSourceRange());
63296329
} else if (auto *wrappedVar = target.getAsUninitializedWrappedVar()) {
6330-
auto *wrapper = wrappedVar->getAttachedPropertyWrappers().back();
6330+
auto *outerWrapper = wrappedVar->getOutermostAttachedPropertyWrapper();
63316331
Type propertyType = wrappedVar->getInterfaceType();
6332-
Type wrapperType = wrapper->getType();
6332+
Type wrapperType = outerWrapper->getType();
63336333

63346334
// Emit the property wrapper fallback diagnostic
63356335
wrappedVar->diagnose(diag::property_wrapper_incompatible_property,

0 commit comments

Comments
 (0)