Skip to content

Commit 5a763f9

Browse files
authored
Merge pull request #3720 from slavapestov/migrate-noreturn-to-never
Fixits for @NoReturn -> Never (SE-0102)
2 parents 7b2f91a + e5f1d73 commit 5a763f9

39 files changed

+179
-370
lines changed

docs/ABI.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,6 @@ mangled in to disambiguate.
10181018
impl-function-attribute ::= 'Cm' // compatible with Swift method
10191019
impl-function-attribute ::= 'CO' // compatible with ObjC method
10201020
impl-function-attribute ::= 'Cw' // compatible with protocol witness
1021-
impl-function-attribute ::= 'N' // noreturn
10221021
impl-function-attribute ::= 'G' // generic
10231022
impl-function-attribute ::= 'g' // pseudogeneric
10241023
impl-parameter ::= impl-convention type
@@ -1029,8 +1028,8 @@ types. However, in some cases it is more useful to encode the exact
10291028
implementation details of a function type.
10301029

10311030
Any ``<impl-function-attribute>`` productions must appear in the order
1032-
in which they are specified above: e.g. a noreturn C function is
1033-
mangled with ``CcN``. ``g`` and ``G`` are exclusive and mark the presence
1031+
in which they are specified above: e.g. a pseudogeneric C function is
1032+
mangled with ``Ccg``. ``g`` and ``G`` are exclusive and mark the presence
10341033
of a generic signature immediately following.
10351034

10361035
Note that the convention and function-attribute productions do not

docs/SIL.rst

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,8 +1216,8 @@ flow, such as a non-``Void`` function failing to ``return`` a value, or a
12161216
``switch`` statement failing to cover all possible values of its subject.
12171217
The guaranteed dead code elimination pass can eliminate truly unreachable
12181218
basic blocks, or ``unreachable`` instructions may be dominated by applications
1219-
of ``@noreturn`` functions. An ``unreachable`` instruction that survives
1220-
guaranteed DCE and is not immediately preceded by a ``@noreturn``
1219+
of functions returning uninhabited types. An ``unreachable`` instruction that
1220+
survives guaranteed DCE and is not immediately preceded by an no-return
12211221
application is a dataflow error.
12221222

12231223
Runtime Failure
@@ -3912,12 +3912,8 @@ in the following ways:
39123912
- A class tuple element of the destination type may be a superclass or
39133913
subclass of the source type's corresponding tuple element.
39143914

3915-
The function types may also differ in attributes, with the following
3916-
caveats:
3917-
3918-
- The ``convention`` attribute cannot be changed.
3919-
- A ``@noreturn`` function may be converted to a non-``@noreturn``
3920-
type and vice-versa.
3915+
The function types may also differ in attributes, except that the
3916+
``convention`` attribute cannot be changed.
39213917

39223918
thin_function_to_pointer
39233919
````````````````````````
@@ -4133,7 +4129,7 @@ unreachable
41334129
Indicates that control flow must not reach the end of the current basic block.
41344130
It is a dataflow error if an unreachable terminator is reachable from the entry
41354131
point of a function and is not immediately preceded by an ``apply`` of a
4136-
``@noreturn`` function.
4132+
no-return function.
41374133

41384134
return
41394135
``````

include/swift/AST/Decl.h

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4838,35 +4838,13 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
48384838
/// depending on the function context.
48394839
bool argumentNameIsAPIByDefault() const;
48404840

4841+
/// \brief Returns the "natural" number of argument clauses taken by this
4842+
/// function. This value is one for free-standing functions, and two for
4843+
/// methods.
48414844
unsigned getNumParameterLists() const {
48424845
return AbstractFunctionDeclBits.NumParameterLists;
48434846
}
48444847

4845-
/// \brief Returns the "natural" number of argument clauses taken by this
4846-
/// function. This value is always at least one, and it may be more if the
4847-
/// function is implicitly or explicitly curried.
4848-
///
4849-
/// For example, this function:
4850-
/// \code
4851-
/// func negate(x : Int) -> Int { return -x }
4852-
/// \endcode
4853-
/// has a natural argument count of 1 if it is freestanding. If it is
4854-
/// a method, it has a natural argument count of 2, as does this
4855-
/// curried function:
4856-
/// \code
4857-
/// func add(x : Int)(y : Int) -> Int { return x + y }
4858-
/// \endcode
4859-
///
4860-
/// This value never exceeds the number of chained function types
4861-
/// in the function's type, but it can be less for functions which
4862-
/// return a value of function type:
4863-
/// \code
4864-
/// func const(x : Int) -> () -> Int { return { x } } // NAC==1
4865-
/// \endcode
4866-
unsigned getNaturalArgumentCount() const {
4867-
return getNumParameterLists();
4868-
}
4869-
48704848
/// \brief Returns the parameter pattern(s) for the function definition that
48714849
/// determine the parameter names bound in the function body.
48724850
///

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,9 @@ ERROR(function_type_access,none,
11181118
WARNING(non_trailing_closure_before_default_args,none,
11191119
"closure parameter prior to parameters with default arguments will "
11201120
"not be treated as a trailing closure", ())
1121+
ERROR(noreturn_not_supported,none,
1122+
"'@noreturn' has been removed; functions that never return should have a "
1123+
"return type of 'Never' instead", ())
11211124

11221125
// Extensions
11231126
ERROR(non_nominal_extension,none,
@@ -1326,8 +1329,6 @@ NOTE(protocol_witness_mutating_conflict,none,
13261329
"candidate is marked 'mutating' but protocol does not allow it", ())
13271330
NOTE(protocol_witness_settable_conflict,none,
13281331
"candidate is not settable, but protocol requires it", ())
1329-
NOTE(protocol_witness_noreturn_conflict,none,
1330-
"candidate is not @noreturn, but protocol requires it", ())
13311332
NOTE(protocol_witness_rethrows_conflict,none,
13321333
"candidate is not 'rethrows', but protocol requires it", ())
13331334
NOTE(protocol_witness_throws_conflict,none,
@@ -1775,9 +1776,6 @@ ERROR(final_not_on_accessors,none,
17751776
"'final' cannot be applied to accessors, it must be put on the "
17761777
"%select{var|let|subscript}0", (unsigned))
17771778

1778-
ERROR(override_noreturn_with_return,none,
1779-
"an override of a @noreturn method should also be @noreturn", ())
1780-
17811779
ERROR(override_rethrows_with_non_rethrows,none,
17821780
"override of 'rethrows' %select{method|initializer}0 should also "
17831781
"be 'rethrows'", (bool))

include/swift/AST/Expr.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2844,8 +2844,6 @@ class AbstractClosureExpr : public Expr, public DeclContext {
28442844
return parameterList ? parameterList : ArrayRef<const ParameterList *>();
28452845
}
28462846

2847-
unsigned getNaturalArgumentCount() const { return 1; }
2848-
28492847
/// \brief Retrieve the result type of this closure.
28502848
Type getResultType() const;
28512849

include/swift/AST/Types.h

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,15 +2125,14 @@ class AnyFunctionType : public TypeBase {
21252125
// you'll need to adjust both the Bits field below and
21262126
// BaseType::AnyFunctionTypeBits.
21272127

2128-
// |representation|isAutoClosure|noReturn|noEscape|throws|
2129-
// | 0 .. 3 | 4 | 5 | 6 | 7 |
2128+
// |representation|isAutoClosure|noEscape|throws|
2129+
// | 0 .. 3 | 4 | 5 | 6 |
21302130
//
21312131
enum : uint16_t { RepresentationMask = 0x00F };
21322132
enum : uint16_t { AutoClosureMask = 0x010 };
2133-
enum : uint16_t { NoReturnMask = 0x020 };
2134-
enum : uint16_t { NoEscapeMask = 0x040 };
2135-
enum : uint16_t { ThrowsMask = 0x080 };
2136-
enum : uint16_t { ExplicitlyEscapingMask = 0x100 };
2133+
enum : uint16_t { NoEscapeMask = 0x020 };
2134+
enum : uint16_t { ThrowsMask = 0x040 };
2135+
enum : uint16_t { ExplicitlyEscapingMask = 0x080 };
21372136

21382137
uint16_t Bits;
21392138

@@ -2148,23 +2147,20 @@ class AnyFunctionType : public TypeBase {
21482147
}
21492148

21502149
// Constructor for polymorphic type.
2151-
ExtInfo(Representation Rep, bool IsNoReturn, bool Throws) {
2152-
Bits = ((unsigned) Rep) |
2153-
(IsNoReturn ? NoReturnMask : 0) |
2154-
(Throws ? ThrowsMask : 0);
2150+
ExtInfo(Representation Rep, bool Throws) {
2151+
Bits = ((unsigned) Rep) | (Throws ? ThrowsMask : 0);
21552152
}
21562153

21572154
// Constructor with no defaults.
2158-
ExtInfo(Representation Rep, bool IsNoReturn,
2155+
ExtInfo(Representation Rep,
21592156
bool IsAutoClosure, bool IsNoEscape, bool IsExplicitlyEscaping,
21602157
bool Throws)
2161-
: ExtInfo(Rep, IsNoReturn, Throws) {
2158+
: ExtInfo(Rep, Throws) {
21622159
Bits |= (IsAutoClosure ? AutoClosureMask : 0);
21632160
Bits |= (IsNoEscape ? NoEscapeMask : 0);
21642161
Bits |= (IsExplicitlyEscaping ? ExplicitlyEscapingMask : 0);
21652162
}
21662163

2167-
bool isNoReturn() const { return Bits & NoReturnMask; }
21682164
bool isAutoClosure() const { return Bits & AutoClosureMask; }
21692165
bool isNoEscape() const { return Bits & NoEscapeMask; }
21702166
bool isExplicitlyEscaping() const { return Bits & ExplicitlyEscapingMask; }
@@ -2211,12 +2207,6 @@ class AnyFunctionType : public TypeBase {
22112207
return ExtInfo((Bits & ~RepresentationMask)
22122208
| (unsigned)Rep);
22132209
}
2214-
ExtInfo withIsNoReturn(bool IsNoReturn = true) const {
2215-
if (IsNoReturn)
2216-
return ExtInfo(Bits | NoReturnMask);
2217-
else
2218-
return ExtInfo(Bits & ~NoReturnMask);
2219-
}
22202210
ExtInfo withIsAutoClosure(bool IsAutoClosure = true) const {
22212211
if (IsAutoClosure)
22222212
return ExtInfo(Bits | AutoClosureMask);
@@ -2285,10 +2275,6 @@ class AnyFunctionType : public TypeBase {
22852275
return getExtInfo().getRepresentation();
22862276
}
22872277

2288-
bool isNoReturn() const {
2289-
return getExtInfo().isNoReturn();
2290-
}
2291-
22922278
/// \brief True if this type allows an implicit conversion from a function
22932279
/// argument expression of type T to a function of type () -> T.
22942280
bool isAutoClosure() const {
@@ -2866,14 +2852,13 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
28662852
class ExtInfo {
28672853
// Feel free to rearrange or add bits, but if you go over 15,
28682854
// you'll need to adjust both the Bits field below and
2869-
// BaseType::AnyFunctionTypeBits.
2855+
// TypeBase::AnyFunctionTypeBits.
28702856

2871-
// |representation|noReturn|pseudogeneric|
2872-
// | 0 .. 3 | 4 | 5 |
2857+
// |representation|pseudogeneric|
2858+
// | 0 .. 3 | 4 |
28732859
//
28742860
enum : uint16_t { RepresentationMask = 0x00F };
2875-
enum : uint16_t { NoReturnMask = 0x010 };
2876-
enum : uint16_t { PseudogenericMask = 0x020 };
2861+
enum : uint16_t { PseudogenericMask = 0x010 };
28772862

28782863
uint16_t Bits;
28792864

@@ -2886,19 +2871,15 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
28862871
ExtInfo() : Bits(0) { }
28872872

28882873
// Constructor for polymorphic type.
2889-
ExtInfo(Representation rep, bool isNoReturn, bool isPseudogeneric) {
2874+
ExtInfo(Representation rep, bool isPseudogeneric) {
28902875
Bits = ((unsigned) rep) |
2891-
(isNoReturn ? NoReturnMask : 0) |
28922876
(isPseudogeneric ? PseudogenericMask : 0);
28932877
}
28942878

28952879
/// Is this function pseudo-generic? A pseudo-generic function
28962880
/// is not permitted to dynamically depend on its type arguments.
28972881
bool isPseudogeneric() const { return Bits & PseudogenericMask; }
28982882

2899-
/// Do functions of this type return normally?
2900-
bool isNoReturn() const { return Bits & NoReturnMask; }
2901-
29022883
/// What is the abstract representation of this function value?
29032884
Representation getRepresentation() const {
29042885
return Representation(Bits & RepresentationMask);
@@ -2956,12 +2937,6 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
29562937
return ExtInfo((Bits & ~RepresentationMask)
29572938
| (unsigned)Rep);
29582939
}
2959-
ExtInfo withIsNoReturn(bool IsNoReturn = true) const {
2960-
if (IsNoReturn)
2961-
return ExtInfo(Bits | NoReturnMask);
2962-
else
2963-
return ExtInfo(Bits & ~NoReturnMask);
2964-
}
29652940
ExtInfo withIsPseudogeneric(bool isPseudogeneric = true) const {
29662941
if (isPseudogeneric)
29672942
return ExtInfo(Bits | PseudogenericMask);
@@ -3207,10 +3182,6 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
32073182
return getExtInfo().getRepresentation();
32083183
}
32093184

3210-
bool isNoReturn() const {
3211-
return getExtInfo().isNoReturn();
3212-
}
3213-
32143185
bool isPseudogeneric() const {
32153186
return getExtInfo().isPseudogeneric();
32163187
}

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const uint16_t VERSION_MAJOR = 0;
5353
/// in source control, you should also update the comment to briefly
5454
/// describe what change you made. The content of this comment isn't important;
5555
/// it just ensures a conflict if two people change the module format.
56-
const uint16_t VERSION_MINOR = 255; // Last change: bind_memory instruction
56+
const uint16_t VERSION_MINOR = 256; // Last change: remove noreturn bit
5757

5858
using DeclID = PointerEmbeddedInt<unsigned, 31>;
5959
using DeclIDField = BCFixed<31>;
@@ -587,7 +587,6 @@ namespace decls_block {
587587
TypeIDField, // output
588588
FunctionTypeRepresentationField, // representation
589589
BCFixed<1>, // auto-closure?
590-
BCFixed<1>, // noreturn?
591590
BCFixed<1>, // noescape?
592591
BCFixed<1>, // explicitlyEscaping?
593592
BCFixed<1> // throws?
@@ -681,7 +680,6 @@ namespace decls_block {
681680
TypeIDField, // output
682681
DeclIDField, // decl that owns the generic params
683682
FunctionTypeRepresentationField, // representation
684-
BCFixed<1>, // noreturn?
685683
BCFixed<1> // throws?
686684
// Trailed by its generic parameters, if the owning decl ID is 0.
687685
>;
@@ -691,7 +689,6 @@ namespace decls_block {
691689
TypeIDField, // input
692690
TypeIDField, // output
693691
FunctionTypeRepresentationField, // representation
694-
BCFixed<1>, // noreturn?
695692
BCFixed<1>, // throws?
696693
BCArray<TypeIDField> // generic parameters
697694
// followed by requirements
@@ -701,7 +698,6 @@ namespace decls_block {
701698
SIL_FUNCTION_TYPE,
702699
ParameterConventionField, // callee convention
703700
SILFunctionTypeRepresentationField, // representation
704-
BCFixed<1>, // noreturn?
705701
BCFixed<1>, // pseudogeneric?
706702
BCFixed<1>, // error result?
707703
BCFixed<30>, // number of parameters

lib/AST/ASTDumper.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2869,7 +2869,6 @@ namespace {
28692869
break;
28702870
}
28712871

2872-
printFlag(T->isNoReturn(), "noreturn");
28732872
printFlag(T->isAutoClosure(), "autoclosure");
28742873
printFlag(T->isNoEscape(), "noescape");
28752874
printFlag(T->isExplicitlyEscaping(), "escaping");

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3752,9 +3752,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37523752
break;
37533753
}
37543754
}
3755-
3756-
if (info.isNoReturn())
3757-
Printer << "@noreturn ";
37583755
}
37593756

37603757
void printFunctionExtInfo(SILFunctionType::ExtInfo info) {
@@ -3789,9 +3786,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37893786

37903787
if (info.isPseudogeneric())
37913788
Printer << "@pseudogeneric ";
3792-
3793-
if (info.isNoReturn())
3794-
Printer << "@noreturn ";
37953789
}
37963790

37973791
void visitFunctionType(FunctionType *T) {

lib/AST/ASTVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2304,7 +2304,7 @@ struct ASTNodeBase {};
23042304
// If a decl has the Throws bit set, the function type should throw,
23052305
// and vice versa.
23062306
auto fnTy = AFD->getType()->castTo<AnyFunctionType>();
2307-
for (unsigned i = 1, e = AFD->getNaturalArgumentCount(); i != e; ++i)
2307+
for (unsigned i = 1, e = AFD->getNumParameterLists(); i != e; ++i)
23082308
fnTy = fnTy->getResult()->castTo<AnyFunctionType>();
23092309

23102310
if (AFD->hasThrows() != fnTy->getExtInfo().throws()) {

lib/AST/Builtins.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ static ValueDecl *getOnceOperation(ASTContext &Context,
984984
auto HandleTy = Context.TheRawPointerType;
985985
auto VoidTy = Context.TheEmptyTupleType;
986986
auto Thin = FunctionType::ExtInfo(FunctionTypeRepresentation::Thin,
987-
/*noreturn*/ false, /*throws*/ false);
987+
/*throws*/ false);
988988

989989
auto BlockTy = FunctionType::get(VoidTy, VoidTy, Thin);
990990
return getBuiltinFunction(Id, {HandleTy, BlockTy}, VoidTy);

lib/AST/Decl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,12 +1426,12 @@ static Type mapSignatureParamType(ASTContext &ctx, Type type) {
14261426
/// we may need to compare the extended information.
14271427
///
14281428
/// In the type of the function declaration, none of the extended information
1429-
/// is relevant. We cannot overload purely on @noreturn, 'throws', or the
1430-
/// calling convention of the declaration itself.
1429+
/// is relevant. We cannot overload purely on 'throws' or the calling
1430+
/// convention of the declaration itself.
14311431
///
14321432
/// For function parameter types, we do want to be able to overload on
14331433
/// 'throws', since that is part of the mangled symbol name, but not
1434-
/// @noreturn or @noescape.
1434+
/// @noescape.
14351435
static AnyFunctionType::ExtInfo
14361436
mapSignatureExtInfo(AnyFunctionType::ExtInfo info,
14371437
bool topLevelFunction) {
@@ -4415,7 +4415,7 @@ Type FuncDecl::getResultType() const {
44154415
if (resultTy->is<ErrorType>())
44164416
return resultTy;
44174417

4418-
for (unsigned i = 0, e = getNaturalArgumentCount(); i != e; ++i)
4418+
for (unsigned i = 0, e = getNumParameterLists(); i != e; ++i)
44194419
resultTy = resultTy->castTo<AnyFunctionType>()->getResult();
44204420

44214421
if (!resultTy)

lib/AST/Mangle.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,6 @@ void Mangler::mangleType(Type type, unsigned uncurryLevel) {
979979
// <impl-function-attribute> ::= 'Cc' // C global function
980980
// <impl-function-attribute> ::= 'Cm' // Swift method
981981
// <impl-function-attribute> ::= 'CO' // ObjC method
982-
// <impl-function-attribute> ::= 'N' // noreturn
983982
// <impl-function-attribute> ::= 'g' // pseudogeneric
984983
// <impl-function-attribute> ::= 'G' // generic
985984
// <impl-parameter> ::= <impl-convention> <type>
@@ -1042,7 +1041,6 @@ void Mangler::mangleType(Type type, unsigned uncurryLevel) {
10421041
break;
10431042
}
10441043

1045-
if (fn->isNoReturn()) Buffer << 'N';
10461044
if (fn->isPolymorphic()) {
10471045
Buffer << (fn->isPseudogeneric() ? 'g' : 'G');
10481046
mangleGenericSignature(fn->getGenericSignature());

0 commit comments

Comments
 (0)