diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 3b94f33ba8039..86c66f6c5df16 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -7845,25 +7845,31 @@ ERROR(lifetime_dependence_invalid_param_name, none, "invalid parameter name specified %0", (Identifier)) ERROR(lifetime_dependence_invalid_param_index, none, "invalid parameter index specified %0", (unsigned)) -ERROR(lifetime_dependence_invalid_self, none, - "invalid lifetime dependence specifier, self is valid in non-static " - "methods only", ()) +ERROR(lifetime_dependence_invalid_self_in_static, none, + "invalid lifetime dependence specifier on non-existent self", ()) +ERROR(lifetime_dependence_invalid_self_in_init, none, + "invalid lifetime dependence on self in an initializer", ()) ERROR(lifetime_dependence_duplicate_param_id, none, "duplicate lifetime dependence specifier", ()) ERROR(lifetime_dependence_cannot_use_kind, none, "invalid use of %0 lifetime dependence for %1 ownership", (StringRef, StringRef)) +ERROR(lifetime_dependence_cannot_use_parsed_scoped_consuming, none, + "invalid use of scoped lifetime dependence with consuming ownership", + ()) +ERROR(lifetime_dependence_cannot_use_inferred_scoped_consuming, none, + "invalid use of lifetime dependence on an Escapable parameter with " + "consuming ownership", + ()) +ERROR(lifetime_dependence_invalid_self_ownership, none, + "invalid scoped lifetime dependence on an Escapable self with consuming " + "ownership", + ()) ERROR(lifetime_dependence_only_on_function_method_init_result, none, "lifetime dependence specifiers may only be used on result of " "functions, methods, initializers", ()) ERROR(lifetime_dependence_invalid_return_type, none, "lifetime dependence can only be specified on ~Escapable results", ()) -ERROR(lifetime_dependence_missing_ownership_modifier, none, - "lifetime dependence can only be specified on parameters with ownership " - "modifiers (borrowing, consuming, inout)", ()) -ERROR(lifetime_dependence_cannot_infer_wo_ownership_modifier_on_method, none, - "cannot infer lifetime dependence, specify ownership modifier for the " - "method", ()) ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none, "cannot infer lifetime dependence, multiple ~Escapable or ~Copyable " "parameters with ownership modifiers, specify explicit lifetime " @@ -7874,9 +7880,6 @@ ERROR(lifetime_dependence_cannot_infer_no_candidates, none, ERROR(lifetime_dependence_ctor_non_self_or_nil_return, none, "expected nil or self as return values in an initializer with " "lifetime dependent specifiers", ()) -ERROR(lifetime_dependence_cannot_use_infer, none, - "invalid use of %0 lifetime dependence on Escapable type", - (StringRef)) ERROR(lifetime_dependence_on_bitwise_copyable, none, "invalid lifetime dependence on bitwise copyable type", ()) ERROR(lifetime_dependence_cannot_infer_implicit_init, none, diff --git a/include/swift/AST/LifetimeDependence.h b/include/swift/AST/LifetimeDependence.h index 802f61a30ce32..9ca9f97f3d978 100644 --- a/include/swift/AST/LifetimeDependence.h +++ b/include/swift/AST/LifetimeDependence.h @@ -32,13 +32,14 @@ class AbstractFunctionDecl; class LifetimeDependentReturnTypeRepr; class SILParameterInfo; -enum class LifetimeDependenceKind : uint8_t { - Copy = 0, - Consume, - Borrow, - Mutate +enum class ParsedLifetimeDependenceKind : uint8_t { + Default = 0, + Scope, + Inherit // Only used with deserialized decls }; +enum class LifetimeDependenceKind : uint8_t { Inherit = 0, Scope }; + class LifetimeDependenceSpecifier { public: enum class SpecifierKind { Named, Ordered, Self }; @@ -46,7 +47,7 @@ class LifetimeDependenceSpecifier { private: SourceLoc loc; SpecifierKind specifierKind; - LifetimeDependenceKind lifetimeDependenceKind; + ParsedLifetimeDependenceKind parsedLifetimeDependenceKind; union Value { struct { Identifier name; @@ -61,26 +62,27 @@ class LifetimeDependenceSpecifier { Value() {} } value; - LifetimeDependenceSpecifier(SourceLoc loc, SpecifierKind specifierKind, - LifetimeDependenceKind lifetimeDependenceKind, - Value value) + LifetimeDependenceSpecifier( + SourceLoc loc, SpecifierKind specifierKind, + ParsedLifetimeDependenceKind parsedLifetimeDependenceKind, Value value) : loc(loc), specifierKind(specifierKind), - lifetimeDependenceKind(lifetimeDependenceKind), value(value) {} + parsedLifetimeDependenceKind(parsedLifetimeDependenceKind), + value(value) {} public: static LifetimeDependenceSpecifier getNamedLifetimeDependenceSpecifier( - SourceLoc loc, LifetimeDependenceKind kind, Identifier name) { + SourceLoc loc, ParsedLifetimeDependenceKind kind, Identifier name) { return {loc, SpecifierKind::Named, kind, name}; } static LifetimeDependenceSpecifier getOrderedLifetimeDependenceSpecifier( - SourceLoc loc, LifetimeDependenceKind kind, unsigned index) { + SourceLoc loc, ParsedLifetimeDependenceKind kind, unsigned index) { return {loc, SpecifierKind::Ordered, kind, index}; } static LifetimeDependenceSpecifier getSelfLifetimeDependenceSpecifier(SourceLoc loc, - LifetimeDependenceKind kind) { + ParsedLifetimeDependenceKind kind) { return {loc, SpecifierKind::Self, kind, {}}; } @@ -88,8 +90,8 @@ class LifetimeDependenceSpecifier { SpecifierKind getSpecifierKind() const { return specifierKind; } - LifetimeDependenceKind getLifetimeDependenceKind() const { - return lifetimeDependenceKind; + ParsedLifetimeDependenceKind getParsedLifetimeDependenceKind() const { + return parsedLifetimeDependenceKind; } Identifier getName() const { @@ -114,19 +116,17 @@ class LifetimeDependenceSpecifier { llvm_unreachable("Invalid LifetimeDependenceSpecifier::SpecifierKind"); } - StringRef getLifetimeDependenceKindString() const { - switch (lifetimeDependenceKind) { - case LifetimeDependenceKind::Borrow: - return "_borrow"; - case LifetimeDependenceKind::Consume: - return "_consume"; - case LifetimeDependenceKind::Copy: - return "_copy"; - case LifetimeDependenceKind::Mutate: - return "_mutate"; + std::string getLifetimeDependenceSpecifierString() const { + switch (parsedLifetimeDependenceKind) { + case ParsedLifetimeDependenceKind::Default: + return "dependsOn(" + getParamString() + ")"; + case ParsedLifetimeDependenceKind::Scope: + return "dependsOn(scoped " + getParamString() + ")"; + case ParsedLifetimeDependenceKind::Inherit: + return "dependsOn(inherited " + getParamString() + ")"; } llvm_unreachable( - "Invalid LifetimeDependenceSpecifier::LifetimeDependenceKind"); + "Invalid LifetimeDependenceSpecifier::ParsedLifetimeDependenceKind"); } }; @@ -137,7 +137,7 @@ class LifetimeDependenceInfo { static LifetimeDependenceInfo getForParamIndex(AbstractFunctionDecl *afd, unsigned index, - ValueOwnership ownership); + LifetimeDependenceKind kind); public: LifetimeDependenceInfo() diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index 9be736a9e6163..ea9c5720a312f 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -1212,7 +1212,7 @@ class Parser { return true; if (Context.LangOpts.hasFeature(Feature::NonescapableTypes) && (Tok.isContextualKeyword("_resultDependsOn") || - Tok.isLifetimeDependenceToken(isInSILMode()))) + isLifetimeDependenceToken())) return true; return false; } @@ -1224,23 +1224,26 @@ class Parser { consumeToken(); } + bool isLifetimeDependenceToken() { + if (!isInSILMode()) { + return Tok.isContextualKeyword("dependsOn"); + } + return Tok.isContextualKeyword("_inherit") || + Tok.isContextualKeyword("_scope"); + } + bool canHaveParameterSpecifierContextualKeyword() { // The parameter specifiers like `isolated`, `consuming`, `borrowing` are // also valid identifiers and could be the name of a type. Check whether // the following token is something that can introduce a type. Thankfully // none of these tokens overlap with the set of tokens that can follow an // identifier in a type production. - return Tok.is(tok::identifier) - && peekToken().isAny(tok::at_sign, - tok::kw_inout, - tok::l_paren, - tok::identifier, - tok::l_square, - tok::kw_Any, - tok::kw_Self, - tok::kw__, - tok::kw_var, - tok::kw_let); + return (Tok.is(tok::identifier) && + peekToken().isAny(tok::at_sign, tok::kw_inout, tok::l_paren, + tok::identifier, tok::l_square, tok::kw_Any, + tok::kw_Self, tok::kw__, tok::kw_var, + tok::kw_let)) || + isLifetimeDependenceToken(); } struct ParsedTypeAttributeList { diff --git a/include/swift/Parse/Token.h b/include/swift/Parse/Token.h index e62e857452159..c472bde171153 100644 --- a/include/swift/Parse/Token.h +++ b/include/swift/Parse/Token.h @@ -267,16 +267,6 @@ class Token { return MultilineString; } - bool isLifetimeDependenceToken(bool isInSILMode) const { - return isContextualKeyword("_copy") || isContextualKeyword("_consume") || - isContextualKeyword("_borrow") || isContextualKeyword("_mutate") || - // SIL tests are currently written with _inherit/_scope - // Once we have dependsOn()/dependsOn(borrowed:) other tokens go - // away. - (isInSILMode && - (isContextualKeyword("_inherit") || isContextualKeyword("_scope"))); - } - /// Count of extending escaping '#'. unsigned getCustomDelimiterLen() const { return CustomDelimiterLen; diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 2cdc7dd548a84..d858d11c3caa0 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3535,8 +3535,7 @@ class PrintTypeRepr : public TypeReprVisitor, for (auto &dep : T->getLifetimeDependencies()) { printFieldRaw( [&](raw_ostream &out) { - out << dep.getLifetimeDependenceKindString() << "("; - out << dep.getParamString() << ")"; + out << " " << dep.getLifetimeDependenceSpecifierString() << " "; }, ""); } diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 9ff0b9373856b..01c6079e830c9 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -3263,20 +3263,14 @@ void ASTMangler::appendParameterTypeListElement( void ASTMangler::appendLifetimeDependenceKind(LifetimeDependenceKind kind, bool isSelfDependence) { - // If we converge on dependsOn(borrowed: paramName)/dependsOn(paramName) - // syntax, this can be a single case value check. - if (kind == LifetimeDependenceKind::Borrow || - kind == LifetimeDependenceKind::Mutate) { + if (kind == LifetimeDependenceKind::Scope) { if (isSelfDependence) { appendOperator("YLs"); } else { appendOperator("Yls"); } } else { - // If we converge on dependsOn(borrowed: paramName)/dependsOn(paramName) - // syntax, this can be a single case value check. - assert(kind == LifetimeDependenceKind::Copy || - kind == LifetimeDependenceKind::Consume); + assert(kind == LifetimeDependenceKind::Inherit); if (isSelfDependence) { appendOperator("YLi"); } else { diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 2f7bcced0653f..f81e785e5d671 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -4137,8 +4137,7 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) { if (auto *typeRepr = dyn_cast_or_null( decl->getResultTypeRepr())) { for (auto &dep : typeRepr->getLifetimeDependencies()) { - Printer << " " << dep.getLifetimeDependenceKindString() << "("; - Printer << dep.getParamString() << ") "; + Printer << " " << dep.getLifetimeDependenceSpecifierString() << " "; } } } @@ -4378,8 +4377,7 @@ void PrintAST::visitConstructorDecl(ConstructorDecl *decl) { auto *typeRepr = cast(decl->getResultTypeRepr()); for (auto &dep : typeRepr->getLifetimeDependencies()) { - Printer << dep.getLifetimeDependenceKindString() << "("; - Printer << dep.getParamString() << ") "; + Printer << dep.getLifetimeDependenceSpecifierString() << " "; } // TODO: Handle failable initializers with lifetime dependent returns Printer << "Self"; diff --git a/lib/AST/TypeRepr.cpp b/lib/AST/TypeRepr.cpp index a964f4e2a7aa8..8f158572e99ff 100644 --- a/lib/AST/TypeRepr.cpp +++ b/lib/AST/TypeRepr.cpp @@ -692,9 +692,9 @@ SourceLoc LifetimeDependentReturnTypeRepr::getLocImpl() const { void LifetimeDependentReturnTypeRepr::printImpl( ASTPrinter &Printer, const PrintOptions &Opts) const { + Printer << " "; for (auto &dep : getLifetimeDependencies()) { - Printer << dep.getLifetimeDependenceKindString() << "("; - Printer << dep.getParamString() << ")"; + Printer << dep.getLifetimeDependenceSpecifierString() << " "; } printTypeRepr(getBase(), Printer, Opts); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 6554ead73a090..5f3a7ecd0ab19 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -5057,21 +5057,12 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result, llvm_unreachable("bad attribute kind"); } -static std::optional -getLifetimeDependenceKind(const Token &T) { - if (T.isContextualKeyword("_copy") || T.isContextualKeyword("_inherit")) { - return LifetimeDependenceKind::Copy; +static ParsedLifetimeDependenceKind getSILLifetimeDependenceKind(const Token &T) { + if (T.isContextualKeyword("_inherit")) { + return ParsedLifetimeDependenceKind::Inherit; } - if (T.isContextualKeyword("_consume")) { - return LifetimeDependenceKind::Consume; - } - if (T.isContextualKeyword("_borrow") || T.isContextualKeyword("_scope")) { - return LifetimeDependenceKind::Borrow; - } - if (T.isContextualKeyword("_mutate")) { - return LifetimeDependenceKind::Mutate; - } - return std::nullopt; + assert(T.isContextualKeyword("_scope")); + return ParsedLifetimeDependenceKind::Scope; } ParserStatus Parser::parseLifetimeDependenceSpecifiers( @@ -5079,12 +5070,20 @@ ParserStatus Parser::parseLifetimeDependenceSpecifiers( ParserStatus status; // TODO: Add fixits for diagnostics in this function. do { - auto lifetimeDependenceKind = getLifetimeDependenceKind(Tok); - if (!lifetimeDependenceKind.has_value()) { + if (!isLifetimeDependenceToken()) { break; } - // consume the lifetime dependence kind - consumeToken(); + + auto lifetimeDependenceKind = ParsedLifetimeDependenceKind::Default; + + if (!isInSILMode()) { + // consume dependsOn + consumeToken(); + } else { + lifetimeDependenceKind = getSILLifetimeDependenceKind(Tok); + // consume _inherit or _scope + consumeToken(); + } if (!Tok.isFollowingLParen()) { diagnose(Tok, diag::expected_lparen_after_lifetime_dependence); @@ -5093,6 +5092,16 @@ ParserStatus Parser::parseLifetimeDependenceSpecifiers( } // consume the l_paren auto lParenLoc = consumeToken(); + + if (!isInSILMode()) { + // look for optional "scoped" + if (Tok.isContextualKeyword("scoped")) { + lifetimeDependenceKind = ParsedLifetimeDependenceKind::Scope; + // consume scoped + consumeToken(); + } + } + SourceLoc rParenLoc; bool foundParamId = false; status = parseList( @@ -5108,7 +5117,7 @@ ParserStatus Parser::parseLifetimeDependenceSpecifiers( specifierList.push_back( LifetimeDependenceSpecifier:: getNamedLifetimeDependenceSpecifier( - paramLoc, *lifetimeDependenceKind, paramName)); + paramLoc, lifetimeDependenceKind, paramName)); break; } case tok::integer_literal: { @@ -5123,14 +5132,14 @@ ParserStatus Parser::parseLifetimeDependenceSpecifiers( specifierList.push_back( LifetimeDependenceSpecifier:: getOrderedLifetimeDependenceSpecifier( - paramLoc, *lifetimeDependenceKind, paramNum)); + paramLoc, lifetimeDependenceKind, paramNum)); break; } case tok::kw_self: { auto paramLoc = consumeToken(tok::kw_self); specifierList.push_back( LifetimeDependenceSpecifier::getSelfLifetimeDependenceSpecifier( - paramLoc, *lifetimeDependenceKind)); + paramLoc, lifetimeDependenceKind)); break; } default: @@ -5465,7 +5474,7 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) { continue; } - if (Tok.isLifetimeDependenceToken(P.isInSILMode())) { + if (P.isLifetimeDependenceToken()) { if (!P.Context.LangOpts.hasFeature(Feature::NonescapableTypes)) { P.diagnose(Tok, diag::requires_experimental_feature, "lifetime dependence specifier", false, diff --git a/lib/Sema/LifetimeDependence.cpp b/lib/Sema/LifetimeDependence.cpp index 4d1a5ff53b740..eb82d5447cdfa 100644 --- a/lib/Sema/LifetimeDependence.cpp +++ b/lib/Sema/LifetimeDependence.cpp @@ -39,44 +39,79 @@ std::string LifetimeDependenceInfo::getString() const { }; if (inheritLifetimeParamIndices && !inheritLifetimeParamIndices->isEmpty()) { lifetimeDependenceString = - "_inherit(" + getOnIndices(inheritLifetimeParamIndices) + ")"; + "_inherit(" + getOnIndices(inheritLifetimeParamIndices) + ") "; } if (scopeLifetimeParamIndices && !scopeLifetimeParamIndices->isEmpty()) { lifetimeDependenceString += - "_scope(" + getOnIndices(scopeLifetimeParamIndices) + ")"; + "_scope(" + getOnIndices(scopeLifetimeParamIndices) + ") "; } return lifetimeDependenceString; } void LifetimeDependenceInfo::Profile(llvm::FoldingSetNodeID &ID) const { if (inheritLifetimeParamIndices) { - // Copy and Consume are the same, can be unified if we converge on dependsOn - // syntax - ID.AddInteger((uint8_t)LifetimeDependenceKind::Copy); + ID.AddInteger((uint8_t)LifetimeDependenceKind::Inherit); inheritLifetimeParamIndices->Profile(ID); } if (scopeLifetimeParamIndices) { - // Borrow and Mutate are the same, can be unified if we converge on - // dependsOn syntax - ID.AddInteger((uint8_t)LifetimeDependenceKind::Borrow); + ID.AddInteger((uint8_t)LifetimeDependenceKind::Scope); scopeLifetimeParamIndices->Profile(ID); } } +static LifetimeDependenceKind +getLifetimeDependenceKindFromType(Type sourceType) { + if (sourceType->isEscapable()) { + return LifetimeDependenceKind::Scope; + } + return LifetimeDependenceKind::Inherit; +} + +static ValueOwnership getLoweredOwnership(AbstractFunctionDecl *afd) { + if (isa(afd)) { + return ValueOwnership::Owned; + } + if (auto *ad = dyn_cast(afd)) { + if (ad->getAccessorKind() == AccessorKind::Set || + ad->getAccessorKind() == AccessorKind::Modify) { + return ValueOwnership::InOut; + } + } + return ValueOwnership::Shared; +} + +static bool +isLifetimeDependenceCompatibleWithOwnership(LifetimeDependenceKind kind, + ValueOwnership ownership, + AbstractFunctionDecl *afd) { + if (kind == LifetimeDependenceKind::Inherit) { + return true; + } + assert(kind == LifetimeDependenceKind::Scope); + auto loweredOwnership = ownership != ValueOwnership::Default + ? ownership + : getLoweredOwnership(afd); + + if (loweredOwnership == ValueOwnership::InOut || + loweredOwnership == ValueOwnership::Shared) { + return true; + } + assert(loweredOwnership == ValueOwnership::Owned); + return false; +} + LifetimeDependenceInfo LifetimeDependenceInfo::getForParamIndex( - AbstractFunctionDecl *afd, unsigned index, ValueOwnership ownership) { + AbstractFunctionDecl *afd, unsigned index, LifetimeDependenceKind kind) { auto *dc = afd->getDeclContext(); auto &ctx = dc->getASTContext(); unsigned capacity = afd->getParameters()->size() + 1; auto indexSubset = IndexSubset::get(ctx, capacity, {index}); - if (ownership == ValueOwnership::Owned) { - return LifetimeDependenceInfo{/*inheritLifetimeParamIndices*/ indexSubset, - /*scopeLifetimeParamIndices*/ nullptr}; + if (kind == LifetimeDependenceKind::Scope) { + return LifetimeDependenceInfo{/*inheritLifetimeParamIndices*/ nullptr, + /*scopeLifetimeParamIndices*/ indexSubset}; } - assert(ownership == ValueOwnership::Shared || - ownership == ValueOwnership::InOut); - return LifetimeDependenceInfo{/*inheritLifetimeParamIndices*/ nullptr, - /*scopeLifetimeParamIndices*/ indexSubset}; + return LifetimeDependenceInfo{/*inheritLifetimeParamIndices*/ indexSubset, + /*scopeLifetimeParamIndices*/ nullptr}; } void LifetimeDependenceInfo::getConcatenatedData( @@ -121,6 +156,19 @@ static bool hasEscapableResultOrYield(AbstractFunctionDecl *afd, return false; } +static LifetimeDependenceKind getLifetimeDependenceKindFromDecl( + ParsedLifetimeDependenceKind parsedLifetimeDependenceKind, Type paramType) { + if (parsedLifetimeDependenceKind == ParsedLifetimeDependenceKind::Scope) { + return LifetimeDependenceKind::Scope; + } + if (parsedLifetimeDependenceKind == ParsedLifetimeDependenceKind::Inherit) { + // TODO: assert that this can happen only on deserialized decls + return LifetimeDependenceKind::Inherit; + } + return paramType->isEscapable() ? LifetimeDependenceKind::Scope + : LifetimeDependenceKind::Inherit; +} + std::optional LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType, bool allowIndex) { @@ -142,70 +190,55 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType, SmallBitVector scopeLifetimeParamIndices(capacity); auto updateLifetimeDependenceInfo = [&](LifetimeDependenceSpecifier specifier, - unsigned paramIndexToSet, Type type, + unsigned paramIndexToSet, + Type paramType, ValueOwnership ownership) { auto loc = specifier.getLoc(); - auto kind = specifier.getLifetimeDependenceKind(); - - if (ownership == ValueOwnership::Default) { - diags.diagnose(loc, diag::lifetime_dependence_missing_ownership_modifier); - return true; - } - if (kind == LifetimeDependenceKind::Borrow && - ownership != ValueOwnership::Shared) { - diags.diagnose(loc, diag::lifetime_dependence_cannot_use_kind, "borrow", - getOwnershipSpelling(ownership)); - return true; - } - if (kind == LifetimeDependenceKind::Mutate && - ownership != ValueOwnership::InOut) { - diags.diagnose(loc, diag::lifetime_dependence_cannot_use_kind, "mutate", - getOwnershipSpelling(ownership)); - return true; - } - if (kind == LifetimeDependenceKind::Consume && - ownership != ValueOwnership::Owned) { - diags.diagnose(loc, diag::lifetime_dependence_cannot_use_kind, "consume", - getOwnershipSpelling(ownership)); - return true; - } - if (kind == LifetimeDependenceKind::Consume || - kind == LifetimeDependenceKind::Copy) { - if (type->isEscapable()) { - diags.diagnose(loc, diag::lifetime_dependence_cannot_use_infer, - specifier.getLifetimeDependenceKindString()); - return true; - } - } // Diagnose when we have lifetime dependence on a type that is // BitwiseCopyable & Escapable. // ~Escapable types are non-trivial in SIL and we should not raise this // error. // TODO: Diagnose ~Escapable types are always non-trivial in SIL. - if (type->isEscapable()) { + if (paramType->isEscapable()) { if (ctx.LangOpts.hasFeature(Feature::BitwiseCopyable)) { auto *bitwiseCopyableProtocol = ctx.getProtocol(KnownProtocolKind::BitwiseCopyable); if (bitwiseCopyableProtocol && - mod->checkConformance(type, bitwiseCopyableProtocol)) { + mod->checkConformance(paramType, bitwiseCopyableProtocol)) { diags.diagnose(loc, diag::lifetime_dependence_on_bitwise_copyable); return true; } } } + auto parsedLifetimeKind = specifier.getParsedLifetimeDependenceKind(); + auto lifetimeKind = + getLifetimeDependenceKindFromDecl(parsedLifetimeKind, paramType); + bool isCompatible = isLifetimeDependenceCompatibleWithOwnership( + lifetimeKind, ownership, afd); + if (parsedLifetimeKind == ParsedLifetimeDependenceKind::Scope && + !isCompatible) { + diags.diagnose( + loc, diag::lifetime_dependence_cannot_use_parsed_scoped_consuming); + return true; + } + if (!isCompatible) { + assert(lifetimeKind == LifetimeDependenceKind::Scope); + diags.diagnose( + loc, diag::lifetime_dependence_cannot_use_inferred_scoped_consuming); + return true; + } + if (inheritLifetimeParamIndices.test(paramIndexToSet) || scopeLifetimeParamIndices.test(paramIndexToSet)) { diags.diagnose(loc, diag::lifetime_dependence_duplicate_param_id); return true; } - if (kind == LifetimeDependenceKind::Copy || - kind == LifetimeDependenceKind::Consume) { + if (lifetimeKind == LifetimeDependenceKind::Inherit) { inheritLifetimeParamIndices.set(paramIndexToSet); } else { - assert(kind == LifetimeDependenceKind::Borrow || - kind == LifetimeDependenceKind::Mutate); + assert(lifetimeKind == LifetimeDependenceKind::Scope); scopeLifetimeParamIndices.set(paramIndexToSet); } return false; @@ -218,7 +251,6 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType, unsigned paramIndex = 0; for (auto *param : *afd->getParameters()) { if (param->getParameterName() == specifier.getName()) { - foundParamName = true; if (updateLifetimeDependenceInfo( specifier, paramIndex + 1, afd->mapTypeIntoContext( @@ -226,6 +258,7 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType, param->getValueOwnership())) { return std::nullopt; } + foundParamName = true; break; } paramIndex++; @@ -260,7 +293,12 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType, case LifetimeDependenceSpecifier::SpecifierKind::Self: { if (!afd->hasImplicitSelfDecl()) { diags.diagnose(specifier.getLoc(), - diag::lifetime_dependence_invalid_self); + diag::lifetime_dependence_invalid_self_in_static); + return std::nullopt; + } + if (isa(afd)) { + diags.diagnose(specifier.getLoc(), + diag::lifetime_dependence_invalid_self_in_init); return std::nullopt; } if (updateLifetimeDependenceInfo( @@ -302,11 +340,9 @@ std::optional LifetimeDependenceInfo::fromTypeRepr( unsigned paramIndexToSet, ParameterConvention paramConvention) { auto loc = specifier.getLoc(); - auto kind = specifier.getLifetimeDependenceKind(); + auto kind = specifier.getParsedLifetimeDependenceKind(); - // Once we have dependsOn()/dependsOn(scoped:) syntax, this enum values will - // be Scope and Inherit. - if (kind == LifetimeDependenceKind::Borrow && + if (kind == ParsedLifetimeDependenceKind::Scope && (!isGuaranteedParameter(paramConvention) && !isMutatingParameter(paramConvention))) { diags.diagnose(loc, diag::lifetime_dependence_cannot_use_kind, "_scope", @@ -319,10 +355,10 @@ std::optional LifetimeDependenceInfo::fromTypeRepr( diags.diagnose(loc, diag::lifetime_dependence_duplicate_param_id); return true; } - if (kind == LifetimeDependenceKind::Copy) { + if (kind == ParsedLifetimeDependenceKind::Inherit) { inheritLifetimeParamIndices.set(paramIndexToSet); } else { - assert(kind == LifetimeDependenceKind::Borrow); + assert(kind == ParsedLifetimeDependenceKind::Scope); scopeLifetimeParamIndices.set(paramIndexToSet); } return false; @@ -339,7 +375,7 @@ std::optional LifetimeDependenceInfo::fromTypeRepr( } if (index == 0 && !hasSelfParam) { diags.diagnose(specifier.getLoc(), - diag::lifetime_dependence_invalid_self); + diag::lifetime_dependence_invalid_self_in_static); return std::nullopt; } auto param = index == 0 ? params.back() : params[index - 1]; @@ -368,8 +404,7 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) { return std::nullopt; } - // Perform lifetime dependence inference under a flag only. Currently all - // stdlib types can appear is ~Escapable and ~Copyable. + // Disable inference if requested. if (!ctx.LangOpts.EnableExperimentalLifetimeDependenceInference) { return std::nullopt; } @@ -386,36 +421,28 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) { return std::nullopt; } - if (afd->getKind() != DeclKind::Constructor && afd->hasImplicitSelfDecl()) { - ValueOwnership ownership = ValueOwnership::Default; - if (auto *AD = dyn_cast(afd)) { - if (AD->getAccessorKind() == AccessorKind::Get || - AD->getAccessorKind() == AccessorKind::Read) { - // We don't support "borrowing/consuming" ownership modifiers on - // getters/_read accessors, they are guaranteed by default for now. - ownership = ValueOwnership::Shared; - } - if (AD->getAccessorKind() == AccessorKind::Modify) { - ownership = ValueOwnership::InOut; - } + auto *cd = dyn_cast(afd); + if (cd && cd->isImplicit()) { + if (cd->getParameters()->size() == 0) { + return std::nullopt; } else { - assert(afd->getKind() == DeclKind::Func); - ownership = afd->getImplicitSelfDecl()->getValueOwnership(); - if (ownership == ValueOwnership::Default) { - diags.diagnose( - returnLoc, - diag:: - lifetime_dependence_cannot_infer_wo_ownership_modifier_on_method); - return std::nullopt; - } + diags.diagnose(cd->getLoc(), + diag::lifetime_dependence_cannot_infer_implicit_init); + return std::nullopt; } - return LifetimeDependenceInfo::getForParamIndex(afd, /*selfIndex*/ 0, - ownership); } - auto *cd = dyn_cast(afd); - if (cd && cd->isImplicit() && cd->getParameters()->size() == 0) { - return std::nullopt; + if (afd->getKind() != DeclKind::Constructor && afd->hasImplicitSelfDecl()) { + Type selfTypeInContext = dc->getSelfTypeInContext(); + auto kind = getLifetimeDependenceKindFromType(selfTypeInContext); + auto selfOwnership = afd->getImplicitSelfDecl()->getValueOwnership(); + if (!isLifetimeDependenceCompatibleWithOwnership(kind, selfOwnership, + afd)) { + diags.diagnose(afd->getLoc(), + diag::lifetime_dependence_invalid_self_ownership); + return std::nullopt; + } + return LifetimeDependenceInfo::getForParamIndex(afd, /*selfIndex*/ 0, kind); } LifetimeDependenceInfo lifetimeDependenceInfo; @@ -428,19 +455,20 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) { }; Type paramTypeInContext = afd->mapTypeIntoContext(param->getInterfaceType()); - if (paramTypeInContext->hasError()) { hasParamError = true; continue; } - if (param->getValueOwnership() == ValueOwnership::Default) { + auto paramOwnership = param->getValueOwnership(); + if (paramTypeInContext->isEscapable() && paramOwnership == ValueOwnership::Default) { continue; } - if (param->getValueOwnership() == ValueOwnership::Owned && - paramTypeInContext->isEscapable()) { + + auto lifetimeKind = getLifetimeDependenceKindFromType(paramTypeInContext); + if (!isLifetimeDependenceCompatibleWithOwnership(lifetimeKind, paramOwnership, + afd)) { continue; } - if (candidateParam) { diags.diagnose( returnLoc, @@ -448,14 +476,10 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) { return std::nullopt; } candidateParam = param; - lifetimeDependenceInfo = LifetimeDependenceInfo::getForParamIndex( - afd, paramIndex + 1, param->getValueOwnership()); - } - if (cd && cd->isImplicit()) { - diags.diagnose(cd->getLoc(), - diag::lifetime_dependence_cannot_infer_implicit_init); - return std::nullopt; + lifetimeDependenceInfo = + LifetimeDependenceInfo::getForParamIndex(afd, paramIndex + 1, lifetimeKind); } + if (!candidateParam && !hasParamError) { // Explicitly turn off error messages for builtins, since some of are // ~Escapable currently. @@ -499,18 +523,12 @@ std::optional LifetimeDependenceInfo::getLifetimeDependenceOnParam(unsigned paramIndex) { if (inheritLifetimeParamIndices) { if (inheritLifetimeParamIndices->contains(paramIndex)) { - // Can arbitarily return copy or consume here. - // If we converge on dependsOn(borrowed: paramName)/dependsOn(borrowed: - // paramName) syntax, this can be a single case value. - return LifetimeDependenceKind::Copy; + return LifetimeDependenceKind::Inherit; } } if (scopeLifetimeParamIndices) { if (scopeLifetimeParamIndices->contains(paramIndex)) { - // Can arbitarily return borrow or mutate here. - // If we converge on dependsOn(borrowed: paramName)/dependsOn(borrowed: - // paramName) syntax, this can be a single case value. - return LifetimeDependenceKind::Borrow; + return LifetimeDependenceKind::Scope; } } return {}; diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 48c52407d1e24..007b0923a459b 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -8823,7 +8823,7 @@ bool ModuleFile::maybeReadLifetimeDependenceSpecifier( lifetimeDependenceData); unsigned startIndex = 0; - auto pushData = [&](LifetimeDependenceKind kind) { + auto pushData = [&](ParsedLifetimeDependenceKind kind) { for (unsigned i = 0; i < numDeclParams + 1; i++) { if (lifetimeDependenceData[startIndex + i]) { specifierList.push_back( @@ -8835,10 +8835,10 @@ bool ModuleFile::maybeReadLifetimeDependenceSpecifier( }; if (hasInheritLifetimeParamIndices) { - pushData(LifetimeDependenceKind::Consume); + pushData(ParsedLifetimeDependenceKind::Inherit); } if (hasScopeLifetimeParamIndices) { - pushData(LifetimeDependenceKind::Borrow); + pushData(ParsedLifetimeDependenceKind::Scope); } return true; } diff --git a/test/ModuleInterface/Inputs/lifetime_dependence.swift b/test/ModuleInterface/Inputs/lifetime_dependence.swift index 3d7fb1eae371d..f1b69441ee5aa 100644 --- a/test/ModuleInterface/Inputs/lifetime_dependence.swift +++ b/test/ModuleInterface/Inputs/lifetime_dependence.swift @@ -19,19 +19,19 @@ public struct BufferView : ~Escapable { } @inlinable - internal init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> _borrow(a) Self { + internal init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> dependsOn(a) Self { self.init(ptr, a.count) return self } @inlinable - internal init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView) -> _consume(a) Self { + internal init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView) -> dependsOn(a) Self { self.init(ptr, a._count) return self } } @inlinable -public func derive(_ x: consuming BufferView) -> _consume(x) BufferView { +public func derive(_ x: consuming BufferView) -> dependsOn(x) BufferView { return BufferView(x._ptr, x._count) } @@ -39,12 +39,12 @@ public func derive(_ x: consuming BufferView) -> _consume(x) BufferView { public func use(_ x: consuming BufferView) {} @inlinable -public func consumeAndCreate(_ view: consuming BufferView) -> _consume(view) BufferView { +public func consumeAndCreate(_ view: consuming BufferView) -> dependsOn(view) BufferView { return BufferView(view._ptr, view._count) } @inlinable -public func deriveThisOrThat(_ this: consuming BufferView, _ that: consuming BufferView) -> _consume(this, that) BufferView { +public func deriveThisOrThat(_ this: consuming BufferView, _ that: consuming BufferView) -> dependsOn(this, that) BufferView { if (Int.random(in: 1..<100) == 0) { return BufferView(this._ptr, this._count) } diff --git a/test/ModuleInterface/lifetime_dependence_test.swift b/test/ModuleInterface/lifetime_dependence_test.swift index 973bfca5832c4..0570c41bca5dd 100644 --- a/test/ModuleInterface/lifetime_dependence_test.swift +++ b/test/ModuleInterface/lifetime_dependence_test.swift @@ -26,18 +26,18 @@ import lifetime_dependence // CHECK: #if compiler(>=5.3) && $NoncopyableGenerics -// CHECK: @inlinable internal init(_ ptr: Swift.UnsafeRawBufferPointer, _ a: borrowing Swift.Array) -> _borrow(a) Self { -// CHECK: @inlinable internal init(_ ptr: Swift.UnsafeRawBufferPointer, _ a: consuming lifetime_dependence.AnotherView) -> _consume(a) Self { +// CHECK: @inlinable internal init(_ ptr: Swift.UnsafeRawBufferPointer, _ a: borrowing Swift.Array) -> dependsOn(a) Self { +// CHECK: @inlinable internal init(_ ptr: Swift.UnsafeRawBufferPointer, _ a: consuming lifetime_dependence.AnotherView) -> dependsOn(a) Self { // CHECK: #endif // CHECK: #if compiler(>=5.3) && $NoncopyableGenerics -// CHECK: @inlinable public func derive(_ x: consuming lifetime_dependence.BufferView) -> _consume(x) lifetime_dependence.BufferView { +// CHECK: @inlinable public func derive(_ x: consuming lifetime_dependence.BufferView) -> dependsOn(x) lifetime_dependence.BufferView { // CHECK: #endif // CHECK: #if compiler(>=5.3) && $NoncopyableGenerics -// CHECK: @inlinable public func consumeAndCreate(_ view: consuming lifetime_dependence.BufferView) -> _consume(view) lifetime_dependence.BufferView { +// CHECK: @inlinable public func consumeAndCreate(_ view: consuming lifetime_dependence.BufferView) -> dependsOn(view) lifetime_dependence.BufferView { // CHECK: #endif // CHECK: #if compiler(>=5.3) && $NoncopyableGenerics -// CHECK: @inlinable public func deriveThisOrThat(_ this: consuming lifetime_dependence.BufferView, _ that: consuming lifetime_dependence.BufferView) -> _consume(this) _consume(that) lifetime_dependence.BufferView { +// CHECK: @inlinable public func deriveThisOrThat(_ this: consuming lifetime_dependence.BufferView, _ that: consuming lifetime_dependence.BufferView) -> dependsOn(this) dependsOn(that) lifetime_dependence.BufferView { // CHECK: #endif diff --git a/test/Parse/explicit_lifetime_dependence_specifiers.swift b/test/Parse/explicit_lifetime_dependence_specifiers.swift index 04a918b5881b9..be0e22bef36c5 100644 --- a/test/Parse/explicit_lifetime_dependence_specifiers.swift +++ b/test/Parse/explicit_lifetime_dependence_specifiers.swift @@ -16,24 +16,24 @@ struct BufferView : ~Escapable { } self.ptr = ptr } - init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> _borrow(a) Self { + init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> dependsOn(a) Self { self.ptr = ptr return self } - init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper) -> _consume(a) Self { + init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper) -> dependsOn(a) Self { self.ptr = ptr return self } - init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper, b: borrowing Array) -> _consume(a) _borrow(b) Self { + init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper, b: borrowing Array) -> dependsOn(a) dependsOn(scoped b) Self { self.ptr = ptr return self } - init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array, b: borrowing Array, c: Double) -> _consume(a) _borrow(b) Int { // expected-error{{expected Self return type for initializers with lifetime dependence specifiers}} + init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array, b: borrowing Array, c: Double) -> dependsOn(scoped a) dependsOn(b) Int { // expected-error{{expected Self return type for initializers with lifetime dependence specifiers}} self.ptr = ptr return 0 } - /* TODO: Enable this test once stdlib builds with NonescapableTypes support - init?(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array, _ i: Int) -> _borrow(a) Self { + /* TODO: Enable this test once Optional is ~Escapable + init?(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array, _ i: Int) -> dependsOn(a) Self? { if (i % 2 == 0) { self.ptr = ptr return self @@ -62,95 +62,95 @@ func testBasic() { } } -func derive(_ x: borrowing BufferView) -> _borrow(x) BufferView { +func derive(_ x: borrowing BufferView) -> dependsOn(x) BufferView { return BufferView(x.ptr) } -func consumeAndCreate(_ x: consuming BufferView) -> _copy(x) BufferView { +func consumeAndCreate(_ x: consuming BufferView) -> dependsOn(x) BufferView { return BufferView(x.ptr) } func use(_ x: borrowing BufferView) {} -func deriveMultiView1(_ x: borrowing BufferView, _ y: borrowing BufferView) -> _borrow(x, y) BufferView { +func deriveMultiView1(_ x: borrowing BufferView, _ y: borrowing BufferView) -> dependsOn(x, y) BufferView { if (Int.random(in: 1..<100) % 2 == 0) { return BufferView(x.ptr) } return BufferView(y.ptr) } -func deriveMultiView2(_ x: borrowing BufferView, _ y: borrowing BufferView) -> _borrow(x) _borrow(y) BufferView { +func deriveMultiView2(_ x: borrowing BufferView, _ y: borrowing BufferView) -> dependsOn(x) dependsOn(y) BufferView { if (Int.random(in: 1..<100) % 2 == 0) { return BufferView(x.ptr) } return BufferView(y.ptr) } -func consumeAndCreateMultiView1(_ x: consuming BufferView, _ y: consuming BufferView) -> _copy(x, y) BufferView { +func consumeAndCreateMultiView1(_ x: consuming BufferView, _ y: consuming BufferView) -> dependsOn(x, y) BufferView { if (Int.random(in: 1..<100) % 2 == 0) { return BufferView(x.ptr) } return BufferView(y.ptr) } -func consumeAndCreateMultiView2(_ x: consuming BufferView, _ y: consuming BufferView) -> _copy(x) _copy(y) BufferView { +func consumeAndCreateMultiView2(_ x: consuming BufferView, _ y: consuming BufferView) -> dependsOn(x) dependsOn(y) BufferView { if (Int.random(in: 1..<100) % 2 == 0) { return BufferView(x.ptr) } return BufferView(y.ptr) } -func mixedMultiView(_ x: consuming BufferView, _ y: borrowing BufferView) -> _copy(x) _borrow(y) BufferView { +func mixedMultiView(_ x: consuming BufferView, _ y: borrowing BufferView) -> dependsOn(x) dependsOn(y) BufferView { if (Int.random(in: 1..<100) % 2 == 0) { return BufferView(x.ptr) } return BufferView(y.ptr) } -func modifiedViewDependsOnInput(_ x: inout MutableBufferView) -> _mutate(x) MutableBufferView { +func modifiedViewDependsOnInput(_ x: inout MutableBufferView) -> dependsOn(x) MutableBufferView { return MutableBufferView(x.ptr) } -func modifiedViewDependsOnParent(_ x: inout MutableBufferView) -> _copy(x) MutableBufferView { +func modifiedViewDependsOnParent(_ x: inout MutableBufferView) -> dependsOn(x) MutableBufferView { return MutableBufferView(x.ptr) } -func invalidSpecifier1(_ x: borrowing BufferView) -> _borrow BufferView { // expected-error{{expected '(' after lifetime dependence specifier}} +func invalidSpecifier1(_ x: borrowing BufferView) -> dependsOn BufferView { // expected-error{{expected '(' after lifetime dependence specifier}} return BufferView(x.ptr) } -func invalidSpecifier2(_ x: borrowing BufferView) -> _borrow() BufferView {// expected-error{{expected identifier, index or self in lifetime dependence specifier}} +func invalidSpecifier2(_ x: borrowing BufferView) -> dependsOn() BufferView {// expected-error{{expected identifier, index or self in lifetime dependence specifier}} return BufferView(x.ptr) } -func invalidSpecifier3(_ x: borrowing BufferView) -> _borrow(*) BufferView { // expected-error{{expected identifier, index or self in lifetime dependence specifier}} +func invalidSpecifier3(_ x: borrowing BufferView) -> dependsOn(*) BufferView { // expected-error{{expected identifier, index or self in lifetime dependence specifier}} return BufferView(x.ptr) } // TODO: Diagnose using param indices on func decls in sema -func invalidSpecifier4(_ x: borrowing BufferView) -> _borrow(0) BufferView { // expected-error{{invalid lifetime dependence specifier, self is valid in non-static methods only}} +func invalidSpecifier4(_ x: borrowing BufferView) -> dependsOn(0) BufferView { // expected-error{{invalid lifetime dependence specifier on non-existent self}} return BufferView(x.ptr) } struct Wrapper : ~Escapable { let view: BufferView - init(_ view: consuming BufferView) -> _consume(view) Self { + init(_ view: consuming BufferView) -> dependsOn(view) Self { self.view = view return self } - borrowing func getView1() -> _borrow(self) BufferView { + borrowing func getView1() -> dependsOn(self) BufferView { return view } - consuming func getView2() -> _consume(self) BufferView { + consuming func getView2() -> dependsOn(self) BufferView { return view } - mutating func getView3() -> _copy(self) BufferView { + mutating func getView3() -> dependsOn(self) BufferView { return view } - borrowing func getView4() -> _copy(self) BufferView { + borrowing func getView4() -> dependsOn(self) BufferView { return view } } diff --git a/test/SIL/Parser/lifetime_dependence.sil b/test/SIL/Parser/lifetime_dependence.sil index 0d9f8f3f58e20..861ed2f58ddac 100644 --- a/test/SIL/Parser/lifetime_dependence.sil +++ b/test/SIL/Parser/lifetime_dependence.sil @@ -10,12 +10,12 @@ import Swift struct BufferView : ~Escapable { @_hasStorage let ptr: UnsafeRawBufferPointer { get } @_unsafeNonescapableResult @inlinable init(_ ptr: UnsafeRawBufferPointer) - init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> _borrow(a) Self + init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> _scope(a) Self } -func derive(_ x: borrowing BufferView) -> _borrow(x) BufferView +func derive(_ x: borrowing BufferView) -> _scope(x) BufferView -func consumeAndCreate(_ x: consuming BufferView) -> _copy(x) BufferView +func consumeAndCreate(_ x: consuming BufferView) -> _inherit(x) BufferView sil hidden [unsafe_nonescapable_result] @bufferviewinit1 : $@convention(method) (UnsafeRawBufferPointer, @thin BufferView.Type) -> @owned BufferView { bb0(%0 : $UnsafeRawBufferPointer, %1 : $@thin BufferView.Type): diff --git a/test/SIL/explicit_lifetime_dependence_specifiers.swift b/test/SIL/explicit_lifetime_dependence_specifiers.swift index 67bcef96b7cc3..d39e75efc042f 100644 --- a/test/SIL/explicit_lifetime_dependence_specifiers.swift +++ b/test/SIL/explicit_lifetime_dependence_specifiers.swift @@ -21,17 +21,17 @@ struct BufferView : ~Escapable { self.ptr = ptr } // CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_SaySiGhYlstcfC : $@convention(method) (UnsafeRawBufferPointer, @guaranteed Array, @thin BufferView.Type) -> _scope(2) @owned BufferView { - init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> _borrow(a) Self { + init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> dependsOn(a) Self { self.ptr = ptr return self } // CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_AA7WrapperVYlitcfC : $@convention(method) (UnsafeRawBufferPointer, @owned Wrapper, @thin BufferView.Type) -> _inherit(2) @owned BufferView { - init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper) -> _consume(a) Self { + init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper) -> dependsOn(a) Self { self.ptr = ptr return self } -// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_AA7WrapperVYliSaySiGhYlstcfC : $@convention(method) (UnsafeRawBufferPointer, @owned Wrapper, @guaranteed Array, @thin BufferView.Type) -> _inherit(2)_scope(3) @owned BufferView { - init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper, _ b: borrowing Array) -> _consume(a) _borrow(b) Self { +// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_AA7WrapperVYliSaySiGhYlstcfC : $@convention(method) (UnsafeRawBufferPointer, @owned Wrapper, @guaranteed Array, @thin BufferView.Type) -> _inherit(2) _scope(3) @owned BufferView { + init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper, _ b: borrowing Array) -> dependsOn(a) dependsOn(b) Self { self.ptr = ptr return self } @@ -57,25 +57,25 @@ func testBasic() { } // CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers6deriveyAA10BufferViewVADYlsF : $@convention(thin) (@guaranteed BufferView) -> _scope(1) @owned BufferView { -func derive(_ x: borrowing BufferView) -> _borrow(x) BufferView { +func derive(_ x: borrowing BufferView) -> dependsOn(scoped x) BufferView { return BufferView(x.ptr) } // CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers16consumeAndCreateyAA10BufferViewVADnYliF : $@convention(thin) (@owned BufferView) -> _inherit(1) @owned BufferView { -func consumeAndCreate(_ x: consuming BufferView) -> _copy(x) BufferView { +func consumeAndCreate(_ x: consuming BufferView) -> dependsOn(x) BufferView { return BufferView(x.ptr) } // CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat1yAA10BufferViewVADYls_ADYlstF : $@convention(thin) (@guaranteed BufferView, @guaranteed BufferView) -> _scope(1, 2) @owned BufferView { -func deriveThisOrThat1(_ this: borrowing BufferView, _ that: borrowing BufferView) -> _borrow(this, that) BufferView { +func deriveThisOrThat1(_ this: borrowing BufferView, _ that: borrowing BufferView) -> dependsOn(scoped this, that) BufferView { if (Int.random(in: 1..<100) == 0) { return BufferView(this.ptr) } return BufferView(that.ptr) } -// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat2yAA10BufferViewVADYls_ADnYlitF : $@convention(thin) (@guaranteed BufferView, @owned BufferView) -> _inherit(2)_scope(1) @owned BufferView { -func deriveThisOrThat2(_ this: borrowing BufferView, _ that: consuming BufferView) -> _borrow(this) _copy(that) BufferView { +// CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat2yAA10BufferViewVADYls_ADnYlitF : $@convention(thin) (@guaranteed BufferView, @owned BufferView) -> _inherit(2) _scope(1) @owned BufferView { +func deriveThisOrThat2(_ this: borrowing BufferView, _ that: consuming BufferView) -> dependsOn(scoped this) dependsOn(that) BufferView { if (Int.random(in: 1..<100) == 0) { return BufferView(this.ptr) } @@ -90,12 +90,12 @@ struct Wrapper : ~Escapable { self.view = view } // CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers7WrapperV8getView1AA10BufferViewVyYLsF : $@convention(method) (@guaranteed Wrapper) -> _scope(0) @owned BufferView { - borrowing func getView1() -> _borrow(self) BufferView { + borrowing func getView1() -> dependsOn(scoped self) BufferView { return view } // CHECK: sil hidden @$s39explicit_lifetime_dependence_specifiers7WrapperV8getView2AA10BufferViewVyYLiF : $@convention(method) (@owned Wrapper) -> _inherit(0) @owned BufferView { - consuming func getView2() -> _consume(self) BufferView { + consuming func getView2() -> dependsOn(self) BufferView { return view } } @@ -109,12 +109,12 @@ struct Container : ~Escapable { } // CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16getConsumingViewyAA06BufferG0VAA9ContainerVnYliF : $@convention(thin) (@owned Container) -> _inherit(1) @owned BufferView { -func getConsumingView(_ x: consuming Container) -> _consume(x) BufferView { +func getConsumingView(_ x: consuming Container) -> dependsOn(x) BufferView { return BufferView(x.ptr) } // CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16getBorrowingViewyAA06BufferG0VAA9ContainerVYlsF : $@convention(thin) (@guaranteed Container) -> _scope(1) @owned BufferView { -func getBorrowingView(_ x: borrowing Container) -> _borrow(x) BufferView { +func getBorrowingView(_ x: borrowing Container) -> dependsOn(scoped x) BufferView { return BufferView(x.ptr) } diff --git a/test/SIL/implicit_lifetime_dependence.swift b/test/SIL/implicit_lifetime_dependence.swift index 438eeec7b058c..8239adfce35b9 100644 --- a/test/SIL/implicit_lifetime_dependence.swift +++ b/test/SIL/implicit_lifetime_dependence.swift @@ -12,7 +12,7 @@ struct BufferView : ~Escapable { self.ptr = ptr self.c = c } -// CHECK: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2ChYlscfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> _scope(1) @owned BufferView { +// CHECK: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2ChYlicfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> _inherit(1) @owned BufferView { init(_ otherBV: borrowing BufferView) { self.ptr = otherBV.ptr self.c = otherBV.c @@ -49,11 +49,15 @@ func testBasic() { } } -// CHECK: sil hidden @$s28implicit_lifetime_dependence6deriveyAA10BufferViewVADYlsF : $@convention(thin) (@guaranteed BufferView) -> _scope(1) @owned BufferView { +// CHECK: sil hidden @$s28implicit_lifetime_dependence6deriveyAA10BufferViewVADYliF : $@convention(thin) (@guaranteed BufferView) -> _inherit(1) @owned BufferView { func derive(_ x: borrowing BufferView) -> BufferView { return BufferView(x.ptr, x.c) } +func derive(_ unused: Int, _ x: borrowing BufferView) -> BufferView { + return BufferView(x.ptr, x.c) +} + // CHECK: sil hidden @$s28implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnYliF : $@convention(thin) (@owned BufferView) -> _inherit(1) @owned BufferView { func consumeAndCreate(_ x: consuming BufferView) -> BufferView { return BufferView(x.ptr, x.c) @@ -64,11 +68,11 @@ func use(_ x: borrowing BufferView) {} struct Wrapper : ~Escapable { var _view: BufferView var view: BufferView { -// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvr : $@yield_once @convention(method) (@guaranteed Wrapper) -> _scope(0) @yields @guaranteed BufferView { +// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvr : $@yield_once @convention(method) (@guaranteed Wrapper) -> _inherit(0) @yields @guaranteed BufferView { _read { yield _view } -// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvM : $@yield_once @convention(method) (@inout Wrapper) -> _scope(0) @yields @inout BufferView { +// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvM : $@yield_once @convention(method) (@inout Wrapper) -> _inherit(0) @yields @inout BufferView { _modify { yield &_view } @@ -77,7 +81,8 @@ struct Wrapper : ~Escapable { init(_ view: consuming BufferView) { self._view = view } -// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView1AA10BufferViewVyYLsF : $@convention(method) (@guaranteed Wrapper) -> _scope(0) @owned BufferView { +// TODO: Investigate why it was mangled as Yli and not YLi before +// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView1AA10BufferViewVyYLiF : $@convention(method) (@guaranteed Wrapper) -> _inherit(0) @owned BufferView { borrowing func getView1() -> BufferView { return _view } @@ -147,7 +152,7 @@ struct GenericBufferView : ~Escapable { } } } -// CHECK: sil hidden @$s28implicit_lifetime_dependence17GenericBufferViewVyACyxGAA9FakeRangeVySVGcig : $@convention(method) (FakeRange, @guaranteed GenericBufferView) -> _scope(0) @owned GenericBufferView { +// CHECK: sil hidden @$s28implicit_lifetime_dependence17GenericBufferViewVyACyxGAA9FakeRangeVySVGcig : $@convention(method) (FakeRange, @guaranteed GenericBufferView) -> _inherit(0) @owned GenericBufferView { subscript(bounds: FakeRange) -> Self { get { GenericBufferView( @@ -158,7 +163,7 @@ struct GenericBufferView : ~Escapable { } } -// CHECK: sil hidden @$s28implicit_lifetime_dependence23tupleLifetimeDependenceyAA10BufferViewV_ADtADYlsF : $@convention(thin) (@guaranteed BufferView) -> _scope(1) (@owned BufferView, @owned BufferView) { +// CHECK: sil hidden @$s28implicit_lifetime_dependence23tupleLifetimeDependenceyAA10BufferViewV_ADtADYliF : $@convention(thin) (@guaranteed BufferView) -> _inherit(1) (@owned BufferView, @owned BufferView) { func tupleLifetimeDependence(_ x: borrowing BufferView) -> (BufferView, BufferView) { return (BufferView(x.ptr, x.c), BufferView(x.ptr, x.c)) } diff --git a/test/SIL/lifetime_dependence_buffer_view_test.swift b/test/SIL/lifetime_dependence_buffer_view_test.swift index af97bb47ec9e3..304f0671d9674 100644 --- a/test/SIL/lifetime_dependence_buffer_view_test.swift +++ b/test/SIL/lifetime_dependence_buffer_view_test.swift @@ -134,18 +134,18 @@ extension BufferView { } } - borrowing public func prefix(upTo index: BufferViewIndex) -> _borrow(self) Self { + borrowing public func prefix(upTo index: BufferViewIndex) -> dependsOn(self) Self { index == startIndex ? Self(start: start, count: 0, dependsOn: copy self) : prefix(through: index.advanced(by: -1)) } - borrowing public func prefix(through index: Index) -> _borrow(self) Self { + borrowing public func prefix(through index: Index) -> dependsOn(self) Self { let nc = distance(from: startIndex, to: index) &+ 1 return Self(start: start, count: nc, dependsOn: copy self) } - consuming public func prefix(_ maxLength: Int) -> _consume(self) Self { + consuming public func prefix(_ maxLength: Int) -> dependsOn(self) Self { precondition(maxLength >= 0, "Can't have a prefix of negative length.") let nc = maxLength < count ? maxLength : count return Self(start: start, count: nc, dependsOn: self) diff --git a/test/SIL/lifetime_dependence_generics.swift b/test/SIL/lifetime_dependence_generics.swift index a18dd08bc380e..040b8c9d78730 100644 --- a/test/SIL/lifetime_dependence_generics.swift +++ b/test/SIL/lifetime_dependence_generics.swift @@ -5,11 +5,11 @@ protocol P { associatedtype E: ~Escapable - borrowing func getE() -> _borrow(self) E + borrowing func getE() -> dependsOn(self) E } extension P { - borrowing func getDefault() -> _borrow(self) E { + borrowing func getDefault() -> dependsOn(self) E { return getE() } } @@ -20,10 +20,10 @@ public struct View: ~Escapable { } public struct PView: P { - borrowing func getE() -> _borrow(self) View { return View() } + borrowing func getE() -> dependsOn(self) View { return View() } } -public func test(pview: borrowing PView) -> _borrow(pview) View { +public func test(pview: borrowing PView) -> dependsOn(pview) View { return pview.getDefault() } diff --git a/test/SILOptimizer/lifetime_dependence_borrow.swift b/test/SILOptimizer/lifetime_dependence_borrow.swift index 29dc5b1512b38..47cc015227e26 100644 --- a/test/SILOptimizer/lifetime_dependence_borrow.swift +++ b/test/SILOptimizer/lifetime_dependence_borrow.swift @@ -47,7 +47,7 @@ struct MBV : ~Copyable { } // Requires a borrow. - borrowing func getBV() -> _borrow(self) BV { + borrowing func getBV() -> dependsOn(self) BV { BV(p, i) } } @@ -63,22 +63,22 @@ struct NEBV { } // Propagate a borrow. -func bv_get_borrow(container: borrowing MBV) -> _borrow(container) BV { +func bv_get_borrow(container: borrowing MBV) -> dependsOn(container) BV { container.getBV() } // Copy a borrow. -func bv_get_copy(container: borrowing MBV) -> _copy(container) BV { +func bv_get_copy(container: borrowing MBV) -> dependsOn(container) BV { return container.getBV() } // Recognize nested accesses as part of the same dependence scope. -func bv_get_mutate(container: inout MBV) -> _mutate(container) BV { +func bv_get_mutate(container: inout MBV) -> dependsOn(container) BV { container.getBV() } // Create and decompose a nonescapable aggregate. -func ne_wrap_and_extract_member(cn: borrowing CN) -> _borrow(cn) BV { +func ne_wrap_and_extract_member(cn: borrowing CN) -> dependsOn(scoped cn) BV { let bv = BV(cn) let ne = NEBV(bv) return ne.bv diff --git a/test/SILOptimizer/lifetime_dependence_borrow_fail.swift b/test/SILOptimizer/lifetime_dependence_borrow_fail.swift index 15d1c5122d77c..02f28bee712c9 100644 --- a/test/SILOptimizer/lifetime_dependence_borrow_fail.swift +++ b/test/SILOptimizer/lifetime_dependence_borrow_fail.swift @@ -29,7 +29,7 @@ struct NC : ~Copyable { self.p = p self.i = i } - borrowing func getBV() -> _borrow(self) BV { + borrowing func getBV() -> dependsOn(self) BV { BV(p, i) } } @@ -44,7 +44,7 @@ struct NE { self.p = p self.i = i } - borrowing func getBV() -> _borrow(self) BV { + borrowing func getBV() -> dependsOn(scoped self) BV { BV(p, i) } } diff --git a/test/SILOptimizer/lifetime_dependence_closure.swift b/test/SILOptimizer/lifetime_dependence_closure.swift index 0d98bb0784019..0921b1e13f0eb 100644 --- a/test/SILOptimizer/lifetime_dependence_closure.swift +++ b/test/SILOptimizer/lifetime_dependence_closure.swift @@ -19,7 +19,7 @@ struct NCInt: ~Copyable { struct NEInt /*: ~Escapable*/ { let value: Int - init(borrowed: borrowing NCInt) -> _borrow(borrowed) Self { + init(borrowed: borrowing NCInt) -> dependsOn(borrowed) Self { self.value = borrowed.value return self } diff --git a/test/SILOptimizer/lifetime_dependence_diagnostics.swift b/test/SILOptimizer/lifetime_dependence_diagnostics.swift index af4a00dec0e49..0039281e8d5e0 100644 --- a/test/SILOptimizer/lifetime_dependence_diagnostics.swift +++ b/test/SILOptimizer/lifetime_dependence_diagnostics.swift @@ -18,7 +18,7 @@ struct BV { } } -func bv_copy(_ bv: borrowing BV) -> _copy(bv) BV { +func bv_copy(_ bv: borrowing BV) -> dependsOn(bv) BV { copy bv } @@ -26,10 +26,10 @@ func bv_copy(_ bv: borrowing BV) -> _copy(bv) BV { // // CHECK-LABEL: sil hidden @$s4test14bv_borrow_copyyAA2BVVADYlsF : $@convention(thin) (@guaranteed BV) -> _scope(1) @owned BV { // CHECK: bb0(%0 : @noImplicitCopy $BV): -// CHECK: apply %{{.*}}(%0) : $@convention(thin) (@guaranteed BV) -> _inherit(1) @owned BV // user: %4 +// CHECK: apply %{{.*}}(%0) : $@convention(thin) (@guaranteed BV) -> _inherit(1) @owned BV // CHECK-NEXT: return %3 : $BV // CHECK-LABEL: } // end sil function '$s4test14bv_borrow_copyyAA2BVVADYlsF' -func bv_borrow_copy(_ bv: borrowing BV) -> _borrow(bv) BV { +func bv_borrow_copy(_ bv: borrowing BV) -> dependsOn(scoped bv) BV { bv_copy(bv) } @@ -42,6 +42,6 @@ func bv_borrow_copy(_ bv: borrowing BV) -> _borrow(bv) BV { // CHECK: %{{.*}} = mark_dependence [nonescaping] [[R]] : $BV on %0 : $BV // CHECK-NEXT: return %{{.*}} : $BV // CHECK-LABEL: } // end sil function '$s4test010bv_borrow_C00B0AA2BVVAEYls_tF' -func bv_borrow_borrow(bv: borrowing BV) -> _borrow(bv) BV { +func bv_borrow_borrow(bv: borrowing BV) -> dependsOn(scoped bv) BV { bv_borrow_copy(bv) } diff --git a/test/SILOptimizer/lifetime_dependence_generic.swift b/test/SILOptimizer/lifetime_dependence_generic.swift index ff27dfafe0e67..f00ccb8f136cb 100644 --- a/test/SILOptimizer/lifetime_dependence_generic.swift +++ b/test/SILOptimizer/lifetime_dependence_generic.swift @@ -18,11 +18,11 @@ precedencegroup AssignmentPrecedence { assignment: true } protocol P { associatedtype E: ~Escapable - borrowing func getE() -> _borrow(self) E + borrowing func getE() -> dependsOn(self) E } extension P { - borrowing func getDefault() -> _borrow(self) E { + borrowing func getDefault() -> dependsOn(self) E { return getE() } } @@ -49,26 +49,26 @@ struct NCInt: ~Copyable { struct NEInt: ~Escapable { let value: Builtin.Int64 - init(v: Builtin.Int64, o: borrowing O) -> _borrow(o) Self { + init(v: Builtin.Int64, o: borrowing O) -> dependsOn(o) Self { self.value = v return self } // Test a generic storage owner. - init(borrowed: borrowing NCInt) -> _borrow(borrowed) Self { + init(borrowed: borrowing NCInt) -> dependsOn(borrowed) Self { self.init(v: borrowed.value, o: borrowed) return self } } -public func consume_indirect(ne: consuming NE) -> _consume(ne) NE { +public func consume_indirect(ne: consuming NE) -> dependsOn(ne) NE { return ne } -public func copy_indirect(ne: borrowing NE) -> _copy(ne) NE { +public func copy_indirect(ne: borrowing NE) -> dependsOn(ne) NE { return copy ne } -public func copy_inout(ne: inout NE) -> _copy(ne) NE { +public func copy_inout(ne: inout NE) -> dependsOn(ne) NE { return copy ne } diff --git a/test/SILOptimizer/lifetime_dependence_inherit.swift b/test/SILOptimizer/lifetime_dependence_inherit.swift index 282cba22febd8..6839e4762fa20 100644 --- a/test/SILOptimizer/lifetime_dependence_inherit.swift +++ b/test/SILOptimizer/lifetime_dependence_inherit.swift @@ -19,7 +19,7 @@ struct BV { self.i = i } - consuming func derive() -> _consume(self) BV { + consuming func derive() -> dependsOn(self) BV { // Technically, this "new" view does not depend on the 'view' argument. // This unsafely creates a new view with no dependence. return BV(self.p, self.i) @@ -31,18 +31,18 @@ struct NE { var bv: BV // Test lifetime inheritance through initialization. - init(_ bv: consuming BV) -> _consume(bv) Self { + init(_ bv: consuming BV) -> dependsOn(bv) Self { self.bv = bv return self } } // Test lifetime inheritance through chained consumes. -func bv_derive(bv: consuming BV) -> _consume(bv) BV { +func bv_derive(bv: consuming BV) -> dependsOn(bv) BV { bv.derive() } // Test lifetime inheritance through stored properties. -func ne_extract_member(ne: consuming NE) -> _consume(ne) BV { +func ne_extract_member(ne: consuming NE) -> dependsOn(ne) BV { return ne.bv } diff --git a/test/SILOptimizer/lifetime_dependence_inherit_fail.swift b/test/SILOptimizer/lifetime_dependence_inherit_fail.swift index 2de5186b81bba..0b6db413fdcd0 100644 --- a/test/SILOptimizer/lifetime_dependence_inherit_fail.swift +++ b/test/SILOptimizer/lifetime_dependence_inherit_fail.swift @@ -19,7 +19,7 @@ struct BV { self.i = i } - consuming func derive() -> _consume(self) BV { + consuming func derive() -> dependsOn(self) BV { // Technically, this "new" view does not depend on the 'view' argument. // This unsafely creates a new view with no dependence. return BV(self.p, self.i) @@ -30,7 +30,7 @@ struct BV { struct NE { var bv: BV - init(_ bv: consuming BV) -> _consume(bv) Self { + init(_ bv: consuming BV) -> dependsOn(bv) Self { self.bv = bv return self } diff --git a/test/SILOptimizer/lifetime_dependence_insertion.swift b/test/SILOptimizer/lifetime_dependence_insertion.swift index bd03aa91a12ab..194e46133645d 100644 --- a/test/SILOptimizer/lifetime_dependence_insertion.swift +++ b/test/SILOptimizer/lifetime_dependence_insertion.swift @@ -25,7 +25,7 @@ struct NC : ~Copyable { let i: Int // Requires a borrow. - borrowing func getBV() -> _borrow(self) BV { + borrowing func getBV() -> dependsOn(self) BV { BV(p, i) } } diff --git a/test/SILOptimizer/lifetime_dependence_mutate.swift b/test/SILOptimizer/lifetime_dependence_mutate.swift index e6999f589c7e1..e0ea16d595842 100644 --- a/test/SILOptimizer/lifetime_dependence_mutate.swift +++ b/test/SILOptimizer/lifetime_dependence_mutate.swift @@ -37,7 +37,7 @@ struct NC : ~Copyable { let c: Int // Requires a mutable borrow. - mutating func getMBV() -> _mutate(self) MBV { + mutating func getMBV() -> dependsOn(self) MBV { MBV(p, c) } } diff --git a/test/SILOptimizer/lifetime_dependence_param.swift b/test/SILOptimizer/lifetime_dependence_param.swift index 3a9d15236d193..57a6392856c30 100644 --- a/test/SILOptimizer/lifetime_dependence_param.swift +++ b/test/SILOptimizer/lifetime_dependence_param.swift @@ -23,7 +23,7 @@ struct BV { public var isEmpty: Bool { i == 0 } // Test consuming `self` - consuming func derive() -> _consume(self) BV { + consuming func derive() -> dependsOn(self) BV { // Technically, this "new" view does not depend on the 'view' argument. // This unsafely creates a new view with no dependence. return BV(self.p, self.i) diff --git a/test/SILOptimizer/lifetime_dependence_param_fail.swift b/test/SILOptimizer/lifetime_dependence_param_fail.swift index 9641f274b721b..465087f17f14a 100644 --- a/test/SILOptimizer/lifetime_dependence_param_fail.swift +++ b/test/SILOptimizer/lifetime_dependence_param_fail.swift @@ -34,7 +34,7 @@ struct NC : ~Copyable { struct NE { var bv: BV - init(_ bv: consuming BV) -> _consume(bv) Self { + init(_ bv: consuming BV) -> dependsOn(bv) Self { self.bv = bv return self } diff --git a/test/SILOptimizer/lifetime_dependence_scope.swift b/test/SILOptimizer/lifetime_dependence_scope.swift index 4d005013a950d..1c5fbd00838f8 100644 --- a/test/SILOptimizer/lifetime_dependence_scope.swift +++ b/test/SILOptimizer/lifetime_dependence_scope.swift @@ -28,7 +28,7 @@ struct NC : ~Copyable { let c: Int // Requires a borrow. - borrowing func getBV() -> _borrow(self) BV { + borrowing func getBV() -> dependsOn(self) BV { BV(p, c) } } @@ -42,6 +42,6 @@ struct NC : ~Copyable { // CHECK: [[R:%.*]] = apply %{{.*}}([[L]]) : $@convention(method) (@guaranteed NC) -> _scope(0) @owned BV // CHECK: [[M:%.*]] = mark_dependence [nonescaping] [[R]] : $BV on %0 : $*NC // CHECK-LABEL: } // end sil function '$s4test13bv_get_mutate9containerAA2BVVAA2NCVzYls_tF' -func bv_get_mutate(container: inout NC) -> _mutate(container) BV { +func bv_get_mutate(container: inout NC) -> dependsOn(container) BV { container.getBV() } diff --git a/test/SILOptimizer/lifetime_dependence_scope_fixup.swift b/test/SILOptimizer/lifetime_dependence_scope_fixup.swift index eb723a98d9de6..44ef7b7da6405 100644 --- a/test/SILOptimizer/lifetime_dependence_scope_fixup.swift +++ b/test/SILOptimizer/lifetime_dependence_scope_fixup.swift @@ -62,15 +62,15 @@ func consume(_ o : consuming View) {} func use(_ o : borrowing MutableView) {} func consume(_ o : consuming MutableView) {} -func getConsumingView(_ x: consuming View) -> _consume(x) View { +func getConsumingView(_ x: consuming View) -> dependsOn(x) View { return View(x.ptr, x.c) } -func getBorrowingView(_ x: borrowing View) -> _borrow(x) View { +func getBorrowingView(_ x: borrowing View) -> dependsOn(x) View { return View(x.ptr, x.c) } -func getBorrowingView(_ x: borrowing NCContainer) -> _borrow(x) View { +func getBorrowingView(_ x: borrowing NCContainer) -> dependsOn(x) View { return View(x.ptr, x.c) } diff --git a/test/Sema/explicit_lifetime_dependence_specifiers1.swift b/test/Sema/explicit_lifetime_dependence_specifiers1.swift index 4130e0f462a4e..c8b3311f30cad 100644 --- a/test/Sema/explicit_lifetime_dependence_specifiers1.swift +++ b/test/Sema/explicit_lifetime_dependence_specifiers1.swift @@ -5,33 +5,57 @@ struct Container { let ptr: UnsafeRawBufferPointer } +struct AnotherBufferView : ~Escapable { + let ptr: UnsafeRawBufferPointer + @_unsafeNonescapableResult + init(_ ptr: UnsafeRawBufferPointer) { + self.ptr = ptr + } +} + struct BufferView : ~Escapable { let ptr: UnsafeRawBufferPointer @_unsafeNonescapableResult init(_ ptr: UnsafeRawBufferPointer) { self.ptr = ptr } - init(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> _borrow(arr) Self { + init(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> dependsOn(arr) Self { self.ptr = ptr return self } - init(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> _borrow(arr) Self { + init(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> dependsOn(arr) Self { self.ptr = ptr } // TODO: Once Optional is ~Escapable, the error will go away - init?(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> _borrow(arr) Self? { // expected-error{{lifetime dependence can only be specified on ~Escapable results}} + init?(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> dependsOn(arr) Self? { // expected-error{{lifetime dependence can only be specified on ~Escapable results}} if (Int.random(in: 1..<100) == 0) { return nil } self.ptr = ptr } - init?(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> _borrow(arr) Self? { // expected-error{{lifetime dependence can only be specified on ~Escapable results}} + init?(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> dependsOn(arr) Self? { // expected-error{{lifetime dependence can only be specified on ~Escapable results}} if (Int.random(in: 1..<100) == 0) { return nil } self.ptr = ptr return self } + init(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array) -> dependsOn(self) Self { // expected-error{{invalid lifetime dependence on self in an initializer}} + self.ptr = ptr + } + init(_ ptr: UnsafeRawBufferPointer, _ arr: Array) -> dependsOn(scoped arr) Self { // expected-error{{invalid use of scoped lifetime dependence with consuming ownership}} + self.ptr = ptr + } + init(_ ptr: UnsafeRawBufferPointer, _ arr: Array) -> dependsOn(arr) Self { // expected-error{{invalid use of lifetime dependence on an Escapable parameter with consuming ownership}} + self.ptr = ptr + } + init(_ ptr: UnsafeRawBufferPointer, _ abv: AnotherBufferView) -> dependsOn(abv) Self { + self.ptr = ptr + } + + consuming func consume() -> dependsOn(scoped self) BufferView { // expected-error{{invalid use of scoped lifetime dependence with consuming ownership}} + return BufferView(self.ptr) + } } struct MutableBufferView : ~Escapable, ~Copyable { @@ -48,72 +72,64 @@ struct WrapperStruct { let k: Klass } -func invalidLifetimeDependenceOnEscapableResult(_ w: borrowing WrapperStruct) -> _borrow(w) Klass { // expected-error{{lifetime dependence can only be specified on ~Escapable results}} +func invalidLifetimeDependenceOnEscapableResult(_ w: borrowing WrapperStruct) -> dependsOn(w) Klass { // expected-error{{lifetime dependence can only be specified on ~Escapable results}} return w.k } -func incorrectSelfInvalidLifetimeDependence(_ x: borrowing BufferView) -> _borrow(self) BufferView { // expected-error{{invalid lifetime dependence specifier, self is valid in non-static methods only}} - return BufferView(x.ptr) -} - -func incorrectParamNameInvalidLifetimeDependence(_ x: borrowing BufferView) -> _borrow(y) BufferView { // expected-error{{invalid parameter name specified 'y'}} - return BufferView(x.ptr) -} - -func duplicateParamInvalidLifetimeDependence1(_ x: borrowing BufferView) -> _borrow(x, x) BufferView { // expected-error{{duplicate lifetime dependence specifier}} +func incorrectSelfInvalidLifetimeDependence(_ x: borrowing BufferView) -> dependsOn(self) BufferView { // expected-error{{invalid lifetime dependence specifier on non-existent self}} return BufferView(x.ptr) } -func duplicateParamInvalidLifetimeDependence2(_ x: borrowing BufferView) -> _borrow(x) _borrow(x) BufferView { // expected-error{{duplicate lifetime dependence specifier}} +func incorrectParamNameInvalidLifetimeDependence(_ x: borrowing BufferView) -> dependsOn(y) BufferView { // expected-error{{invalid parameter name specified 'y'}} return BufferView(x.ptr) } -func duplicateParamInvalidLifetimeDependence3(_ x: borrowing BufferView) -> _borrow(x) _copy(x) BufferView { // expected-error{{duplicate lifetime dependence specifier}} +func duplicateParamInvalidLifetimeDependence1(_ x: borrowing BufferView) -> dependsOn(x, x) BufferView { // expected-error{{duplicate lifetime dependence specifier}} return BufferView(x.ptr) } -func consumingParamInvalidLifetimeDependence1(_ x: consuming BufferView) -> _borrow(x) BufferView { // expected-error{{invalid use of borrow lifetime dependence for consuming ownership}} +func duplicateParamInvalidLifetimeDependence2(_ x: borrowing BufferView) -> dependsOn(x) dependsOn(x) BufferView { // expected-error{{duplicate lifetime dependence specifier}} return BufferView(x.ptr) } -func consumingParamInvalidLifetimeDependence2(_ x: consuming BufferView) -> _mutate(x) BufferView { // expected-error{{invalid use of mutate lifetime dependence for consuming ownership}} +func duplicateParamInvalidLifetimeDependence3(_ x: borrowing BufferView) -> dependsOn(x) dependsOn(x) BufferView { // expected-error{{duplicate lifetime dependence specifier}} return BufferView(x.ptr) } -func borrowingParamInvalidLifetimeDependence1(_ x: borrowing BufferView) -> _consume(x) BufferView { // expected-error{{invalid use of consume lifetime dependence for borrowing ownership}} +func consumingParamInvalidLifetimeDependence1(_ x: consuming BufferView) -> dependsOn(scoped x) BufferView { // expected-error{{invalid use of scoped lifetime dependence with consuming ownership}} return BufferView(x.ptr) } -func borrowingParamInvalidLifetimeDependence2(_ x: borrowing BufferView) -> _mutate(x) BufferView { // expected-error{{invalid use of mutate lifetime dependence for borrowing ownership}} +func borrowingParamInvalidLifetimeDependence1(_ x: borrowing BufferView) -> dependsOn(x) BufferView { return BufferView(x.ptr) } -func implicitBorrowingParamInvalidLifetimeDependence1(_ x: BufferView) -> _consume(x) BufferView { // expected-error{{lifetime dependence can only be specified on parameters with ownership modifiers (borrowing, consuming, inout)}} +func implicitBorrowingParamLifetimeDependence1(_ x: BufferView) -> dependsOn(x) BufferView { return BufferView(x.ptr) } -func implicitBorrowingParamInvalidLifetimeDependence2(_ x: BufferView) -> _mutate(x) BufferView {// expected-error{{lifetime dependence can only be specified on parameters with ownership modifiers (borrowing, consuming, inout)}} +func implicitBorrowingParamLifetimeDependence2(_ x: BufferView) -> dependsOn(scoped x) BufferView { return BufferView(x.ptr) } -func inoutParamInvalidLifetimeDependence1(_ x: inout BufferView) -> _consume(x) BufferView { // expected-error{{invalid use of consume lifetime dependence for inout ownership}} +func inoutParamLifetimeDependence1(_ x: inout BufferView) -> dependsOn(x) BufferView { return BufferView(x.ptr) } -func inoutParamInvalidLifetimeDependence2(_ x: inout BufferView) -> _borrow(x) BufferView { // expected-error{{invalid use of borrow lifetime dependence for inout ownership}} +func inoutParamLifetimeDependence2(_ x: inout BufferView) -> dependsOn(scoped x) BufferView { return BufferView(x.ptr) } -func invalidSpecifierPosition1(_ x: borrowing _borrow(x) BufferView) -> BufferView { // expected-error{{lifetime dependence specifiers may only be used on result of functions, methods, initializers}} +func invalidSpecifierPosition1(_ x: borrowing dependsOn(x) BufferView) -> BufferView { // expected-error{{lifetime dependence specifiers may only be used on result of functions, methods, initializers}} return BufferView(x.ptr) } func invalidSpecifierPosition2(_ x: borrowing BufferView) -> BufferView { - let y: _borrow(x) x // expected-error{{lifetime dependence specifiers may only be used on result of functions, methods, initializers}} + let y: dependsOn(x) x // expected-error{{lifetime dependence specifiers may only be used on result of functions, methods, initializers}} return BufferView(y.ptr) } -func invalidTupleLifetimeDependence(_ x: inout BufferView) -> (_mutate(x) BufferView, BufferView) { // expected-error{{lifetime dependence specifiers cannot be applied to tuple elements}} +func invalidTupleLifetimeDependence(_ x: inout BufferView) -> (dependsOn(x) BufferView, BufferView) { // expected-error{{lifetime dependence specifiers cannot be applied to tuple elements}} return (BufferView(x.ptr), BufferView(x.ptr)) } @@ -122,43 +138,43 @@ struct Wrapper : ~Escapable { init(_ view: consuming BufferView) { self.view = view } - borrowing func getView1() -> _borrow(self) BufferView { + borrowing func getView1() -> dependsOn(self) BufferView { return view } - consuming func getView2() -> _consume(self) BufferView { + consuming func getView2() -> dependsOn(self) BufferView { return view } - mutating func getView3() -> _copy(self) BufferView { + mutating func getView3() -> dependsOn(self) BufferView { return view } - borrowing func getView4() -> _copy(self) BufferView { + borrowing func getView4() -> dependsOn(self) BufferView { return view } - borrowing func borrowingMethodInvalidLifetimeDependence1() -> _consume(self) BufferView { // expected-error{{invalid use of consume lifetime dependence for borrowing ownership}} + borrowing func borrowingMethodLifetimeDependence1() -> dependsOn(self) BufferView { return view } - borrowing func borrowingMethodInvalidLifetimeDependence2() -> _mutate(self) BufferView { // expected-error{{invalid use of mutate lifetime dependence for borrowing ownership}} + borrowing func borrowingMethodLifetimeDependence2() -> dependsOn(scoped self) BufferView { return view } - consuming func consumingMethodInvalidLifetimeDependence1() -> _borrow(self) BufferView { // expected-error{{invalid use of borrow lifetime dependence for consuming ownership}} + consuming func consumingMethodLifetimeDependence1() -> dependsOn(self) BufferView { return view } - consuming func consumingMethodInvalidLifetimeDependence2() -> _mutate(self) BufferView { // expected-error{{invalid use of mutate lifetime dependence for consuming ownership}} + consuming func consumingMethodInvalidLifetimeDependence1() -> dependsOn(scoped self) BufferView { // expected-error{{invalid use of scoped lifetime dependence with consuming ownership}} return view } - mutating func mutatingMethodInvalidLifetimeDependence1() -> _borrow(self) BufferView { // expected-error{{invalid use of borrow lifetime dependence for inout ownership}} + mutating func mutatingMethodLifetimeDependence1() -> dependsOn(self) BufferView { return view } - mutating func mutatingMethodInvalidLifetimeDependence2() -> _consume(self) BufferView { // expected-error{{invalid use of consume lifetime dependence for inout ownership}} + mutating func mutatingMethodLifetimeDependence2() -> dependsOn(scoped self) BufferView { return view } } @@ -172,7 +188,7 @@ public struct GenericBufferView : ~Escapable { public init(unsafeBuffer: UnsafeBufferPointer, storage: borrowing Storage) - -> _borrow(storage) Self { + -> dependsOn(storage) Self { let baseAddress = unsafeBuffer.baseAddress! self = GenericBufferView(baseAddress: baseAddress, count: unsafeBuffer.count) diff --git a/test/Serialization/Inputs/def_explicit_lifetime_dependence.swift b/test/Serialization/Inputs/def_explicit_lifetime_dependence.swift index 808abca2aa839..f2370ba387565 100644 --- a/test/Serialization/Inputs/def_explicit_lifetime_dependence.swift +++ b/test/Serialization/Inputs/def_explicit_lifetime_dependence.swift @@ -13,15 +13,15 @@ public struct BufferView : ~Escapable { public init(_ ptr: UnsafeRawBufferPointer) { self.ptr = ptr } - public init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> _borrow(a) Self { + public init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array) -> dependsOn(a) Self { self.ptr = ptr return self } - public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView) -> _consume(a) Self { + public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView) -> dependsOn(a) Self { self.ptr = ptr return self } - public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView, _ b: borrowing Array) -> _consume(a) _borrow(b) Self { + public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView, _ b: borrowing Array) -> dependsOn(a) dependsOn(b) Self { self.ptr = ptr return self } @@ -36,21 +36,21 @@ public struct MutableBufferView : ~Escapable, ~Copyable { } @inlinable -public func derive(_ x: borrowing BufferView) -> _borrow(x) BufferView { +public func derive(_ x: borrowing BufferView) -> dependsOn(scoped x) BufferView { return BufferView(x.ptr) } public func use(_ x: borrowing BufferView) {} -public func borrowAndCreate(_ view: borrowing BufferView) -> _borrow(view) BufferView { +public func borrowAndCreate(_ view: borrowing BufferView) -> dependsOn(scoped view) BufferView { return BufferView(view.ptr) } -public func consumeAndCreate(_ view: consuming BufferView) -> _consume(view) BufferView { +public func consumeAndCreate(_ view: consuming BufferView) -> dependsOn(view) BufferView { return BufferView(view.ptr) } -public func deriveThisOrThat(_ this: borrowing BufferView, _ that: borrowing BufferView) -> _borrow(this, that) BufferView { +public func deriveThisOrThat(_ this: borrowing BufferView, _ that: borrowing BufferView) -> dependsOn(scoped this, that) BufferView { if (Int.random(in: 1..<100) == 0) { return BufferView(this.ptr) } diff --git a/test/Serialization/implicit_lifetime_dependence.swift b/test/Serialization/implicit_lifetime_dependence.swift index 291b594cc645a..cfdd034d29bf6 100644 --- a/test/Serialization/implicit_lifetime_dependence.swift +++ b/test/Serialization/implicit_lifetime_dependence.swift @@ -62,16 +62,16 @@ func testReadMutateAccessors() { } } -// CHECK: sil @$s32def_implicit_lifetime_dependence6deriveyAA10BufferViewVADYlsF : $@convention(thin) (@guaranteed BufferView) -> _scope(1) @owned BufferView +// CHECK: sil @$s32def_implicit_lifetime_dependence6deriveyAA10BufferViewVADYliF : $@convention(thin) (@guaranteed BufferView) -> _inherit(1) @owned BufferView // CHECK: sil @$s32def_implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnYliF : $@convention(thin) (@owned BufferView) -> _inherit(1) @owned BufferView -// CHECK: sil @$s32def_implicit_lifetime_dependence15borrowAndCreateyAA10BufferViewVADYlsF : $@convention(thin) (@guaranteed BufferView) -> _scope(1) @owned BufferView +// CHECK: sil @$s32def_implicit_lifetime_dependence15borrowAndCreateyAA10BufferViewVADYliF : $@convention(thin) (@guaranteed BufferView) -> _inherit(1) @owned BufferView -// CHECK: sil @$s32def_implicit_lifetime_dependence10BufferViewVyA2ChYlscfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> _scope(1) @owned BufferView +// CHECK: sil @$s32def_implicit_lifetime_dependence10BufferViewVyA2ChYlicfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> _inherit(1) @owned BufferView // CHECK: sil @$s32def_implicit_lifetime_dependence9ContainerV4viewAA10BufferViewVvg : $@convention(method) (@guaranteed Container) -> _scope(0) @owned BufferView -// CHECK: sil @$s32def_implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvr : $@yield_once @convention(method) (@guaranteed Wrapper) -> _scope(0) @yields @guaranteed BufferView +// CHECK: sil @$s32def_implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvr : $@yield_once @convention(method) (@guaranteed Wrapper) -> _inherit(0) @yields @guaranteed BufferView -// CHECK: sil @$s32def_implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvM : $@yield_once @convention(method) (@inout Wrapper) -> _scope(0) @yields @inout BufferView +// CHECK: sil @$s32def_implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvM : $@yield_once @convention(method) (@inout Wrapper) -> _inherit(0) @yields @inout BufferView