@@ -1573,13 +1573,17 @@ class DestructureInputs {
15731573 SmallVectorImpl<SILParameterInfo> &Inputs;
15741574 SubstFunctionTypeCollector &Subst;
15751575 unsigned NextOrigParamIndex = 0 ;
1576+ Optional<SmallBitVector> NoImplicitCopyIndices;
1577+
15761578public:
15771579 DestructureInputs (TypeExpansionContext expansion, TypeConverter &TC,
15781580 const Conventions &conventions, const ForeignInfo &foreign,
15791581 SmallVectorImpl<SILParameterInfo> &inputs,
1580- SubstFunctionTypeCollector &subst)
1582+ SubstFunctionTypeCollector &subst,
1583+ Optional<SmallBitVector> noImplicitCopyIndices)
15811584 : expansion(expansion), TC(TC), Convs(conventions), Foreign(foreign),
1582- Inputs(inputs), Subst(subst) {}
1585+ Inputs(inputs), Subst(subst),
1586+ NoImplicitCopyIndices(noImplicitCopyIndices) {}
15831587
15841588 void destructure (AbstractionPattern origType,
15851589 CanAnyFunctionType::CanParamArrayRef params,
@@ -1617,14 +1621,18 @@ class DestructureInputs {
16171621 // Add any foreign parameters that are positioned here.
16181622 maybeAddForeignParameters ();
16191623
1624+ bool hasNoImplicitCopy =
1625+ NoImplicitCopyIndices.hasValue () && NoImplicitCopyIndices->any ();
1626+
16201627 // Process all the non-self parameters.
16211628 for (unsigned i = 0 ; i != numNonSelfParams; ++i) {
16221629 auto ty = params[i].getParameterType ();
16231630 auto eltPattern = origType.getFunctionParamType (i);
16241631 auto flags = params[i].getParameterFlags ();
16251632
16261633 visit (flags.getValueOwnership (), /* forSelf=*/ false , eltPattern, ty,
1627- flags.isNoDerivative ());
1634+ flags.isNoDerivative (),
1635+ hasNoImplicitCopy && (*NoImplicitCopyIndices)[i]);
16281636 }
16291637
16301638 // Process the self parameter. Note that we implicitly drop self
@@ -1635,8 +1643,8 @@ class DestructureInputs {
16351643 auto eltPattern = origType.getFunctionParamType (numNonSelfParams);
16361644 auto flags = selfParam.getParameterFlags ();
16371645
1638- visit (flags.getValueOwnership (), /* forSelf=*/ true ,
1639- eltPattern, ty );
1646+ visit (flags.getValueOwnership (), /* forSelf=*/ true , eltPattern, ty, false ,
1647+ false );
16401648 }
16411649
16421650 TopLevelOrigType = AbstractionPattern::getInvalid ();
@@ -1645,7 +1653,7 @@ class DestructureInputs {
16451653
16461654 void visit (ValueOwnership ownership, bool forSelf,
16471655 AbstractionPattern origType, CanType substType,
1648- bool isNonDifferentiable = false ) {
1656+ bool isNonDifferentiable, bool isNoImplicitCopy ) {
16491657 assert (!isa<InOutType>(substType));
16501658
16511659 // Tuples get handled specially, in some cases:
@@ -1662,9 +1670,8 @@ class DestructureInputs {
16621670 auto ownership = elt.getParameterFlags ().getValueOwnership ();
16631671 assert (ownership == ValueOwnership::Default);
16641672 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 );
16681675 }
16691676 return ;
16701677 case ValueOwnership::InOut:
@@ -1692,6 +1699,9 @@ class DestructureInputs {
16921699 } else if (substTL.isTrivial ()) {
16931700 convention = ParameterConvention::Direct_Unowned;
16941701 } else {
1702+ // If we are no implicit copy, our ownership is always Owned.
1703+ if (isNoImplicitCopy)
1704+ ownership = ValueOwnership::Owned;
16951705 convention = Convs.getDirect (ownership, forSelf, origParamIndex, origType,
16961706 substTLConv);
16971707 assert (!isIndirectFormalParameter (convention));
@@ -1757,9 +1767,8 @@ class DestructureInputs {
17571767 if (ForeignSelf) {
17581768 // This is a "self", but it's not a Swift self, we handle it differently.
17591769 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 );
17631772 }
17641773 return true ;
17651774 }
@@ -2107,7 +2116,8 @@ static CanSILFunctionType getSILFunctionType(
21072116 SILExtInfoBuilder extInfoBuilder, const Conventions &conventions,
21082117 const ForeignInfo &foreignInfo, Optional<SILDeclRef> origConstant,
21092118 Optional<SILDeclRef> constant, Optional<SubstitutionMap> reqtSubs,
2110- ProtocolConformanceRef witnessMethodConformance) {
2119+ ProtocolConformanceRef witnessMethodConformance,
2120+ Optional<SmallBitVector> noImplicitCopyIndices) {
21112121 // Find the generic parameters.
21122122 CanGenericSignature genericSig =
21132123 substFnInterfaceType.getOptGenericSignature ();
@@ -2197,7 +2207,8 @@ static CanSILFunctionType getSILFunctionType(
21972207 SmallVector<SILParameterInfo, 8 > inputs;
21982208 {
21992209 DestructureInputs destructurer (expansionContext, TC, conventions,
2200- foreignInfo, inputs, subst);
2210+ foreignInfo, inputs, subst,
2211+ noImplicitCopyIndices);
22012212 destructurer.destructure (origType, substFnInterfaceType.getParams (),
22022213 extInfoBuilder);
22032214 }
@@ -2498,14 +2509,15 @@ static CanSILFunctionType getNativeSILFunctionType(
24982509 AbstractionPattern origType, CanAnyFunctionType substInterfaceType,
24992510 SILExtInfoBuilder extInfoBuilder, Optional<SILDeclRef> origConstant,
25002511 Optional<SILDeclRef> constant, Optional<SubstitutionMap> reqtSubs,
2501- ProtocolConformanceRef witnessMethodConformance) {
2512+ ProtocolConformanceRef witnessMethodConformance,
2513+ Optional<SmallBitVector> noImplicitCopyIndices) {
25022514 assert (bool (origConstant) == bool (constant));
25032515 auto getSILFunctionTypeForConventions =
25042516 [&](const Conventions &convs) -> CanSILFunctionType {
25052517 return getSILFunctionType (TC, context, origType, substInterfaceType,
25062518 extInfoBuilder, convs, ForeignInfo (),
25072519 origConstant, constant, reqtSubs,
2508- witnessMethodConformance);
2520+ witnessMethodConformance, noImplicitCopyIndices );
25092521 };
25102522 switch (extInfoBuilder.getRepresentation ()) {
25112523 case SILFunctionType::Representation::Block:
@@ -2568,7 +2580,7 @@ CanSILFunctionType swift::getNativeSILFunctionType(
25682580
25692581 return ::getNativeSILFunctionType (
25702582 TC, context, origType, substType, silExtInfo.intoBuilder (), origConstant,
2571- substConstant, reqtSubs, witnessMethodConformance);
2583+ substConstant, reqtSubs, witnessMethodConformance, None );
25722584}
25732585
25742586// ===----------------------------------------------------------------------===//
@@ -2947,7 +2959,7 @@ static CanSILFunctionType getSILFunctionTypeForClangDecl(
29472959 return getSILFunctionType (
29482960 TC, TypeExpansionContext::minimal (), origPattern, substInterfaceType,
29492961 extInfoBuilder, ObjCMethodConventions (method), foreignInfo, constant,
2950- constant, None, ProtocolConformanceRef ());
2962+ constant, None, ProtocolConformanceRef (), None );
29512963 }
29522964
29532965 if (auto method = dyn_cast<clang::CXXMethodDecl>(clangDecl)) {
@@ -2963,7 +2975,7 @@ static CanSILFunctionType getSILFunctionTypeForClangDecl(
29632975 return getSILFunctionType (TC, TypeExpansionContext::minimal (), origPattern,
29642976 substInterfaceType, extInfoBuilder, conventions,
29652977 foreignInfo, constant, constant, None,
2966- ProtocolConformanceRef ());
2978+ ProtocolConformanceRef (), None );
29672979 }
29682980
29692981 if (auto func = dyn_cast<clang::FunctionDecl>(clangDecl)) {
@@ -2976,7 +2988,7 @@ static CanSILFunctionType getSILFunctionTypeForClangDecl(
29762988 return getSILFunctionType (TC, TypeExpansionContext::minimal (), origPattern,
29772989 substInterfaceType, extInfoBuilder,
29782990 CFunctionConventions (func), foreignInfo, constant,
2979- constant, None, ProtocolConformanceRef ());
2991+ constant, None, ProtocolConformanceRef (), None );
29802992 }
29812993
29822994 llvm_unreachable (" call to unknown kind of C function" );
@@ -3004,15 +3016,15 @@ static CanSILFunctionType getSILFunctionTypeForAbstractCFunction(
30043016 return getSILFunctionType (
30053017 TC, TypeExpansionContext::minimal (), origType, substType,
30063018 extInfoBuilder, CFunctionTypeConventions (fnType), ForeignInfo (),
3007- constant, constant, None, ProtocolConformanceRef ());
3019+ constant, constant, None, ProtocolConformanceRef (), None );
30083020 }
30093021 }
30103022
30113023 // TODO: Ought to support captures in block funcs.
30123024 return getSILFunctionType (TC, TypeExpansionContext::minimal (), origType,
30133025 substType, extInfoBuilder,
30143026 DefaultBlockConventions (), ForeignInfo (), constant,
3015- constant, None, ProtocolConformanceRef ());
3027+ constant, None, ProtocolConformanceRef (), None );
30163028}
30173029
30183030// / Try to find a clang method declaration for the given function.
@@ -3180,7 +3192,7 @@ static CanSILFunctionType getSILFunctionTypeForObjCSelectorFamily(
31803192 TC, TypeExpansionContext::minimal (), AbstractionPattern (origType),
31813193 substInterfaceType, extInfoBuilder, ObjCSelectorFamilyConventions (family),
31823194 foreignInfo, constant, constant,
3183- /* requirement subs*/ None, ProtocolConformanceRef ());
3195+ /* requirement subs*/ None, ProtocolConformanceRef (), None );
31843196}
31853197
31863198static bool isImporterGeneratedAccessor (const clang::Decl *clangDecl,
@@ -3250,10 +3262,23 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant(
32503262 }
32513263 }();
32523264
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+
32533278 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 );
32573282 }
32583283
32593284 ForeignInfo foreignInfo;
0 commit comments