[gccrs,COMMIT] gccrs: Add compatible version option
Checks
Commit Message
From: Owen Avery <powerboat9.gamer@gmail.com>
GCCRS targets version 1.49 of rust. However, rust for linux expects rust
1.78 or later (soon 1.85 or later) and we will want to bump our main
target version from 1.49 eventually. This patch adds an option for the
user to specify a rust version to target for compatibility, so that
we can account for backwards incompatible behavior between rust
versions.
This should allow libcore 1.49 to compile without explicitly enabling
post-1.49 features.
gcc/rust/ChangeLog:
* checks/errors/feature/rust-feature-collector.cc: Include
"rust-session-manager.h".
(FeatureCollector::collect): Automatically enable
EXTENDED_KEY_VALUE_ATTRIBUTES when targeting compatibility with
rust versions before 1.50.
* expand/rust-macro-expand.cc: Include "rust-session-manager.h".
(MacroExpander::expand_invoc): Use Session to determine whether
offset_of is supported.
* lang.opt (frust-assume-builtin-offset-of): Remove option,
superseded by...
(frust-compat-version): ...new option.
* resolve/rust-early-name-resolver-2.0.cc: Include
"rust-session-manager.h".
(Early::visit (MacroInvocation)): Use Session to determine
whether offset_of is supported.
* rust-session-manager.cc (Session::handle_option): Handle
frust-compat-version.
* rust-session-manager.h (CompileOptions::compat_version): New
member variable.
(CompileOptions::set_compat_version): New member function.
(CompileOptions::get_compat_version): Likewise.
(Session::get_compat_version): Likewise.
(Session::should_support_offset_of): Likewise.
gcc/testsuite/ChangeLog:
* rust/compile/early_feature_gate_in_macro.rs: Change test
options.
* rust/compile/offset_of1.rs: Likewise.
* rust/compile/offset_of2.rs: Likewise.
* rust/compile/parse_time_feature_gate.rs: Likewise.
* rust/execute/torture/offset_of1.rs: Likewise.
Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github: https://github.com/Rust-GCC/gccrs/commit/5d40f402ffe51bbea5746bab076b8d02e452db30
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4659
.../errors/feature/rust-feature-collector.cc | 6 ++++
gcc/rust/expand/rust-macro-expand.cc | 3 +-
gcc/rust/lang.opt | 6 ++--
.../resolve/rust-early-name-resolver-2.0.cc | 5 ++--
gcc/rust/rust-session-manager.cc | 3 ++
gcc/rust/rust-session-manager.h | 30 +++++++++++++++++++
.../compile/early_feature_gate_in_macro.rs | 1 +
gcc/testsuite/rust/compile/offset_of1.rs | 2 +-
gcc/testsuite/rust/compile/offset_of2.rs | 2 +-
.../rust/compile/parse_time_feature_gate.rs | 1 +
.../rust/execute/torture/offset_of1.rs | 2 +-
11 files changed, 52 insertions(+), 9 deletions(-)
base-commit: 836bd832f52d2becdfaf6c2103cada5bf7054e1b
@@ -18,6 +18,7 @@
#include "rust-feature-collector.h"
#include "rust-attribute-values.h"
+#include "rust-session-manager.h"
namespace Rust {
namespace Features {
@@ -32,6 +33,11 @@ FeatureCollector::collect (AST::Crate &crate)
features.valid_lib_features.clear ();
features.crate_id = crate.get_node_id ();
+ // TODO: this is a hack, remove when possible
+ if (Session::get_instance ().get_compat_version () < 50)
+ features.valid_lang_features.insert (
+ Feature::Name::EXTENDED_KEY_VALUE_ATTRIBUTES);
+
visit (crate);
return features;
@@ -29,6 +29,7 @@
#include "rust-cfg-strip.h"
#include "rust-proc-macro.h"
#include "rust-token-tree-desugar.h"
+#include "rust-session-manager.h"
namespace Rust {
@@ -311,7 +312,7 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc,
// We special case the `offset_of!()` macro if the flag is here and manually
// resolve to the builtin transcriber we have specified
auto assume_builtin_offset_of
- = flag_assume_builtin_offset_of
+ = Session::get_instance ().should_support_offset_of ()
&& (invoc.get_invoc_data ().get_path ().as_string () == "offset_of")
&& !rules_def;
@@ -229,9 +229,9 @@ frust-overflow-checks
Rust Var(flag_overflow_checks) Init(1)
Enable the overflow checks in code generation.
-frust-assume-builtin-offset-of
-Rust Var(flag_assume_builtin_offset_of)
-Define a built-in offset_of macro in the compiler and assume it is present.
+frust-compat-version=
+Rust Joined RejectNegative Var(flag_rust_compat_version)
+Select a version of rust to target for compatibility. Must be of form '1.x' or 'max'.
frust-unused-check-2.0
Rust Var(flag_unused_check_2_0)
@@ -30,6 +30,7 @@
#include "rust-finalize-imports-2.0.h"
#include "rust-attribute-values.h"
#include "rust-identifier-path.h"
+#include "rust-session-manager.h"
namespace Rust {
namespace Resolver2_0 {
@@ -318,8 +319,8 @@ Early::visit (AST::MacroInvocation &invoc)
// We special case the `offset_of!()` macro if the flag is here, otherwise
// we accept whatever `offset_of!()` definition we resolved to.
- auto resolve_offset_of
- = flag_assume_builtin_offset_of && (path.as_string () == "offset_of");
+ auto resolve_offset_of = Session::get_instance ().should_support_offset_of ()
+ && (path.as_string () == "offset_of");
if (invoc.get_kind () == AST::MacroInvocation::InvocKind::Builtin)
for (auto &pending_invoc : invoc.get_pending_eager_invocations ())
@@ -289,6 +289,9 @@ Session::handle_option (
case OPT_frust_edition_:
options.set_edition (flag_rust_edition);
break;
+ case OPT_frust_compat_version_:
+ options.set_compat_version (flag_rust_compat_version);
+ break;
case OPT_frust_compile_until_:
options.set_compile_step (flag_rust_compile_until);
break;
@@ -242,6 +242,8 @@ struct CompileOptions
bool debug_assertions = false;
std::string metadata_output_path;
+ int compat_version = 49;
+
/** Structure containing additional attributes to be injected within the
* compiled crate from the command line instead of the source code.
*
@@ -344,6 +346,30 @@ struct CompileOptions
const Edition &get_edition () const { return edition; }
+ void set_compat_version (const char *version)
+ {
+ if (!strcmp (version, "max"))
+ {
+ compat_version = INT_MAX;
+ return;
+ }
+
+ long res;
+ char *end_ptr;
+ if (version[0] != '1' || version[1] != '.' || version[2] == '\0'
+ || (res = strtol (version + 2, &end_ptr, 10), *end_ptr) || res < 0
+ || res > INT_MAX)
+ {
+ rust_error_at (UNKNOWN_LOCATION,
+ "compat version must be of form 1.x or be \"max\"");
+ return;
+ }
+
+ compat_version = res;
+ }
+
+ int get_compat_version () const { return compat_version; }
+
void set_crate_type (int raw_type) { target_data.set_crate_type (raw_type); }
bool is_proc_macro () const
@@ -474,6 +500,10 @@ public:
tl::expected<LoadedCrate, LoadingError>
load_extern_crate (const std::string &crate_name, location_t locus);
+ int get_compat_version () const { return options.get_compat_version (); }
+
+ bool should_support_offset_of () const { return get_compat_version () >= 71; }
+
private:
Session () : mappings (Analysis::Mappings::get ()) {}
void compile_crate (const char *filename);
@@ -1,3 +1,4 @@
+// { dg-additional-options "-frust-compat-version=1.50" }
#![feature(rustc_attrs)]
#![feature(lang_items)]
#![feature(no_core)]
@@ -1,4 +1,4 @@
-// { dg-additional-options "-frust-compile-until=lowering -frust-assume-builtin-offset-of" }
+// { dg-additional-options "-frust-compile-until=lowering -frust-compat-version=1.71" }
#![feature(no_core)]
#![no_core]
@@ -1,4 +1,4 @@
-// { dg-additional-options "-frust-compile-until=compilation -frust-assume-builtin-offset-of" }
+// { dg-additional-options "-frust-compile-until=compilation -frust-compat-version=1.71" }
#![feature(no_core)]
#![no_core]
@@ -1,3 +1,4 @@
+// { dg-additional-options "-frust-compat-version=1.50" }
#![feature(no_core)]
#![no_core]
#![feature(rustc_attrs)]
@@ -1,5 +1,5 @@
// { dg-do run { target x86_64*-*-* } }
-// { dg-additional-options "-frust-assume-builtin-offset-of" }
+// { dg-additional-options "-frust-compat-version=1.71" }
#![feature(no_core)]
#![no_core]