From 400dd0134d43b8c5aeb59879150465e76b152c08 Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Wed, 27 Mar 2024 14:21:24 +0100 Subject: [PATCH] Start implementation of editions --- compiler/src/dmd/astenums.d | 9 +++++++++ compiler/src/dmd/dmodule.d | 3 +++ compiler/src/dmd/dscope.d | 10 ++++++++-- compiler/src/dmd/frontend.h | 9 +++++++++ compiler/src/dmd/id.d | 3 +++ compiler/src/dmd/module.h | 9 +++++++++ compiler/src/dmd/parse.d | 9 +++++++++ compiler/test/fail_compilation/editions.d | 16 ++++++++++++++++ 8 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 compiler/test/fail_compilation/editions.d diff --git a/compiler/src/dmd/astenums.d b/compiler/src/dmd/astenums.d index 3a2d65735cd0..1e30b9f8fc25 100644 --- a/compiler/src/dmd/astenums.d +++ b/compiler/src/dmd/astenums.d @@ -18,6 +18,15 @@ enum Sizeok : ubyte done, /// size of aggregate is set correctly } +/// D Language version +enum Edition : ubyte +{ + none, + legacy, /// Before the introduction of editions + v2024, /// Experimental first new edition + latest = v2024 /// Newest edition that this compiler knows of +} + enum Baseok : ubyte { none, /// base classes not computed yet diff --git a/compiler/src/dmd/dmodule.d b/compiler/src/dmd/dmodule.d index 4f84eec7c0db..a1a337bd3a52 100644 --- a/compiler/src/dmd/dmodule.d +++ b/compiler/src/dmd/dmodule.d @@ -358,6 +358,7 @@ extern (C++) final class Module : Package FileType filetype; // source file type bool hasAlwaysInlines; // contains references to functions that must be inlined bool isPackageFile; // if it is a package.d + Edition edition; // language edition that this module is compiled with Package pkg; // if isPackageFile is true, the Package that contains this package.d Strings contentImportedFiles; // array of files whose content was imported int needmoduleinfo; @@ -477,6 +478,8 @@ extern (C++) final class Module : Package setDocfile(); if (doHdrGen) hdrfile = setOutfilename(global.params.dihdr.name, global.params.dihdr.dir, arg, hdr_ext); + + this.edition = Edition.legacy; } extern (D) this(const(char)[] filename, Identifier ident, int doDocComment, int doHdrGen) diff --git a/compiler/src/dmd/dscope.d b/compiler/src/dmd/dscope.d index 76a26a245fb4..471952955478 100644 --- a/compiler/src/dmd/dscope.d +++ b/compiler/src/dmd/dscope.d @@ -830,12 +830,18 @@ extern (C++) struct Scope /// Returns: whether to raise DIP1000 warnings (FeatureStabe.default) or errors (FeatureState.enabled) extern (D) FeatureState useDIP1000() { - return (flags & SCOPE.dip1000) ? FeatureState.enabled : FeatureState.disabled; + return (flags & SCOPE.dip1000 || hasEdition(Edition.v2024)) ? FeatureState.enabled : FeatureState.disabled; } /// Returns: whether to raise DIP25 warnings (FeatureStabe.default) or errors (FeatureState.enabled) extern (D) FeatureState useDIP25() { - return (flags & SCOPE.dip25) ? FeatureState.enabled : FeatureState.disabled; + return (flags & SCOPE.dip25 || hasEdition(Edition.v2024)) ? FeatureState.enabled : FeatureState.disabled; + } + + /// Returns: whether this scope compiles with `edition` or later + extern (D) bool hasEdition(Edition edition) + { + return _module && _module.edition >= edition; } } diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 22e02c382f29..0bbabafbcf34 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -834,6 +834,14 @@ enum class FileType : uint8_t c = 3u, }; +enum class Edition : uint8_t +{ + none = 0u, + legacy = 1u, + v2024 = 2u, + latest = 2u, +}; + struct OutBuffer final { private: @@ -7073,6 +7081,7 @@ class Module final : public Package FileType filetype; bool hasAlwaysInlines; bool isPackageFile; + Edition edition; Package* pkg; Array contentImportedFiles; int32_t needmoduleinfo; diff --git a/compiler/src/dmd/id.d b/compiler/src/dmd/id.d index 9dcf2f5d4732..6dbc60b020cc 100644 --- a/compiler/src/dmd/id.d +++ b/compiler/src/dmd/id.d @@ -531,6 +531,9 @@ immutable Msgtable[] msgtable = { "udaMustUse", "mustuse" }, { "udaStandalone", "standalone" }, + // Editions + { "__edition_latest_do_not_use", }, + // C names, for undefined identifier error messages { "NULL" }, { "TRUE" }, diff --git a/compiler/src/dmd/module.h b/compiler/src/dmd/module.h index 379e8e6973aa..7f02bec2f3a0 100644 --- a/compiler/src/dmd/module.h +++ b/compiler/src/dmd/module.h @@ -28,6 +28,14 @@ enum PKG PKGpackage // already determined that's an actual package }; +enum class Edition : unsigned char +{ + none = 0u, + legacy = 1u, + v2024 = 2u, + latest = 2u, +}; + class Package : public ScopeDsymbol { public: @@ -75,6 +83,7 @@ class Module final : public Package FileType filetype; // source file type d_bool hasAlwaysInlines; // contains references to functions that must be inlined d_bool isPackageFile; // if it is a package.d + Edition edition; // language edition that this module is compiled with Package *pkg; // if isPackageFile is true, the Package that contains this package.d Strings contentImportedFiles; // array of files whose content was imported int needmoduleinfo; diff --git a/compiler/src/dmd/parse.d b/compiler/src/dmd/parse.d index 646c4b7d3dbc..f3a844dff2ea 100644 --- a/compiler/src/dmd/parse.d +++ b/compiler/src/dmd/parse.d @@ -233,6 +233,15 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } else { + static if (is(typeof(mod.edition))) + if (exps && exps.length > 0) + if (auto id = (*exps)[0].isIdentifierExp()) + if (id.ident == Id.__edition_latest_do_not_use) + { + mod.edition = Edition.latest; + continue; + } + udas = AST.UserAttributeDeclaration.concat(udas, exps); } if (stc) diff --git a/compiler/test/fail_compilation/editions.d b/compiler/test/fail_compilation/editions.d new file mode 100644 index 000000000000..869ee22c11cb --- /dev/null +++ b/compiler/test/fail_compilation/editions.d @@ -0,0 +1,16 @@ +/** +Test language editions (currently experimental) + +TEST_OUTPUT: +--- +fail_compilation/editions.d(15): Error: scope parameter `x` may not be returned +--- +*/ +@__edition_latest_do_not_use +module editions; + +@safe: +int* f(scope int* x) +{ + return x; +}