@@ -1643,6 +1643,40 @@ void synthesizeAccessorBody(AbstractFunctionDecl *fn, void *) {
1643
1643
llvm_unreachable (" bad synthesized function kind" );
1644
1644
}
1645
1645
1646
+ static void maybeAddMemberwiseDefaultArg (ParamDecl *arg, VarDecl *var,
1647
+ SmallVectorImpl<DefaultArgumentInitializer *> &defaultInits,
1648
+ unsigned paramSize, ASTContext &ctx) {
1649
+ // First and foremost, if this is a constant don't bother.
1650
+ if (var->isLet ())
1651
+ return ;
1652
+
1653
+ // We can only provide default values for patterns binding a single variable.
1654
+ // i.e. var (a, b) = getSomeTuple() is not allowed.
1655
+ if (!var->getParentPattern ()->getSingleVar ())
1656
+ return ;
1657
+
1658
+ // If we don't have an initializer and we can't assign a default initializer
1659
+ // in silgen, then we can't generate a default value. An example of a default
1660
+ // initializer would be var x: Int? where the default is nil.
1661
+ if (!var->getParentInitializer () &&
1662
+ !var->getParentPatternBinding ()->isDefaultInitializable ())
1663
+ return ;
1664
+
1665
+ // We can add a default value now.
1666
+
1667
+ // Give this some bogus context right now, we'll fix it after making
1668
+ // the constructor.
1669
+ auto *initDC = new (ctx) DefaultArgumentInitializer (
1670
+ arg->getDeclContext (), paramSize);
1671
+
1672
+ defaultInits.push_back (initDC);
1673
+
1674
+ // Set the default value to the variable. When we emit this in silgen
1675
+ // we're going to call the variable's initializer expression.
1676
+ arg->setStoredProperty (var);
1677
+ arg->setDefaultArgumentKind (DefaultArgumentKind::StoredProperty);
1678
+ }
1679
+
1646
1680
// / Create an implicit struct or class constructor.
1647
1681
// /
1648
1682
// / \param decl The struct or class for which a constructor will be created.
@@ -1655,7 +1689,7 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
1655
1689
ImplicitConstructorKind ICK) {
1656
1690
assert (!decl->hasClangNode ());
1657
1691
1658
- ASTContext &C = tc.Context ;
1692
+ ASTContext &ctx = tc.Context ;
1659
1693
SourceLoc Loc = decl->getLoc ();
1660
1694
auto accessLevel = AccessLevel::Internal;
1661
1695
@@ -1700,59 +1734,24 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
1700
1734
varInterfaceType = OptionalType::get (varInterfaceType);
1701
1735
1702
1736
// Create the parameter.
1703
- auto *arg = new (C )
1737
+ auto *arg = new (ctx )
1704
1738
ParamDecl (VarDecl::Specifier::Default, SourceLoc (), Loc,
1705
1739
var->getName (), Loc, var->getName (), decl);
1706
1740
arg->setInterfaceType (varInterfaceType);
1707
1741
arg->setImplicit ();
1708
1742
1709
- // If this is a var that has a default value, and is only binding one var,
1710
- // i.e, var (a, b) = (3, 3) is not allowed, lets assign a default value
1711
- // to the parameter with the same expression.
1712
- if (!var->isLet () && var->getParentPattern ()->getSingleVar ()) {
1713
- if (auto init = var->getParentInitializer ()) {
1714
- // Give this some bogus context right now, we'll fix it after making
1715
- // the constructor.
1716
- auto *initDC = new (C) DefaultArgumentInitializer (
1717
- arg->getDeclContext (), params.size ());
1718
-
1719
- defaultInits.push_back (initDC);
1720
-
1721
- // Set the default value to the variable. When we emit this in silgen
1722
- // we're going to call the variable's initializer expression.
1723
- arg->setStoredProperty (var);
1724
- arg->setDefaultArgumentKind (DefaultArgumentKind::StoredProperty);
1725
- }
1726
- }
1727
-
1728
- // Now that we have default values for this synthesized constructor,
1729
- // if the property is an optional and does not have an initializer,
1730
- // and is not a let property because it can never be reassigned,
1731
- // assign nil as the default value.
1732
- if (var->getType ()->getOptionalObjectType () &&
1733
- var->getParentPatternBinding ()->isDefaultInitializable () &&
1734
- !var->isLet () &&
1735
- !var->getParentInitializer ()) {
1736
- auto *initDC = new (C) DefaultArgumentInitializer (
1737
- arg->getDeclContext (), params.size ());
1738
-
1739
- defaultInits.push_back (initDC);
1740
-
1741
- auto nil = new (C) NilLiteralExpr (SourceLoc (), /* implicit*/ true );
1742
- arg->setDefaultValue (nil);
1743
- arg->setDefaultArgumentKind (DefaultArgumentKind::NilLiteral);
1744
- }
1743
+ maybeAddMemberwiseDefaultArg (arg, var, defaultInits, params.size (), ctx);
1745
1744
1746
1745
params.push_back (arg);
1747
1746
}
1748
1747
}
1749
1748
1750
- auto paramList = ParameterList::create (C , params);
1749
+ auto paramList = ParameterList::create (ctx , params);
1751
1750
1752
1751
// Create the constructor.
1753
- DeclName name (C , DeclBaseName::createConstructor (), paramList);
1752
+ DeclName name (ctx , DeclBaseName::createConstructor (), paramList);
1754
1753
auto *ctor =
1755
- new (C ) ConstructorDecl (name, Loc,
1754
+ new (ctx ) ConstructorDecl (name, Loc,
1756
1755
OTK_None, /* FailabilityLoc=*/ SourceLoc (),
1757
1756
/* Throws=*/ false , /* ThrowsLoc=*/ SourceLoc (),
1758
1757
paramList, /* GenericParams=*/ nullptr , decl);
@@ -1761,20 +1760,21 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
1761
1760
ctor->setImplicit ();
1762
1761
ctor->setAccess (accessLevel);
1763
1762
1764
- // Fix default argument init contexts now that we have a constructor
1765
- for (auto initDC : defaultInits) {
1766
- initDC->changeFunction (ctor, paramList);
1767
- }
1768
-
1769
- if (ICK == ImplicitConstructorKind::Memberwise)
1763
+ if (ICK == ImplicitConstructorKind::Memberwise) {
1770
1764
ctor->setIsMemberwiseInitializer ();
1771
1765
1766
+ // Fix default argument init contexts now that we have a constructor.
1767
+ for (auto initDC : defaultInits) {
1768
+ initDC->changeFunction (ctor, paramList);
1769
+ }
1770
+ }
1771
+
1772
1772
// If we are defining a default initializer for a class that has a superclass,
1773
1773
// it overrides the default initializer of its superclass. Add an implicit
1774
1774
// 'override' attribute.
1775
1775
if (auto classDecl = dyn_cast<ClassDecl>(decl)) {
1776
1776
if (classDecl->getSuperclass ())
1777
- ctor->getAttrs ().add (new (C ) OverrideAttr (/* IsImplicit=*/ true ));
1777
+ ctor->getAttrs ().add (new (ctx ) OverrideAttr (/* IsImplicit=*/ true ));
1778
1778
}
1779
1779
1780
1780
return ctor;
0 commit comments