Skip to content

Commit 57c5817

Browse files
committed
AST: Remove noreturn bit from function types
1 parent 5a71bd5 commit 57c5817

33 files changed

+51
-204
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/DiagnosticsSema.def

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,8 +1329,6 @@ NOTE(protocol_witness_mutating_conflict,none,
13291329
"candidate is marked 'mutating' but protocol does not allow it", ())
13301330
NOTE(protocol_witness_settable_conflict,none,
13311331
"candidate is not settable, but protocol requires it", ())
1332-
NOTE(protocol_witness_noreturn_conflict,none,
1333-
"candidate is not @noreturn, but protocol requires it", ())
13341332
NOTE(protocol_witness_rethrows_conflict,none,
13351333
"candidate is not 'rethrows', but protocol requires it", ())
13361334
NOTE(protocol_witness_throws_conflict,none,
@@ -1778,9 +1776,6 @@ ERROR(final_not_on_accessors,none,
17781776
"'final' cannot be applied to accessors, it must be put on the "
17791777
"%select{var|let|subscript}0", (unsigned))
17801778

1781-
ERROR(override_noreturn_with_return,none,
1782-
"an override of a @noreturn method should also be @noreturn", ())
1783-
17841779
ERROR(override_rethrows_with_non_rethrows,none,
17851780
"override of 'rethrows' %select{method|initializer}0 should also "
17861781
"be 'rethrows'", (bool))

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/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: 3 additions & 3 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) {

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());

lib/AST/Type.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,8 +1541,6 @@ bool TypeBase::isSpelledLike(Type other) {
15411541
return false;
15421542
if (fMe->getRepresentation() != fThem->getRepresentation())
15431543
return false;
1544-
if (fMe->isNoReturn() != fThem->isNoReturn())
1545-
return false;
15461544
if (!fMe->getInput()->isSpelledLike(fThem->getInput()))
15471545
return false;
15481546
if (!fMe->getResult()->isSpelledLike(fThem->getResult()))
@@ -2421,13 +2419,10 @@ static bool canOverride(CanType t1, CanType t2,
24212419
if (!fn1)
24222420
return false;
24232421

2424-
// Allow ExtInfos to differ in these ways:
2425-
// - the overriding type may be noreturn even if the base type isn't
2426-
// - the base type may be throwing even if the overriding type isn't
2422+
// Allow the base type to be throwing even if the overriding type isn't
24272423
auto ext1 = fn1->getExtInfo();
24282424
auto ext2 = fn2->getExtInfo();
24292425
if (ext2.throws()) ext1 = ext1.withThrows(true);
2430-
if (ext1.isNoReturn()) ext2 = ext2.withIsNoReturn(true);
24312426
if (ext1 != ext2)
24322427
return false;
24332428

lib/AST/TypeRepr.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ void AttributedTypeRepr::printAttrs(llvm::raw_ostream &OS) const {
275275

276276
void AttributedTypeRepr::printAttrs(ASTPrinter &Printer) const {
277277
const TypeAttributes &Attrs = getAttrs();
278-
if (Attrs.has(TAK_noreturn)) Printer << "@noreturn ";
279278

280279
switch (Attrs.has(TAK_autoclosure)*2 + Attrs.has(TAK_noescape)) {
281280
case 0: break; // Nothing specified.

lib/Basic/Demangle.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,7 +2122,6 @@ class Demangler {
21222122
// impl-function-attribute ::= 'Cm' // compatible with Swift method
21232123
// impl-function-attribute ::= 'CO' // compatible with ObjC method
21242124
// impl-function-attribute ::= 'Cw' // compatible with protocol witness
2125-
// impl-function-attribute ::= 'N' // noreturn
21262125
// impl-function-attribute ::= 'G' // generic
21272126
NodePointer demangleImplFunctionType() {
21282127
NodePointer type = NodeFactory::create(Node::Kind::ImplFunctionType);
@@ -2145,9 +2144,6 @@ class Demangler {
21452144
return nullptr;
21462145
}
21472146

2148-
if (Mangled.nextIf('N'))
2149-
addImplFunctionAttribute(type, "@noreturn");
2150-
21512147
// Enter a new generic context if this type is generic.
21522148
// FIXME: replace with std::optional, when we have it.
21532149
bool isPseudogeneric = false;

lib/Basic/Remangle.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,8 +1125,6 @@ void Remangler::mangleImplFunctionAttribute(Node *node) {
11251125
Out << "CO";
11261126
} else if (text == "@convention(witness_method)") {
11271127
Out << "Cw";
1128-
} else if (text == "@noreturn") {
1129-
Out << "CN";
11301128
} else {
11311129
unreachable("bad impl-function-attribute");
11321130
}

lib/IRGen/GenObjC.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,6 @@ static CanSILFunctionType getAllocObjectFormalType(ASTContext &ctx,
740740
};
741741
auto result = SILResultInfo(classType, ResultConvention::Owned);
742742
auto extInfo = SILFunctionType::ExtInfo(SILFunctionType::Representation::ObjCMethod,
743-
/*noreturn*/ false,
744743
/*pseudogeneric*/ true);
745744

746745
return SILFunctionType::get(nullptr, extInfo,

lib/RemoteAST/RemoteAST.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,6 @@ class RemoteASTTypeBuilder {
274274
}
275275

276276
auto einfo = AnyFunctionType::ExtInfo(representation,
277-
/*noreturn*/ false,
278277
/*throws*/ flags.throws());
279278

280279
// The result type must be materializable.

0 commit comments

Comments
 (0)