diff --git a/include/swift/AST/GenericParamList.h b/include/swift/AST/GenericParamList.h index 9fd2bb13f2d..ac9730cdeb0 100644 --- a/include/swift/AST/GenericParamList.h +++ b/include/swift/AST/GenericParamList.h @@ -81,8 +81,6 @@ class RequirementRepr { : SeparatorLoc(SeparatorLoc), Kind(Kind), Invalid(false), FirstType(FirstType), SecondLayout(SecondLayout) { } - void printImpl(ASTPrinter &OS) const; - public: /// Construct a new type-constraint requirement. /// diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h index 4699af716ba..af273f17a30 100644 --- a/include/swift/AST/TypeRepr.h +++ b/include/swift/AST/TypeRepr.h @@ -1114,8 +1114,7 @@ class NamedOpaqueReturnTypeRepr : public TypeRepr { GenericParamList *GenericParams; public: - NamedOpaqueReturnTypeRepr(TypeRepr *Base, - GenericParamList *GenericParams) + NamedOpaqueReturnTypeRepr(TypeRepr *Base, GenericParamList *GenericParams) : TypeRepr(TypeReprKind::NamedOpaqueReturn), Base(Base), GenericParams(GenericParams) { assert(Base && GenericParams); @@ -1127,9 +1126,7 @@ public: static bool classof(const TypeRepr *T) { return T->getKind() == TypeReprKind::NamedOpaqueReturn; } - static bool classof(const NamedOpaqueReturnTypeRepr *T) { - return true; - } + static bool classof(const NamedOpaqueReturnTypeRepr *T) { return true; } private: SourceLoc getStartLocImpl() const; diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index 2b06dccab13..3a0f8024fe9 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -1223,6 +1223,13 @@ public: ParserResult parseType(Diag<> MessageID, bool IsSILFuncDecl = false); + /// Parse a type optionally prefixed by a list of named opaque parameters. If + /// no params present, return 'type'. Otherwise, return 'type-named-opaque'. + /// + /// type-named-opaque: + /// generic-params type + ParserResult parseTypeWithOpaqueParams(Diag<> MessageID); + ParserResult parseTypeSimpleOrComposition(Diag<> MessageID); diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index cf5c794eb0e..172cdc10664 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -21,7 +21,6 @@ #include "swift/AST/ForeignAsyncConvention.h" #include "swift/AST/ForeignErrorConvention.h" #include "swift/AST/GenericEnvironment.h" -#include "swift/AST/GenericParamList.h" #include "swift/AST/Initializer.h" #include "swift/AST/ParameterList.h" #include "swift/AST/ProtocolConformance.h" @@ -114,111 +113,6 @@ namespace { }; } // end anonymous namespace -//===----------------------------------------------------------------------===// -// Generic param list printing. -//===----------------------------------------------------------------------===// - -void RequirementRepr::dump() const { - print(llvm::errs()); - llvm::errs() << "\n"; -} - -void RequirementRepr::printImpl(ASTPrinter &out) const { - auto printLayoutConstraint = - [&](const LayoutConstraintLoc &LayoutConstraintLoc) { - LayoutConstraintLoc.getLayoutConstraint()->print(out, PrintOptions()); - }; - - switch (getKind()) { - case RequirementReprKind::LayoutConstraint: - if (auto *repr = getSubjectRepr()) { - repr->print(out, PrintOptions()); - } - out << " : "; - printLayoutConstraint(getLayoutConstraintLoc()); - break; - - case RequirementReprKind::TypeConstraint: - if (auto *repr = getSubjectRepr()) { - repr->print(out, PrintOptions()); - } - out << " : "; - if (auto *repr = getConstraintRepr()) { - repr->print(out, PrintOptions()); - } - break; - - case RequirementReprKind::SameType: - if (auto *repr = getFirstTypeRepr()) { - repr->print(out, PrintOptions()); - } - out << " == "; - if (auto *repr = getSecondTypeRepr()) { - repr->print(out, PrintOptions()); - } - break; - } -} - -void RequirementRepr::print(raw_ostream &out) const { - StreamPrinter printer(out); - printImpl(printer); -} -void RequirementRepr::print(ASTPrinter &out) const { - printImpl(out); -} - -void GenericParamList::dump() const { - print(llvm::errs()); - llvm::errs() << '\n'; -} - -void GenericParamList::print(raw_ostream &out, const PrintOptions &PO) const { - StreamPrinter printer(out); - print(printer, PO); -} - -static void printTrailingRequirements(ASTPrinter &Printer, - ArrayRef Reqs, - bool printWhereKeyword) { - if (Reqs.empty()) return; - - if (printWhereKeyword) - Printer << " where "; - interleave( - Reqs, - [&](const RequirementRepr &req) { - Printer.callPrintStructurePre(PrintStructureKind::GenericRequirement); - req.print(Printer); - Printer.printStructurePost(PrintStructureKind::GenericRequirement); - }, - [&] { Printer << ", "; }); -} - -void GenericParamList::print(ASTPrinter &Printer, const PrintOptions &PO) const { - Printer << '<'; - interleave(*this, - [&](const GenericTypeParamDecl *P) { - Printer << P->getName(); - if (!P->getInherited().empty()) { - Printer << " : "; - P->getInherited()[0].getType().print(Printer, PO); - } - }, - [&] { Printer << ", "; }); - - printTrailingRequirements(Printer, getRequirements(), - /*printWhereKeyword*/true); - Printer << '>'; -} - -void TrailingWhereClause::print(llvm::raw_ostream &OS, - bool printWhereKeyword) const { - StreamPrinter Printer(OS); - printTrailingRequirements(Printer, getRequirements(), - printWhereKeyword); -} - static void printGenericParameters(raw_ostream &OS, GenericParamList *Params) { if (!Params) return; @@ -3143,9 +3037,8 @@ public: PrintWithColorRAII(OS, ParenthesisColor) << ')'; } - void - visitNamedOpaqueReturnTypeRepr(NamedOpaqueReturnTypeRepr *T) { - printCommon("type_opaque_return_parameterized") << '\n'; + void visitNamedOpaqueReturnTypeRepr(NamedOpaqueReturnTypeRepr *T) { + printCommon("type_named_opaque_return") << '\n'; printRec(T->getBase()); PrintWithColorRAII(OS, ParenthesisColor) << ')'; } diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index b05cdd770de..c125570fa68 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -26,6 +26,7 @@ #include "swift/AST/ExistentialLayout.h" #include "swift/AST/Expr.h" #include "swift/AST/FileUnit.h" +#include "swift/AST/GenericParamList.h" #include "swift/AST/GenericSignature.h" #include "swift/AST/Module.h" #include "swift/AST/NameLookup.h" @@ -5851,3 +5852,113 @@ swift::getInheritedForPrinting(const Decl *decl, const PrintOptions &options, } } } + +//===----------------------------------------------------------------------===// +// Generic param list printing. +//===----------------------------------------------------------------------===// + +void RequirementRepr::dump() const { + print(llvm::errs()); + llvm::errs() << "\n"; +} + +void RequirementRepr::print(raw_ostream &out) const { + StreamPrinter printer(out); + print(printer); +} + +void RequirementRepr::print(ASTPrinter &out) const { + auto printLayoutConstraint = + [&](const LayoutConstraintLoc &LayoutConstraintLoc) { + LayoutConstraintLoc.getLayoutConstraint()->print(out, PrintOptions()); + }; + + switch (getKind()) { + case RequirementReprKind::LayoutConstraint: + if (auto *repr = getSubjectRepr()) { + repr->print(out, PrintOptions()); + } + out << " : "; + printLayoutConstraint(getLayoutConstraintLoc()); + break; + + case RequirementReprKind::TypeConstraint: + if (auto *repr = getSubjectRepr()) { + repr->print(out, PrintOptions()); + } + out << " : "; + if (auto *repr = getConstraintRepr()) { + repr->print(out, PrintOptions()); + } + break; + + case RequirementReprKind::SameType: + if (auto *repr = getFirstTypeRepr()) { + repr->print(out, PrintOptions()); + } + out << " == "; + if (auto *repr = getSecondTypeRepr()) { + repr->print(out, PrintOptions()); + } + break; + } +} + +void GenericParamList::dump() const { + print(llvm::errs()); + llvm::errs() << '\n'; +} + +void GenericParamList::print(raw_ostream &out, const PrintOptions &PO) const { + StreamPrinter printer(out); + print(printer, PO); +} + +static void printTrailingRequirements(ASTPrinter &Printer, + ArrayRef Reqs, + bool printWhereKeyword) { + if (Reqs.empty()) + return; + + if (printWhereKeyword) + Printer << " where "; + interleave( + Reqs, + [&](const RequirementRepr &req) { + Printer.callPrintStructurePre(PrintStructureKind::GenericRequirement); + req.print(Printer); + Printer.printStructurePost(PrintStructureKind::GenericRequirement); + }, + [&] { Printer << ", "; }); +} + +void GenericParamList::print(ASTPrinter &Printer, + const PrintOptions &PO) const { + Printer << '<'; + interleave( + *this, + [&](const GenericTypeParamDecl *P) { + Printer << P->getName(); + if (!P->getInherited().empty()) { + Printer << " : "; + + auto loc = P->getInherited()[0]; + if (willUseTypeReprPrinting(loc, nullptr, PO)) { + loc.getTypeRepr()->print(Printer, PO); + } else { + loc.getType()->print(Printer, PO); + } + } + }, + [&] { Printer << ", "; }); + + printTrailingRequirements(Printer, getRequirements(), + /*printWhereKeyword*/ true); + Printer << '>'; +} + +void TrailingWhereClause::print(llvm::raw_ostream &OS, + bool printWhereKeyword) const { + StreamPrinter Printer(OS); + printTrailingRequirements(Printer, getRequirements(), printWhereKeyword); +} diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp index 63b4a8155e6..7437e906527 100644 --- a/lib/AST/ASTWalker.cpp +++ b/lib/AST/ASTWalker.cpp @@ -1858,8 +1858,7 @@ bool Traversal::visitOpaqueReturnTypeRepr(OpaqueReturnTypeRepr *T) { return doIt(T->getConstraint()); } -bool Traversal::visitNamedOpaqueReturnTypeRepr( - NamedOpaqueReturnTypeRepr *T) { +bool Traversal::visitNamedOpaqueReturnTypeRepr(NamedOpaqueReturnTypeRepr *T) { return doIt(T->getBase()); } diff --git a/lib/AST/TypeRepr.cpp b/lib/AST/TypeRepr.cpp index 70e5579aaea..613b1f31719 100644 --- a/lib/AST/TypeRepr.cpp +++ b/lib/AST/TypeRepr.cpp @@ -453,8 +453,8 @@ SourceLoc NamedOpaqueReturnTypeRepr::getLocImpl() const { return Base->getLoc(); } -void NamedOpaqueReturnTypeRepr::printImpl( - ASTPrinter &Printer, const PrintOptions &Opts) const { +void NamedOpaqueReturnTypeRepr::printImpl(ASTPrinter &Printer, + const PrintOptions &Opts) const { GenericParams->print(Printer, Opts); Printer << ' '; printTypeRepr(Base, Printer, Opts); diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index 65b60551f28..94788e8d904 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -824,7 +824,7 @@ Parser::parseFunctionArguments(SmallVectorImpl &NamePieces, /// func-signature: /// func-arguments ('async'|'reasync')? func-throws? func-signature-result? /// func-signature-result: -/// '->' generic-params? type +/// '->' type /// /// Note that this leaves retType as null if unspecified. ParserStatus @@ -865,22 +865,10 @@ Parser::parseFunctionSignature(Identifier SimpleName, arrowLoc = consumeToken(tok::colon); } - // Check for effect specifiers after the arrow, but before the generic - // parameters, and correct it. + // Check for effect specifiers after the arrow, but before the return type, + // and correct it. parseEffectsSpecifiers(arrowLoc, asyncLoc, &reasync, throwsLoc, &rethrows); - GenericParamList *genericParams = nullptr; - if (Context.LangOpts.EnableExperimentalOpaqueReturnTypes) { - auto genericParamsResult = maybeParseGenericParams(); - genericParams = genericParamsResult.getPtrOrNull(); - Status |= genericParamsResult; - - // Check for effect specifiers after the generic parameters, but before - // the return type, and correct it. - parseEffectsSpecifiers(arrowLoc, asyncLoc, &reasync, throwsLoc, - &rethrows); - } - ParserResult ResultType = parseDeclResultType(diag::expected_type_function_result); retType = ResultType.getPtrOrNull(); @@ -888,11 +876,6 @@ Parser::parseFunctionSignature(Identifier SimpleName, if (Status.isErrorOrHasCompletion()) return Status; - if (genericParams != nullptr) { - retType = new (Context) - NamedOpaqueReturnTypeRepr(retType, genericParams); - } - // Check for effect specifiers after the type and correct it. parseEffectsSpecifiers(arrowLoc, asyncLoc, &reasync, throwsLoc, &rethrows); } else { diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index cde01afc773..ce1bb62925f 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -547,6 +547,27 @@ ParserResult Parser::parseType(Diag<> MessageID, applyAttributeToType(tyR, attrs, specifier, specifierLoc, isolatedLoc)); } +ParserResult Parser::parseTypeWithOpaqueParams(Diag<> MessageID) { + GenericParamList *genericParams = nullptr; + if (Context.LangOpts.EnableExperimentalOpaqueReturnTypes) { + auto result = maybeParseGenericParams(); + genericParams = result.getPtrOrNull(); + if (result.hasCodeCompletion()) + return makeParserCodeCompletionStatus(); + } + + auto typeResult = parseType(MessageID); + if (auto type = typeResult.getPtrOrNull()) { + return makeParserResult( + ParserStatus(typeResult), + genericParams ? new (Context) + NamedOpaqueReturnTypeRepr(type, genericParams) + : type); + } else { + return typeResult; + } +} + ParserResult Parser::parseDeclResultType(Diag<> MessageID) { if (Tok.is(tok::code_complete)) { if (CodeCompletion) @@ -555,7 +576,7 @@ ParserResult Parser::parseDeclResultType(Diag<> MessageID) { return makeParserCodeCompletionStatus(); } - auto result = parseType(MessageID); + auto result = parseTypeWithOpaqueParams(MessageID); if (!result.isParseErrorOrHasCompletion()) { if (Tok.is(tok::r_square)) { diff --git a/test/IDE/print_ast_named_opaque_return.swift b/test/IDE/print_ast_named_opaque_return.swift index 00d8070677b..eb1161b5678 100644 --- a/test/IDE/print_ast_named_opaque_return.swift +++ b/test/IDE/print_ast_named_opaque_return.swift @@ -1,10 +1,14 @@ -func f() -> () { +func f0() -> () { } -func g() -> Int { +func f1() -> Int { +} +func f2() -> Int { } // RUN: %target-swift-ide-test -print-ast-typechecked -enable-experimental-opaque-return-types -source-filename %s | %FileCheck %s -check-prefix=CHECK1 -// CHECK1: {{^}}func f() {{{$}} +// CHECK1: {{^}}func f0() {{{$}} // CHECK1: {{^}}}{{$}} -// CHECK1: {{^}}func g() -> Int {{{$}} +// CHECK1: {{^}}func f1() -> Int {{{$}} +// CHECK1: {{^}}}{{$}} +// CHECK1: {{^}}func f2() -> Int {{{$}} // CHECK1: {{^}}}{{$}} \ No newline at end of file diff --git a/test/type/opaque_experimental.swift b/test/type/opaque_experimental.swift index acb29268606..054cc843784 100644 --- a/test/type/opaque_experimental.swift +++ b/test/type/opaque_experimental.swift @@ -9,5 +9,4 @@ func f4() async -> () { } func g0() -> { } // expected-error{{expected type for function result}} func g1() -> async () { } // expected-error{{'async' may only occur before '->'}} -func g2() -> async () { } // expected-error{{'async' may only occur before '->'}} -func g3() -> () async { } // expected-error{{'async' may only occur before '->'}} +func g2() -> () async { } // expected-error{{'async' may only occur before '->'}} diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp index 6e4e3dcd3ee..1ae1982b671 100644 --- a/tools/swift-ide-test/swift-ide-test.cpp +++ b/tools/swift-ide-test/swift-ide-test.cpp @@ -763,12 +763,11 @@ DisableImplicitConcurrencyImport("disable-implicit-concurrency-module-import", llvm::cl::desc("Disable implicit import of _Concurrency module"), llvm::cl::init(false)); -static llvm::cl::opt -EnableExperimentalOpaqueReturnTypes("enable-experimental-opaque-return-types", - llvm::cl::desc("Enable experimental extensions to opaque return type support"), - llvm::cl::Hidden, - llvm::cl::cat(Category), - llvm::cl::init(false)); +static llvm::cl::opt EnableExperimentalOpaqueReturnTypes( + "enable-experimental-opaque-return-types", + llvm::cl::desc( + "Enable experimental extensions to opaque return type support"), + llvm::cl::Hidden, llvm::cl::cat(Category), llvm::cl::init(false)); static llvm::cl::opt EnableExperimentalDistributed("enable-experimental-distributed",