Skip to content

Commit 03c76bd

Browse files
committed
sema: diagnose passing a non-constant value into a constant parameter
1 parent 06e6389 commit 03c76bd

File tree

14 files changed

+119
-2
lines changed

14 files changed

+119
-2
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/DiagnosticsSema.def

Lines changed: 3 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
//------------------------------------------------------------------------------

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/Types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,11 @@ class ParameterTypeFlags {
19811981
return withValueOwnership(isInout ? ValueOwnership::InOut
19821982
: ValueOwnership::Default);
19831983
}
1984+
1985+
ParameterTypeFlags withCompileTimeConst(bool isConst) const {
1986+
return ParameterTypeFlags(isConst ? value | ParameterTypeFlags::CompileTimeConst
1987+
: value | ParameterTypeFlags::CompileTimeConst);
1988+
}
19841989

19851990
ParameterTypeFlags withShared(bool isShared) const {
19861991
return withValueOwnership(isShared ? ValueOwnership::Shared

include/swift/Sema/CSFix.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,9 @@ enum class FixKind : uint8_t {
379379

380380
/// Produce a warning for a tuple label mismatch.
381381
AllowTupleLabelMismatch,
382+
383+
/// Produce an error for not getting a compile-time constant
384+
NotCompileTimeConst,
382385
};
383386

384387
class ConstraintFix {
@@ -1861,6 +1864,23 @@ class RemoveReturn final : public ContextualMismatch {
18611864
}
18621865
};
18631866

1867+
class NotCompileTimeConst final : public ContextualMismatch {
1868+
NotCompileTimeConst(ConstraintSystem &cs, Type paramTy, ConstraintLocator *locator);
1869+
1870+
public:
1871+
std::string getName() const override { return "replace with an literal"; }
1872+
1873+
bool diagnose(const Solution &solution, bool asNote = false) const override;
1874+
1875+
static NotCompileTimeConst *create(ConstraintSystem &cs,
1876+
Type paramTy,
1877+
ConstraintLocator *locator);
1878+
1879+
static bool classof(ConstraintFix *fix) {
1880+
return fix->getKind() == FixKind::NotCompileTimeConst;
1881+
}
1882+
};
1883+
18641884
class CollectionElementContextualMismatch final
18651885
: public ContextualMismatch,
18661886
private llvm::TrailingObjects<CollectionElementContextualMismatch,

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3464,6 +3464,7 @@ namespace {
34643464
printFlag(paramFlags.isVariadic(), "vararg");
34653465
printFlag(paramFlags.isAutoClosure(), "autoclosure");
34663466
printFlag(paramFlags.isNonEphemeral(), "nonEphemeral");
3467+
printFlag(paramFlags.isCompileTimeConst(), "compileTimeConst");
34673468
switch (paramFlags.getValueOwnership()) {
34683469
case ValueOwnership::Default: break;
34693470
case ValueOwnership::Owned: printFlag("owned"); break;

lib/AST/ArgumentList.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ bool Argument::isInOut() const {
3939
return ArgExpr->isSemanticallyInOutExpr();
4040
}
4141

42+
bool Argument::isConst() const {
43+
return ArgExpr->isSemanticallyConstExpr();
44+
}
45+
4246
ArgumentList *ArgumentList::create(ASTContext &ctx, SourceLoc lParenLoc,
4347
ArrayRef<Argument> args, SourceLoc rParenLoc,
4448
Optional<unsigned> firstTrailingClosureIndex,

lib/AST/Expr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,13 @@ Expr *Expr::getSemanticsProvidingExpr() {
198198
return this;
199199
}
200200

201+
bool Expr:: isSemanticallyConstExpr() const {
202+
if (auto *LE = dyn_cast<LiteralExpr>(getSemanticsProvidingExpr())) {
203+
return LE->getKind() != ExprKind::InterpolatedStringLiteral;
204+
}
205+
return false;
206+
}
207+
201208
Expr *Expr::getValueProvidingExpr() {
202209
Expr *E = getSemanticsProvidingExpr();
203210

lib/Sema/CSDiagnostics.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5436,6 +5436,11 @@ bool ExtraneousReturnFailure::diagnoseAsError() {
54365436
return true;
54375437
}
54385438

5439+
bool NotCompileTimeConstFailure::diagnoseAsError() {
5440+
emitDiagnostic(diag::expect_compile_time_const);
5441+
return true;
5442+
}
5443+
54395444
bool CollectionElementContextualFailure::diagnoseAsError() {
54405445
auto anchor = getRawAnchor();
54415446
auto *locator = getLocator();

lib/Sema/CSDiagnostics.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,14 @@ class ExtraneousReturnFailure final : public FailureDiagnostic {
17531753
bool diagnoseAsError() override;
17541754
};
17551755

1756+
class NotCompileTimeConstFailure final : public FailureDiagnostic {
1757+
public:
1758+
NotCompileTimeConstFailure(const Solution &solution, ConstraintLocator *locator)
1759+
: FailureDiagnostic(solution, locator) {}
1760+
1761+
bool diagnoseAsError() override;
1762+
};
1763+
17561764
/// Diagnose a contextual mismatch between expected collection element type
17571765
/// and the one provided (e.g. source of the assignment or argument to a call)
17581766
/// e.g.:

0 commit comments

Comments
 (0)