@@ -1573,13 +1573,17 @@ class DestructureInputs {
1573
1573
SmallVectorImpl<SILParameterInfo> &Inputs;
1574
1574
SubstFunctionTypeCollector &Subst;
1575
1575
unsigned NextOrigParamIndex = 0 ;
1576
+ Optional<SmallBitVector> NoImplicitCopyIndices;
1577
+
1576
1578
public:
1577
1579
DestructureInputs (TypeExpansionContext expansion, TypeConverter &TC,
1578
1580
const Conventions &conventions, const ForeignInfo &foreign,
1579
1581
SmallVectorImpl<SILParameterInfo> &inputs,
1580
- SubstFunctionTypeCollector &subst)
1582
+ SubstFunctionTypeCollector &subst,
1583
+ Optional<SmallBitVector> noImplicitCopyIndices)
1581
1584
: expansion(expansion), TC(TC), Convs(conventions), Foreign(foreign),
1582
- Inputs(inputs), Subst(subst) {}
1585
+ Inputs(inputs), Subst(subst),
1586
+ NoImplicitCopyIndices(noImplicitCopyIndices) {}
1583
1587
1584
1588
void destructure (AbstractionPattern origType,
1585
1589
CanAnyFunctionType::CanParamArrayRef params,
@@ -1617,14 +1621,18 @@ class DestructureInputs {
1617
1621
// Add any foreign parameters that are positioned here.
1618
1622
maybeAddForeignParameters ();
1619
1623
1624
+ bool hasNoImplicitCopy =
1625
+ NoImplicitCopyIndices.hasValue () && NoImplicitCopyIndices->any ();
1626
+
1620
1627
// Process all the non-self parameters.
1621
1628
for (unsigned i = 0 ; i != numNonSelfParams; ++i) {
1622
1629
auto ty = params[i].getParameterType ();
1623
1630
auto eltPattern = origType.getFunctionParamType (i);
1624
1631
auto flags = params[i].getParameterFlags ();
1625
1632
1626
1633
visit (flags.getValueOwnership (), /* forSelf=*/ false , eltPattern, ty,
1627
- flags.isNoDerivative ());
1634
+ flags.isNoDerivative (),
1635
+ hasNoImplicitCopy && (*NoImplicitCopyIndices)[i]);
1628
1636
}
1629
1637
1630
1638
// Process the self parameter. Note that we implicitly drop self
@@ -1635,8 +1643,8 @@ class DestructureInputs {
1635
1643
auto eltPattern = origType.getFunctionParamType (numNonSelfParams);
1636
1644
auto flags = selfParam.getParameterFlags ();
1637
1645
1638
- visit (flags.getValueOwnership (), /* forSelf=*/ true ,
1639
- eltPattern, ty );
1646
+ visit (flags.getValueOwnership (), /* forSelf=*/ true , eltPattern, ty, false ,
1647
+ false );
1640
1648
}
1641
1649
1642
1650
TopLevelOrigType = AbstractionPattern::getInvalid ();
@@ -1645,7 +1653,7 @@ class DestructureInputs {
1645
1653
1646
1654
void visit (ValueOwnership ownership, bool forSelf,
1647
1655
AbstractionPattern origType, CanType substType,
1648
- bool isNonDifferentiable = false ) {
1656
+ bool isNonDifferentiable, bool isNoImplicitCopy ) {
1649
1657
assert (!isa<InOutType>(substType));
1650
1658
1651
1659
// Tuples get handled specially, in some cases:
@@ -1662,9 +1670,8 @@ class DestructureInputs {
1662
1670
auto ownership = elt.getParameterFlags ().getValueOwnership ();
1663
1671
assert (ownership == ValueOwnership::Default);
1664
1672
assert (!elt.isVararg ());
1665
- visit (ownership, forSelf,
1666
- origType.getTupleElementType (i),
1667
- CanType (elt.getRawType ()));
1673
+ visit (ownership, forSelf, origType.getTupleElementType (i),
1674
+ CanType (elt.getRawType ()), false , false );
1668
1675
}
1669
1676
return ;
1670
1677
case ValueOwnership::InOut:
@@ -1692,6 +1699,9 @@ class DestructureInputs {
1692
1699
} else if (substTL.isTrivial ()) {
1693
1700
convention = ParameterConvention::Direct_Unowned;
1694
1701
} else {
1702
+ // If we are no implicit copy, our ownership is always Owned.
1703
+ if (isNoImplicitCopy)
1704
+ ownership = ValueOwnership::Owned;
1695
1705
convention = Convs.getDirect (ownership, forSelf, origParamIndex, origType,
1696
1706
substTLConv);
1697
1707
assert (!isIndirectFormalParameter (convention));
@@ -1757,9 +1767,8 @@ class DestructureInputs {
1757
1767
if (ForeignSelf) {
1758
1768
// This is a "self", but it's not a Swift self, we handle it differently.
1759
1769
visit (ForeignSelf->SubstSelfParam .getValueOwnership (),
1760
- /* forSelf=*/ false ,
1761
- ForeignSelf->OrigSelfParam ,
1762
- ForeignSelf->SubstSelfParam .getParameterType ());
1770
+ /* forSelf=*/ false , ForeignSelf->OrigSelfParam ,
1771
+ ForeignSelf->SubstSelfParam .getParameterType (), false , false );
1763
1772
}
1764
1773
return true ;
1765
1774
}
@@ -2107,7 +2116,8 @@ static CanSILFunctionType getSILFunctionType(
2107
2116
SILExtInfoBuilder extInfoBuilder, const Conventions &conventions,
2108
2117
const ForeignInfo &foreignInfo, Optional<SILDeclRef> origConstant,
2109
2118
Optional<SILDeclRef> constant, Optional<SubstitutionMap> reqtSubs,
2110
- ProtocolConformanceRef witnessMethodConformance) {
2119
+ ProtocolConformanceRef witnessMethodConformance,
2120
+ Optional<SmallBitVector> noImplicitCopyIndices) {
2111
2121
// Find the generic parameters.
2112
2122
CanGenericSignature genericSig =
2113
2123
substFnInterfaceType.getOptGenericSignature ();
@@ -2197,7 +2207,8 @@ static CanSILFunctionType getSILFunctionType(
2197
2207
SmallVector<SILParameterInfo, 8 > inputs;
2198
2208
{
2199
2209
DestructureInputs destructurer (expansionContext, TC, conventions,
2200
- foreignInfo, inputs, subst);
2210
+ foreignInfo, inputs, subst,
2211
+ noImplicitCopyIndices);
2201
2212
destructurer.destructure (origType, substFnInterfaceType.getParams (),
2202
2213
extInfoBuilder);
2203
2214
}
@@ -2498,14 +2509,15 @@ static CanSILFunctionType getNativeSILFunctionType(
2498
2509
AbstractionPattern origType, CanAnyFunctionType substInterfaceType,
2499
2510
SILExtInfoBuilder extInfoBuilder, Optional<SILDeclRef> origConstant,
2500
2511
Optional<SILDeclRef> constant, Optional<SubstitutionMap> reqtSubs,
2501
- ProtocolConformanceRef witnessMethodConformance) {
2512
+ ProtocolConformanceRef witnessMethodConformance,
2513
+ Optional<SmallBitVector> noImplicitCopyIndices) {
2502
2514
assert (bool (origConstant) == bool (constant));
2503
2515
auto getSILFunctionTypeForConventions =
2504
2516
[&](const Conventions &convs) -> CanSILFunctionType {
2505
2517
return getSILFunctionType (TC, context, origType, substInterfaceType,
2506
2518
extInfoBuilder, convs, ForeignInfo (),
2507
2519
origConstant, constant, reqtSubs,
2508
- witnessMethodConformance);
2520
+ witnessMethodConformance, noImplicitCopyIndices );
2509
2521
};
2510
2522
switch (extInfoBuilder.getRepresentation ()) {
2511
2523
case SILFunctionType::Representation::Block:
@@ -2568,7 +2580,7 @@ CanSILFunctionType swift::getNativeSILFunctionType(
2568
2580
2569
2581
return ::getNativeSILFunctionType (
2570
2582
TC, context, origType, substType, silExtInfo.intoBuilder (), origConstant,
2571
- substConstant, reqtSubs, witnessMethodConformance);
2583
+ substConstant, reqtSubs, witnessMethodConformance, None );
2572
2584
}
2573
2585
2574
2586
// ===----------------------------------------------------------------------===//
@@ -2947,7 +2959,7 @@ static CanSILFunctionType getSILFunctionTypeForClangDecl(
2947
2959
return getSILFunctionType (
2948
2960
TC, TypeExpansionContext::minimal (), origPattern, substInterfaceType,
2949
2961
extInfoBuilder, ObjCMethodConventions (method), foreignInfo, constant,
2950
- constant, None, ProtocolConformanceRef ());
2962
+ constant, None, ProtocolConformanceRef (), None );
2951
2963
}
2952
2964
2953
2965
if (auto method = dyn_cast<clang::CXXMethodDecl>(clangDecl)) {
@@ -2963,7 +2975,7 @@ static CanSILFunctionType getSILFunctionTypeForClangDecl(
2963
2975
return getSILFunctionType (TC, TypeExpansionContext::minimal (), origPattern,
2964
2976
substInterfaceType, extInfoBuilder, conventions,
2965
2977
foreignInfo, constant, constant, None,
2966
- ProtocolConformanceRef ());
2978
+ ProtocolConformanceRef (), None );
2967
2979
}
2968
2980
2969
2981
if (auto func = dyn_cast<clang::FunctionDecl>(clangDecl)) {
@@ -2976,7 +2988,7 @@ static CanSILFunctionType getSILFunctionTypeForClangDecl(
2976
2988
return getSILFunctionType (TC, TypeExpansionContext::minimal (), origPattern,
2977
2989
substInterfaceType, extInfoBuilder,
2978
2990
CFunctionConventions (func), foreignInfo, constant,
2979
- constant, None, ProtocolConformanceRef ());
2991
+ constant, None, ProtocolConformanceRef (), None );
2980
2992
}
2981
2993
2982
2994
llvm_unreachable (" call to unknown kind of C function" );
@@ -3004,15 +3016,15 @@ static CanSILFunctionType getSILFunctionTypeForAbstractCFunction(
3004
3016
return getSILFunctionType (
3005
3017
TC, TypeExpansionContext::minimal (), origType, substType,
3006
3018
extInfoBuilder, CFunctionTypeConventions (fnType), ForeignInfo (),
3007
- constant, constant, None, ProtocolConformanceRef ());
3019
+ constant, constant, None, ProtocolConformanceRef (), None );
3008
3020
}
3009
3021
}
3010
3022
3011
3023
// TODO: Ought to support captures in block funcs.
3012
3024
return getSILFunctionType (TC, TypeExpansionContext::minimal (), origType,
3013
3025
substType, extInfoBuilder,
3014
3026
DefaultBlockConventions (), ForeignInfo (), constant,
3015
- constant, None, ProtocolConformanceRef ());
3027
+ constant, None, ProtocolConformanceRef (), None );
3016
3028
}
3017
3029
3018
3030
// / Try to find a clang method declaration for the given function.
@@ -3180,7 +3192,7 @@ static CanSILFunctionType getSILFunctionTypeForObjCSelectorFamily(
3180
3192
TC, TypeExpansionContext::minimal (), AbstractionPattern (origType),
3181
3193
substInterfaceType, extInfoBuilder, ObjCSelectorFamilyConventions (family),
3182
3194
foreignInfo, constant, constant,
3183
- /* requirement subs*/ None, ProtocolConformanceRef ());
3195
+ /* requirement subs*/ None, ProtocolConformanceRef (), None );
3184
3196
}
3185
3197
3186
3198
static bool isImporterGeneratedAccessor (const clang::Decl *clangDecl,
@@ -3250,10 +3262,23 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant(
3250
3262
}
3251
3263
}();
3252
3264
3265
+ Optional<SmallBitVector> noImplicitCopyIndices;
3266
+ if (constant.hasDecl ()) {
3267
+ auto decl = constant.getDecl ();
3268
+ if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(decl)) {
3269
+ noImplicitCopyIndices.emplace (funcDecl->getParameters ()->size ());
3270
+ for (auto p : llvm::enumerate (*funcDecl->getParameters ())) {
3271
+ if (p.value ()->isNoImplicitCopy ()) {
3272
+ noImplicitCopyIndices->set (p.index ());
3273
+ }
3274
+ }
3275
+ }
3276
+ }
3277
+
3253
3278
return ::getNativeSILFunctionType (
3254
- TC, context, origType,
3255
- origLoweredInterfaceType, extInfoBuilder, constant, constant, None,
3256
- witnessMethodConformance );
3279
+ TC, context, origType, origLoweredInterfaceType, extInfoBuilder,
3280
+ constant, constant, None, witnessMethodConformance ,
3281
+ noImplicitCopyIndices );
3257
3282
}
3258
3283
3259
3284
ForeignInfo foreignInfo;
0 commit comments