Skip to content

Commit 709d9b9

Browse files
authored
Merge pull request #40272 from nkcsgexi/85268028
ModuleInterface: consume _const keyword at var and parameter decls and keep them in textual/binary modules
2 parents 231fa1b + 6891f17 commit 709d9b9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+460
-39
lines changed

include/swift/AST/ArgumentList.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class Argument final {
8383
/// Whether the argument is \c inout, denoted with the '&' prefix.
8484
bool isInOut() const;
8585

86+
/// Whether the argument is a compile-time constant value.
87+
bool isConst() const;
88+
8689
bool operator==(const Argument &other) {
8790
return LabelLoc == other.LabelLoc && Label == other.Label &&
8891
ArgExpr == other.ArgExpr;

include/swift/AST/Attr.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,11 @@ SIMPLE_DECL_ATTR(_predatesConcurrency, PredatesConcurrency,
694694
ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
695695
125)
696696

697+
CONTEXTUAL_SIMPLE_DECL_ATTR(_const, CompileTimeConst,
698+
DeclModifier | OnParam | OnVar |
699+
ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove,
700+
126)
701+
697702
// If you're adding a new underscored attribute here, please document it in
698703
// docs/ReferenceGuides/UnderscoredAttributes.md.
699704

include/swift/AST/Decl.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4583,6 +4583,7 @@ class AbstractStorageDecl : public ValueDecl {
45834583
void setStatic(bool IsStatic) {
45844584
Bits.AbstractStorageDecl.IsStatic = IsStatic;
45854585
}
4586+
bool isCompileTimeConst() const;
45864587

45874588
/// \returns the way 'static'/'class' should be spelled for this declaration.
45884589
StaticSpellingKind getCorrectStaticSpelling() const;
@@ -5356,7 +5357,7 @@ class ParamDecl : public VarDecl {
53565357

53575358
TypeRepr *TyRepr = nullptr;
53585359

5359-
struct alignas(1 << DeclAlignInBits) StoredDefaultArgument {
5360+
struct alignas(1 << StoredDefaultArgumentAlignInBits) StoredDefaultArgument {
53605361
PointerUnion<Expr *, VarDecl *> DefaultArg;
53615362

53625363
/// Stores the context for the default argument as well as a bit to
@@ -5380,10 +5381,13 @@ class ParamDecl : public VarDecl {
53805381

53815382
/// Whether or not this parameter is 'isolated'.
53825383
IsIsolated = 1 << 2,
5384+
5385+
/// Whether or not this parameter is '_const'.
5386+
IsCompileTimeConst = 1 << 3,
53835387
};
53845388

53855389
/// The default value, if any, along with flags.
5386-
llvm::PointerIntPair<StoredDefaultArgument *, 3, OptionSet<Flags>>
5390+
llvm::PointerIntPair<StoredDefaultArgument *, 4, OptionSet<Flags>>
53875391
DefaultValueAndFlags;
53885392

53895393
friend class ParamSpecifierRequest;
@@ -5552,6 +5556,17 @@ class ParamDecl : public VarDecl {
55525556
: flags - Flags::IsIsolated);
55535557
}
55545558

5559+
/// Whether or not this parameter is marked with '_const'.
5560+
bool isCompileTimeConst() const {
5561+
return DefaultValueAndFlags.getInt().contains(Flags::IsCompileTimeConst);
5562+
}
5563+
5564+
void setCompileTimeConst(bool value = true) {
5565+
auto flags = DefaultValueAndFlags.getInt();
5566+
DefaultValueAndFlags.setInt(value ? flags | Flags::IsCompileTimeConst
5567+
: flags - Flags::IsCompileTimeConst);
5568+
}
5569+
55555570
/// Does this parameter reject temporary pointer conversions?
55565571
bool isNonEphemeral() const;
55575572

include/swift/AST/DiagnosticsCommon.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ ERROR(class_subscript_not_in_class,none,
7171
"class subscripts are only allowed within classes; "
7272
"use 'static' to declare a %select{static|requirement fulfilled by either a static or class}0 subscript", (bool))
7373

74+
ERROR(require_static_for_const,none,
75+
"'static' is required for _const variable declaration", ())
76+
77+
ERROR(require_let_for_const,none,
78+
"let is required for a _const variable declaration", ())
79+
80+
ERROR(require_const_initializer_for_const,none,
81+
"_const let should be initialized with a compile-time literal", ())
82+
7483
// FIXME: Used by both the parser and the type-checker.
7584
ERROR(func_decl_without_brace,PointsToFirstBadToken,
7685
"expected '{' in body of function declaration", ())

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,9 @@ ERROR(cannot_return_value_from_void_func,none,
722722
NOTE(add_return_type_note,none,
723723
"did you mean to add a return type?", ())
724724

725+
ERROR(expect_compile_time_const,none,
726+
"expect a compile-time constant literal", ())
727+
725728
//------------------------------------------------------------------------------
726729
// MARK: Import Resolution
727730
//------------------------------------------------------------------------------
@@ -2320,6 +2323,9 @@ WARNING(warn_protocol_witness_optionality,none,
23202323
NOTE(protocol_witness_static_conflict,none,
23212324
"candidate operates on %select{a type|an instance}0, not "
23222325
"%select{an instance|a type}0 as required", (bool))
2326+
NOTE(protocol_witness_const_conflict,none,
2327+
"candidate operates as %select{const|non-const}0, not "
2328+
"%select{non-const|const}0 as required", (bool))
23232329
NOTE(protocol_witness_prefix_postfix_conflict,none,
23242330
"candidate is %select{|prefix, |postfix, }1not "
23252331
"%select{prefix|postfix}0 as required", (bool, unsigned))

include/swift/AST/Expr.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,9 @@ class alignas(8) Expr : public ASTAllocated<Expr> {
486486
bool isSemanticallyInOutExpr() const {
487487
return getSemanticsProvidingExpr()->getKind() == ExprKind::InOut;
488488
}
489-
489+
490+
bool isSemanticallyConstExpr() const;
491+
490492
/// Returns false if this expression needs to be wrapped in parens when
491493
/// used inside of a any postfix expression, true otherwise.
492494
///

include/swift/AST/TypeAlignments.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ namespace swift {
7575
constexpr size_t SILFunctionAlignInBits = 2;
7676
constexpr size_t ASTContextAlignInBits = 2;
7777
constexpr size_t TypeVariableAlignInBits = 4;
78+
constexpr size_t StoredDefaultArgumentAlignInBits = 4;
7879

7980
// Well, this is the *minimum* pointer alignment; it's going to be 3 on
8081
// 64-bit targets, but that doesn't matter.

include/swift/AST/TypeRepr.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,21 @@ class IsolatedTypeRepr : public SpecifierTypeRepr {
10181018
static bool classof(const IsolatedTypeRepr *T) { return true; }
10191019
};
10201020

1021+
/// An '_const' type.
1022+
/// \code
1023+
/// x : _const Int
1024+
/// \endcode
1025+
class CompileTimeConstTypeRepr : public SpecifierTypeRepr {
1026+
public:
1027+
CompileTimeConstTypeRepr(TypeRepr *Base, SourceLoc InOutLoc)
1028+
: SpecifierTypeRepr(TypeReprKind::CompileTimeConst, Base, InOutLoc) {}
1029+
1030+
static bool classof(const TypeRepr *T) {
1031+
return T->getKind() == TypeReprKind::CompileTimeConst;
1032+
}
1033+
static bool classof(const CompileTimeConstTypeRepr *T) { return true; }
1034+
};
1035+
10211036
/// A TypeRepr for a known, fixed type.
10221037
///
10231038
/// Fixed type representations should be used sparingly, in places
@@ -1287,6 +1302,7 @@ inline bool TypeRepr::isSimple() const {
12871302
case TypeReprKind::Owned:
12881303
case TypeReprKind::Isolated:
12891304
case TypeReprKind::Placeholder:
1305+
case TypeReprKind::CompileTimeConst:
12901306
return true;
12911307
}
12921308
llvm_unreachable("bad TypeRepr kind");

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ ABSTRACT_TYPEREPR(Specifier, TypeRepr)
6161
TYPEREPR(Shared, SpecifierTypeRepr)
6262
TYPEREPR(Owned, SpecifierTypeRepr)
6363
TYPEREPR(Isolated, SpecifierTypeRepr)
64+
TYPEREPR(CompileTimeConst, SpecifierTypeRepr)
6465
TYPEREPR(Fixed, TypeRepr)
6566
TYPEREPR(SILBox, TypeRepr)
6667
LAST_TYPEREPR(SILBox)

include/swift/AST/Types.h

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,7 +1917,7 @@ class TypeAliasType final
19171917
/// Provide parameter type relevant flags, i.e. variadic, autoclosure, and
19181918
/// escaping.
19191919
class ParameterTypeFlags {
1920-
enum ParameterFlags : uint8_t {
1920+
enum ParameterFlags : uint16_t {
19211921
None = 0,
19221922
Variadic = 1 << 0,
19231923
AutoClosure = 1 << 1,
@@ -1926,32 +1926,36 @@ class ParameterTypeFlags {
19261926
Ownership = 7 << OwnershipShift,
19271927
NoDerivative = 1 << 6,
19281928
Isolated = 1 << 7,
1929-
NumBits = 8
1929+
CompileTimeConst = 1 << 8,
1930+
NumBits = 9
19301931
};
19311932
OptionSet<ParameterFlags> value;
19321933
static_assert(NumBits <= 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
19331934

1934-
ParameterTypeFlags(OptionSet<ParameterFlags, uint8_t> val) : value(val) {}
1935+
ParameterTypeFlags(OptionSet<ParameterFlags, uint16_t> val) : value(val) {}
19351936

19361937
public:
19371938
ParameterTypeFlags() = default;
1938-
static ParameterTypeFlags fromRaw(uint8_t raw) {
1939+
static ParameterTypeFlags fromRaw(uint16_t raw) {
19391940
return ParameterTypeFlags(OptionSet<ParameterFlags>(raw));
19401941
}
19411942

19421943
ParameterTypeFlags(bool variadic, bool autoclosure, bool nonEphemeral,
1943-
ValueOwnership ownership, bool isolated, bool noDerivative)
1944+
ValueOwnership ownership, bool isolated, bool noDerivative,
1945+
bool compileTimeConst)
19441946
: value((variadic ? Variadic : 0) | (autoclosure ? AutoClosure : 0) |
19451947
(nonEphemeral ? NonEphemeral : 0) |
19461948
uint8_t(ownership) << OwnershipShift |
19471949
(isolated ? Isolated : 0) |
1948-
(noDerivative ? NoDerivative : 0)) {}
1950+
(noDerivative ? NoDerivative : 0) |
1951+
(compileTimeConst ? CompileTimeConst : 0)){}
19491952

19501953
/// Create one from what's present in the parameter type
19511954
inline static ParameterTypeFlags
19521955
fromParameterType(Type paramTy, bool isVariadic, bool isAutoClosure,
19531956
bool isNonEphemeral, ValueOwnership ownership,
1954-
bool isolated, bool isNoDerivative);
1957+
bool isolated, bool isNoDerivative,
1958+
bool compileTimeConst);
19551959

19561960
bool isNone() const { return !value; }
19571961
bool isVariadic() const { return value.contains(Variadic); }
@@ -1961,6 +1965,7 @@ class ParameterTypeFlags {
19611965
bool isShared() const { return getValueOwnership() == ValueOwnership::Shared;}
19621966
bool isOwned() const { return getValueOwnership() == ValueOwnership::Owned; }
19631967
bool isIsolated() const { return value.contains(Isolated); }
1968+
bool isCompileTimeConst() const { return value.contains(CompileTimeConst); }
19641969
bool isNoDerivative() const { return value.contains(NoDerivative); }
19651970

19661971
ValueOwnership getValueOwnership() const {
@@ -1976,6 +1981,11 @@ class ParameterTypeFlags {
19761981
return withValueOwnership(isInout ? ValueOwnership::InOut
19771982
: ValueOwnership::Default);
19781983
}
1984+
1985+
ParameterTypeFlags withCompileTimeConst(bool isConst) const {
1986+
return ParameterTypeFlags(isConst ? value | ParameterTypeFlags::CompileTimeConst
1987+
: value | ParameterTypeFlags::CompileTimeConst);
1988+
}
19791989

19801990
ParameterTypeFlags withShared(bool isShared) const {
19811991
return withValueOwnership(isShared ? ValueOwnership::Shared
@@ -2083,7 +2093,8 @@ class YieldTypeFlags {
20832093
return ParameterTypeFlags(/*variadic*/ false,
20842094
/*autoclosure*/ false,
20852095
/*nonEphemeral*/ false, getValueOwnership(),
2086-
/*isolated*/ false, /*noDerivative*/ false);
2096+
/*isolated*/ false, /*noDerivative*/ false,
2097+
/*compileTimeConst*/false);
20872098
}
20882099

20892100
bool operator ==(const YieldTypeFlags &other) const {
@@ -2882,6 +2893,9 @@ class AnyFunctionType : public TypeBase {
28822893
/// Whether the parameter is 'isolated'.
28832894
bool isIsolated() const { return Flags.isIsolated(); }
28842895

2896+
/// Whether the parameter is 'isCompileTimeConst'.
2897+
bool isCompileTimeConst() const { return Flags.isCompileTimeConst(); }
2898+
28852899
/// Whether the parameter is marked '@noDerivative'.
28862900
bool isNoDerivative() const { return Flags.isNoDerivative(); }
28872901

@@ -6325,7 +6339,8 @@ inline TupleTypeElt TupleTypeElt::getWithType(Type T) const {
63256339
/// Create one from what's present in the parameter decl and type
63266340
inline ParameterTypeFlags ParameterTypeFlags::fromParameterType(
63276341
Type paramTy, bool isVariadic, bool isAutoClosure, bool isNonEphemeral,
6328-
ValueOwnership ownership, bool isolated, bool isNoDerivative) {
6342+
ValueOwnership ownership, bool isolated, bool isNoDerivative,
6343+
bool compileTimeConst) {
63296344
// FIXME(Remove InOut): The last caller that needs this is argument
63306345
// decomposition. Start by enabling the assertion there and fixing up those
63316346
// callers, then remove this, then remove
@@ -6336,7 +6351,7 @@ inline ParameterTypeFlags ParameterTypeFlags::fromParameterType(
63366351
ownership = ValueOwnership::InOut;
63376352
}
63386353
return {isVariadic, isAutoClosure, isNonEphemeral, ownership, isolated,
6339-
isNoDerivative};
6354+
isNoDerivative, compileTimeConst};
63406355
}
63416356

63426357
inline const Type *BoundGenericType::getTrailingObjectsPointer() const {

0 commit comments

Comments
 (0)