diff --git a/changelog/dmd.deprecation-limit.dd b/changelog/dmd.deprecation-limit.dd new file mode 100644 index 000000000000..fc3364c087f7 --- /dev/null +++ b/changelog/dmd.deprecation-limit.dd @@ -0,0 +1,26 @@ +Deprecation warnings are now also limited by `-verrors` + +By default, the compiler stops after 20 error messages, unless a different amount is specified by passing e.g. `-verrors=50` or `-verrors=0` for no limit. +This error limit now also applies to deprecation messages, so the command line isn't flooded with hundreds of them when compiling a big project that hasn't fixed all deprecations yet. + +--- +deprecated void f() +{ +} + +void main() +{ + f(); + f(); + f(); + f(); +} +--- + +$(CONSOLE +> dmd -verrors=3 app.d +app.d(7): Deprecation: function `deprecationlimit.x` is deprecated +app.d(8): Deprecation: function `deprecationlimit.x` is deprecated +app.d(9): Deprecation: function `deprecationlimit.x` is deprecated +1 deprecation warning omitted, use `-verrors=0` to show all +) diff --git a/compiler/src/dmd/cli.d b/compiler/src/dmd/cli.d index b69fed52ae57..71651d6572ba 100644 --- a/compiler/src/dmd/cli.d +++ b/compiler/src/dmd/cli.d @@ -818,7 +818,7 @@ dmd -cov -unittest myprog.d "limit the number of supplemental messages for each error (0 means unlimited)" ), Option("verrors=", - "limit the number of error messages (0 means unlimited)" + "limit the number of error/deprecation messages (0 means unlimited)" ), Option("verrors=context", "show error messages with the context of the erroring source line" diff --git a/compiler/src/dmd/errors.d b/compiler/src/dmd/errors.d index 704bb9d77e7c..4dd000409fda 100644 --- a/compiler/src/dmd/errors.d +++ b/compiler/src/dmd/errors.d @@ -478,8 +478,12 @@ extern (C++) void verrorReport(const ref Loc loc, const(char)* format, va_list a { if (!global.gag) { - info.headerColor = Classification.deprecation; - verrorPrint(format, ap, info); + global.deprecations++; + if (global.params.v.errorLimit == 0 || global.deprecations <= global.params.v.errorLimit) + { + info.headerColor = Classification.deprecation; + verrorPrint(format, ap, info); + } } else { diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index c4394042077b..d1c1d6358b9f 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -8294,6 +8294,7 @@ struct Global final CompileEnv compileEnv; Param params; uint32_t errors; + uint32_t deprecations; uint32_t warnings; uint32_t gag; uint32_t gaggedErrors; @@ -8324,6 +8325,7 @@ struct Global final compileEnv(), params(), errors(), + deprecations(), warnings(), gag(), gaggedErrors(), @@ -8339,7 +8341,7 @@ struct Global final preprocess() { } - Global(_d_dynamicArray< const char > inifilename, _d_dynamicArray< const char > copyright = { 73, "Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved" }, _d_dynamicArray< const char > written = { 24, "written by Walter Bright" }, Array path = Array(), Array filePath = Array(), CompileEnv compileEnv = CompileEnv(), Param params = Param(), uint32_t errors = 0u, uint32_t warnings = 0u, uint32_t gag = 0u, uint32_t gaggedErrors = 0u, uint32_t gaggedWarnings = 0u, void* console = nullptr, Array versionids = Array(), Array debugids = Array(), bool hasMainFunction = false, uint32_t varSequenceNumber = 1u, FileManager* fileManager = nullptr, ErrorSink* errorSink = nullptr, ErrorSink* errorSinkNull = nullptr, DArray(*preprocess)(FileName , const Loc& , OutBuffer& ) = nullptr) : + Global(_d_dynamicArray< const char > inifilename, _d_dynamicArray< const char > copyright = { 73, "Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved" }, _d_dynamicArray< const char > written = { 24, "written by Walter Bright" }, Array path = Array(), Array filePath = Array(), CompileEnv compileEnv = CompileEnv(), Param params = Param(), uint32_t errors = 0u, uint32_t deprecations = 0u, uint32_t warnings = 0u, uint32_t gag = 0u, uint32_t gaggedErrors = 0u, uint32_t gaggedWarnings = 0u, void* console = nullptr, Array versionids = Array(), Array debugids = Array(), bool hasMainFunction = false, uint32_t varSequenceNumber = 1u, FileManager* fileManager = nullptr, ErrorSink* errorSink = nullptr, ErrorSink* errorSinkNull = nullptr, DArray(*preprocess)(FileName , const Loc& , OutBuffer& ) = nullptr) : inifilename(inifilename), copyright(copyright), written(written), @@ -8348,6 +8350,7 @@ struct Global final compileEnv(compileEnv), params(params), errors(errors), + deprecations(deprecations), warnings(warnings), gag(gag), gaggedErrors(gaggedErrors), diff --git a/compiler/src/dmd/globals.d b/compiler/src/dmd/globals.d index f8291fa5ce7e..c97aeb6d4d08 100644 --- a/compiler/src/dmd/globals.d +++ b/compiler/src/dmd/globals.d @@ -284,6 +284,7 @@ extern (C++) struct Global Param params; /// command line parameters uint errors; /// number of errors reported so far + uint deprecations; /// number of deprecations reported so far uint warnings; /// number of warnings reported so far uint gag; /// !=0 means gag reporting of errors & warnings uint gaggedErrors; /// number of errors reported while gagged diff --git a/compiler/src/dmd/globals.h b/compiler/src/dmd/globals.h index ac2b2867fb7c..bd28d7be7b8b 100644 --- a/compiler/src/dmd/globals.h +++ b/compiler/src/dmd/globals.h @@ -307,6 +307,7 @@ struct Global Param params; unsigned errors; // number of errors reported so far + unsigned deprecations; // number of deprecations reported so far unsigned warnings; // number of warnings reported so far unsigned gag; // !=0 means gag reporting of errors & warnings unsigned gaggedErrors; // number of errors reported while gagged diff --git a/compiler/src/dmd/main.d b/compiler/src/dmd/main.d index 27f79379abae..0485b191aa5c 100644 --- a/compiler/src/dmd/main.d +++ b/compiler/src/dmd/main.d @@ -250,6 +250,18 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) errorSupplemental(Loc.initial, "Use -wi if you wish to treat warnings only as informational."); } + // In case deprecation messages were omitted, inform the user about it + static void mentionOmittedDeprecations() + { + if (global.params.v.errorLimit != 0 && + global.deprecations > global.params.v.errorLimit) + { + const omitted = global.deprecations - global.params.v.errorLimit; + message(Loc.initial, "%d deprecation warning%s omitted, use `-verrors=0` to show all", + omitted, omitted == 1 ? "".ptr : "s".ptr); + } + } + /* Generates code to check for all `params` whether any usage page has been requested. @@ -582,6 +594,9 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) if (global.warnings) errorOnWarning(); + if (global.params.useDeprecated == DiagnosticReporting.inform) + mentionOmittedDeprecations(); + // Do not attempt to generate output files if errors or warnings occurred if (global.errors || global.warnings) removeHdrFilesAndFail(params, modules); diff --git a/compiler/test/compilable/deprecationlimit.d b/compiler/test/compilable/deprecationlimit.d new file mode 100644 index 000000000000..dcdc9e118ca5 --- /dev/null +++ b/compiler/test/compilable/deprecationlimit.d @@ -0,0 +1,22 @@ +/* +REQUIRED_ARGS: -verrors=3 +TEST_OUTPUT: +--- +compilable/deprecationlimit.d(18): Deprecation: function `deprecationlimit.f` is deprecated +compilable/deprecationlimit.d(19): Deprecation: function `deprecationlimit.f` is deprecated +compilable/deprecationlimit.d(20): Deprecation: function `deprecationlimit.f` is deprecated +1 deprecation warning omitted, use `-verrors=0` to show all +--- +*/ + +deprecated void f() +{ +} + +void main() +{ + f(); + f(); + f(); + f(); +} diff --git a/compiler/test/compilable/sw_transition_complex.d b/compiler/test/compilable/sw_transition_complex.d index b6dbc8a34607..3b2735603327 100644 --- a/compiler/test/compilable/sw_transition_complex.d +++ b/compiler/test/compilable/sw_transition_complex.d @@ -1,5 +1,5 @@ // PERMUTE_ARGS: -// REQUIRED_ARGS: -unittest +// REQUIRED_ARGS: -unittest -verrors=0 /* TEST_OUTPUT: diff --git a/compiler/test/runnable/template10.d b/compiler/test/runnable/template10.d index cd6f6fe8b83a..e0bec9be7817 100644 --- a/compiler/test/runnable/template10.d +++ b/compiler/test/runnable/template10.d @@ -1,4 +1,5 @@ // PERMUTE_ARGS: -inline +// REQUIRED_ARGS: -verrors=0 /* TEST_OUTPUT: --- runnable/template10.d(89): Deprecation: function `template10.test1b.f0.f!(a).f` function requires a dual-context, which is deprecated @@ -58,7 +59,6 @@ runnable/template10.d(741): instantiated from here: `fun!(n)` */ /********************************************/ - void test1a() { int a = 1;