Skip to content

Commit 9a4bb73

Browse files
authored
Merge pull request #70263 from meg-gupta/resultdependson
Add support for _resultDependsOn
2 parents 12cb8be + f6afc00 commit 9a4bb73

30 files changed

+231
-57
lines changed

include/swift/AST/ASTBridging.h

+1
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,7 @@ enum ENUM_EXTENSIBILITY_ATTR(open) BridgedAttributedTypeSpecifier : size_t {
898898
BridgedAttributedTypeSpecifierLegacyOwned,
899899
BridgedAttributedTypeSpecifierConst,
900900
BridgedAttributedTypeSpecifierIsolated,
901+
BridgedAttributedTypeSpecifierResultDependsOn,
901902
};
902903

903904
SWIFT_NAME("BridgedSimpleIdentTypeRepr.createParsed(_:loc:name:)")

include/swift/AST/Attr.def

+3-1
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,9 @@ SIMPLE_DECL_ATTR(_noExistentials, NoExistentials,
545545
SIMPLE_DECL_ATTR(_noObjCBridging, NoObjCBridging,
546546
OnAbstractFunction | OnSubscript | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
547547
155)
548-
548+
CONTEXTUAL_SIMPLE_DECL_ATTR(_resultDependsOn, ResultDependsOn,
549+
OnParam | DeclModifier | UserInaccessible | ABIBreakingToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove,
550+
156)
549551
#undef TYPE_ATTR
550552
#undef DECL_ATTR_ALIAS
551553
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/Decl.h

+13
Original file line numberDiff line numberDiff line change
@@ -6424,6 +6424,9 @@ class ParamDecl : public VarDecl {
64246424

64256425
/// Whether or not this parameter is 'isolated'.
64266426
IsIsolated = 1 << 2,
6427+
6428+
/// Whether or not this paramater is '_resultDependsOn'
6429+
IsResultDependsOn = 1 << 3,
64276430
};
64286431

64296432
/// The default value, if any, along with flags.
@@ -6637,6 +6640,16 @@ class ParamDecl : public VarDecl {
66376640
ArgumentNameAndFlags.setInt(flags);
66386641
}
66396642

6643+
bool hasResultDependsOn() const {
6644+
return DefaultValueAndFlags.getInt().contains(Flags::IsResultDependsOn);
6645+
}
6646+
6647+
void setResultDependsOn(bool value = true) {
6648+
auto flags = DefaultValueAndFlags.getInt();
6649+
DefaultValueAndFlags.setInt(value ? flags | Flags::IsResultDependsOn
6650+
: flags - Flags::IsResultDependsOn);
6651+
}
6652+
66406653
/// Does this parameter reject temporary pointer conversions?
66416654
bool isNonEphemeral() const;
66426655

include/swift/AST/TypeRepr.h

+16
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,21 @@ class CompileTimeConstTypeRepr : public SpecifierTypeRepr {
11631163
static bool classof(const CompileTimeConstTypeRepr *T) { return true; }
11641164
};
11651165

1166+
/// A lifetime dependent type.
1167+
/// \code
1168+
/// x : _resultDependsOn Int
1169+
/// \endcode
1170+
class ResultDependsOnTypeRepr : public SpecifierTypeRepr {
1171+
public:
1172+
ResultDependsOnTypeRepr(TypeRepr *Base, SourceLoc InOutLoc)
1173+
: SpecifierTypeRepr(TypeReprKind::ResultDependsOn, Base, InOutLoc) {}
1174+
1175+
static bool classof(const TypeRepr *T) {
1176+
return T->getKind() == TypeReprKind::ResultDependsOn;
1177+
}
1178+
static bool classof(const ResultDependsOnTypeRepr *T) { return true; }
1179+
};
1180+
11661181
/// A TypeRepr for a known, fixed type.
11671182
///
11681183
/// Fixed type representations should be used sparingly, in places
@@ -1522,6 +1537,7 @@ inline bool TypeRepr::isSimple() const {
15221537
case TypeReprKind::Isolated:
15231538
case TypeReprKind::Placeholder:
15241539
case TypeReprKind::CompileTimeConst:
1540+
case TypeReprKind::ResultDependsOn:
15251541
return true;
15261542
}
15271543
llvm_unreachable("bad TypeRepr kind");

include/swift/AST/TypeReprNodes.def

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ ABSTRACT_TYPEREPR(Specifier, TypeRepr)
7373
SPECIFIER_TYPEREPR(Ownership, SpecifierTypeRepr)
7474
SPECIFIER_TYPEREPR(Isolated, SpecifierTypeRepr)
7575
SPECIFIER_TYPEREPR(CompileTimeConst, SpecifierTypeRepr)
76+
SPECIFIER_TYPEREPR(ResultDependsOn, SpecifierTypeRepr)
7677
TYPEREPR(Fixed, TypeRepr)
7778
TYPEREPR(SILBox, TypeRepr)
7879
TYPEREPR(Self, TypeRepr)

include/swift/AST/Types.h

+9-7
Original file line numberDiff line numberDiff line change
@@ -2228,23 +2228,24 @@ enum class ParamSpecifier : uint8_t {
22282228
/// `__shared`, a legacy spelling of `borrowing`.
22292229
LegacyShared = 4,
22302230
/// `__owned`, a legacy spelling of `consuming`.
2231-
LegacyOwned = 5,
2231+
LegacyOwned = 5
22322232
};
22332233

22342234
/// Provide parameter type relevant flags, i.e. variadic, autoclosure, and
22352235
/// escaping.
22362236
class ParameterTypeFlags {
22372237
enum ParameterFlags : uint16_t {
2238-
None = 0,
2239-
Variadic = 1 << 0,
2240-
AutoClosure = 1 << 1,
2238+
None = 0,
2239+
Variadic = 1 << 0,
2240+
AutoClosure = 1 << 1,
22412241
NonEphemeral = 1 << 2,
22422242
SpecifierShift = 3,
2243-
Specifier = 7 << SpecifierShift,
2243+
Specifier = 7 << SpecifierShift,
22442244
NoDerivative = 1 << 6,
2245-
Isolated = 1 << 7,
2245+
Isolated = 1 << 7,
22462246
CompileTimeConst = 1 << 8,
2247-
NumBits = 9
2247+
ResultDependsOn = 1 << 9,
2248+
NumBits = 10
22482249
};
22492250
OptionSet<ParameterFlags> value;
22502251
static_assert(NumBits <= 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
@@ -2284,6 +2285,7 @@ class ParameterTypeFlags {
22842285
bool isIsolated() const { return value.contains(Isolated); }
22852286
bool isCompileTimeConst() const { return value.contains(CompileTimeConst); }
22862287
bool isNoDerivative() const { return value.contains(NoDerivative); }
2288+
bool hasResultDependsOn() const { return value.contains(ResultDependsOn); }
22872289

22882290
/// Get the spelling of the parameter specifier used on the parameter.
22892291
ParamSpecifier getOwnershipSpecifier() const {

include/swift/Option/FrontendOptions.td

+5
Original file line numberDiff line numberDiff line change
@@ -1310,4 +1310,9 @@ def platform_c_calling_convention :
13101310
def platform_c_calling_convention_EQ :
13111311
Joined<["-"], "experimental-platform-c-calling-convention=">,
13121312
Alias<platform_c_calling_convention>;
1313+
1314+
def disable_experimental_parser_round_trip : Flag<["-"],
1315+
"disable-experimental-parser-round-trip">,
1316+
HelpText<"Disable round trip through the new swift parser">;
1317+
13131318
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

include/swift/Parse/Parser.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,7 @@ class Parser {
11971197
SourceLoc &SpecifierLoc,
11981198
SourceLoc &IsolatedLoc,
11991199
SourceLoc &ConstLoc,
1200+
SourceLoc &ResultDependsOnLoc,
12001201
TypeAttributes &Attributes) {
12011202
if (Tok.isAny(tok::at_sign, tok::kw_inout) ||
12021203
(canHaveParameterSpecifierContextualKeyword() &&
@@ -1205,16 +1206,19 @@ class Parser {
12051206
Tok.getRawText().equals("consuming") ||
12061207
Tok.getRawText().equals("borrowing") ||
12071208
Tok.isContextualKeyword("isolated") ||
1208-
Tok.isContextualKeyword("_const"))))
1209-
return parseTypeAttributeListPresent(
1210-
Specifier, SpecifierLoc, IsolatedLoc, ConstLoc, Attributes);
1209+
Tok.isContextualKeyword("_const") ||
1210+
Tok.getRawText().equals("_resultDependsOn"))))
1211+
return parseTypeAttributeListPresent(Specifier, SpecifierLoc, IsolatedLoc,
1212+
ConstLoc, ResultDependsOnLoc,
1213+
Attributes);
12111214
return makeParserSuccess();
12121215
}
12131216

12141217
ParserStatus parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
12151218
SourceLoc &SpecifierLoc,
12161219
SourceLoc &IsolatedLoc,
12171220
SourceLoc &ConstLoc,
1221+
SourceLoc &ResultDependsOnLoc,
12181222
TypeAttributes &Attributes);
12191223

12201224
bool parseConventionAttributeInternal(bool justChecking,
@@ -1510,6 +1514,9 @@ class Parser {
15101514
/// The location of the '_const' keyword, if present.
15111515
SourceLoc CompileConstLoc;
15121516

1517+
/// The location of the '_resultDependsOn' keyword, if present.
1518+
SourceLoc ResultDependsOnLoc;
1519+
15131520
/// The type following the ':'.
15141521
TypeRepr *Type = nullptr;
15151522

lib/AST/ASTBridging.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,9 @@ BridgedTypeRepr BridgedSpecifierTypeRepr_createParsed(
13111311
case BridgedAttributedTypeSpecifierIsolated: {
13121312
return new (context) IsolatedTypeRepr(baseType, loc);
13131313
}
1314+
case BridgedAttributedTypeSpecifierResultDependsOn: {
1315+
return new (context) ResultDependsOnTypeRepr(baseType, loc);
1316+
}
13141317
}
13151318
}
13161319

lib/AST/ASTDumper.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -3385,6 +3385,13 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr, void, StringRef>,
33853385
printFoot();
33863386
}
33873387

3388+
void visitResultDependsOnTypeRepr(ResultDependsOnTypeRepr *T,
3389+
StringRef label) {
3390+
printCommon("_resultDependsOn", label);
3391+
printRec(T->getBase());
3392+
printFoot();
3393+
}
3394+
33883395
void visitOptionalTypeRepr(OptionalTypeRepr *T, StringRef label) {
33893396
printCommon("type_optional", label);
33903397
printRec(T->getBase());

lib/AST/ASTPrinter.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -3605,6 +3605,10 @@ static bool usesFeatureNonEscapableTypes(Decl *decl) {
36053605
if (fd && fd->getAttrs().getAttribute(DAK_ResultDependsOnSelf)) {
36063606
return true;
36073607
}
3608+
auto *pd = dyn_cast<ParamDecl>(decl);
3609+
if (pd && pd->hasResultDependsOn()) {
3610+
return true;
3611+
}
36083612
return false;
36093613
}
36103614

@@ -4360,6 +4364,9 @@ static void printParameterFlags(ASTPrinter &printer,
43604364
if (flags.isIsolated())
43614365
printer.printKeyword("isolated", options, " ");
43624366

4367+
if (flags.hasResultDependsOn())
4368+
printer.printKeyword("resultDependsOn", options, " ");
4369+
43634370
if (!options.excludeAttrKind(TAK_escaping) && escaping)
43644371
printer.printKeyword("@escaping", options, " ");
43654372

lib/AST/ASTWalker.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,10 @@ bool Traversal::visitCompileTimeConstTypeRepr(CompileTimeConstTypeRepr *T) {
22132213
return doIt(T->getBase());
22142214
}
22152215

2216+
bool Traversal::visitResultDependsOnTypeRepr(ResultDependsOnTypeRepr *T) {
2217+
return doIt(T->getBase());
2218+
}
2219+
22162220
bool Traversal::visitOpaqueReturnTypeRepr(OpaqueReturnTypeRepr *T) {
22172221
return doIt(T->getConstraint());
22182222
}

lib/AST/Decl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -7671,7 +7671,7 @@ void ParamDecl::setSpecifier(Specifier specifier) {
76717671
VarDecl::Introducer introducer;
76727672
switch (specifier) {
76737673
// Unannotated or `borrowing` parameters are locally immutable.
7674-
// So are parameters using the legacy `__shared` or `__owned` modifiers.
7674+
// So are parameters using the legacy `__shared` or `__owned` modifiers.
76757675
case ParamSpecifier::Default:
76767676
case ParamSpecifier::Borrowing:
76777677
case ParamSpecifier::LegacyShared:

lib/AST/NameLookup.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -3022,12 +3022,11 @@ directReferencesForTypeRepr(Evaluator &evaluator,
30223022
case TypeReprKind::SILBox:
30233023
case TypeReprKind::Placeholder:
30243024
case TypeReprKind::Pack:
3025-
return { };
3026-
30273025
case TypeReprKind::OpaqueReturn:
30283026
case TypeReprKind::NamedOpaqueReturn:
30293027
case TypeReprKind::Existential:
30303028
case TypeReprKind::Inverse:
3029+
case TypeReprKind::ResultDependsOn:
30313030
return { };
30323031

30333032
case TypeReprKind::Fixed:

lib/AST/TypeRepr.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,9 @@ void SpecifierTypeRepr::printImpl(ASTPrinter &Printer,
620620
case TypeReprKind::CompileTimeConst:
621621
Printer.printKeyword("_const", Opts, " ");
622622
break;
623+
case TypeReprKind::ResultDependsOn:
624+
Printer.printKeyword("_resultDependsOn", Opts, " ");
625+
break;
623626
}
624627
printTypeRepr(Base, Printer, Opts);
625628
}

lib/ASTGen/Sources/ASTGen/Types.swift

+1
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ extension BridgedAttributedTypeSpecifier {
329329
case .keyword(.__owned): self = .legacyOwned
330330
case .keyword(._const): self = .const
331331
case .keyword(.isolated): self = .isolated
332+
case .keyword(._resultDependsOn): self = .resultDependsOn
332333
default: return nil
333334
}
334335
}

lib/Basic/LangOptions.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ using namespace swift;
3333

3434
LangOptions::LangOptions() {
3535
// Note: Introduce default-on language options here.
36-
#ifndef NDEBUG
37-
Features.insert(Feature::ParserRoundTrip);
38-
Features.insert(Feature::ParserValidation);
39-
#endif
4036
// Enable any playground options that are enabled by default.
4137
#define PLAYGROUND_OPTION(OptionName, Description, DefaultOn, HighPerfOn) \
4238
if (DefaultOn) \

lib/Frontend/CompilerInvocation.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,16 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
14021402
}
14031403
}
14041404

1405+
#ifndef NDEBUG
1406+
/// Enable round trip parsing via the new swift parser unless it is disabled
1407+
/// explicitly. The new Swift parser can have mismatches with C++ parser -
1408+
/// rdar://118013482 Use this flag to disable round trip through the new
1409+
/// Swift parser for such cases.
1410+
if (!Args.hasArg(OPT_disable_experimental_parser_round_trip)) {
1411+
Opts.Features.insert(Feature::ParserRoundTrip);
1412+
Opts.Features.insert(Feature::ParserValidation);
1413+
}
1414+
#endif
14051415
return HadError || UnsupportedOS || UnsupportedArch;
14061416
}
14071417

lib/Parse/ParseDecl.cpp

+22-14
Original file line numberDiff line numberDiff line change
@@ -5128,22 +5128,21 @@ ParserStatus Parser::parseDeclModifierList(DeclAttributes &Attributes,
51285128
/// '@' attribute
51295129
/// '@' attribute attribute-list-clause
51305130
/// \endverbatim
5131-
ParserStatus
5132-
Parser::parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
5133-
SourceLoc &SpecifierLoc,
5134-
SourceLoc &IsolatedLoc,
5135-
SourceLoc &ConstLoc,
5136-
TypeAttributes &Attributes) {
5131+
ParserStatus Parser::parseTypeAttributeListPresent(
5132+
ParamDecl::Specifier &Specifier, SourceLoc &SpecifierLoc,
5133+
SourceLoc &IsolatedLoc, SourceLoc &ConstLoc, SourceLoc &ResultDependsOnLoc,
5134+
TypeAttributes &Attributes) {
51375135
PatternBindingInitializer *initContext = nullptr;
51385136
Specifier = ParamDecl::Specifier::Default;
5139-
while (Tok.is(tok::kw_inout)
5140-
|| (canHaveParameterSpecifierContextualKeyword()
5141-
&& (Tok.isContextualKeyword("__shared")
5142-
|| Tok.isContextualKeyword("__owned")
5143-
|| Tok.isContextualKeyword("isolated")
5144-
|| Tok.isContextualKeyword("consuming")
5145-
|| Tok.isContextualKeyword("borrowing")
5146-
|| Tok.isContextualKeyword("_const")))) {
5137+
while (Tok.is(tok::kw_inout) ||
5138+
(canHaveParameterSpecifierContextualKeyword() &&
5139+
(Tok.isContextualKeyword("__shared") ||
5140+
Tok.isContextualKeyword("__owned") ||
5141+
Tok.isContextualKeyword("isolated") ||
5142+
Tok.isContextualKeyword("consuming") ||
5143+
Tok.isContextualKeyword("borrowing") ||
5144+
Tok.isContextualKeyword("_const") ||
5145+
Tok.isContextualKeyword("_resultDependsOn")))) {
51475146

51485147
if (Tok.isContextualKeyword("isolated")) {
51495148
if (IsolatedLoc.isValid()) {
@@ -5160,6 +5159,15 @@ Parser::parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
51605159
continue;
51615160
}
51625161

5162+
if (Tok.isContextualKeyword("_resultDependsOn")) {
5163+
if (!Context.LangOpts.hasFeature(Feature::NonEscapableTypes)) {
5164+
diagnose(Tok, diag::requires_non_escapable_types, "resultDependsOn",
5165+
false);
5166+
}
5167+
ResultDependsOnLoc = consumeToken();
5168+
continue;
5169+
}
5170+
51635171
if (SpecifierLoc.isValid()) {
51645172
diagnose(Tok, diag::parameter_specifier_repeated)
51655173
.fixItRemove(SpecifierLoc);

0 commit comments

Comments
 (0)