@@ -1378,10 +1378,9 @@ bool PatternBindingEntry::isInitialized() const {
13781378
13791379  //  Initialized via a property wrapper.
13801380  if  (auto  var = getPattern ()->getSingleVar ()) {
1381-     if  (auto  customAttr = var->getAttachedPropertyWrapper ()) {
1382-       if  (customAttr->getArg () != nullptr )
1383-         return  true ;
1384-     }
1381+     auto  customAttrs = var->getAttachedPropertyWrappers ();
1382+     if  (customAttrs.size () > 0  && customAttrs[0 ]->getArg () != nullptr )
1383+       return  true ;
13851384  }
13861385
13871386  return  false ;
@@ -1571,10 +1570,10 @@ bool PatternBindingDecl::isDefaultInitializable(unsigned i) const {
15711570  if  (entry.isInitialized ())
15721571    return  true ;
15731572
1574-   //  If it has an  attached property wrapper that  vends an `init()`, use that
1573+   //  If the outermost  attached property wrapper vends an `init()`, use that
15751574  //  for default initialization.
15761575  if  (auto  singleVar = getSingleVar ()) {
1577-     if  (auto  wrapperInfo = singleVar->getAttachedPropertyWrapperTypeInfo ()) {
1576+     if  (auto  wrapperInfo = singleVar->getAttachedPropertyWrapperTypeInfo (0 )) {
15781577      if  (wrapperInfo.defaultInit )
15791578        return  true ;
15801579    }
@@ -5252,12 +5251,12 @@ static bool isBackingStorageForDeclaredProperty(const VarDecl *var) {
52525251  return  name.str ().startswith (" $__lazy_storage_$_"  );
52535252}
52545253
5255- // / Whether the given variable
5254+ // / Whether the given variable is a delcared property that has separate backing storage. 
52565255static  bool  isDeclaredPropertyWithBackingStorage (const  VarDecl *var) {
52575256  if  (var->getAttrs ().hasAttribute <LazyAttr>())
52585257    return  true ;
52595258
5260-   if  (var->getAttachedPropertyWrapper ())
5259+   if  (var->hasAttachedPropertyWrapper ())
52615260    return  true ;
52625261
52635262  return  false ;
@@ -5298,7 +5297,7 @@ bool VarDecl::isMemberwiseInitialized(bool preferDeclaredProperties) const {
52985297  if  (auto  origWrapped = getOriginalWrappedProperty ())
52995298    origVar = origWrapped;
53005299  if  (origVar->getFormalAccess () < AccessLevel::Internal &&
5301-       origVar->getAttachedPropertyWrapper () &&
5300+       origVar->hasAttachedPropertyWrapper () &&
53025301      (origVar->isParentInitialized () ||
53035302       (origVar->getParentPatternBinding () &&
53045303        origVar->getParentPatternBinding ()->isDefaultInitializable ())))
@@ -5340,22 +5339,39 @@ StaticSpellingKind AbstractStorageDecl::getCorrectStaticSpelling() const {
53405339  return  getCorrectStaticSpellingForDecl (this );
53415340}
53425341
5343- CustomAttr *VarDecl::getAttachedPropertyWrapper  () const  {
5342+ llvm::TinyPtrVector< CustomAttr *>  VarDecl::getAttachedPropertyWrappers  () const  {
53445343  auto  &ctx = getASTContext ();
53455344  if  (!ctx.getLazyResolver ())
5346-     return  nullptr ;
5345+     return  { } ;
53475346
53485347  auto  mutableThis = const_cast <VarDecl *>(this );
53495348  return  evaluateOrDefault (ctx.evaluator ,
5350-                            AttachedPropertyWrapperRequest {mutableThis},
5351-                            nullptr );
5349+                            AttachedPropertyWrappersRequest {mutableThis},
5350+                            { } );
53525351}
53535352
5354- PropertyWrapperTypeInfo VarDecl::getAttachedPropertyWrapperTypeInfo () const  {
5355-   auto  attr = getAttachedPropertyWrapper ();
5356-   if  (!attr)
5357-     return  PropertyWrapperTypeInfo ();
5353+ // / Whether this property has any attached property wrappers.
5354+ bool  VarDecl::hasAttachedPropertyWrapper () const  {
5355+   return  !getAttachedPropertyWrappers ().empty ();
5356+ }
5357+ 
5358+ // / Whether all of the attached property wrappers have an init(initialValue:) initializer.
5359+ bool  VarDecl::allAttachedPropertyWrappersHaveInitialValueInit () const  {
5360+   for  (unsigned  i : indices (getAttachedPropertyWrappers ())) {
5361+     if  (!getAttachedPropertyWrapperTypeInfo (i).initialValueInit )
5362+       return  false ;
5363+   }
5364+   
5365+   return  true ;
5366+ }
53585367
5368+ PropertyWrapperTypeInfo
5369+ VarDecl::getAttachedPropertyWrapperTypeInfo (unsigned  i) const  {
5370+   auto  attrs = getAttachedPropertyWrappers ();
5371+   if  (i >= attrs.size ())
5372+     return  PropertyWrapperTypeInfo ();
5373+   
5374+   auto  attr = attrs[i];
53595375  auto  dc = getDeclContext ();
53605376  ASTContext &ctx = getASTContext ();
53615377  auto  nominal = evaluateOrDefault (
@@ -5366,12 +5382,13 @@ PropertyWrapperTypeInfo VarDecl::getAttachedPropertyWrapperTypeInfo() const {
53665382  return  nominal->getPropertyWrapperTypeInfo ();
53675383}
53685384
5369- Type VarDecl::getAttachedPropertyWrapperType () const  {
5385+ Type VarDecl::getAttachedPropertyWrapperType (unsigned  index ) const  {
53705386  auto  &ctx = getASTContext ();
53715387  auto  mutableThis = const_cast <VarDecl *>(this );
5372-   return  evaluateOrDefault (ctx.evaluator ,
5373-                            AttachedPropertyWrapperTypeRequest{mutableThis},
5374-                            Type ());
5388+   return  evaluateOrDefault (
5389+       ctx.evaluator ,
5390+       AttachedPropertyWrapperTypeRequest{mutableThis, index},
5391+       Type ());
53755392}
53765393
53775394Type VarDecl::getPropertyWrapperBackingPropertyType () const  {
@@ -5397,8 +5414,8 @@ VarDecl *VarDecl::getPropertyWrapperBackingProperty() const {
53975414}
53985415
53995416bool  VarDecl::isPropertyWrapperInitializedWithInitialValue () const  {
5400-   auto  customAttr  = getAttachedPropertyWrapper ();
5401-   if  (!customAttr )
5417+   auto  customAttrs  = getAttachedPropertyWrappers ();
5418+   if  (customAttrs. empty () )
54025419    return  false ;
54035420
54045421  auto  *PBD = getParentPatternBinding ();
@@ -5410,24 +5427,23 @@ bool VarDecl::isPropertyWrapperInitializedWithInitialValue() const {
54105427  if  (PBD->getPatternList ()[0 ].getEqualLoc ().isValid ())
54115428    return  true ;
54125429
5413-   //  If there was an initializer on the attribute itself , initialize
5430+   //  If there was an initializer on the outermost wrapper , initialize
54145431  //  via the full wrapper.
5415-   if  (customAttr ->getArg () != nullptr )
5432+   if  (customAttrs[ 0 ] ->getArg () != nullptr )
54165433    return  false ;
54175434
54185435  //  Default initialization does not use a value.
5419-   auto  wrapperTypeInfo = getAttachedPropertyWrapperTypeInfo ();
5420-   if  (wrapperTypeInfo.defaultInit )
5436+   if  (getAttachedPropertyWrapperTypeInfo (0 ).defaultInit )
54215437    return  false ;
54225438
5423-   //  There is no initializer, so the initialization form depends on 
5424-   //  whether the property  wrapper type has an init(initialValue:) .
5425-   return  wrapperTypeInfo. initialValueInit  !=  nullptr ;
5439+   //  If all property wrappers have an initialValue initializer, the property 
5440+   //  wrapper will be initialized that way .
5441+   return  allAttachedPropertyWrappersHaveInitialValueInit () ;
54265442}
54275443
54285444bool  VarDecl::isPropertyMemberwiseInitializedWithWrappedType () const  {
5429-   auto  customAttr  = getAttachedPropertyWrapper ();
5430-   if  (!customAttr )
5445+   auto  customAttrs  = getAttachedPropertyWrappers ();
5446+   if  (customAttrs. empty () )
54315447    return  false ;
54325448
54335449  auto  *PBD = getParentPatternBinding ();
@@ -5439,15 +5455,14 @@ bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType() const {
54395455  if  (PBD->getPatternList ()[0 ].getEqualLoc ().isValid ())
54405456    return  true ;
54415457
5442-   //  If there was an initializer on the attribute itself , initialize
5458+   //  If there was an initializer on the outermost wrapper , initialize
54435459  //  via the full wrapper.
5444-   if  (customAttr ->getArg () != nullptr )
5460+   if  (customAttrs[ 0 ] ->getArg () != nullptr )
54455461    return  false ;
54465462
5447-   //  There is no initializer, so the initialization form depends on
5448-   //  whether the property wrapper type has an init(initialValue:).
5449-   auto  wrapperTypeInfo = getAttachedPropertyWrapperTypeInfo ();
5450-   return  wrapperTypeInfo.initialValueInit  != nullptr ;
5463+   //  If all property wrappers have an initialValue initializer, the property
5464+   //  wrapper will be initialized that way.
5465+   return  allAttachedPropertyWrappersHaveInitialValueInit ();
54515466}
54525467
54535468Identifier VarDecl::getObjCPropertyName () const  {
@@ -5699,9 +5714,8 @@ void ParamDecl::setDefaultArgumentInitContext(Initializer *initContext) {
56995714}
57005715
57015716Expr *swift::findOriginalPropertyWrapperInitialValue (VarDecl *var,
5702-                                                       Expr *init) {
5703-   auto  attr = var->getAttachedPropertyWrapper ();
5704-   assert (attr && " No attached property wrapper?"  );
5717+                                                      Expr *init) {
5718+   auto  attr = var->getAttachedPropertyWrappers ().front ();
57055719
57065720  //  Direct initialization implies no original initial value.
57075721  if  (attr->getArg ())
@@ -5755,7 +5769,9 @@ ParamDecl::getDefaultValueStringRepresentation(
57555769    auto  var = getStoredProperty ();
57565770
57575771    if  (auto  original = var->getOriginalWrappedProperty ()) {
5758-       if  (auto  attr = original->getAttachedPropertyWrapper ()) {
5772+       auto  wrapperAttrs = original->getAttachedPropertyWrappers ();
5773+       if  (wrapperAttrs.size () > 0 ) {
5774+         auto  attr = wrapperAttrs.front ();
57595775        if  (auto  arg = attr->getArg ()) {
57605776          SourceRange fullRange (attr->getTypeLoc ().getSourceRange ().Start ,
57615777                                arg->getEndLoc ());
0 commit comments