aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/checks
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/checks')
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h65
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc47
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h16
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-function-collector.h10
-rw-r--r--gcc/rust/checks/errors/feature/contrib/.gitignore1
-rw-r--r--gcc/rust/checks/errors/feature/contrib/Makefile59
-rw-r--r--gcc/rust/checks/errors/feature/contrib/README3
-rw-r--r--gcc/rust/checks/errors/feature/contrib/copyright-stub.h19
-rwxr-xr-xgcc/rust/checks/errors/feature/contrib/fetch30
-rw-r--r--gcc/rust/checks/errors/feature/contrib/parse.y143
-rwxr-xr-xgcc/rust/checks/errors/feature/contrib/regen23
-rw-r--r--gcc/rust/checks/errors/feature/contrib/scan.l55
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature-defs.h600
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature-gate.cc (renamed from gcc/rust/checks/errors/rust-feature-gate.cc)144
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature-gate.h (renamed from gcc/rust/checks/errors/rust-feature-gate.h)19
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature.cc100
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature.h85
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-check.cc9
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc56
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.h7
-rw-r--r--gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc29
-rw-r--r--gcc/rust/checks/errors/privacy/rust-visibility-resolver.h6
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.cc16
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.h10
-rw-r--r--gcc/rust/checks/errors/rust-feature.cc98
-rw-r--r--gcc/rust/checks/errors/rust-feature.h89
-rw-r--r--gcc/rust/checks/errors/rust-hir-pattern-analysis.cc86
-rw-r--r--gcc/rust/checks/errors/rust-hir-pattern-analysis.h14
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check.cc340
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check.h59
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check2.cc253
-rw-r--r--gcc/rust/checks/errors/rust-readonly-check2.h67
-rw-r--r--gcc/rust/checks/errors/rust-unsafe-checker.cc16
-rw-r--r--gcc/rust/checks/errors/rust-unsafe-checker.h10
-rw-r--r--gcc/rust/checks/lints/rust-lint-marklive-base.h3
35 files changed, 1712 insertions, 875 deletions
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
index e2cc2dd..de8a830 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -24,7 +24,6 @@
#include "rust-hir-item.h"
#include "rust-hir-type-check.h"
#include "rust-hir-visitor.h"
-#include "rust-name-resolver.h"
#include "rust-bir.h"
#include "rust-bir-free-region.h"
#include "rust-immutable-name-resolution-context.h"
@@ -75,7 +74,7 @@ struct BuilderContext
// External context.
Resolver::TypeCheckContext &tyctx;
- Resolver::Resolver &resolver;
+ const Resolver2_0::NameResolutionContext &resolver;
// BIR output
BasicBlocks basic_blocks;
@@ -104,7 +103,7 @@ struct BuilderContext
public:
BuilderContext ()
: tyctx (*Resolver::TypeCheckContext::get ()),
- resolver (*Resolver::Resolver::get ())
+ resolver (Resolver2_0::ImmutableNameResolutionContext::get ().resolver ())
{
basic_blocks.emplace_back (); // StartBB
}
@@ -403,69 +402,31 @@ protected: // HIR resolution helpers
template <typename T> NodeId resolve_label (T &expr)
{
- NodeId resolved_label;
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto res = nr_ctx.lookup (expr.get_mappings ().get_nodeid ());
- rust_assert (res.has_value ());
- resolved_label = res.value ();
- }
- else
- {
- bool ok = ctx.resolver.lookup_resolved_label (
- expr.get_mappings ().get_nodeid (), &resolved_label);
- rust_assert (ok);
- }
- return resolved_label;
+ auto res = ctx.resolver.lookup (expr.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ return res.value ();
}
template <typename T> PlaceId resolve_variable (T &variable)
{
- NodeId variable_id;
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ());
- rust_assert (res.has_value ());
- variable_id = res.value ();
- }
- else
- {
- bool ok = ctx.resolver.lookup_resolved_name (
- variable.get_mappings ().get_nodeid (), &variable_id);
- rust_assert (ok);
- }
- return ctx.place_db.lookup_variable (variable_id);
+ auto res = ctx.resolver.lookup (variable.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ return ctx.place_db.lookup_variable (res.value ());
}
template <typename T>
PlaceId resolve_variable_or_fn (T &variable, TyTy::BaseType *ty)
{
ty = (ty) ? ty : lookup_type (variable);
+
// Unlike variables,
// functions do not have to be declared in PlaceDB before use.
- NodeId variable_id;
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ());
- rust_assert (res.has_value ());
- variable_id = res.value ();
- }
- else
- {
- bool ok = ctx.resolver.lookup_resolved_name (
- variable.get_mappings ().get_nodeid (), &variable_id);
- rust_assert (ok);
- }
if (ty->is<TyTy::FnType> ())
return ctx.place_db.get_constant (ty);
- else
- return ctx.place_db.lookup_or_add_variable (variable_id, ty);
+
+ auto res = ctx.resolver.lookup (variable.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ return ctx.place_db.lookup_or_add_variable (res.value (), ty);
}
protected: // Implicit conversions.
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
index 2d655f9..e78d750 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
@@ -70,11 +70,34 @@ PatternBindingBuilder::visit (HIR::SlicePattern &pattern)
return ty->as<TyTy::SliceType> ()->get_element_type ();
});
- // Regions are unchnaged.
+ // Regions are unchanged.
- for (auto &item : pattern.get_items ())
+ switch (pattern.get_items ().get_item_type ())
{
- item->accept_vis (*this);
+ case HIR::SlicePatternItems::NO_REST:
+ {
+ auto &items
+ = static_cast<HIR::SlicePatternItemsNoRest &> (pattern.get_items ());
+ for (auto &member : items.get_patterns ())
+ {
+ member->accept_vis (*this);
+ }
+ break;
+ }
+ case HIR::SlicePatternItems::HAS_REST:
+ {
+ auto &items
+ = static_cast<HIR::SlicePatternItemsHasRest &> (pattern.get_items ());
+ for (auto &member : items.get_lower_patterns ())
+ {
+ member->accept_vis (*this);
+ }
+ for (auto &member : items.get_upper_patterns ())
+ {
+ member->accept_vis (*this);
+ }
+ break;
+ }
}
}
@@ -202,17 +225,17 @@ PatternBindingBuilder::visit (HIR::TuplePattern &pattern)
size_t index = 0;
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::MULTIPLE:
+ case HIR::TuplePatternItems::NO_REST:
{
- auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- pattern.get_items ());
+ auto &items
+ = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
- case HIR::TuplePatternItems::RANGED:
+ case HIR::TuplePatternItems::HAS_REST:
{
auto &items
- = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+ = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
auto tyty = ctx.place_db[init.value ()].tyty;
rust_assert (tyty->get_kind () == TyTy::TUPLE);
@@ -249,10 +272,10 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
size_t index = 0;
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TupleStructItems::RANGED:
+ case HIR::TupleStructItems::HAS_REST:
{
auto &items
- = static_cast<HIR::TupleStructItemsRange &> (pattern.get_items ());
+ = static_cast<HIR::TupleStructItemsHasRest &> (pattern.get_items ());
rust_assert (type->get_kind () == TyTy::ADT);
auto adt_ty = static_cast<TyTy::ADTType *> (type);
@@ -267,10 +290,10 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
visit_tuple_fields (items.get_upper_patterns (), saved, index);
break;
}
- case HIR::TupleStructItems::MULTIPLE:
+ case HIR::TupleStructItems::NO_REST:
{
auto &items
- = static_cast<HIR::TupleStructItemsNoRange &> (pattern.get_items ());
+ = static_cast<HIR::TupleStructItemsNoRest &> (pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index d87ff8c..6cb87c7 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -225,11 +225,11 @@ protected:
rust_unreachable ();
}
void visit (HIR::StructPattern &pattern) override { rust_unreachable (); }
- void visit (HIR::TupleStructItemsNoRange &tuple_items) override
+ void visit (HIR::TupleStructItemsNoRest &tuple_items) override
{
rust_unreachable ();
}
- void visit (HIR::TupleStructItemsRange &tuple_items) override
+ void visit (HIR::TupleStructItemsHasRest &tuple_items) override
{
rust_unreachable ();
}
@@ -237,15 +237,23 @@ protected:
{
rust_unreachable ();
}
- void visit (HIR::TuplePatternItemsMultiple &tuple_items) override
+ void visit (HIR::TuplePatternItemsNoRest &tuple_items) override
{
rust_unreachable ();
}
- void visit (HIR::TuplePatternItemsRanged &tuple_items) override
+ void visit (HIR::TuplePatternItemsHasRest &tuple_items) override
{
rust_unreachable ();
}
void visit (HIR::TuplePattern &pattern) override { rust_unreachable (); }
+ void visit (HIR::SlicePatternItemsNoRest &tuple_items) override
+ {
+ rust_unreachable ();
+ }
+ void visit (HIR::SlicePatternItemsHasRest &tuple_items) override
+ {
+ rust_unreachable ();
+ }
void visit (HIR::SlicePattern &pattern) override { rust_unreachable (); }
void visit (HIR::AltPattern &pattern) override { rust_unreachable (); }
void visit (HIR::EmptyStmt &stmt) override { rust_unreachable (); }
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index 86f96c1..63f2a95 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -170,12 +170,14 @@ public:
void visit (HIR::StructPatternFieldIdentPat &field) override {}
void visit (HIR::StructPatternFieldIdent &field) override {}
void visit (HIR::StructPattern &pattern) override {}
- void visit (HIR::TupleStructItemsNoRange &tuple_items) override {}
- void visit (HIR::TupleStructItemsRange &tuple_items) override {}
+ void visit (HIR::TupleStructItemsNoRest &tuple_items) override {}
+ void visit (HIR::TupleStructItemsHasRest &tuple_items) override {}
void visit (HIR::TupleStructPattern &pattern) override {}
- void visit (HIR::TuplePatternItemsMultiple &tuple_items) override {}
- void visit (HIR::TuplePatternItemsRanged &tuple_items) override {}
+ void visit (HIR::TuplePatternItemsNoRest &tuple_items) override {}
+ void visit (HIR::TuplePatternItemsHasRest &tuple_items) override {}
void visit (HIR::TuplePattern &pattern) override {}
+ void visit (HIR::SlicePatternItemsNoRest &tuple_items) override {}
+ void visit (HIR::SlicePatternItemsHasRest &tuple_items) override {}
void visit (HIR::SlicePattern &pattern) override {}
void visit (HIR::AltPattern &pattern) override {}
void visit (HIR::EmptyStmt &stmt) override {}
diff --git a/gcc/rust/checks/errors/feature/contrib/.gitignore b/gcc/rust/checks/errors/feature/contrib/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/contrib/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/gcc/rust/checks/errors/feature/contrib/Makefile b/gcc/rust/checks/errors/feature/contrib/Makefile
new file mode 100644
index 0000000..7c828ab
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/contrib/Makefile
@@ -0,0 +1,59 @@
+# Copyright (C) 2025 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+OUT = ../rust-feature-defs.h
+
+all: $(OUT)
+
+mk-build-dir:
+ mkdir -p build
+
+build/parse.c: parse.y mk-build-dir
+ $(YACC) $(YFLAGS) -o $@ --defines=build/parse.h $<
+
+build/parse.h: build/parse.c;
+
+build/scan.c: scan.l
+ $(LEX) $(LFLAGS) -o $@ -Ca --header-file=build/scan.h $<
+
+build/scan.h: build/scan.c;
+
+build/%.o: build/%.c build/parse.h build/scan.h
+ $(CC) $(CFLAGS) -c -Ibuild -o $@ $<
+
+build/feature-extract: build/parse.o build/scan.o
+ $(CC) $(LDFLAGS) $(LDLIBS) -o $@ $^
+
+build/download.rs: fetch
+ ./$< $@
+
+$(OUT): build/feature-extract build/download.rs
+ # add copyright header + newline
+ echo | \
+ cat copyright-stub.h - | \
+ sed "s/YYYY/$$(date +%Y)/" > build/rust-feature-defs.h
+ cat build/download.rs | ./$< >> build/rust-feature-defs.h
+ clang-format -i build/rust-feature-defs.h \
+ --style=file:../../../../../../contrib/clang-format
+ mv build/rust-feature-defs.h $(OUT)
+
+clean:
+ $(RM) -r build
+
+clean-all: clean
+ $(RM) $(OUT)
diff --git a/gcc/rust/checks/errors/feature/contrib/README b/gcc/rust/checks/errors/feature/contrib/README
new file mode 100644
index 0000000..e85fe09
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/contrib/README
@@ -0,0 +1,3 @@
+This program is intended for use in generating rust-feature-defs.h
+
+To use, run `./regen`
diff --git a/gcc/rust/checks/errors/feature/contrib/copyright-stub.h b/gcc/rust/checks/errors/feature/contrib/copyright-stub.h
new file mode 100644
index 0000000..1a5f52c
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/contrib/copyright-stub.h
@@ -0,0 +1,19 @@
+// Copyright (C) YYYY Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// AUTO-GENERATED -- SEE LOCAL contrib SUBDIRECTORY
diff --git a/gcc/rust/checks/errors/feature/contrib/fetch b/gcc/rust/checks/errors/feature/contrib/fetch
new file mode 100755
index 0000000..b26ed3c
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/contrib/fetch
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# Copyright (C) 2025 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+RUST_VERSION="1.49.0"
+
+[ $# = 1 ] || exit 1
+
+# Fetches files from the official rustc git repository
+
+URL_PREFIX='https://raw.githubusercontent.com/rust-lang/rust/refs/tags'
+URL_TEMPLATE="$URL_PREFIX/$RUST_VERSION/compiler/rustc_feature/src"
+
+wget -O $1 "$URL_TEMPLATE"/{accepted,active,removed}.rs
diff --git a/gcc/rust/checks/errors/feature/contrib/parse.y b/gcc/rust/checks/errors/feature/contrib/parse.y
new file mode 100644
index 0000000..34c0138
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/contrib/parse.y
@@ -0,0 +1,143 @@
+/* Copyright (C) 2025 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+%{
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+int yylex (void);
+void yyerror (char const *);
+
+#include "scan.h"
+
+// expands to three %s parameters
+#define UNWRAP_OPT_STR(prefix, s) (s ? prefix "_SOME (" : prefix "_NONE"), (s ? s : ""), (s ? ")" : "")
+
+%}
+
+%union
+{
+ char *str;
+};
+
+%token <str> IDENT STR NUM
+%token SCOPE
+%token K_SOME K_NONE
+%token K_ACTIVE K_ACCEPTED K_REMOVED K_STABLE_REMOVED
+%token K_E_START K_E_2018
+
+%type <str> issue
+%type <str> edition
+%type <str> reason
+
+%%
+
+multi_database: multi_database database
+| database
+;
+
+database: '(' entry_list ')';
+
+entry_list: entry_list entry ','
+| entry ','
+;
+
+entry: '(' K_ACTIVE ',' IDENT ',' STR ',' issue ',' edition ')' {
+ char *ident_upper = strdup ($4);
+ for (size_t i = 0; ident_upper[i]; i++)
+ ident_upper[i] = toupper (ident_upper[i]);
+ printf ("FEATURE_ACTIVE (\"%s\", %s, %s, %s%s%s, EDITION_%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8), $10 ? $10 : "NONE");
+ free ($4);
+ free (ident_upper);
+ free ($6);
+ free ($8);
+}
+| '(' K_ACCEPTED ',' IDENT ',' STR ',' issue ',' K_NONE ')' {
+ char *ident_upper = strdup ($4);
+ for (size_t i = 0; ident_upper[i]; i++)
+ ident_upper[i] = toupper (ident_upper[i]);
+ printf ("FEATURE_ACCEPTED (\"%s\", %s, %s, %s%s%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8));
+ free ($4);
+ free (ident_upper);
+ free ($6);
+ free ($8);
+}
+| '(' K_REMOVED ',' IDENT ',' STR ',' issue ',' K_NONE ',' reason ')' {
+ char *ident_upper;
+ // HACK: convert no_debug to F_NO_DEBUG instead
+ // since NO_DEBUG is used as an unrelated macro
+ if (!strcmp ($4, "no_debug"))
+ {
+ ident_upper = strdup ("F_NO_DEBUG");
+ }
+ else
+ {
+ ident_upper = strdup ($4);
+ for (size_t i = 0; ident_upper[i]; i++)
+ ident_upper[i] = toupper (ident_upper[i]);
+ }
+ printf ("FEATURE_REMOVED (\"%s\", %s, %s, %s%s%s, %s%s%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8), UNWRAP_OPT_STR ("REASON", $12));
+ free ($4);
+ free (ident_upper);
+ free ($6);
+ free ($8);
+ free ($12);
+}
+| '(' K_STABLE_REMOVED ',' IDENT ',' STR ',' issue ',' K_NONE ')' {
+ char *ident_upper = strdup ($4);
+ for (size_t i = 0; ident_upper[i]; i++)
+ ident_upper[i] = toupper (ident_upper[i]);
+ printf ("FEATURE_STABLE_REMOVED (\"%s\", %s, %s, %s%s%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8));
+ free ($4);
+ free (ident_upper);
+ free ($6);
+ free ($8);
+}
+;
+
+issue: K_SOME '(' NUM ')' { $$ = $3; }
+| K_NONE { $$ = NULL; }
+;
+
+/* TODO: expand this as needed */
+edition: K_NONE { $$ = NULL; }
+| K_SOME '(' K_E_START SCOPE K_E_2018 ')' { $$ = "2018"; }
+;
+
+reason: K_SOME '(' STR ')' { $$ = $3; }
+| K_NONE { $$ = NULL; }
+;
+
+%%
+
+void yyerror (const char *msg)
+{
+ fprintf (stderr, "%s\n", msg);
+}
+
+int yywrap (void)
+{
+ return 1;
+}
+
+int main (void)
+{
+ return yyparse ();
+}
diff --git a/gcc/rust/checks/errors/feature/contrib/regen b/gcc/rust/checks/errors/feature/contrib/regen
new file mode 100755
index 0000000..0dc6cc5
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/contrib/regen
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Copyright (C) 2025 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+cd "$(dirname "$0")"
+rm -f ../rust-feature-defs.h
+make all
diff --git a/gcc/rust/checks/errors/feature/contrib/scan.l b/gcc/rust/checks/errors/feature/contrib/scan.l
new file mode 100644
index 0000000..768f4c7
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/contrib/scan.l
@@ -0,0 +1,55 @@
+/* Copyright (C) 2025 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+%{
+
+#include "parse.h"
+
+static int p_count = 0;
+
+%}
+
+%x INSIDE COMMENT
+
+%%
+
+declare_features! BEGIN (INSIDE);
+.|\n /* ignore */
+
+<INSIDE>\( p_count++; return '(';
+<INSIDE>\) if (!--p_count) { BEGIN (0); } return ')';
+<INSIDE>, return ',';
+<INSIDE>:: return SCOPE;
+<INSIDE>Some return K_SOME;
+<INSIDE>None return K_NONE;
+<INSIDE>active return K_ACTIVE;
+<INSIDE>accepted return K_ACCEPTED;
+<INSIDE>removed return K_REMOVED;
+<INSIDE>stable_removed return K_STABLE_REMOVED;
+<INSIDE>Edition return K_E_START;
+<INSIDE>Edition2018 return K_E_2018;
+
+<INSIDE>[A-Za-z_][A-Za-z0-9_]* yylval.str = strdup (yytext); return IDENT;
+<INSIDE>[1-9][0-9]* yylval.str = strdup (yytext); return NUM;
+<INSIDE>\"[^"]+\" yylval.str = strdup (yytext); return STR;
+<INSIDE>"/""/" BEGIN (COMMENT);
+<INSIDE>[ \n] /* ignore */
+<INSIDE>. { fprintf (stderr, "unrecognized character %u\n", (unsigned int) yytext[0]); exit (1); }
+
+<COMMENT>. /* skip */
+<COMMENT>\n BEGIN (INSIDE);
diff --git a/gcc/rust/checks/errors/feature/rust-feature-defs.h b/gcc/rust/checks/errors/feature/rust-feature-defs.h
new file mode 100644
index 0000000..d8514e1
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/rust-feature-defs.h
@@ -0,0 +1,600 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// AUTO-GENERATED -- SEE LOCAL contrib SUBDIRECTORY
+
+FEATURE_ACCEPTED ("issue_5723_bootstrap", ISSUE_5723_BOOTSTRAP, "1.0.0",
+ ISSUE_NONE)
+FEATURE_ACCEPTED ("test_accepted_feature", TEST_ACCEPTED_FEATURE, "1.0.0",
+ ISSUE_NONE)
+FEATURE_ACCEPTED ("associated_types", ASSOCIATED_TYPES, "1.0.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("default_type_params", DEFAULT_TYPE_PARAMS, "1.0.0",
+ ISSUE_NONE)
+FEATURE_ACCEPTED ("globs", GLOBS, "1.0.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("macro_rules", MACRO_RULES, "1.0.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("slicing_syntax", SLICING_SYNTAX, "1.0.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("struct_variant", STRUCT_VARIANT, "1.0.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("tuple_indexing", TUPLE_INDEXING, "1.0.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("if_let", IF_LET, "1.0.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("while_let", WHILE_LET, "1.0.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("no_std", NO_STD, "1.6.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("augmented_assignments", AUGMENTED_ASSIGNMENTS, "1.8.0",
+ ISSUE_SOME (28235))
+FEATURE_ACCEPTED ("braced_empty_structs", BRACED_EMPTY_STRUCTS, "1.8.0",
+ ISSUE_SOME (29720))
+FEATURE_ACCEPTED ("deprecated", DEPRECATED, "1.9.0", ISSUE_SOME (29935))
+FEATURE_ACCEPTED ("type_macros", TYPE_MACROS, "1.13.0", ISSUE_SOME (27245))
+FEATURE_ACCEPTED ("question_mark", QUESTION_MARK, "1.13.0", ISSUE_SOME (31436))
+FEATURE_ACCEPTED ("dotdot_in_tuple_patterns", DOTDOT_IN_TUPLE_PATTERNS,
+ "1.14.0", ISSUE_SOME (33627))
+FEATURE_ACCEPTED ("item_like_imports", ITEM_LIKE_IMPORTS, "1.15.0",
+ ISSUE_SOME (35120))
+FEATURE_ACCEPTED ("more_struct_aliases", MORE_STRUCT_ALIASES, "1.16.0",
+ ISSUE_SOME (37544))
+FEATURE_ACCEPTED ("static_in_const", STATIC_IN_CONST, "1.17.0",
+ ISSUE_SOME (35897))
+FEATURE_ACCEPTED ("field_init_shorthand", FIELD_INIT_SHORTHAND, "1.17.0",
+ ISSUE_SOME (37340))
+FEATURE_ACCEPTED ("static_recursion", STATIC_RECURSION, "1.17.0",
+ ISSUE_SOME (29719))
+FEATURE_ACCEPTED ("pub_restricted", PUB_RESTRICTED, "1.18.0",
+ ISSUE_SOME (32409))
+FEATURE_ACCEPTED ("windows_subsystem", WINDOWS_SUBSYSTEM, "1.18.0",
+ ISSUE_SOME (37499))
+FEATURE_ACCEPTED ("loop_break_value", LOOP_BREAK_VALUE, "1.19.0",
+ ISSUE_SOME (37339))
+FEATURE_ACCEPTED ("relaxed_adts", RELAXED_ADTS, "1.19.0", ISSUE_SOME (35626))
+FEATURE_ACCEPTED ("closure_to_fn_coercion", CLOSURE_TO_FN_COERCION, "1.19.0",
+ ISSUE_SOME (39817))
+FEATURE_ACCEPTED ("struct_field_attributes", STRUCT_FIELD_ATTRIBUTES, "1.20.0",
+ ISSUE_SOME (38814))
+FEATURE_ACCEPTED ("associated_consts", ASSOCIATED_CONSTS, "1.20.0",
+ ISSUE_SOME (29646))
+FEATURE_ACCEPTED ("compile_error", COMPILE_ERROR, "1.20.0", ISSUE_SOME (40872))
+FEATURE_ACCEPTED ("rvalue_static_promotion", RVALUE_STATIC_PROMOTION, "1.21.0",
+ ISSUE_SOME (38865))
+FEATURE_ACCEPTED ("drop_types_in_const", DROP_TYPES_IN_CONST, "1.22.0",
+ ISSUE_SOME (33156))
+FEATURE_ACCEPTED ("abi_sysv64", ABI_SYSV64, "1.24.0", ISSUE_SOME (36167))
+FEATURE_ACCEPTED ("repr_align", REPR_ALIGN, "1.25.0", ISSUE_SOME (33626))
+FEATURE_ACCEPTED ("match_beginning_vert", MATCH_BEGINNING_VERT, "1.25.0",
+ ISSUE_SOME (44101))
+FEATURE_ACCEPTED ("use_nested_groups", USE_NESTED_GROUPS, "1.25.0",
+ ISSUE_SOME (44494))
+FEATURE_ACCEPTED ("const_indexing", CONST_INDEXING, "1.26.0",
+ ISSUE_SOME (29947))
+FEATURE_ACCEPTED ("inclusive_range_syntax", INCLUSIVE_RANGE_SYNTAX, "1.26.0",
+ ISSUE_SOME (28237))
+FEATURE_ACCEPTED ("dotdoteq_in_patterns", DOTDOTEQ_IN_PATTERNS, "1.26.0",
+ ISSUE_SOME (28237))
+FEATURE_ACCEPTED ("termination_trait", TERMINATION_TRAIT, "1.26.0",
+ ISSUE_SOME (43301))
+FEATURE_ACCEPTED ("clone_closures", CLONE_CLOSURES, "1.26.0",
+ ISSUE_SOME (44490))
+FEATURE_ACCEPTED ("copy_closures", COPY_CLOSURES, "1.26.0", ISSUE_SOME (44490))
+FEATURE_ACCEPTED ("universal_impl_trait", UNIVERSAL_IMPL_TRAIT, "1.26.0",
+ ISSUE_SOME (34511))
+FEATURE_ACCEPTED ("conservative_impl_trait", CONSERVATIVE_IMPL_TRAIT, "1.26.0",
+ ISSUE_SOME (34511))
+FEATURE_ACCEPTED ("i128_type", I128_TYPE, "1.26.0", ISSUE_SOME (35118))
+FEATURE_ACCEPTED ("match_default_bindings", MATCH_DEFAULT_BINDINGS, "1.26.0",
+ ISSUE_SOME (42640))
+FEATURE_ACCEPTED ("underscore_lifetimes", UNDERSCORE_LIFETIMES, "1.26.0",
+ ISSUE_SOME (44524))
+FEATURE_ACCEPTED ("generic_param_attrs", GENERIC_PARAM_ATTRS, "1.27.0",
+ ISSUE_SOME (48848))
+FEATURE_ACCEPTED ("cfg_target_feature", CFG_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (29717))
+FEATURE_ACCEPTED ("target_feature", TARGET_FEATURE, "1.27.0", ISSUE_NONE)
+FEATURE_ACCEPTED ("dyn_trait", DYN_TRAIT, "1.27.0", ISSUE_SOME (44662))
+FEATURE_ACCEPTED ("fn_must_use", FN_MUST_USE, "1.27.0", ISSUE_SOME (43302))
+FEATURE_ACCEPTED ("macro_lifetime_matcher", MACRO_LIFETIME_MATCHER, "1.27.0",
+ ISSUE_SOME (34303))
+FEATURE_ACCEPTED ("termination_trait_test", TERMINATION_TRAIT_TEST, "1.27.0",
+ ISSUE_SOME (48854))
+FEATURE_ACCEPTED ("global_allocator", GLOBAL_ALLOCATOR, "1.28.0",
+ ISSUE_SOME (27389))
+FEATURE_ACCEPTED ("repr_transparent", REPR_TRANSPARENT, "1.28.0",
+ ISSUE_SOME (43036))
+FEATURE_ACCEPTED ("proc_macro", PROC_MACRO, "1.29.0", ISSUE_SOME (38356))
+FEATURE_ACCEPTED ("non_modrs_mods", NON_MODRS_MODS, "1.30.0",
+ ISSUE_SOME (44660))
+FEATURE_ACCEPTED ("macro_vis_matcher", MACRO_VIS_MATCHER, "1.30.0",
+ ISSUE_SOME (41022))
+FEATURE_ACCEPTED ("use_extern_macros", USE_EXTERN_MACROS, "1.30.0",
+ ISSUE_SOME (35896))
+FEATURE_ACCEPTED ("raw_identifiers", RAW_IDENTIFIERS, "1.30.0",
+ ISSUE_SOME (48589))
+FEATURE_ACCEPTED ("tool_attributes", TOOL_ATTRIBUTES, "1.30.0",
+ ISSUE_SOME (44690))
+FEATURE_ACCEPTED ("proc_macro_path_invoc", PROC_MACRO_PATH_INVOC, "1.30.0",
+ ISSUE_SOME (38356))
+FEATURE_ACCEPTED ("attr_literals", ATTR_LITERALS, "1.30.0", ISSUE_SOME (34981))
+FEATURE_ACCEPTED ("infer_outlives_requirements", INFER_OUTLIVES_REQUIREMENTS,
+ "1.30.0", ISSUE_SOME (44493))
+FEATURE_ACCEPTED ("panic_handler", PANIC_HANDLER, "1.30.0", ISSUE_SOME (44489))
+FEATURE_ACCEPTED ("used", USED, "1.30.0", ISSUE_SOME (40289))
+FEATURE_ACCEPTED ("crate_in_paths", CRATE_IN_PATHS, "1.30.0",
+ ISSUE_SOME (45477))
+FEATURE_ACCEPTED ("extern_absolute_paths", EXTERN_ABSOLUTE_PATHS, "1.30.0",
+ ISSUE_SOME (44660))
+FEATURE_ACCEPTED ("extern_prelude", EXTERN_PRELUDE, "1.30.0",
+ ISSUE_SOME (44660))
+FEATURE_ACCEPTED ("pattern_parentheses", PATTERN_PARENTHESES, "1.31.0",
+ ISSUE_SOME (51087))
+FEATURE_ACCEPTED ("min_const_fn", MIN_CONST_FN, "1.31.0", ISSUE_SOME (53555))
+FEATURE_ACCEPTED ("tool_lints", TOOL_LINTS, "1.31.0", ISSUE_SOME (44690))
+FEATURE_ACCEPTED ("impl_header_lifetime_elision", IMPL_HEADER_LIFETIME_ELISION,
+ "1.31.0", ISSUE_SOME (15872))
+FEATURE_ACCEPTED ("extern_crate_item_prelude", EXTERN_CRATE_ITEM_PRELUDE,
+ "1.31.0", ISSUE_SOME (55599))
+FEATURE_ACCEPTED ("macro_literal_matcher", MACRO_LITERAL_MATCHER, "1.32.0",
+ ISSUE_SOME (35625))
+FEATURE_ACCEPTED ("macro_at_most_once_rep", MACRO_AT_MOST_ONCE_REP, "1.32.0",
+ ISSUE_SOME (48075))
+FEATURE_ACCEPTED ("self_struct_ctor", SELF_STRUCT_CTOR, "1.32.0",
+ ISSUE_SOME (51994))
+FEATURE_ACCEPTED ("self_in_typedefs", SELF_IN_TYPEDEFS, "1.32.0",
+ ISSUE_SOME (49303))
+FEATURE_ACCEPTED ("uniform_paths", UNIFORM_PATHS, "1.32.0", ISSUE_SOME (53130))
+FEATURE_ACCEPTED ("exhaustive_integer_patterns", EXHAUSTIVE_INTEGER_PATTERNS,
+ "1.33.0", ISSUE_SOME (50907))
+FEATURE_ACCEPTED ("underscore_imports", UNDERSCORE_IMPORTS, "1.33.0",
+ ISSUE_SOME (48216))
+FEATURE_ACCEPTED ("repr_packed", REPR_PACKED, "1.33.0", ISSUE_SOME (33158))
+FEATURE_ACCEPTED ("irrefutable_let_patterns", IRREFUTABLE_LET_PATTERNS,
+ "1.33.0", ISSUE_SOME (44495))
+FEATURE_ACCEPTED ("min_const_unsafe_fn", MIN_CONST_UNSAFE_FN, "1.33.0",
+ ISSUE_SOME (55607))
+FEATURE_ACCEPTED ("const_let", CONST_LET, "1.33.0", ISSUE_SOME (48821))
+FEATURE_ACCEPTED ("cfg_attr_multi", CFG_ATTR_MULTI, "1.33.0",
+ ISSUE_SOME (54881))
+FEATURE_ACCEPTED ("if_while_or_patterns", IF_WHILE_OR_PATTERNS, "1.33.0",
+ ISSUE_SOME (48215))
+FEATURE_ACCEPTED ("cfg_target_vendor", CFG_TARGET_VENDOR, "1.33.0",
+ ISSUE_SOME (29718))
+FEATURE_ACCEPTED ("extern_crate_self", EXTERN_CRATE_SELF, "1.34.0",
+ ISSUE_SOME (56409))
+FEATURE_ACCEPTED ("unrestricted_attribute_tokens",
+ UNRESTRICTED_ATTRIBUTE_TOKENS, "1.34.0", ISSUE_SOME (55208))
+FEATURE_ACCEPTED ("type_alias_enum_variants", TYPE_ALIAS_ENUM_VARIANTS,
+ "1.37.0", ISSUE_SOME (49683))
+FEATURE_ACCEPTED ("repr_align_enum", REPR_ALIGN_ENUM, "1.37.0",
+ ISSUE_SOME (57996))
+FEATURE_ACCEPTED ("underscore_const_names", UNDERSCORE_CONST_NAMES, "1.37.0",
+ ISSUE_SOME (54912))
+FEATURE_ACCEPTED ("async_await", ASYNC_AWAIT, "1.39.0", ISSUE_SOME (50547))
+FEATURE_ACCEPTED ("bind_by_move_pattern_guards", BIND_BY_MOVE_PATTERN_GUARDS,
+ "1.39.0", ISSUE_SOME (15287))
+FEATURE_ACCEPTED ("param_attrs", PARAM_ATTRS, "1.39.0", ISSUE_SOME (60406))
+FEATURE_ACCEPTED ("macros_in_extern", MACROS_IN_EXTERN, "1.40.0",
+ ISSUE_SOME (49476))
+FEATURE_ACCEPTED ("non_exhaustive", NON_EXHAUSTIVE, "1.40.0",
+ ISSUE_SOME (44109))
+FEATURE_ACCEPTED ("const_constructor", CONST_CONSTRUCTOR, "1.40.0",
+ ISSUE_SOME (61456))
+FEATURE_ACCEPTED ("cfg_doctest", CFG_DOCTEST, "1.40.0", ISSUE_SOME (62210))
+FEATURE_ACCEPTED ("re_rebalance_coherence", RE_REBALANCE_COHERENCE, "1.41.0",
+ ISSUE_SOME (55437))
+FEATURE_ACCEPTED ("transparent_enums", TRANSPARENT_ENUMS, "1.42.0",
+ ISSUE_SOME (60405))
+FEATURE_ACCEPTED ("slice_patterns", SLICE_PATTERNS, "1.42.0",
+ ISSUE_SOME (62254))
+FEATURE_ACCEPTED ("const_if_match", CONST_IF_MATCH, "1.46.0",
+ ISSUE_SOME (49146))
+FEATURE_ACCEPTED ("const_loop", CONST_LOOP, "1.46.0", ISSUE_SOME (52000))
+FEATURE_ACCEPTED ("track_caller", TRACK_CALLER, "1.46.0", ISSUE_SOME (47809))
+FEATURE_ACCEPTED ("doc_alias", DOC_ALIAS, "1.48.0", ISSUE_SOME (50146))
+FEATURE_ACCEPTED ("move_ref_pattern", MOVE_REF_PATTERN, "1.48.0",
+ ISSUE_SOME (68354))
+FEATURE_ACTIVE ("rustc_attrs", RUSTC_ATTRS, "1.0.0", ISSUE_NONE, EDITION_NONE)
+FEATURE_ACTIVE ("rustc_private", RUSTC_PRIVATE, "1.0.0", ISSUE_SOME (27812),
+ EDITION_NONE)
+FEATURE_ACTIVE ("intrinsics", INTRINSICS, "1.0.0", ISSUE_NONE, EDITION_NONE)
+FEATURE_ACTIVE ("lang_items", LANG_ITEMS, "1.0.0", ISSUE_NONE, EDITION_NONE)
+FEATURE_ACTIVE ("staged_api", STAGED_API, "1.0.0", ISSUE_NONE, EDITION_NONE)
+FEATURE_ACTIVE ("allow_internal_unstable", ALLOW_INTERNAL_UNSTABLE, "1.0.0",
+ ISSUE_NONE, EDITION_NONE)
+FEATURE_ACTIVE ("allow_internal_unsafe", ALLOW_INTERNAL_UNSAFE, "1.0.0",
+ ISSUE_NONE, EDITION_NONE)
+FEATURE_ACTIVE ("link_llvm_intrinsics", LINK_LLVM_INTRINSICS, "1.0.0",
+ ISSUE_SOME (29602), EDITION_NONE)
+FEATURE_ACTIVE ("box_syntax", BOX_SYNTAX, "1.0.0", ISSUE_SOME (49733),
+ EDITION_NONE)
+FEATURE_ACTIVE ("main", MAIN, "1.0.0", ISSUE_SOME (29634), EDITION_NONE)
+FEATURE_ACTIVE ("start", START, "1.0.0", ISSUE_SOME (29633), EDITION_NONE)
+FEATURE_ACTIVE ("fundamental", FUNDAMENTAL, "1.0.0", ISSUE_SOME (29635),
+ EDITION_NONE)
+FEATURE_ACTIVE ("unboxed_closures", UNBOXED_CLOSURES, "1.0.0",
+ ISSUE_SOME (29625), EDITION_NONE)
+FEATURE_ACTIVE ("linkage", LINKAGE, "1.0.0", ISSUE_SOME (29603), EDITION_NONE)
+FEATURE_ACTIVE ("optin_builtin_traits", OPTIN_BUILTIN_TRAITS, "1.0.0",
+ ISSUE_SOME (13231), EDITION_NONE)
+FEATURE_ACTIVE ("box_patterns", BOX_PATTERNS, "1.0.0", ISSUE_SOME (29641),
+ EDITION_NONE)
+FEATURE_ACTIVE ("prelude_import", PRELUDE_IMPORT, "1.2.0", ISSUE_NONE,
+ EDITION_NONE)
+FEATURE_ACTIVE ("omit_gdb_pretty_printer_section",
+ OMIT_GDB_PRETTY_PRINTER_SECTION, "1.5.0", ISSUE_NONE,
+ EDITION_NONE)
+FEATURE_ACTIVE ("abi_vectorcall", ABI_VECTORCALL, "1.7.0", ISSUE_NONE,
+ EDITION_NONE)
+FEATURE_ACTIVE ("structural_match", STRUCTURAL_MATCH, "1.8.0",
+ ISSUE_SOME (31434), EDITION_NONE)
+FEATURE_ACTIVE ("dropck_eyepatch", DROPCK_EYEPATCH, "1.10.0",
+ ISSUE_SOME (34761), EDITION_NONE)
+FEATURE_ACTIVE ("panic_runtime", PANIC_RUNTIME, "1.10.0", ISSUE_SOME (32837),
+ EDITION_NONE)
+FEATURE_ACTIVE ("needs_panic_runtime", NEEDS_PANIC_RUNTIME, "1.10.0",
+ ISSUE_SOME (32837), EDITION_NONE)
+FEATURE_ACTIVE ("compiler_builtins", COMPILER_BUILTINS, "1.13.0", ISSUE_NONE,
+ EDITION_NONE)
+FEATURE_ACTIVE ("abi_unadjusted", ABI_UNADJUSTED, "1.16.0", ISSUE_NONE,
+ EDITION_NONE)
+FEATURE_ACTIVE ("profiler_runtime", PROFILER_RUNTIME, "1.18.0", ISSUE_NONE,
+ EDITION_NONE)
+FEATURE_ACTIVE ("abi_thiscall", ABI_THISCALL, "1.19.0", ISSUE_NONE,
+ EDITION_NONE)
+FEATURE_ACTIVE ("allocator_internals", ALLOCATOR_INTERNALS, "1.20.0",
+ ISSUE_NONE, EDITION_NONE)
+FEATURE_ACTIVE ("test_2018_feature", TEST_2018_FEATURE, "1.31.0", ISSUE_NONE,
+ EDITION_2018)
+FEATURE_ACTIVE ("no_niche", NO_NICHE, "1.42.0", ISSUE_NONE, EDITION_NONE)
+FEATURE_ACTIVE ("rustc_allow_const_fn_unstable", RUSTC_ALLOW_CONST_FN_UNSTABLE,
+ "1.49.0", ISSUE_SOME (69399), EDITION_NONE)
+FEATURE_ACTIVE ("arm_target_feature", ARM_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("aarch64_target_feature", AARCH64_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("hexagon_target_feature", HEXAGON_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("powerpc_target_feature", POWERPC_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("mips_target_feature", MIPS_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("avx512_target_feature", AVX512_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("sse4a_target_feature", SSE4A_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("tbm_target_feature", TBM_TARGET_FEATURE, "1.27.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("wasm_target_feature", WASM_TARGET_FEATURE, "1.30.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("adx_target_feature", ADX_TARGET_FEATURE, "1.32.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("cmpxchg16b_target_feature", CMPXCHG16B_TARGET_FEATURE,
+ "1.32.0", ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("movbe_target_feature", MOVBE_TARGET_FEATURE, "1.34.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("rtm_target_feature", RTM_TARGET_FEATURE, "1.35.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("f16c_target_feature", F16C_TARGET_FEATURE, "1.36.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("riscv_target_feature", RISCV_TARGET_FEATURE, "1.45.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("ermsb_target_feature", ERMSB_TARGET_FEATURE, "1.49.0",
+ ISSUE_SOME (44839), EDITION_NONE)
+FEATURE_ACTIVE ("link_args", LINK_ARGS, "1.0.0", ISSUE_SOME (29596),
+ EDITION_NONE)
+FEATURE_ACTIVE ("non_ascii_idents", NON_ASCII_IDENTS, "1.0.0",
+ ISSUE_SOME (55467), EDITION_NONE)
+FEATURE_ACTIVE ("plugin_registrar", PLUGIN_REGISTRAR, "1.0.0",
+ ISSUE_SOME (29597), EDITION_NONE)
+FEATURE_ACTIVE ("plugin", PLUGIN, "1.0.0", ISSUE_SOME (29597), EDITION_NONE)
+FEATURE_ACTIVE ("thread_local", THREAD_LOCAL, "1.0.0", ISSUE_SOME (29594),
+ EDITION_NONE)
+FEATURE_ACTIVE ("simd_ffi", SIMD_FFI, "1.0.0", ISSUE_SOME (27731), EDITION_NONE)
+FEATURE_ACTIVE ("nll", NLL, "1.0.0", ISSUE_SOME (43234), EDITION_NONE)
+FEATURE_ACTIVE ("const_fn", CONST_FN, "1.2.0", ISSUE_SOME (57563), EDITION_NONE)
+FEATURE_ACTIVE ("associated_type_defaults", ASSOCIATED_TYPE_DEFAULTS, "1.2.0",
+ ISSUE_SOME (29661), EDITION_NONE)
+FEATURE_ACTIVE ("no_core", NO_CORE, "1.3.0", ISSUE_SOME (29639), EDITION_NONE)
+FEATURE_ACTIVE ("default_type_parameter_fallback",
+ DEFAULT_TYPE_PARAMETER_FALLBACK, "1.3.0", ISSUE_SOME (27336),
+ EDITION_NONE)
+FEATURE_ACTIVE ("repr_simd", REPR_SIMD, "1.4.0", ISSUE_SOME (27731),
+ EDITION_NONE)
+FEATURE_ACTIVE ("platform_intrinsics", PLATFORM_INTRINSICS, "1.4.0",
+ ISSUE_SOME (27731), EDITION_NONE)
+FEATURE_ACTIVE ("unwind_attributes", UNWIND_ATTRIBUTES, "1.4.0",
+ ISSUE_SOME (58760), EDITION_NONE)
+FEATURE_ACTIVE ("stmt_expr_attributes", STMT_EXPR_ATTRIBUTES, "1.6.0",
+ ISSUE_SOME (15701), EDITION_NONE)
+FEATURE_ACTIVE ("type_ascription", TYPE_ASCRIPTION, "1.6.0", ISSUE_SOME (23416),
+ EDITION_NONE)
+FEATURE_ACTIVE ("cfg_target_thread_local", CFG_TARGET_THREAD_LOCAL, "1.7.0",
+ ISSUE_SOME (29594), EDITION_NONE)
+FEATURE_ACTIVE ("specialization", SPECIALIZATION, "1.7.0", ISSUE_SOME (31844),
+ EDITION_NONE)
+FEATURE_ACTIVE ("min_specialization", MIN_SPECIALIZATION, "1.7.0",
+ ISSUE_SOME (31844), EDITION_NONE)
+FEATURE_ACTIVE ("naked_functions", NAKED_FUNCTIONS, "1.9.0", ISSUE_SOME (32408),
+ EDITION_NONE)
+FEATURE_ACTIVE ("cfg_target_has_atomic", CFG_TARGET_HAS_ATOMIC, "1.9.0",
+ ISSUE_SOME (32976), EDITION_NONE)
+FEATURE_ACTIVE ("exclusive_range_pattern", EXCLUSIVE_RANGE_PATTERN, "1.11.0",
+ ISSUE_SOME (37854), EDITION_NONE)
+FEATURE_ACTIVE ("never_type", NEVER_TYPE, "1.13.0", ISSUE_SOME (35121),
+ EDITION_NONE)
+FEATURE_ACTIVE ("exhaustive_patterns", EXHAUSTIVE_PATTERNS, "1.13.0",
+ ISSUE_SOME (51085), EDITION_NONE)
+FEATURE_ACTIVE ("untagged_unions", UNTAGGED_UNIONS, "1.13.0",
+ ISSUE_SOME (55149), EDITION_NONE)
+FEATURE_ACTIVE ("link_cfg", LINK_CFG, "1.14.0", ISSUE_SOME (37406),
+ EDITION_NONE)
+FEATURE_ACTIVE ("abi_ptx", ABI_PTX, "1.15.0", ISSUE_SOME (38788), EDITION_NONE)
+FEATURE_ACTIVE ("repr128", REPR128, "1.16.0", ISSUE_SOME (56071), EDITION_NONE)
+FEATURE_ACTIVE ("static_nobundle", STATIC_NOBUNDLE, "1.16.0",
+ ISSUE_SOME (37403), EDITION_NONE)
+FEATURE_ACTIVE ("abi_msp430_interrupt", ABI_MSP430_INTERRUPT, "1.16.0",
+ ISSUE_SOME (38487), EDITION_NONE)
+FEATURE_ACTIVE ("decl_macro", DECL_MACRO, "1.17.0", ISSUE_SOME (39412),
+ EDITION_NONE)
+FEATURE_ACTIVE ("abi_x86_interrupt", ABI_X86_INTERRUPT, "1.17.0",
+ ISSUE_SOME (40180), EDITION_NONE)
+FEATURE_ACTIVE ("allow_fail", ALLOW_FAIL, "1.19.0", ISSUE_SOME (46488),
+ EDITION_NONE)
+FEATURE_ACTIVE ("unsized_tuple_coercion", UNSIZED_TUPLE_COERCION, "1.20.0",
+ ISSUE_SOME (42877), EDITION_NONE)
+FEATURE_ACTIVE ("generators", GENERATORS, "1.21.0", ISSUE_SOME (43122),
+ EDITION_NONE)
+FEATURE_ACTIVE ("doc_cfg", DOC_CFG, "1.21.0", ISSUE_SOME (43781), EDITION_NONE)
+FEATURE_ACTIVE ("doc_masked", DOC_MASKED, "1.21.0", ISSUE_SOME (44027),
+ EDITION_NONE)
+FEATURE_ACTIVE ("doc_spotlight", DOC_SPOTLIGHT, "1.22.0", ISSUE_SOME (45040),
+ EDITION_NONE)
+FEATURE_ACTIVE ("external_doc", EXTERNAL_DOC, "1.22.0", ISSUE_SOME (44732),
+ EDITION_NONE)
+FEATURE_ACTIVE ("crate_visibility_modifier", CRATE_VISIBILITY_MODIFIER,
+ "1.23.0", ISSUE_SOME (53120), EDITION_NONE)
+FEATURE_ACTIVE ("extern_types", EXTERN_TYPES, "1.23.0", ISSUE_SOME (43467),
+ EDITION_NONE)
+FEATURE_ACTIVE ("arbitrary_self_types", ARBITRARY_SELF_TYPES, "1.23.0",
+ ISSUE_SOME (44874), EDITION_NONE)
+FEATURE_ACTIVE ("in_band_lifetimes", IN_BAND_LIFETIMES, "1.23.0",
+ ISSUE_SOME (44524), EDITION_NONE)
+FEATURE_ACTIVE ("generic_associated_types", GENERIC_ASSOCIATED_TYPES, "1.23.0",
+ ISSUE_SOME (44265), EDITION_NONE)
+FEATURE_ACTIVE ("trait_alias", TRAIT_ALIAS, "1.24.0", ISSUE_SOME (41517),
+ EDITION_NONE)
+FEATURE_ACTIVE ("infer_static_outlives_requirements",
+ INFER_STATIC_OUTLIVES_REQUIREMENTS, "1.26.0",
+ ISSUE_SOME (54185), EDITION_NONE)
+FEATURE_ACTIVE ("const_fn_union", CONST_FN_UNION, "1.27.0", ISSUE_SOME (51909),
+ EDITION_NONE)
+FEATURE_ACTIVE ("const_raw_ptr_to_usize_cast", CONST_RAW_PTR_TO_USIZE_CAST,
+ "1.27.0", ISSUE_SOME (51910), EDITION_NONE)
+FEATURE_ACTIVE ("const_raw_ptr_deref", CONST_RAW_PTR_DEREF, "1.27.0",
+ ISSUE_SOME (51911), EDITION_NONE)
+FEATURE_ACTIVE ("trivial_bounds", TRIVIAL_BOUNDS, "1.28.0", ISSUE_SOME (48214),
+ EDITION_NONE)
+FEATURE_ACTIVE ("label_break_value", LABEL_BREAK_VALUE, "1.28.0",
+ ISSUE_SOME (48594), EDITION_NONE)
+FEATURE_ACTIVE ("doc_keyword", DOC_KEYWORD, "1.28.0", ISSUE_SOME (51315),
+ EDITION_NONE)
+FEATURE_ACTIVE ("try_blocks", TRY_BLOCKS, "1.29.0", ISSUE_SOME (31436),
+ EDITION_NONE)
+FEATURE_ACTIVE ("alloc_error_handler", ALLOC_ERROR_HANDLER, "1.29.0",
+ ISSUE_SOME (51540), EDITION_NONE)
+FEATURE_ACTIVE ("abi_amdgpu_kernel", ABI_AMDGPU_KERNEL, "1.29.0",
+ ISSUE_SOME (51575), EDITION_NONE)
+FEATURE_ACTIVE ("const_panic", CONST_PANIC, "1.30.0", ISSUE_SOME (51999),
+ EDITION_NONE)
+FEATURE_ACTIVE ("marker_trait_attr", MARKER_TRAIT_ATTR, "1.30.0",
+ ISSUE_SOME (29864), EDITION_NONE)
+FEATURE_ACTIVE ("proc_macro_hygiene", PROC_MACRO_HYGIENE, "1.30.0",
+ ISSUE_SOME (54727), EDITION_NONE)
+FEATURE_ACTIVE ("unsized_locals", UNSIZED_LOCALS, "1.30.0", ISSUE_SOME (48055),
+ EDITION_NONE)
+FEATURE_ACTIVE ("custom_test_frameworks", CUSTOM_TEST_FRAMEWORKS, "1.30.0",
+ ISSUE_SOME (50297), EDITION_NONE)
+FEATURE_ACTIVE ("custom_inner_attributes", CUSTOM_INNER_ATTRIBUTES, "1.30.0",
+ ISSUE_SOME (54726), EDITION_NONE)
+FEATURE_ACTIVE ("impl_trait_in_bindings", IMPL_TRAIT_IN_BINDINGS, "1.30.0",
+ ISSUE_SOME (63065), EDITION_NONE)
+FEATURE_ACTIVE ("lint_reasons", LINT_REASONS, "1.31.0", ISSUE_SOME (54503),
+ EDITION_NONE)
+FEATURE_ACTIVE ("precise_pointer_size_matching", PRECISE_POINTER_SIZE_MATCHING,
+ "1.32.0", ISSUE_SOME (56354), EDITION_NONE)
+FEATURE_ACTIVE ("ffi_returns_twice", FFI_RETURNS_TWICE, "1.34.0",
+ ISSUE_SOME (58314), EDITION_NONE)
+FEATURE_ACTIVE ("const_generics", CONST_GENERICS, "1.34.0", ISSUE_SOME (44580),
+ EDITION_NONE)
+FEATURE_ACTIVE ("optimize_attribute", OPTIMIZE_ATTRIBUTE, "1.34.0",
+ ISSUE_SOME (54882), EDITION_NONE)
+FEATURE_ACTIVE ("c_variadic", C_VARIADIC, "1.34.0", ISSUE_SOME (44930),
+ EDITION_NONE)
+FEATURE_ACTIVE ("associated_type_bounds", ASSOCIATED_TYPE_BOUNDS, "1.34.0",
+ ISSUE_SOME (52662), EDITION_NONE)
+FEATURE_ACTIVE ("let_chains", LET_CHAINS, "1.37.0", ISSUE_SOME (53667),
+ EDITION_NONE)
+FEATURE_ACTIVE ("transparent_unions", TRANSPARENT_UNIONS, "1.37.0",
+ ISSUE_SOME (60405), EDITION_NONE)
+FEATURE_ACTIVE ("arbitrary_enum_discriminant", ARBITRARY_ENUM_DISCRIMINANT,
+ "1.37.0", ISSUE_SOME (60553), EDITION_NONE)
+FEATURE_ACTIVE ("member_constraints", MEMBER_CONSTRAINTS, "1.37.0",
+ ISSUE_SOME (61997), EDITION_NONE)
+FEATURE_ACTIVE ("async_closure", ASYNC_CLOSURE, "1.37.0", ISSUE_SOME (62290),
+ EDITION_NONE)
+FEATURE_ACTIVE ("const_in_array_repeat_expressions",
+ CONST_IN_ARRAY_REPEAT_EXPRESSIONS, "1.37.0", ISSUE_SOME (49147),
+ EDITION_NONE)
+FEATURE_ACTIVE ("type_alias_impl_trait", TYPE_ALIAS_IMPL_TRAIT, "1.38.0",
+ ISSUE_SOME (63063), EDITION_NONE)
+FEATURE_ACTIVE ("or_patterns", OR_PATTERNS, "1.38.0", ISSUE_SOME (54883),
+ EDITION_NONE)
+FEATURE_ACTIVE ("const_extern_fn", CONST_EXTERN_FN, "1.40.0",
+ ISSUE_SOME (64926), EDITION_NONE)
+FEATURE_ACTIVE ("raw_dylib", RAW_DYLIB, "1.40.0", ISSUE_SOME (58713),
+ EDITION_NONE)
+FEATURE_ACTIVE ("object_safe_for_dispatch", OBJECT_SAFE_FOR_DISPATCH, "1.40.0",
+ ISSUE_SOME (43561), EDITION_NONE)
+FEATURE_ACTIVE ("abi_efiapi", ABI_EFIAPI, "1.40.0", ISSUE_SOME (65815),
+ EDITION_NONE)
+FEATURE_ACTIVE ("raw_ref_op", RAW_REF_OP, "1.41.0", ISSUE_SOME (64490),
+ EDITION_NONE)
+FEATURE_ACTIVE ("never_type_fallback", NEVER_TYPE_FALLBACK, "1.41.0",
+ ISSUE_SOME (65992), EDITION_NONE)
+FEATURE_ACTIVE ("register_attr", REGISTER_ATTR, "1.41.0", ISSUE_SOME (66080),
+ EDITION_NONE)
+FEATURE_ACTIVE ("register_tool", REGISTER_TOOL, "1.41.0", ISSUE_SOME (66079),
+ EDITION_NONE)
+FEATURE_ACTIVE ("cfg_sanitize", CFG_SANITIZE, "1.41.0", ISSUE_SOME (39699),
+ EDITION_NONE)
+FEATURE_ACTIVE ("half_open_range_patterns", HALF_OPEN_RANGE_PATTERNS, "1.41.0",
+ ISSUE_SOME (67264), EDITION_NONE)
+FEATURE_ACTIVE ("const_mut_refs", CONST_MUT_REFS, "1.41.0", ISSUE_SOME (57349),
+ EDITION_NONE)
+FEATURE_ACTIVE ("bindings_after_at", BINDINGS_AFTER_AT, "1.41.0",
+ ISSUE_SOME (65490), EDITION_NONE)
+FEATURE_ACTIVE ("const_trait_impl", CONST_TRAIT_IMPL, "1.42.0",
+ ISSUE_SOME (67792), EDITION_NONE)
+FEATURE_ACTIVE ("const_trait_bound_opt_out", CONST_TRAIT_BOUND_OPT_OUT,
+ "1.42.0", ISSUE_SOME (67794), EDITION_NONE)
+FEATURE_ACTIVE ("no_sanitize", NO_SANITIZE, "1.42.0", ISSUE_SOME (39699),
+ EDITION_NONE)
+FEATURE_ACTIVE ("const_eval_limit", CONST_EVAL_LIMIT, "1.43.0",
+ ISSUE_SOME (67217), EDITION_NONE)
+FEATURE_ACTIVE ("negative_impls", NEGATIVE_IMPLS, "1.44.0", ISSUE_SOME (68318),
+ EDITION_NONE)
+FEATURE_ACTIVE ("target_feature_11", TARGET_FEATURE_11, "1.45.0",
+ ISSUE_SOME (69098), EDITION_NONE)
+FEATURE_ACTIVE ("cfg_version", CFG_VERSION, "1.45.0", ISSUE_SOME (64796),
+ EDITION_NONE)
+FEATURE_ACTIVE ("ffi_pure", FFI_PURE, "1.45.0", ISSUE_SOME (58329),
+ EDITION_NONE)
+FEATURE_ACTIVE ("ffi_const", FFI_CONST, "1.45.0", ISSUE_SOME (58328),
+ EDITION_NONE)
+FEATURE_ACTIVE ("unsafe_block_in_unsafe_fn", UNSAFE_BLOCK_IN_UNSAFE_FN,
+ "1.45.0", ISSUE_SOME (71668), EDITION_NONE)
+FEATURE_ACTIVE ("abi_avr_interrupt", ABI_AVR_INTERRUPT, "1.45.0",
+ ISSUE_SOME (69664), EDITION_NONE)
+FEATURE_ACTIVE ("const_precise_live_drops", CONST_PRECISE_LIVE_DROPS, "1.46.0",
+ ISSUE_SOME (73255), EDITION_NONE)
+FEATURE_ACTIVE ("format_args_capture", FORMAT_ARGS_CAPTURE, "1.46.0",
+ ISSUE_SOME (67984), EDITION_NONE)
+FEATURE_ACTIVE ("lazy_normalization_consts", LAZY_NORMALIZATION_CONSTS,
+ "1.46.0", ISSUE_SOME (72219), EDITION_NONE)
+FEATURE_ACTIVE ("const_fn_transmute", CONST_FN_TRANSMUTE, "1.46.0",
+ ISSUE_SOME (53605), EDITION_NONE)
+FEATURE_ACTIVE ("min_const_generics", MIN_CONST_GENERICS, "1.47.0",
+ ISSUE_SOME (74878), EDITION_NONE)
+FEATURE_ACTIVE ("if_let_guard", IF_LET_GUARD, "1.47.0", ISSUE_SOME (51114),
+ EDITION_NONE)
+FEATURE_ACTIVE ("const_evaluatable_checked", CONST_EVALUATABLE_CHECKED,
+ "1.48.0", ISSUE_SOME (76560), EDITION_NONE)
+FEATURE_ACTIVE ("const_fn_floating_point_arithmetic",
+ CONST_FN_FLOATING_POINT_ARITHMETIC, "1.48.0",
+ ISSUE_SOME (57241), EDITION_NONE)
+FEATURE_ACTIVE ("const_fn_fn_ptr_basics", CONST_FN_FN_PTR_BASICS, "1.48.0",
+ ISSUE_SOME (57563), EDITION_NONE)
+FEATURE_ACTIVE ("cmse_nonsecure_entry", CMSE_NONSECURE_ENTRY, "1.48.0",
+ ISSUE_SOME (75835), EDITION_NONE)
+FEATURE_ACTIVE ("default_alloc_error_handler", DEFAULT_ALLOC_ERROR_HANDLER,
+ "1.48.0", ISSUE_SOME (66741), EDITION_NONE)
+FEATURE_ACTIVE ("const_impl_trait", CONST_IMPL_TRAIT, "1.48.0",
+ ISSUE_SOME (77463), EDITION_NONE)
+FEATURE_ACTIVE ("isa_attribute", ISA_ATTRIBUTE, "1.48.0", ISSUE_SOME (74727),
+ EDITION_NONE)
+FEATURE_ACTIVE ("inline_const", INLINE_CONST, "1.49.0", ISSUE_SOME (76001),
+ EDITION_NONE)
+FEATURE_ACTIVE ("unsized_fn_params", UNSIZED_FN_PARAMS, "1.49.0",
+ ISSUE_SOME (48055), EDITION_NONE)
+FEATURE_ACTIVE ("destructuring_assignment", DESTRUCTURING_ASSIGNMENT, "1.49.0",
+ ISSUE_SOME (71126), EDITION_NONE)
+FEATURE_ACTIVE ("cfg_panic", CFG_PANIC, "1.49.0", ISSUE_SOME (77443),
+ EDITION_NONE)
+FEATURE_REMOVED ("import_shadowing", IMPORT_SHADOWING, "1.0.0", ISSUE_NONE,
+ REASON_NONE)
+FEATURE_REMOVED ("managed_boxes", MANAGED_BOXES, "1.0.0", ISSUE_NONE,
+ REASON_NONE)
+FEATURE_REMOVED ("negate_unsigned", NEGATE_UNSIGNED, "1.0.0",
+ ISSUE_SOME (29645), REASON_NONE)
+FEATURE_REMOVED ("reflect", REFLECT, "1.0.0", ISSUE_SOME (27749), REASON_NONE)
+FEATURE_REMOVED ("opt_out_copy", OPT_OUT_COPY, "1.0.0", ISSUE_NONE, REASON_NONE)
+FEATURE_REMOVED ("quad_precision_float", QUAD_PRECISION_FLOAT, "1.0.0",
+ ISSUE_NONE, REASON_NONE)
+FEATURE_REMOVED ("struct_inherit", STRUCT_INHERIT, "1.0.0", ISSUE_NONE,
+ REASON_NONE)
+FEATURE_REMOVED ("test_removed_feature", TEST_REMOVED_FEATURE, "1.0.0",
+ ISSUE_NONE, REASON_NONE)
+FEATURE_REMOVED ("visible_private_types", VISIBLE_PRIVATE_TYPES, "1.0.0",
+ ISSUE_NONE, REASON_NONE)
+FEATURE_REMOVED ("unsafe_no_drop_flag", UNSAFE_NO_DROP_FLAG, "1.0.0",
+ ISSUE_NONE, REASON_NONE)
+FEATURE_REMOVED ("unmarked_api", UNMARKED_API, "1.0.0", ISSUE_NONE, REASON_NONE)
+FEATURE_REMOVED ("allocator", ALLOCATOR, "1.0.0", ISSUE_NONE, REASON_NONE)
+FEATURE_REMOVED ("simd", SIMD, "1.0.0", ISSUE_SOME (27731),
+ REASON_SOME ("removed in favor of `#[repr(simd)]`"))
+FEATURE_REMOVED ("advanced_slice_patterns", ADVANCED_SLICE_PATTERNS, "1.0.0",
+ ISSUE_SOME (62254),
+ REASON_SOME ("merged into `#![feature(slice_patterns)]`"))
+FEATURE_REMOVED ("macro_reexport", MACRO_REEXPORT, "1.0.0", ISSUE_SOME (29638),
+ REASON_SOME ("subsumed by `pub use`"))
+FEATURE_REMOVED (
+ "custom_attribute", CUSTOM_ATTRIBUTE, "1.0.0", ISSUE_SOME (29642),
+ REASON_SOME (
+ "removed in favor of `#![register_tool]` and `#![register_attr]`"))
+FEATURE_REMOVED ("pushpop_unsafe", PUSHPOP_UNSAFE, "1.2.0", ISSUE_NONE,
+ REASON_NONE)
+FEATURE_REMOVED ("needs_allocator", NEEDS_ALLOCATOR, "1.4.0",
+ ISSUE_SOME (27389),
+ REASON_SOME ("subsumed by `#![feature(allocator_internals)]`"))
+FEATURE_REMOVED ("sanitizer_runtime", SANITIZER_RUNTIME, "1.17.0", ISSUE_NONE,
+ REASON_NONE)
+FEATURE_REMOVED ("proc_macro_mod", PROC_MACRO_MOD, "1.27.0", ISSUE_SOME (54727),
+ REASON_SOME ("subsumed by `#![feature(proc_macro_hygiene)]`"))
+FEATURE_REMOVED ("proc_macro_expr", PROC_MACRO_EXPR, "1.27.0",
+ ISSUE_SOME (54727),
+ REASON_SOME ("subsumed by `#![feature(proc_macro_hygiene)]`"))
+FEATURE_REMOVED ("proc_macro_non_items", PROC_MACRO_NON_ITEMS, "1.27.0",
+ ISSUE_SOME (54727),
+ REASON_SOME ("subsumed by `#![feature(proc_macro_hygiene)]`"))
+FEATURE_REMOVED ("proc_macro_gen", PROC_MACRO_GEN, "1.27.0", ISSUE_SOME (54727),
+ REASON_SOME ("subsumed by `#![feature(proc_macro_hygiene)]`"))
+FEATURE_REMOVED ("panic_implementation", PANIC_IMPLEMENTATION, "1.28.0",
+ ISSUE_SOME (44489),
+ REASON_SOME ("subsumed by `#[panic_handler]`"))
+FEATURE_REMOVED ("custom_derive", CUSTOM_DERIVE, "1.32.0", ISSUE_SOME (29644),
+ REASON_SOME ("subsumed by `#[proc_macro_derive]`"))
+FEATURE_REMOVED ("extern_in_paths", EXTERN_IN_PATHS, "1.33.0",
+ ISSUE_SOME (55600),
+ REASON_SOME ("subsumed by `::foo::bar` paths"))
+FEATURE_REMOVED ("quote", QUOTE, "1.33.0", ISSUE_SOME (29601), REASON_NONE)
+FEATURE_REMOVED ("dropck_parametricity", DROPCK_PARAMETRICITY, "1.38.0",
+ ISSUE_SOME (28498), REASON_NONE)
+FEATURE_REMOVED ("await_macro", AWAIT_MACRO, "1.38.0", ISSUE_SOME (50547),
+ REASON_SOME ("subsumed by `.await` syntax"))
+FEATURE_REMOVED (
+ "existential_type", EXISTENTIAL_TYPE, "1.38.0", ISSUE_SOME (63063),
+ REASON_SOME ("removed in favor of `#![feature(type_alias_impl_trait)]`"))
+FEATURE_REMOVED ("rustc_diagnostic_macros", RUSTC_DIAGNOSTIC_MACROS, "1.38.0",
+ ISSUE_NONE, REASON_NONE)
+FEATURE_REMOVED ("on_unimplemented", ON_UNIMPLEMENTED, "1.40.0", ISSUE_NONE,
+ REASON_NONE)
+FEATURE_REMOVED (
+ "overlapping_marker_traits", OVERLAPPING_MARKER_TRAITS, "1.42.0",
+ ISSUE_SOME (29864),
+ REASON_SOME ("removed in favor of `#![feature(marker_trait_attr)]`"))
+FEATURE_REMOVED ("no_debug", F_NO_DEBUG, "1.43.0", ISSUE_SOME (29721),
+ REASON_SOME ("removed due to lack of demand"))
+FEATURE_REMOVED (
+ "const_compare_raw_pointers", CONST_COMPARE_RAW_POINTERS, "1.46.0",
+ ISSUE_SOME (53020),
+ REASON_SOME ("cannot be allowed in const eval in any meaningful way"))
+FEATURE_STABLE_REMOVED ("no_stack_check", NO_STACK_CHECK, "1.0.0", ISSUE_NONE)
diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc b/gcc/rust/checks/errors/feature/rust-feature-gate.cc
index 44007f9..9df822b 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/feature/rust-feature-gate.cc
@@ -34,7 +34,10 @@ FeatureGate::check (AST::Crate &crate)
void
FeatureGate::visit (AST::Crate &crate)
{
- valid_features.clear ();
+ valid_lang_features.clear ();
+ valid_lib_features.clear ();
+
+ // avoid clearing defined features (?)
for (const auto &attr : crate.inner_attrs)
{
@@ -58,31 +61,47 @@ FeatureGate::visit (AST::Crate &crate)
for (const auto &item : meta_item->get_items ())
{
const auto &name_str = item->as_string ();
- auto tname = Feature::as_name (name_str);
- if (tname.has_value ())
- {
- auto name = tname.value ();
- valid_features.insert (name);
- }
+ // TODO: detect duplicates
+ if (auto tname = Feature::as_name (name_str))
+ valid_lang_features.insert (tname.value ());
else
- rust_error_at (item->get_locus (), ErrorCode::E0635,
- "unknown feature %qs", name_str.c_str ());
+ valid_lib_features.emplace (name_str, item->get_locus ());
}
}
}
}
AST::DefaultASTVisitor::visit (crate);
+
+ for (auto &ent : valid_lib_features)
+ {
+ const std::string &feature = ent.first;
+ location_t locus = ent.second;
+
+ // rustc treats these as valid,
+ // but apparently has special handling for them
+ if (feature == "libc" || feature == "test")
+ continue;
+
+ if (defined_lib_features.find (feature) != defined_lib_features.end ())
+ {
+ // TODO: emit warning if stable
+ continue;
+ }
+
+ rust_error_at (locus, ErrorCode::E0635, "unknown feature %qs",
+ feature.c_str ());
+ }
}
void
FeatureGate::gate (Feature::Name name, location_t loc,
const std::string &error_msg)
{
- if (!valid_features.count (name))
+ if (!valid_lang_features.count (name))
{
- auto feature = Feature::create (name);
+ auto &feature = Feature::lookup (name);
if (auto issue = feature.issue ())
{
auto issue_number = issue.value ();
@@ -147,9 +166,77 @@ FeatureGate::check_may_dangle_attribute (
}
void
+FeatureGate::check_lang_item_attribute (
+ const std::vector<AST::Attribute> &attributes)
+{
+ for (const AST::Attribute &attr : attributes)
+ {
+ const auto &str_path = attr.get_path ().as_string ();
+ bool is_lang_item = str_path == Values::Attributes::LANG
+ && attr.has_attr_input ()
+ && attr.get_attr_input ().get_attr_input_type ()
+ == AST::AttrInput::AttrInputType::LITERAL;
+
+ if (is_lang_item)
+ gate (Feature::Name::LANG_ITEMS, attr.get_locus (),
+ "lang items are subject to change");
+ }
+}
+
+void
+FeatureGate::note_stability_attribute (
+ const std::vector<AST::Attribute> &attributes)
+{
+ for (const AST::Attribute &attr : attributes)
+ {
+ std::string attr_name = attr.get_path ().as_string ();
+
+ Stability stability;
+
+ if (attr_name == Values::Attributes::STABLE)
+ stability = Stability::STABLE;
+ else if (attr_name == Values::Attributes::UNSTABLE)
+ stability = Stability::UNSTABLE;
+ else if (attr_name == Values::Attributes::RUSTC_CONST_STABLE)
+ stability = Stability::STABLE;
+ else if (attr_name == Values::Attributes::RUSTC_CONST_UNSTABLE)
+ stability = Stability::UNSTABLE;
+ else
+ continue;
+
+ if (attr.empty_input ())
+ // TODO: error?
+ continue;
+
+ auto &attr_input = attr.get_attr_input ();
+ if (attr_input.get_attr_input_type ()
+ != AST::AttrInput::AttrInputType::TOKEN_TREE)
+ // TODO: error?
+ continue;
+
+ std::unique_ptr<AST::AttrInputMetaItemContainer> meta_item (
+ static_cast<const AST::DelimTokenTree &> (attr_input)
+ .parse_to_meta_item ());
+
+ for (auto &item : meta_item->get_items ())
+ {
+ // TODO: more thorough error checking?
+ // ~only the standard libraries should ever exercise this
+ if (item->is_key_value_pair ())
+ {
+ auto &pair = static_cast<const AST::MetaNameValueStr &> (*item);
+ if (pair.get_name ().as_string () == "feature")
+ defined_lib_features.emplace (pair.get_value (), stability);
+ }
+ }
+ }
+}
+
+void
FeatureGate::visit (AST::MacroRulesDefinition &rules_def)
{
check_rustc_attri (rules_def.get_outer_attrs ());
+ note_stability_attribute (rules_def.get_outer_attrs ());
}
void
@@ -158,6 +245,10 @@ FeatureGate::visit (AST::Function &function)
if (!function.is_external ())
check_rustc_attri (function.get_outer_attrs ());
+ check_lang_item_attribute (function.get_outer_attrs ());
+
+ note_stability_attribute (function.get_outer_attrs ());
+
AST::DefaultASTVisitor::visit (function);
}
@@ -184,8 +275,9 @@ void
FeatureGate::visit (AST::Trait &trait)
{
if (trait.is_auto ())
- gate (Feature::Name::AUTO_TRAITS, trait.get_locus (),
+ gate (Feature::Name::OPTIN_BUILTIN_TRAITS, trait.get_locus (),
"auto traits are experimental and possibly buggy");
+ check_lang_item_attribute (trait.get_outer_attrs ());
AST::DefaultASTVisitor::visit (trait);
}
@@ -243,4 +335,32 @@ FeatureGate::visit (AST::UseTreeGlob &use)
// #[feature(prelude_import)]
}
+void
+FeatureGate::visit (AST::StructStruct &struct_item)
+{
+ check_lang_item_attribute (struct_item.get_outer_attrs ());
+ AST::DefaultASTVisitor::visit (struct_item);
+}
+
+void
+FeatureGate::visit (AST::TraitItemType &trait_item_type)
+{
+ check_lang_item_attribute (trait_item_type.get_outer_attrs ());
+ AST::DefaultASTVisitor::visit (trait_item_type);
+}
+
+void
+FeatureGate::visit (AST::Enum &enum_item)
+{
+ check_lang_item_attribute (enum_item.get_outer_attrs ());
+ AST::DefaultASTVisitor::visit (enum_item);
+}
+
+void
+FeatureGate::visit (AST::EnumItem &enum_variant)
+{
+ check_lang_item_attribute (enum_variant.get_outer_attrs ());
+ AST::DefaultASTVisitor::visit (enum_variant);
+}
+
} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-feature-gate.h b/gcc/rust/checks/errors/feature/rust-feature-gate.h
index f1011e5..8ff491c 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/feature/rust-feature-gate.h
@@ -47,13 +47,30 @@ public:
void visit (AST::ExternBlock &block) override;
void visit (AST::MacroRulesDefinition &rules_def) override;
void visit (AST::RangePattern &pattern) override;
+ void visit (AST::StructStruct &struct_item) override;
+ void visit (AST::TraitItemType &trait_item_type) override;
+ void visit (AST::Enum &enum_item) override;
+ void visit (AST::EnumItem &enum_variant) override;
private:
void gate (Feature::Name name, location_t loc, const std::string &error_msg);
void check_rustc_attri (const std::vector<AST::Attribute> &attributes);
void
check_may_dangle_attribute (const std::vector<AST::Attribute> &attributes);
- std::set<Feature::Name> valid_features;
+ void
+ check_lang_item_attribute (const std::vector<AST::Attribute> &attributes);
+ void note_stability_attribute (const std::vector<AST::Attribute> &attributes);
+
+ std::set<Feature::Name> valid_lang_features;
+ std::map<std::string, location_t> valid_lib_features;
+
+ enum class Stability
+ {
+ STABLE,
+ UNSTABLE,
+ };
+
+ std::map<std::string, Stability> defined_lib_features;
};
} // namespace Rust
#endif
diff --git a/gcc/rust/checks/errors/feature/rust-feature.cc b/gcc/rust/checks/errors/feature/rust-feature.cc
new file mode 100644
index 0000000..1a967aa
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/rust-feature.cc
@@ -0,0 +1,100 @@
+// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-feature.h"
+
+namespace Rust {
+
+Feature Feature::feature_list[] = {
+#define ISSUE_SOME(n) n
+#define ISSUE_NONE tl::nullopt
+#define EDITION_2018 Edition::E2018
+#define EDITION_NONE tl::nullopt
+#define REASON_SOME(r) r
+#define REASON_NONE tl::nullopt
+
+#define FEATURE_BASE(state, name_str, name, rust_since, issue, ...) \
+ Feature (Feature::Name::name, Feature::State::state, name_str, rust_since, \
+ issue, __VA_ARGS__),
+
+#define FEATURE_ACTIVE(a, b, c, d, edition) \
+ FEATURE_BASE (ACTIVE, a, b, c, d, edition, tl::nullopt)
+
+#define FEATURE_ACCEPTED(a, b, c, d) \
+ FEATURE_BASE (ACCEPTED, a, b, c, d, tl::nullopt, tl::nullopt)
+
+#define FEATURE_REMOVED(a, b, c, d, reason) \
+ FEATURE_BASE (REMOVED, a, b, c, d, tl::nullopt, reason)
+
+#define FEATURE_STABLE_REMOVED(a, b, c, d) \
+ FEATURE_BASE (ACCEPTED, a, b, c, d, tl::nullopt, tl::nullopt)
+
+#include "rust-feature-defs.h"
+
+#undef ISSUE_SOME
+#undef ISSUE_NONE
+#undef EDITION_2018
+#undef EDITION_NONE
+#undef REASON_SOME
+#undef REASON_NONE
+
+#undef FEATURE_BASE
+#undef FEATURE_ACTIVE
+#undef FEATURE_ACCEPTED
+#undef FEATURE_REMOVED
+#undef FEATURE_STABLE_REMOVED
+};
+
+const std::map<std::string, Feature::Name> Feature::name_hash_map = {
+#define FEATURE(s, name, ...) {s, Feature::Name::name},
+#define FEATURE_ACTIVE(...) FEATURE (__VA_ARGS__)
+#define FEATURE_ACCEPTED(...) FEATURE (__VA_ARGS__)
+#define FEATURE_REMOVED(...) FEATURE (__VA_ARGS__)
+#define FEATURE_STABLE_REMOVED(...) FEATURE (__VA_ARGS__)
+#include "rust-feature-defs.h"
+#undef FEATURE
+#undef FEATURE_ACTIVE
+#undef FEATURE_ACCEPTED
+#undef FEATURE_REMOVED
+#undef FEATURE_STABLE_REMOVED
+};
+
+tl::optional<Feature::Name>
+Feature::as_name (const std::string &name)
+{
+ auto it = Feature::name_hash_map.find (name);
+ if (it == Feature::name_hash_map.end ())
+ return tl::nullopt;
+ else
+ return it->second;
+}
+
+tl::optional<std::reference_wrapper<const Feature>>
+Feature::lookup (const std::string &name)
+{
+ return as_name (name).map (
+ [] (Name n) { return std::ref (Feature::lookup (n)); });
+}
+
+const Feature &
+Feature::lookup (Feature::Name name)
+{
+ return feature_list[static_cast<size_t> (name)];
+}
+
+} // namespace Rust
diff --git a/gcc/rust/checks/errors/feature/rust-feature.h b/gcc/rust/checks/errors/feature/rust-feature.h
new file mode 100644
index 0000000..8686cf4
--- /dev/null
+++ b/gcc/rust/checks/errors/feature/rust-feature.h
@@ -0,0 +1,85 @@
+// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_FEATURE_H
+#define RUST_FEATURE_H
+
+#include "rust-edition.h"
+#include "optional.h"
+
+namespace Rust {
+
+class Feature
+{
+public:
+ enum class State
+ {
+ ACCEPTED, // stabilized
+ ACTIVE, // unstable
+ REMOVED, // removed
+ STABILIZED, // removed after stabilization
+ };
+
+ enum class Name
+ {
+#define FEATURE_ACTIVE(x, name, ...) name,
+#define FEATURE_ACCEPTED(x, name, ...) name,
+#define FEATURE_REMOVED(x, name, ...) name,
+#define FEATURE_STABLE_REMOVED(x, name, ...) name,
+#include "rust-feature-defs.h"
+#undef FEATURE_ACTIVE
+#undef FEATURE_ACCEPTED
+#undef FEATURE_REMOVED
+#undef FEATURE_STABLE_REMOVED
+ };
+
+ const std::string &as_string () const { return m_name_str; }
+
+ Name name () const { return m_name; }
+ State state () const { return m_state; }
+ tl::optional<unsigned> issue () const { return m_issue; }
+
+ static tl::optional<Name> as_name (const std::string &name);
+
+ static tl::optional<std::reference_wrapper<const Feature>>
+ lookup (const std::string &name);
+ static const Feature &lookup (Name name);
+
+private:
+ Feature (Name name, State state, const char *name_str, const char *rust_since,
+ tl::optional<unsigned> issue_number, tl::optional<Edition> edition,
+ tl::optional<const char *> reason)
+ : m_name (name), m_state (state), m_name_str (name_str),
+ m_rust_since (rust_since), m_issue (issue_number), edition (edition),
+ m_reason (reason)
+ {}
+
+ Name m_name;
+ State m_state;
+ std::string m_name_str;
+ std::string m_rust_since;
+ tl::optional<unsigned> m_issue;
+ tl::optional<Edition> edition;
+ tl::optional<const char *> m_reason;
+
+ static Feature feature_list[];
+ static const std::map<std::string, Name> name_hash_map;
+};
+
+} // namespace Rust
+#endif
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
index 5291276..90248d3 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
@@ -20,7 +20,7 @@
#include "rust-reachability.h"
#include "rust-hir-type-check.h"
#include "rust-hir-map.h"
-#include "rust-name-resolver.h"
+#include "rust-immutable-name-resolution-context.h"
#include "rust-visibility-resolver.h"
#include "rust-pub-restricted-visitor.h"
#include "rust-privacy-reporter.h"
@@ -35,12 +35,13 @@ Resolver::resolve (HIR::Crate &crate)
{
PrivacyContext ctx;
auto &mappings = Analysis::Mappings::get ();
- auto resolver = Rust::Resolver::Resolver::get ();
+ auto &resolver
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
auto ty_ctx = ::Rust::Resolver::TypeCheckContext::get ();
- VisibilityResolver (mappings, *resolver).go (crate);
+ VisibilityResolver (mappings, resolver).go (crate);
PubRestrictedVisitor (mappings).go (crate);
- PrivacyReporter (mappings, *resolver, *ty_ctx).go (crate);
+ PrivacyReporter (mappings, resolver, *ty_ctx).go (crate);
auto visitor = ReachabilityVisitor (ctx, *ty_ctx);
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 4af9639..c1a3d45 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -28,7 +28,8 @@ namespace Rust {
namespace Privacy {
PrivacyReporter::PrivacyReporter (
- Analysis::Mappings &mappings, Resolver::Resolver &resolver,
+ Analysis::Mappings &mappings,
+ const Resolver2_0::NameResolutionContext &resolver,
const Rust::Resolver::TypeCheckContext &ty_ctx)
: mappings (mappings), resolver (resolver), ty_ctx (ty_ctx),
current_module (tl::nullopt)
@@ -90,59 +91,18 @@ PrivacyReporter::go (HIR::Crate &crate)
}
}
-static bool
-is_child_module (Analysis::Mappings &mappings, NodeId parent,
- NodeId possible_child)
-{
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
-
- return nr_ctx.values.is_module_descendant (parent, possible_child);
- }
-
- auto children = mappings.lookup_module_children (parent);
-
- if (!children)
- return false;
-
- // Visit all toplevel children
- for (auto &child : *children)
- if (child == possible_child)
- return true;
-
- // Now descend recursively in the child module tree
- for (auto &child : *children)
- if (is_child_module (mappings, child, possible_child))
- return true;
-
- return false;
-}
-
// FIXME: This function needs a lot of refactoring
void
PrivacyReporter::check_for_privacy_violation (const NodeId &use_id,
const location_t locus)
{
- NodeId ref_node_id = UNKNOWN_NODEID;
-
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
-
- if (auto id = nr_ctx.lookup (use_id))
- ref_node_id = *id;
- }
- // FIXME: Don't assert here - we might be dealing with a type
- else if (!resolver.lookup_resolved_name (use_id, &ref_node_id))
- resolver.lookup_resolved_type (use_id, &ref_node_id);
+ NodeId ref_node_id;
// FIXME: Assert here. For now, we return since this causes issues when
// checking inferred types (#1260)
- // rust_assert (ref_node_id != UNKNOWN_NODEID);
- if (ref_node_id == UNKNOWN_NODEID)
+ if (auto id = resolver.lookup (use_id))
+ ref_node_id = *id;
+ else
return;
auto vis = mappings.lookup_visibility (ref_node_id);
@@ -175,7 +135,9 @@ PrivacyReporter::check_for_privacy_violation (const NodeId &use_id,
// FIXME: This needs a LOT of TLC: hinting about the definition, a
// string to say if it's a module, function, type, etc...
- if (!is_child_module (mappings, mod_node_id, current_module.value ()))
+
+ if (!resolver.values.is_module_descendant (mod_node_id,
+ current_module.value ()))
valid = false;
}
break;
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
index 72716a6..d64b7a7 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
@@ -22,8 +22,9 @@
#include "rust-hir-expr.h"
#include "rust-hir-map.h"
#include "rust-hir-visitor.h"
+#include "rust-hir-type-check.h"
#include "rust-mapping-common.h"
-#include "rust-name-resolver.h"
+#include "rust-name-resolution-context.h"
namespace Rust {
namespace Privacy {
@@ -38,7 +39,7 @@ class PrivacyReporter : public HIR::HIRExpressionVisitor,
{
public:
PrivacyReporter (Analysis::Mappings &mappings,
- Rust::Resolver::Resolver &resolver,
+ const Resolver2_0::NameResolutionContext &resolver,
const Rust::Resolver::TypeCheckContext &ty_ctx);
/**
@@ -157,7 +158,7 @@ types
virtual void visit (HIR::ExprStmt &stmt);
Analysis::Mappings &mappings;
- Rust::Resolver::Resolver &resolver;
+ const Resolver2_0::NameResolutionContext &resolver;
const Rust::Resolver::TypeCheckContext &ty_ctx;
// `None` means we're in the root module - the crate
diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
index c59763d..4240673 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
@@ -20,16 +20,14 @@
#include "rust-ast.h"
#include "rust-hir.h"
#include "rust-hir-item.h"
-#include "rust-immutable-name-resolution-context.h"
-
-// for flag_name_resolution_2_0
-#include "options.h"
+#include "rust-name-resolution-context.h"
namespace Rust {
namespace Privacy {
-VisibilityResolver::VisibilityResolver (Analysis::Mappings &mappings,
- Resolver::Resolver &resolver)
+VisibilityResolver::VisibilityResolver (
+ Analysis::Mappings &mappings,
+ const Resolver2_0::NameResolutionContext &resolver)
: mappings (mappings), resolver (resolver)
{}
@@ -64,23 +62,12 @@ VisibilityResolver::resolve_module_path (const HIR::SimplePath &restriction,
= Error (restriction.get_locus (),
"cannot use non-module path as privacy restrictor");
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (flag_name_resolution_2_0)
+ NodeId ref_node_id;
+ if (auto id = resolver.lookup (ast_node_id))
{
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
-
- if (auto id = nr_ctx.lookup (ast_node_id))
- {
- ref_node_id = *id;
- }
- else
- {
- invalid_path.emit ();
- return false;
- }
+ ref_node_id = *id;
}
- else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ else
{
invalid_path.emit ();
return false;
diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h
index 4dfba4c..ddd70a8 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h
@@ -24,7 +24,7 @@
#include "rust-hir-stmt.h"
#include "rust-hir-item.h"
#include "rust-hir-map.h"
-#include "rust-name-resolver.h"
+#include "rust-name-resolution-context.h"
#include "rust-hir-visitor.h"
namespace Rust {
@@ -34,7 +34,7 @@ class VisibilityResolver : public HIR::HIRVisItemVisitor
{
public:
VisibilityResolver (Analysis::Mappings &mappings,
- Rust::Resolver::Resolver &resolver);
+ const Resolver2_0::NameResolutionContext &resolver);
/**
* Perform visibility resolving on an entire crate
@@ -93,7 +93,7 @@ public:
private:
Analysis::Mappings &mappings;
- Rust::Resolver::Resolver &resolver;
+ const Resolver2_0::NameResolutionContext &resolver;
DefId current_module;
};
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index c40f9db..782d694 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -813,11 +813,11 @@ ConstChecker::visit (StructPattern &)
{}
void
-ConstChecker::visit (TupleStructItemsNoRange &)
+ConstChecker::visit (TupleStructItemsNoRest &)
{}
void
-ConstChecker::visit (TupleStructItemsRange &)
+ConstChecker::visit (TupleStructItemsHasRest &)
{}
void
@@ -825,11 +825,11 @@ ConstChecker::visit (TupleStructPattern &)
{}
void
-ConstChecker::visit (TuplePatternItemsMultiple &)
+ConstChecker::visit (TuplePatternItemsNoRest &)
{}
void
-ConstChecker::visit (TuplePatternItemsRanged &)
+ConstChecker::visit (TuplePatternItemsHasRest &)
{}
void
@@ -837,6 +837,14 @@ ConstChecker::visit (TuplePattern &)
{}
void
+ConstChecker::visit (SlicePatternItemsNoRest &)
+{}
+
+void
+ConstChecker::visit (SlicePatternItemsHasRest &)
+{}
+
+void
ConstChecker::visit (SlicePattern &)
{}
diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h
index eb63095..d464b7b 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -180,12 +180,14 @@ private:
virtual void visit (StructPatternFieldIdentPat &field) override;
virtual void visit (StructPatternFieldIdent &field) override;
virtual void visit (StructPattern &pattern) override;
- virtual void visit (TupleStructItemsNoRange &tuple_items) override;
- virtual void visit (TupleStructItemsRange &tuple_items) override;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) override;
virtual void visit (TupleStructPattern &pattern) override;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) override;
- virtual void visit (TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (TuplePattern &pattern) override;
+ virtual void visit (SlicePatternItemsNoRest &items) override;
+ virtual void visit (SlicePatternItemsHasRest &items) override;
virtual void visit (SlicePattern &pattern) override;
virtual void visit (AltPattern &pattern) override;
virtual void visit (EmptyStmt &stmt) override;
diff --git a/gcc/rust/checks/errors/rust-feature.cc b/gcc/rust/checks/errors/rust-feature.cc
deleted file mode 100644
index 071d3f8..0000000
--- a/gcc/rust/checks/errors/rust-feature.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (C) 2020-2025 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#include "rust-feature.h"
-
-namespace Rust {
-
-Feature
-Feature::create (Feature::Name f)
-{
- switch (f)
- {
- case Feature::Name::ASSOCIATED_TYPE_BOUNDS:
- return Feature (Feature::Name::ASSOCIATED_TYPE_BOUNDS,
- Feature::State::ACCEPTED, "associated_type_bounds",
- "1.34.0", 52662);
- case Feature::Name::INTRINSICS:
- return Feature (f, Feature::State::ACCEPTED, "intrinsics", "1.0.0");
- case Feature::Name::RUSTC_ATTRS:
- return Feature (f, Feature::State::ACCEPTED, "rustc_attrs", "1.0.0");
- case Feature::Name::DECL_MACRO:
- return Feature (f, Feature::State::ACCEPTED, "decl_macro", "1.0.0",
- 39412);
- case Feature::Name::EXTERN_TYPES:
- return Feature (f, Feature::State::ACTIVE, "extern_types", "1.23.0",
- 43467);
- case Feature::Name::NEGATIVE_IMPLS:
- return Feature (f, Feature::State::ACTIVE, "negative_impls", "1.0.0",
- 68318);
- case Feature::Name::BOX_SYNTAX:
- return Feature (f, Feature::State::ACTIVE, "box_syntax", "1.0.0", 49733);
- case Feature::Name::DROPCK_EYEPATCH:
- return Feature (f, Feature::State::ACTIVE, "dropck_eyepatch", "1.10.0",
- 34761);
- case Feature::Name::RAW_REF_OP:
- return Feature (f, Feature::State::ACTIVE, "raw_ref_op", "1.41.0", 64490);
- case Feature::Name::EXCLUSIVE_RANGE_PATTERN:
- return Feature (Feature::Name::EXCLUSIVE_RANGE_PATTERN,
- Feature::State::ACTIVE, "exclusive_range_pattern",
- "1.11.0", 37854);
- case Feature::Name::PRELUDE_IMPORT:
- return Feature (f, Feature::State::ACTIVE, "prelude_import", "1.0.0");
- case Feature::Name::MIN_SPECIALIZATION:
- return Feature (f, Feature::State::ACTIVE, "min_specialization",
- "1.0.0" /* FIXME: What version here? */, 31844);
- case Feature::Name::AUTO_TRAITS:
- return Feature (f, Feature::State::ACTIVE, "optin_builtin_traits",
- "1.0.0", 13231);
- default:
- rust_unreachable ();
- }
-}
-
-const std::map<std::string, Feature::Name> Feature::name_hash_map = {
- {"associated_type_bounds", Feature::Name::ASSOCIATED_TYPE_BOUNDS},
- {"intrinsics", Feature::Name::INTRINSICS},
- {"rustc_attrs", Feature::Name::RUSTC_ATTRS},
- {"decl_macro", Feature::Name::DECL_MACRO},
- {"negative_impls", Feature::Name::NEGATIVE_IMPLS},
- // TODO: Rename to "auto_traits" when supporting
- // later Rust versions
- {"optin_builtin_traits", Feature::Name::AUTO_TRAITS},
- {"extern_types", Feature::Name::EXTERN_TYPES},
- {"lang_items", Feature::Name::LANG_ITEMS},
- {"no_core", Feature::Name::NO_CORE},
- {"box_syntax", Feature::Name::BOX_SYNTAX},
- {"dropck_eyepatch", Feature::Name::DROPCK_EYEPATCH},
- {"raw_ref_op", Feature::Name::RAW_REF_OP},
- {"exclusive_range_pattern", Feature::Name::EXCLUSIVE_RANGE_PATTERN},
- {"prelude_import", Feature::Name::PRELUDE_IMPORT},
- {"min_specialization", Feature::Name::MIN_SPECIALIZATION},
-};
-
-tl::optional<Feature::Name>
-Feature::as_name (const std::string &name)
-{
- if (Feature::name_hash_map.count (name))
- return Feature::name_hash_map.at (name);
-
- return tl::nullopt;
-}
-
-} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-feature.h b/gcc/rust/checks/errors/rust-feature.h
deleted file mode 100644
index e7cb0af..0000000
--- a/gcc/rust/checks/errors/rust-feature.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (C) 2020-2025 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#ifndef RUST_FEATURE_H
-#define RUST_FEATURE_H
-
-#include "rust-edition.h"
-#include "optional.h"
-
-namespace Rust {
-
-class Feature
-{
-public:
- enum class State
- {
- ACCEPTED,
- ACTIVE,
- REMOVED,
- STABILIZED,
- };
-
- enum class Name
- {
- ASSOCIATED_TYPE_BOUNDS,
- INTRINSICS,
- NEGATIVE_IMPLS,
- RUSTC_ATTRS,
- DECL_MACRO,
- AUTO_TRAITS,
- EXTERN_TYPES,
- LANG_ITEMS,
- NO_CORE,
- BOX_SYNTAX,
- DROPCK_EYEPATCH,
- RAW_REF_OP,
- EXCLUSIVE_RANGE_PATTERN,
- PRELUDE_IMPORT,
- MIN_SPECIALIZATION,
- };
-
- const std::string &as_string () { return m_name_str; }
- Name name () { return m_name; }
- const std::string &description () { return m_description; }
- State state () { return m_state; }
- tl::optional<unsigned> issue () { return m_issue; }
-
- static tl::optional<Name> as_name (const std::string &name);
- static Feature create (Name name);
-
-private:
- Feature (Name name, State state, const char *name_str,
- const char *rustc_since,
- tl::optional<unsigned> issue_number = tl::nullopt,
- const tl::optional<Edition> &edition = tl::nullopt,
- const char *description = "")
- : m_state (state), m_name (name), m_name_str (name_str),
- m_rustc_since (rustc_since), m_issue (issue_number), edition (edition),
- m_description (description)
- {}
-
- State m_state;
- Name m_name;
- std::string m_name_str;
- std::string m_rustc_since;
- tl::optional<unsigned> m_issue;
- tl::optional<Edition> edition;
- std::string m_description; // TODO: Switch to optional?
-
- static const std::map<std::string, Name> name_hash_map;
-};
-
-} // namespace Rust
-#endif
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index 2566971..f132e04 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -28,15 +28,12 @@
#include "rust-tyty.h"
#include "rust-immutable-name-resolution-context.h"
-// for flag_name_resolution_2_0
-#include "options.h"
-
namespace Rust {
namespace Analysis {
PatternChecker::PatternChecker ()
: tyctx (*Resolver::TypeCheckContext::get ()),
- resolver (*Resolver::Resolver::get ()),
+ resolver (Resolver2_0::ImmutableNameResolutionContext::get ().resolver ()),
mappings (Analysis::Mappings::get ())
{}
@@ -238,17 +235,9 @@ PatternChecker::visit (CallExpr &expr)
NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid ();
NodeId ref_node_id;
- if (flag_name_resolution_2_0)
- {
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
-
- if (auto id = nr_ctx.lookup (ast_node_id))
- ref_node_id = *id;
- else
- return;
- }
- else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ if (auto id = resolver.lookup (ast_node_id))
+ ref_node_id = *id;
+ else
return;
if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id))
@@ -640,11 +629,11 @@ PatternChecker::visit (StructPattern &)
{}
void
-PatternChecker::visit (TupleStructItemsNoRange &)
+PatternChecker::visit (TupleStructItemsNoRest &)
{}
void
-PatternChecker::visit (TupleStructItemsRange &)
+PatternChecker::visit (TupleStructItemsHasRest &)
{}
void
@@ -652,11 +641,11 @@ PatternChecker::visit (TupleStructPattern &)
{}
void
-PatternChecker::visit (TuplePatternItemsMultiple &)
+PatternChecker::visit (TuplePatternItemsNoRest &)
{}
void
-PatternChecker::visit (TuplePatternItemsRanged &)
+PatternChecker::visit (TuplePatternItemsHasRest &)
{}
void
@@ -664,6 +653,14 @@ PatternChecker::visit (TuplePattern &)
{}
void
+PatternChecker::visit (SlicePatternItemsNoRest &)
+{}
+
+void
+PatternChecker::visit (SlicePatternItemsHasRest &)
+{}
+
+void
PatternChecker::visit (SlicePattern &)
{}
@@ -980,7 +977,7 @@ Matrix::specialize (const Constructor &ctor) const
if (ctor.is_covered_by (hd.ctor ()))
{
pats.pop_head_constructor (ctor, subfields_place_info.size ());
- new_rows.push_back (MatrixRow (pats, row.is_under_guard ()));
+ new_rows.emplace_back (pats, row.is_under_guard ());
}
}
@@ -1186,7 +1183,7 @@ WitnessMatrix::apply_constructor (const Constructor &ctor,
}
}
- stack.push_back (WitnessPat (ctor, subfield, ty));
+ stack.emplace_back (ctor, subfield, ty);
}
}
@@ -1213,27 +1210,54 @@ lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
std::vector<DeconstructedPat> fields;
switch (elems.get_item_type ())
{
- case HIR::TupleStructItems::ItemType::MULTIPLE:
+ case HIR::TupleStructItems::ItemType::NO_REST:
{
- HIR::TupleStructItemsNoRange &multiple
- = static_cast<HIR::TupleStructItemsNoRange &> (elems);
+ HIR::TupleStructItemsNoRest &items_no_rest
+ = static_cast<HIR::TupleStructItemsNoRest &> (elems);
rust_assert (variant->get_fields ().size ()
- == multiple.get_patterns ().size ());
+ == items_no_rest.get_patterns ().size ());
- for (size_t i = 0; i < multiple.get_patterns ().size (); i++)
+ for (size_t i = 0; i < items_no_rest.get_patterns ().size (); i++)
{
fields.push_back (
- lower_pattern (ctx, *multiple.get_patterns ().at (i),
+ lower_pattern (ctx, *items_no_rest.get_patterns ().at (i),
variant->get_fields ().at (i)->get_field_type ()));
}
return DeconstructedPat (ctor, arity, fields, pattern.get_locus ());
}
break;
- case HIR::TupleStructItems::ItemType::RANGED:
+ case HIR::TupleStructItems::ItemType::HAS_REST:
{
- // TODO: ranged tuple struct items
- rust_unreachable ();
+ HIR::TupleStructItemsHasRest &items_has_rest
+ = static_cast<HIR::TupleStructItemsHasRest &> (elems);
+
+ size_t num_patterns = items_has_rest.get_lower_patterns ().size ()
+ + items_has_rest.get_upper_patterns ().size ();
+
+ rust_assert (num_patterns <= variant->num_fields ());
+
+ size_t i = 0;
+ for (auto &pattern_member : items_has_rest.get_lower_patterns ())
+ {
+ fields.push_back (lower_pattern (
+ ctx, *pattern_member,
+ variant->get_fields ().at (i++)->get_field_type ()));
+ }
+ while (i < variant->num_fields ()
+ - items_has_rest.get_upper_patterns ().size ())
+ {
+ fields.push_back (
+ DeconstructedPat::make_wildcard (pattern.get_locus ()));
+ i++;
+ }
+ for (auto &pattern_member : items_has_rest.get_upper_patterns ())
+ {
+ fields.push_back (lower_pattern (
+ ctx, *pattern_member,
+ variant->get_fields ().at (i++)->get_field_type ()));
+ }
+ return DeconstructedPat (ctor, arity, fields, pattern.get_locus ());
}
break;
default:
@@ -1597,7 +1621,7 @@ check_match_usefulness (Resolver::TypeCheckContext *ctx,
MatchArm lowered = lower_arm (ctx, arm, scrutinee_ty);
PatOrWild pat = PatOrWild::make_pattern (lowered.get_pat ());
pats.push (pat);
- rows.push_back (MatrixRow (pats, lowered.has_guard ()));
+ rows.emplace_back (pats, lowered.has_guard ());
}
std::vector<PlaceInfo> place_infos = {{PlaceInfo (scrutinee_ty)}};
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
index dd44abc..645e61d 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
@@ -26,7 +26,7 @@
#include "rust-tyty.h"
#include "optional.h"
#include "rust-hir-visitor.h"
-#include "rust-name-resolver.h"
+#include "rust-immutable-name-resolution-context.h"
namespace Rust {
namespace Analysis {
@@ -46,7 +46,7 @@ public:
private:
Resolver::TypeCheckContext &tyctx;
- Resolver::Resolver &resolver;
+ const Resolver2_0::NameResolutionContext &resolver;
Analysis::Mappings &mappings;
virtual void visit (Lifetime &lifetime) override;
@@ -153,12 +153,14 @@ private:
virtual void visit (StructPatternFieldIdentPat &field) override;
virtual void visit (StructPatternFieldIdent &field) override;
virtual void visit (StructPattern &pattern) override;
- virtual void visit (TupleStructItemsNoRange &tuple_items) override;
- virtual void visit (TupleStructItemsRange &tuple_items) override;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) override;
virtual void visit (TupleStructPattern &pattern) override;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) override;
- virtual void visit (TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (TuplePattern &pattern) override;
+ virtual void visit (SlicePatternItemsNoRest &items) override;
+ virtual void visit (SlicePatternItemsHasRest &items) override;
virtual void visit (SlicePattern &pattern) override;
virtual void visit (AltPattern &pattern) override;
virtual void visit (EmptyStmt &stmt) override;
diff --git a/gcc/rust/checks/errors/rust-readonly-check.cc b/gcc/rust/checks/errors/rust-readonly-check.cc
index c128933..f484047 100644
--- a/gcc/rust/checks/errors/rust-readonly-check.cc
+++ b/gcc/rust/checks/errors/rust-readonly-check.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2021-2025 Free Software Foundation, Inc.
+// Copyright (C) 2025 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -17,184 +17,252 @@
// <http://www.gnu.org/licenses/>.
#include "rust-readonly-check.h"
-#include "rust-tree.h"
-#include "rust-gcc.h"
-#include "print-tree.h"
+#include "rust-hir-expr.h"
+#include "rust-hir-node.h"
+#include "rust-hir-path.h"
+#include "rust-hir-map.h"
+#include "rust-hir-pattern.h"
+#include "rust-mapping-common.h"
+#include "rust-system.h"
+#include "rust-immutable-name-resolution-context.h"
+#include "rust-tyty.h"
namespace Rust {
-namespace Analysis {
+namespace HIR {
-static std::map<tree, int> assignment_map = {};
+static std::set<HirId> already_assigned_variables = {};
+
+ReadonlyChecker::ReadonlyChecker ()
+ : resolver (*Resolver::Resolver::get ()),
+ mappings (Analysis::Mappings::get ()),
+ context (*Resolver::TypeCheckContext::get ())
+{}
+
+void
+ReadonlyChecker::go (Crate &crate)
+{
+ for (auto &item : crate.get_items ())
+ item->accept_vis (*this);
+}
-// ported over from c-family/c-warn.cc
void
-readonly_error (location_t loc, tree arg, enum lvalue_use use)
+ReadonlyChecker::visit (AssignmentExpr &expr)
{
- gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement
- || use == lv_asm);
- STRIP_ANY_LOCATION_WRAPPER (arg);
- /* Using this macro rather than (for example) arrays of messages
- ensures that all the format strings are checked at compile
- time. */
-#define READONLY_MSG(A, I, D, AS) \
- (use == lv_assign \
- ? (A) \
- : (use == lv_increment ? (I) : (use == lv_decrement ? (D) : (AS))))
- if (TREE_CODE (arg) == COMPONENT_REF)
+ Expr &lhs = expr.get_lhs ();
+ mutable_context.enter (expr.get_mappings ().get_hirid ());
+ lhs.accept_vis (*this);
+ mutable_context.exit ();
+}
+
+void
+ReadonlyChecker::visit (PathInExpression &expr)
+{
+ if (!mutable_context.is_in_context ())
+ return;
+
+ NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
+ NodeId def_id;
+
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+ if (auto id = nr_ctx.lookup (ast_node_id))
+ def_id = *id;
+ else
+ return;
+
+ auto hir_id = mappings.lookup_node_to_hir (def_id);
+ if (!hir_id)
+ return;
+
+ // Check if the local variable is mutable.
+ auto maybe_pattern = mappings.lookup_hir_pattern (*hir_id);
+ if (maybe_pattern
+ && maybe_pattern.value ()->get_pattern_type ()
+ == HIR::Pattern::PatternType::IDENTIFIER)
+ check_variable (static_cast<IdentifierPattern *> (maybe_pattern.value ()),
+ expr.get_locus ());
+
+ // Check if the static item is mutable.
+ auto maybe_item = mappings.lookup_hir_item (*hir_id);
+ if (maybe_item
+ && maybe_item.value ()->get_item_kind () == HIR::Item::ItemKind::Static)
{
- if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
- error_at (loc,
- READONLY_MSG (G_ ("assignment of member "
- "%qD in read-only object"),
- G_ ("increment of member "
- "%qD in read-only object"),
- G_ ("decrement of member "
- "%qD in read-only object"),
- G_ ("member %qD in read-only object "
- "used as %<asm%> output")),
- TREE_OPERAND (arg, 1));
- else
- error_at (
- loc,
- READONLY_MSG (G_ ("assignment of read-only member %qD"),
- G_ ("increment of read-only member %qD"),
- G_ ("decrement of read-only member %qD"),
- G_ ("read-only member %qD used as %<asm%> output")),
- TREE_OPERAND (arg, 1));
+ auto static_item = static_cast<HIR::StaticItem *> (*maybe_item);
+ if (!static_item->is_mut ())
+ rust_error_at (expr.get_locus (),
+ "assignment of read-only location '%s'",
+ static_item->get_identifier ().as_string ().c_str ());
}
- else if (VAR_P (arg))
- error_at (loc,
- READONLY_MSG (G_ ("assignment of read-only variable %qD"),
- G_ ("increment of read-only variable %qD"),
- G_ ("decrement of read-only variable %qD"),
- G_ (
- "read-only variable %qD used as %<asm%> output")),
- arg);
- else if (TREE_CODE (arg) == PARM_DECL)
- error_at (loc,
- READONLY_MSG (G_ ("assignment of read-only parameter %qD"),
- G_ ("increment of read-only parameter %qD"),
- G_ ("decrement of read-only parameter %qD"),
- G_ (
- "read-only parameter %qD use as %<asm%> output")),
- arg);
- else if (TREE_CODE (arg) == RESULT_DECL)
+
+ // Check if the constant item is mutable.
+ if (maybe_item
+ && maybe_item.value ()->get_item_kind () == HIR::Item::ItemKind::Constant)
{
- error_at (loc,
- READONLY_MSG (G_ ("assignment of "
- "read-only named return value %qD"),
- G_ ("increment of "
- "read-only named return value %qD"),
- G_ ("decrement of "
- "read-only named return value %qD"),
- G_ ("read-only named return value %qD "
- "used as %<asm%>output")),
- arg);
+ auto const_item = static_cast<HIR::ConstantItem *> (*maybe_item);
+ rust_error_at (expr.get_locus (), "assignment of read-only location '%s'",
+ const_item->get_identifier ().as_string ().c_str ());
}
- else if (TREE_CODE (arg) == FUNCTION_DECL)
- error_at (loc,
- READONLY_MSG (G_ ("assignment of function %qD"),
- G_ ("increment of function %qD"),
- G_ ("decrement of function %qD"),
- G_ ("function %qD used as %<asm%> output")),
- arg);
- else
- error_at (loc,
- READONLY_MSG (G_ ("assignment of read-only location %qE"),
- G_ ("increment of read-only location %qE"),
- G_ ("decrement of read-only location %qE"),
- G_ (
- "read-only location %qE used as %<asm%> output")),
- arg);
}
-static void
-emit_error (tree *t, tree lhs, enum lvalue_use use)
+void
+ReadonlyChecker::check_variable (IdentifierPattern *pattern,
+ location_t assigned_loc)
{
- readonly_error (EXPR_LOCATION (*t), lhs, use);
- TREE_OPERAND (*t, 0) = error_mark_node;
+ if (!mutable_context.is_in_context ())
+ return;
+
+ TyTy::BaseType *type;
+ if (context.lookup_type (pattern->get_mappings ().get_hirid (), &type)
+ && is_mutable_type (type))
+ return;
+ if (pattern->is_mut ())
+ return;
+
+ auto hir_id = pattern->get_mappings ().get_hirid ();
+ if (already_assigned_variables.count (hir_id) > 0)
+ rust_error_at (assigned_loc, "assignment of read-only variable '%s'",
+ pattern->as_string ().c_str ());
+ already_assigned_variables.insert (hir_id);
}
-static void
-check_modify_expr (tree *t)
+void
+ReadonlyChecker::collect_assignment_identifier (IdentifierPattern &pattern,
+ bool has_init_expr)
{
- tree lhs = TREE_OPERAND (*t, 0);
- if (TREE_CODE (lhs) == ARRAY_REF || TREE_CODE (lhs) == COMPONENT_REF)
- lhs = TREE_OPERAND (lhs, 0);
-
- tree lhs_type = TREE_TYPE (lhs);
- if (TYPE_READONLY (lhs_type) || TREE_READONLY (lhs) || TREE_CONSTANT (lhs))
+ if (has_init_expr)
{
- if (TREE_CODE (lhs) != VAR_DECL)
- emit_error (t, lhs, lv_assign);
- else if (!DECL_ARTIFICIAL (lhs))
- {
- if (DECL_INITIAL (lhs) != NULL)
- emit_error (t, lhs, lv_assign);
- else
- {
- if (assignment_map.find (lhs) == assignment_map.end ())
- {
- assignment_map.insert ({lhs, 0});
- }
- assignment_map[lhs]++;
-
- if (assignment_map[lhs] > 1)
- emit_error (t, lhs, lv_assign);
- }
- }
+ HirId pattern_id = pattern.get_mappings ().get_hirid ();
+ already_assigned_variables.insert (pattern_id);
}
}
-static void
-check_decl (tree *t)
+void
+ReadonlyChecker::collect_assignment_tuple (TuplePattern &tuple_pattern,
+ bool has_init_expr)
{
- switch (TREE_CODE (*t))
+ switch (tuple_pattern.get_items ().get_item_type ())
{
- case MODIFY_EXPR:
- check_modify_expr (t);
+ case HIR::TuplePatternItems::ItemType::NO_REST:
+ {
+ auto &items_no_rest = static_cast<HIR::TuplePatternItemsNoRest &> (
+ tuple_pattern.get_items ());
+ for (auto &sub : items_no_rest.get_patterns ())
+ {
+ collect_assignment (*sub, has_init_expr);
+ }
+ }
+ break;
+ case HIR::TuplePatternItems::ItemType::HAS_REST:
+ {
+ auto &items_has_rest = static_cast<HIR::TuplePatternItemsHasRest &> (
+ tuple_pattern.get_items ());
+ for (auto &sub : items_has_rest.get_lower_patterns ())
+ collect_assignment (*sub, has_init_expr);
+ for (auto &sub : items_has_rest.get_upper_patterns ())
+ collect_assignment (*sub, has_init_expr);
+ }
+ break;
+ default:
break;
+ }
+}
+void
+ReadonlyChecker::collect_assignment (Pattern &pattern, bool has_init_expr)
+{
+ switch (pattern.get_pattern_type ())
+ {
+ case HIR::Pattern::PatternType::IDENTIFIER:
+ {
+ collect_assignment_identifier (static_cast<IdentifierPattern &> (
+ pattern),
+ has_init_expr);
+ }
+ break;
+ case HIR::Pattern::PatternType::TUPLE:
+ {
+ auto &tuple_pattern = static_cast<HIR::TuplePattern &> (pattern);
+ collect_assignment_tuple (tuple_pattern, has_init_expr);
+ }
+ break;
default:
break;
}
}
-static tree
-readonly_walk_fn (tree *t, int *, void *)
+void
+ReadonlyChecker::visit (LetStmt &stmt)
+{
+ HIR::Pattern &pattern = stmt.get_pattern ();
+ collect_assignment (pattern, stmt.has_init_expr ());
+}
+
+void
+ReadonlyChecker::visit (FieldAccessExpr &expr)
{
- check_decl (t);
- return NULL_TREE;
+ if (mutable_context.is_in_context ())
+ {
+ expr.get_receiver_expr ().accept_vis (*this);
+ }
}
void
-ReadonlyCheck::Lint (Compile::Context &ctx)
+ReadonlyChecker::visit (TupleIndexExpr &expr)
{
- assignment_map.clear ();
- for (auto &fndecl : ctx.get_func_decls ())
+ if (mutable_context.is_in_context ())
{
- for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN (p))
- {
- check_decl (&p);
- }
+ expr.get_tuple_expr ().accept_vis (*this);
+ }
+}
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
- &readonly_walk_fn, &ctx);
+void
+ReadonlyChecker::visit (ArrayIndexExpr &expr)
+{
+ if (mutable_context.is_in_context ())
+ {
+ expr.get_array_expr ().accept_vis (*this);
}
+}
- assignment_map.clear ();
- for (auto &var : ctx.get_var_decls ())
+void
+ReadonlyChecker::visit (TupleExpr &expr)
+{
+ if (mutable_context.is_in_context ())
{
- tree decl = var->get_decl ();
- check_decl (&decl);
+ // TODO: Add check for tuple expression
}
+}
- assignment_map.clear ();
- for (auto &const_decl : ctx.get_const_decls ())
+void
+ReadonlyChecker::visit (LiteralExpr &expr)
+{
+ if (mutable_context.is_in_context ())
{
- check_decl (&const_decl);
+ rust_error_at (expr.get_locus (), "assignment of read-only location");
}
}
-} // namespace Analysis
+void
+ReadonlyChecker::visit (DereferenceExpr &expr)
+{
+ if (!mutable_context.is_in_context ())
+ return;
+ TyTy::BaseType *to_deref_type;
+ auto to_deref = expr.get_expr ().get_mappings ().get_hirid ();
+ if (!context.lookup_type (to_deref, &to_deref_type))
+ return;
+ if (!is_mutable_type (to_deref_type))
+ rust_error_at (expr.get_locus (), "assignment of read-only location");
+}
+
+bool
+ReadonlyChecker::is_mutable_type (TyTy::BaseType *type)
+{
+ if (type->get_kind () == TyTy::TypeKind::REF)
+ return static_cast<TyTy::ReferenceType *> (type)->is_mutable ();
+ if (type->get_kind () == TyTy::TypeKind::POINTER)
+ return static_cast<TyTy::PointerType *> (type)->is_mutable ();
+ return false;
+}
+} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-readonly-check.h b/gcc/rust/checks/errors/rust-readonly-check.h
index b39eee3..3525620 100644
--- a/gcc/rust/checks/errors/rust-readonly-check.h
+++ b/gcc/rust/checks/errors/rust-readonly-check.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2021-2025 Free Software Foundation, Inc.
+// Copyright (C) 2025 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -16,21 +16,54 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#ifndef RUST_READONLY_CHECK
-#define RUST_READONLY_CHECK
-
-#include "rust-compile-context.h"
+#include "rust-hir-visitor.h"
+#include "rust-name-resolver.h"
+#include "rust-stacked-contexts.h"
+#include "rust-hir-type-check.h"
namespace Rust {
-namespace Analysis {
-
-class ReadonlyCheck
+namespace HIR {
+class ReadonlyChecker : public DefaultHIRVisitor
{
public:
- static void Lint (Compile::Context &ctx);
-};
+ ReadonlyChecker ();
+
+ void go (HIR::Crate &crate);
+
+private:
+ enum class lvalue_use
+ {
+ assign,
+ increment,
+ decrement,
+ };
+
+ Resolver::Resolver &resolver;
+ Analysis::Mappings &mappings;
+ Resolver::TypeCheckContext &context;
+ StackedContexts<HirId> mutable_context;
-} // namespace Analysis
-} // namespace Rust
+ using DefaultHIRVisitor::visit;
+
+ virtual void visit (AssignmentExpr &expr) override;
+ virtual void visit (PathInExpression &expr) override;
+ virtual void visit (FieldAccessExpr &expr) override;
+ virtual void visit (ArrayIndexExpr &expr) override;
+ virtual void visit (TupleExpr &expr) override;
+ virtual void visit (TupleIndexExpr &expr) override;
+ virtual void visit (LetStmt &stmt) override;
+ virtual void visit (LiteralExpr &expr) override;
+ virtual void visit (DereferenceExpr &expr) override;
+
+ void collect_assignment (Pattern &pattern, bool has_init_expr);
+ void collect_assignment_identifier (IdentifierPattern &pattern,
+ bool has_init_expr);
+ void collect_assignment_tuple (TuplePattern &pattern, bool has_init_expr);
+
+ void check_variable (IdentifierPattern *pattern, location_t assigned_loc);
+
+ bool is_mutable_type (TyTy::BaseType *type);
+};
-#endif // RUST_READONLY_CHECK
+} // namespace HIR
+} // namespace Rust \ No newline at end of file
diff --git a/gcc/rust/checks/errors/rust-readonly-check2.cc b/gcc/rust/checks/errors/rust-readonly-check2.cc
deleted file mode 100644
index 2fa92ae..0000000
--- a/gcc/rust/checks/errors/rust-readonly-check2.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (C) 2025 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#include "rust-readonly-check2.h"
-#include "rust-hir-expr.h"
-#include "rust-hir-node.h"
-#include "rust-hir-path.h"
-#include "rust-hir-map.h"
-#include "rust-hir-pattern.h"
-#include "rust-mapping-common.h"
-#include "rust-system.h"
-#include "rust-immutable-name-resolution-context.h"
-#include "rust-tyty.h"
-
-namespace Rust {
-namespace HIR {
-
-static std::set<HirId> already_assigned_variables = {};
-
-ReadonlyChecker::ReadonlyChecker ()
- : resolver (*Resolver::Resolver::get ()),
- mappings (Analysis::Mappings::get ()),
- context (*Resolver::TypeCheckContext::get ())
-{}
-
-void
-ReadonlyChecker::go (Crate &crate)
-{
- for (auto &item : crate.get_items ())
- item->accept_vis (*this);
-}
-
-void
-ReadonlyChecker::visit (AssignmentExpr &expr)
-{
- Expr &lhs = expr.get_lhs ();
- mutable_context.enter (expr.get_mappings ().get_hirid ());
- lhs.accept_vis (*this);
- mutable_context.exit ();
-}
-
-void
-ReadonlyChecker::visit (PathInExpression &expr)
-{
- if (!mutable_context.is_in_context ())
- return;
-
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
- NodeId def_id;
-
- auto &nr_ctx
- = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- if (auto id = nr_ctx.lookup (ast_node_id))
- def_id = *id;
- else
- return;
-
- auto hir_id = mappings.lookup_node_to_hir (def_id);
- if (!hir_id)
- return;
-
- // Check if the local variable is mutable.
- auto maybe_pattern = mappings.lookup_hir_pattern (*hir_id);
- if (maybe_pattern
- && maybe_pattern.value ()->get_pattern_type ()
- == HIR::Pattern::PatternType::IDENTIFIER)
- check_variable (static_cast<IdentifierPattern *> (maybe_pattern.value ()),
- expr.get_locus ());
-
- // Check if the static item is mutable.
- auto maybe_item = mappings.lookup_hir_item (*hir_id);
- if (maybe_item
- && maybe_item.value ()->get_item_kind () == HIR::Item::ItemKind::Static)
- {
- auto static_item = static_cast<HIR::StaticItem *> (*maybe_item);
- if (!static_item->is_mut ())
- rust_error_at (expr.get_locus (),
- "assignment of read-only location '%s'",
- static_item->get_identifier ().as_string ().c_str ());
- }
-
- // Check if the constant item is mutable.
- if (maybe_item
- && maybe_item.value ()->get_item_kind () == HIR::Item::ItemKind::Constant)
- {
- auto const_item = static_cast<HIR::ConstantItem *> (*maybe_item);
- rust_error_at (expr.get_locus (), "assignment of read-only location '%s'",
- const_item->get_identifier ().as_string ().c_str ());
- }
-}
-
-void
-ReadonlyChecker::check_variable (IdentifierPattern *pattern,
- location_t assigned_loc)
-{
- if (!mutable_context.is_in_context ())
- return;
- if (pattern->is_mut ())
- return;
-
- auto hir_id = pattern->get_mappings ().get_hirid ();
- if (already_assigned_variables.count (hir_id) > 0)
- rust_error_at (assigned_loc, "assignment of read-only variable '%s'",
- pattern->as_string ().c_str ());
- already_assigned_variables.insert (hir_id);
-}
-
-void
-ReadonlyChecker::collect_assignment_identifier (IdentifierPattern &pattern,
- bool has_init_expr)
-{
- if (has_init_expr)
- {
- HirId pattern_id = pattern.get_mappings ().get_hirid ();
- already_assigned_variables.insert (pattern_id);
- }
-}
-
-void
-ReadonlyChecker::collect_assignment_tuple (TuplePattern &tuple_pattern,
- bool has_init_expr)
-{
- switch (tuple_pattern.get_items ().get_item_type ())
- {
- case HIR::TuplePatternItems::ItemType::MULTIPLE:
- {
- auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- tuple_pattern.get_items ());
- for (auto &sub : items.get_patterns ())
- {
- collect_assignment (*sub, has_init_expr);
- }
- }
- break;
- default:
- break;
- }
-}
-
-void
-ReadonlyChecker::collect_assignment (Pattern &pattern, bool has_init_expr)
-{
- switch (pattern.get_pattern_type ())
- {
- case HIR::Pattern::PatternType::IDENTIFIER:
- {
- collect_assignment_identifier (static_cast<IdentifierPattern &> (
- pattern),
- has_init_expr);
- }
- break;
- case HIR::Pattern::PatternType::TUPLE:
- {
- auto &tuple_pattern = static_cast<HIR::TuplePattern &> (pattern);
- collect_assignment_tuple (tuple_pattern, has_init_expr);
- }
- break;
- default:
- break;
- }
-}
-
-void
-ReadonlyChecker::visit (LetStmt &stmt)
-{
- HIR::Pattern &pattern = stmt.get_pattern ();
- collect_assignment (pattern, stmt.has_init_expr ());
-}
-
-void
-ReadonlyChecker::visit (FieldAccessExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- expr.get_receiver_expr ().accept_vis (*this);
- }
-}
-
-void
-ReadonlyChecker::visit (TupleIndexExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- expr.get_tuple_expr ().accept_vis (*this);
- }
-}
-
-void
-ReadonlyChecker::visit (ArrayIndexExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- expr.get_array_expr ().accept_vis (*this);
- }
-}
-
-void
-ReadonlyChecker::visit (TupleExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- // TODO: Add check for tuple expression
- }
-}
-
-void
-ReadonlyChecker::visit (LiteralExpr &expr)
-{
- if (mutable_context.is_in_context ())
- {
- rust_error_at (expr.get_locus (), "assignment of read-only location");
- }
-}
-
-void
-ReadonlyChecker::visit (DereferenceExpr &expr)
-{
- if (!mutable_context.is_in_context ())
- return;
- TyTy::BaseType *to_deref_type;
- auto to_deref = expr.get_expr ().get_mappings ().get_hirid ();
- if (!context.lookup_type (to_deref, &to_deref_type))
- return;
- if (to_deref_type->get_kind () == TyTy::TypeKind::REF)
- {
- auto ref_type = static_cast<TyTy::ReferenceType *> (to_deref_type);
- if (!ref_type->is_mutable ())
- rust_error_at (expr.get_locus (), "assignment of read-only location");
- }
- if (to_deref_type->get_kind () == TyTy::TypeKind::POINTER)
- {
- auto ptr_type = static_cast<TyTy::PointerType *> (to_deref_type);
- if (!ptr_type->is_mutable ())
- rust_error_at (expr.get_locus (), "assignment of read-only location");
- }
-}
-} // namespace HIR
-} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-readonly-check2.h b/gcc/rust/checks/errors/rust-readonly-check2.h
deleted file mode 100644
index 06af9db..0000000
--- a/gcc/rust/checks/errors/rust-readonly-check2.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2025 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#include "rust-hir-visitor.h"
-#include "rust-name-resolver.h"
-#include "rust-stacked-contexts.h"
-#include "rust-hir-type-check.h"
-
-namespace Rust {
-namespace HIR {
-class ReadonlyChecker : public DefaultHIRVisitor
-{
-public:
- ReadonlyChecker ();
-
- void go (HIR::Crate &crate);
-
-private:
- enum class lvalue_use
- {
- assign,
- increment,
- decrement,
- };
-
- Resolver::Resolver &resolver;
- Analysis::Mappings &mappings;
- Resolver::TypeCheckContext &context;
- StackedContexts<HirId> mutable_context;
-
- using DefaultHIRVisitor::visit;
-
- virtual void visit (AssignmentExpr &expr) override;
- virtual void visit (PathInExpression &expr) override;
- virtual void visit (FieldAccessExpr &expr) override;
- virtual void visit (ArrayIndexExpr &expr) override;
- virtual void visit (TupleExpr &expr) override;
- virtual void visit (TupleIndexExpr &expr) override;
- virtual void visit (LetStmt &stmt) override;
- virtual void visit (LiteralExpr &expr) override;
- virtual void visit (DereferenceExpr &expr) override;
-
- void collect_assignment (Pattern &pattern, bool has_init_expr);
- void collect_assignment_identifier (IdentifierPattern &pattern,
- bool has_init_expr);
- void collect_assignment_tuple (TuplePattern &pattern, bool has_init_expr);
-
- void check_variable (IdentifierPattern *pattern, location_t assigned_loc);
-};
-
-} // namespace HIR
-} // namespace Rust \ No newline at end of file
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 405c59b..607d20f 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -926,11 +926,11 @@ UnsafeChecker::visit (StructPattern &)
{}
void
-UnsafeChecker::visit (TupleStructItemsNoRange &)
+UnsafeChecker::visit (TupleStructItemsNoRest &)
{}
void
-UnsafeChecker::visit (TupleStructItemsRange &)
+UnsafeChecker::visit (TupleStructItemsHasRest &)
{}
void
@@ -938,11 +938,11 @@ UnsafeChecker::visit (TupleStructPattern &)
{}
void
-UnsafeChecker::visit (TuplePatternItemsMultiple &)
+UnsafeChecker::visit (TuplePatternItemsNoRest &)
{}
void
-UnsafeChecker::visit (TuplePatternItemsRanged &)
+UnsafeChecker::visit (TuplePatternItemsHasRest &)
{}
void
@@ -950,6 +950,14 @@ UnsafeChecker::visit (TuplePattern &)
{}
void
+UnsafeChecker::visit (SlicePatternItemsNoRest &)
+{}
+
+void
+UnsafeChecker::visit (SlicePatternItemsHasRest &)
+{}
+
+void
UnsafeChecker::visit (SlicePattern &)
{}
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h
index dc3b482..420668f 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -161,12 +161,14 @@ private:
virtual void visit (StructPatternFieldIdentPat &field) override;
virtual void visit (StructPatternFieldIdent &field) override;
virtual void visit (StructPattern &pattern) override;
- virtual void visit (TupleStructItemsNoRange &tuple_items) override;
- virtual void visit (TupleStructItemsRange &tuple_items) override;
+ virtual void visit (TupleStructItemsNoRest &tuple_items) override;
+ virtual void visit (TupleStructItemsHasRest &tuple_items) override;
virtual void visit (TupleStructPattern &pattern) override;
- virtual void visit (TuplePatternItemsMultiple &tuple_items) override;
- virtual void visit (TuplePatternItemsRanged &tuple_items) override;
+ virtual void visit (TuplePatternItemsNoRest &tuple_items) override;
+ virtual void visit (TuplePatternItemsHasRest &tuple_items) override;
virtual void visit (TuplePattern &pattern) override;
+ virtual void visit (SlicePatternItemsNoRest &items) override;
+ virtual void visit (SlicePatternItemsHasRest &items) override;
virtual void visit (SlicePattern &pattern) override;
virtual void visit (AltPattern &pattern) override;
virtual void visit (EmptyStmt &stmt) override;
diff --git a/gcc/rust/checks/lints/rust-lint-marklive-base.h b/gcc/rust/checks/lints/rust-lint-marklive-base.h
index 2a97577..dec9396 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive-base.h
+++ b/gcc/rust/checks/lints/rust-lint-marklive-base.h
@@ -19,9 +19,6 @@
#ifndef RUST_HIR_LIVENESS_BASE
#define RUST_HIR_LIVENESS_BASE
-#include "rust-diagnostics.h"
-#include "rust-lint-marklive.h"
-#include "rust-lint-marklive-base.h"
#include "rust-hir-visitor.h"
#include "rust-hir-map.h"