From 0834c750aa167f163c60c4cae123a090d63d3a3d Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Mon, 26 Aug 2024 16:36:18 +0800 Subject: [PATCH] [Deprecation -> Error] nothrow function contracts that throw (#16801) --- changelog/dmd.deprecation-throwing-contracts.dd | 17 +++++++++++++++++ compiler/src/dmd/semantic3.d | 10 ++-------- compiler/test/fail_compilation/fail13123.d | 5 ++--- 3 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 changelog/dmd.deprecation-throwing-contracts.dd diff --git a/changelog/dmd.deprecation-throwing-contracts.dd b/changelog/dmd.deprecation-throwing-contracts.dd new file mode 100644 index 0000000000..cbb0e96c94 --- /dev/null +++ b/changelog/dmd.deprecation-throwing-contracts.dd @@ -0,0 +1,17 @@ +An error is now issued for `in`/`out` contracts of `nothrow` functions that may throw + +This used to issue a deprecation, it is now an error: +``` +void test() nothrow +in +{ + throw new Exception(null); // Error: `in` contract may throw but function is marked as `nothrow` +} +out +{ + throw new Exception(null); // Error: `out` contract may throw but function is marked as `nothrow` +} +do +{ +} +``` diff --git a/compiler/src/dmd/semantic3.d b/compiler/src/dmd/semantic3.d index 036bc67196..a71b88e78a 100644 --- a/compiler/src/dmd/semantic3.d +++ b/compiler/src/dmd/semantic3.d @@ -1009,14 +1009,11 @@ private extern(C++) final class Semantic3Visitor : Visitor // BUG: verify that all in and ref parameters are read freq = freq.statementSemantic(sc2); - // @@@DEPRECATED_2.111@@@ - pass `isnothrow` instead of `false` to print a more detailed error msg` const blockExit = freq.blockExit(funcdecl, null); if (blockExit & BE.throw_) { if (isnothrow) - // @@@DEPRECATED_2.111@@@ - // Deprecated in 2.101, can be made an error in 2.111 - deprecation(funcdecl.loc, "`%s`: `in` contract may throw but function is marked as `nothrow`", + error(funcdecl.loc, "`%s`: `in` contract may throw but function is marked as `nothrow`", funcdecl.toPrettyChars()); else if (funcdecl.nothrowInprocess) f.isnothrow = false; @@ -1056,14 +1053,11 @@ private extern(C++) final class Semantic3Visitor : Visitor fens = fens.statementSemantic(sc2); - // @@@DEPRECATED_2.111@@@ - pass `isnothrow` instead of `false` to print a more detailed error msg` const blockExit = fens.blockExit(funcdecl, null); if (blockExit & BE.throw_) { if (isnothrow) - // @@@DEPRECATED_2.111@@@ - // Deprecated in 2.101, can be made an error in 2.111 - deprecation(funcdecl.loc, "`%s`: `out` contract may throw but function is marked as `nothrow`", + error(funcdecl.loc, "`%s`: `out` contract may throw but function is marked as `nothrow`", funcdecl.toPrettyChars()); else if (funcdecl.nothrowInprocess) f.isnothrow = false; diff --git a/compiler/test/fail_compilation/fail13123.d b/compiler/test/fail_compilation/fail13123.d index 7784cba67b..4a3be08308 100644 --- a/compiler/test/fail_compilation/fail13123.d +++ b/compiler/test/fail_compilation/fail13123.d @@ -1,9 +1,8 @@ -// REQUIRED_ARGS: -de /* TEST_OUTPUT: --- -fail_compilation/fail13123.d(10): Deprecation: `fail13123.test`: `in` contract may throw but function is marked as `nothrow` -fail_compilation/fail13123.d(10): Deprecation: `fail13123.test`: `out` contract may throw but function is marked as `nothrow` +fail_compilation/fail13123.d(9): Error: `fail13123.test`: `in` contract may throw but function is marked as `nothrow` +fail_compilation/fail13123.d(9): Error: `fail13123.test`: `out` contract may throw but function is marked as `nothrow` --- */