aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/ChangeLog297
-rw-r--r--gcc/rust/ast/rust-ast.cc44
-rw-r--r--gcc/rust/ast/rust-ast.h1
-rw-r--r--gcc/rust/ast/rust-fmt.h3
-rw-r--r--gcc/rust/ast/rust-item.h25
-rw-r--r--gcc/rust/ast/rust-macro.h4
-rw-r--r--gcc/rust/ast/rust-pattern.cc2
-rw-r--r--gcc/rust/ast/rust-pattern.h22
-rw-r--r--gcc/rust/ast/rust-type.h3
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc6
-rw-r--r--gcc/rust/backend/rust-compile-item.cc11
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc28
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc21
-rw-r--r--gcc/rust/backend/rust-constexpr.cc2
-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.cc144
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature-gate.h19
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature.cc132
-rw-r--r--gcc/rust/checks/errors/feature/rust-feature.h68
-rw-r--r--gcc/rust/expand/rust-derive.cc11
-rw-r--r--gcc/rust/expand/rust-expand-visitor.cc8
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc15
-rw-r--r--gcc/rust/expand/rust-macro-expand.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc14
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.cc32
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.cc3
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.cc11
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h14
-rw-r--r--gcc/rust/hir/tree/rust-hir-pattern.h14
-rw-r--r--gcc/rust/hir/tree/rust-hir.cc14
-rw-r--r--gcc/rust/lang.opt.urls2
-rw-r--r--gcc/rust/lex/rust-lex.cc32
-rw-r--r--gcc/rust/metadata/rust-export-metadata.cc9
-rw-r--r--gcc/rust/metadata/rust-export-metadata.h2
-rw-r--r--gcc/rust/parse/rust-parse-impl.h130
-rw-r--r--gcc/rust/rust-backend.h18
-rw-r--r--gcc/rust/rust-gcc.cc41
-rw-r--r--gcc/rust/rust-gcc.h24
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc20
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.cc36
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.cc22
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc11
-rw-r--r--gcc/rust/typecheck/rust-type-util.cc10
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.h66
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.h1
-rw-r--r--gcc/rust/typecheck/rust-tyty-util.cc7
-rw-r--r--gcc/rust/typecheck/rust-tyty-util.h3
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc38
-rw-r--r--gcc/rust/typecheck/rust-tyty.h222
-rw-r--r--gcc/rust/typecheck/rust-unify.cc62
-rw-r--r--gcc/rust/typecheck/rust-unify.h8
-rw-r--r--gcc/rust/util/rust-attribute-values.h2
-rw-r--r--gcc/rust/util/rust-attributes.cc43
-rw-r--r--gcc/rust/util/rust-attributes.h8
-rw-r--r--gcc/rust/util/rust-hir-map.cc16
-rw-r--r--gcc/rust/util/rust-hir-map.h9
65 files changed, 2228 insertions, 520 deletions
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog
index 556ce28..ec156ac 100644
--- a/gcc/rust/ChangeLog
+++ b/gcc/rust/ChangeLog
@@ -1,3 +1,300 @@
+2025-12-03 Marc Poulhiès <dkm@kataplop.net>
+
+ * lex/rust-lex.cc (rust_input_source_test): Reindent.
+
+2025-12-03 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * ast/rust-macro.h (MetaNameValueStr::get_name): New function.
+ (MetaNameValueStr::get_value): Likewise.
+ * checks/errors/feature/rust-feature-gate.cc
+ (FeatureGate::visit): Tweak unknown feature detection.
+ (FeatureGate::gate): Handle field rename.
+ (FeatureGate::note_stability_attribute): New function
+ definition.
+ * checks/errors/feature/rust-feature-gate.h
+ (FeatureGate::note_stability_attribute): New function
+ declaration.
+ (FeatureGate::Stability): New enum class.
+ (FeatureGate::valid_features): Rename field to...
+ (FeatureGate::valid_lang_features): ...here.
+ (FeatureGate::valid_lib_features): New field.
+ (FeatureGate::defined_lib_features): Likewise.
+ * checks/errors/feature/rust-feature.cc (Feature::as_name):
+ Improve implementation.
+
+2025-12-03 Raiki Tamura <tamaron1203@gmail.com>
+
+ * checks/errors/feature/rust-feature-gate.cc (FeatureGate::visit): Add check for lang_items.
+ * checks/errors/feature/rust-feature-gate.h: Likewise.
+
+2025-12-03 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_function): Return a nullptr on
+ error instead of a valid function.
+ (Parser::parse_let_stmt): Remove non leaf error.
+ (Parser::parse_if_expr): Likewise.
+ (Parser::parse_loop_expr): Likewise.
+ (Parser::parse_expr): Return error on null denotation error.
+
+2025-12-03 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_delim_token_tree):
+ Remove error message.
+ (Parser::parse_token_tree): Split error message.
+
+2025-12-03 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * backend/rust-constexpr.cc (eval_binary_expression): Set initial value
+ equality value to false.
+
+2025-12-03 Jonathan Wakely <jwakely@redhat.com>
+
+ * expand/rust-macro-expand.h: Fix typos in comment.
+
+2025-12-03 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_items): Remove item parsing
+ error.
+
+2025-12-03 Ryutaro Okada <1015ryu88@gmail.com>
+
+ * expand/rust-expand-visitor.cc (builtin_derive_item): Collect derived nodes.
+ (derive_item): Collect derived nodes.
+ * util/rust-hir-map.cc (Mappings::add_derived_nodes): Add derived set to collect derived
+ nodes.
+ (Mappings::is_derived_node): Add derived set to collect derived nodes.
+ * util/rust-hir-map.h: Add derived set to collect derived nodes.
+
+2025-11-30 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ * lang.opt.urls: Regenerate.
+
+2025-11-27 Jakub Jelinek <jakub@redhat.com>
+
+ * lex/rust-lex.cc (rust_input_source_test): Cast char8_t string
+ literals to (const char *) to make it compilable with C++20. Use
+ char16_t or char32_t character literals instead of ordinary
+ character literals or wide character literals in expected
+ initializers.
+
+2025-11-27 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * typecheck/rust-tyty-subst.h: Remove now useless inclusion.
+ * typecheck/rust-tyty.h (class TypeBoundPredicate): New, moved from rust-tyty-bounds.h
+ (class TypeBoundsMappings): Likewise.
+ * typecheck/rust-tyty-bounds.h: Removed.
+
+2025-11-25 Lúcio Boari Fleury <lucboari@gmail.com>
+
+ * parse/rust-parse-impl.h: Add early exit condition to parsing loop.
+
+2025-11-25 Philip Herron <herron.philip@googlemail.com>
+
+ * ast/rust-ast.cc (TraitItemType::as_string): add generic params
+ * ast/rust-ast.h: remove old comment
+ * ast/rust-item.h: add generic params to associated type
+ * ast/rust-type.h: remove old comment
+ * hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit): hir lowering for gat's
+ * hir/tree/rust-hir-item.cc (TraitItemType::TraitItemType): gat's on TraitItemType
+ (TraitItemType::operator=): preserve generic params
+ * hir/tree/rust-hir-item.h: likewise
+ * hir/tree/rust-hir.cc (TraitItemType::as_string): likewise
+ * parse/rust-parse-impl.h (Parser::parse_trait_type): hit the < and parse params
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItemWithTrait::visit): typecheck
+ * typecheck/rust-tyty.cc (BaseType::has_substitutions_defined): dont destructure
+
+2025-11-25 Lucas Ly Ba <lucas.ly-ba@outlook.com>
+
+ * expand/rust-derive.cc (DeriveVisitor::derive):
+ Add check and error.
+
+2025-11-25 Lucas Ly Ba <lucas.ly-ba@outlook.com>
+
+ * hir/rust-ast-lower-base.cc (ASTLoweringBase::handle_doc_item_attribute): Make error.
+
+2025-11-25 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * backend/rust-compile-expr.cc (compile_float_literal): Add is_negative
+ check to compile negative float literals properly.
+ * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit(RangePattern)):
+ Minor optimization to E0579 checks to reduce memory copy.
+
+2025-11-25 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * checks/errors/feature/rust-feature-gate.cc
+ (FeatureGate::gate): Handle removal of Feature::create.
+ (FeatureGate::visit): Refer to AUTO_TRAITS as
+ OPTIN_BUILTIN_TRAITS.
+ * checks/errors/feature/rust-feature.cc (Feature::create):
+ Remove.
+ (Feature::feature_list): New static member variable.
+ (Feature::name_hash_map): Use "rust-feature-defs.h" to define.
+ (Feature::lookup): New member function definition.
+ * checks/errors/feature/rust-feature.h (Feature::State): Add
+ comments.
+ (Feature::Name): Use "rust-feature-defs.h" to define.
+ (Feature::as_string): Make const.
+ (Feature::name): Likewise.
+ (Feature::state): Likewise.
+ (Feature::issue): Likewise.
+ (Feature::description): Remove member function declaration.
+ (Feature::create): Remove static member function declaration.
+ (Feature::lookup): New member function declarations.
+ (Feature::Feature): Adjust arguments.
+ (Feature::m_rustc_since): Rename to...
+ (Feature::m_rust_since): ...here.
+ (Feature::m_description): Remove.
+ (Feature::m_reason): New member variable.
+ (Feature::feature_list): New static member variable.
+ * checks/errors/feature/rust-feature-defs.h: New file.
+ * checks/errors/feature/contrib/parse.y: New file.
+ * checks/errors/feature/contrib/scan.l: New file.
+ * checks/errors/feature/contrib/.gitignore: New file.
+ * checks/errors/feature/contrib/Makefile: New file.
+ * checks/errors/feature/contrib/fetch: New file.
+ * checks/errors/feature/contrib/regen: New file.
+ * checks/errors/feature/contrib/copyright-stub.h: New file.
+ * checks/errors/feature/contrib/README: New file.
+
+2025-11-25 Lucas Ly Ba <lucas.ly-ba@outlook.com>
+
+ * ast/rust-ast.cc (Attribute::check_cfg_predicate): Make error when attribute has no input.
+
+2025-11-25 Owen Avery <powerboat9.gamer@gmail.com>
+
+ * backend/rust-compile-expr.cc (CompileExpr::visit): Implicitly
+ convert LocalVariable to pointer to Bvariable.
+ * rust-backend.h (local_variable): Return LocalVariable.
+ (parameter_variable): Likewise.
+ (static_chain_variable): Likewise.
+ (temporary_variable): Likewise.
+ * rust-gcc.cc (local_variable): Likewise.
+ (parameter_variable): Likewise.
+ (static_chain_variable): Likewise.
+ (temporary_variable): Likewise.
+ (LocalVariable::get_tree): New function.
+ (LocalVariable::error_variable): Likewise.
+ * rust-gcc.h (class LocalVariable): New class.
+
+2025-11-25 lenny.chiadmi-delage <lenny.chiadmi-delage@epita.fr>
+
+ * expand/rust-macro-expand.cc (transcribe_expression): Check if
+ parser didn't fail.
+ (transcribe_type): Likewise.
+ (transcribe_pattern): Likewise.
+
+2025-11-17 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItemWithTrait::visit): null guard
+ * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn): default to anon
+
+2025-11-17 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-item.cc (CompileItem::visit): support the synthetic function consts
+ * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::Resolve): likewise
+ * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItem::visit): create the synth
+ * typecheck/rust-tyty.h: new flag for synthetic constant
+
+2025-11-17 Philip Herron <herron.philip@googlemail.com>
+
+ * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): fix mappings
+
+2025-11-17 Lucas Ly Ba <lucas.ly-ba@outlook.com>
+
+ * ast/rust-ast.cc (Attribute::is_derive):
+ Change is_derive method with its valid path.
+ * util/rust-attribute-values.h:
+ Delete redudant derive attribute.
+ * util/rust-attributes.cc (AttributeChecker::check_inner_attribute):
+ Helper method for check_inner_attributes
+ (AttributeChecker::check_inner_attributes):
+ Implement method for errors check.
+ * util/rust-attributes.h:
+ Add methods above in header.
+
+2025-11-17 Lucas Ly Ba <lucas.ly-ba@outlook.com>
+
+ * parse/rust-parse-impl.h(Parser<ManagedTokenSource>::parse_while_let_loop_expr):
+ Add check for missing pattern.
+
+2025-11-17 Lucas Ly Ba <lucas.ly-ba@outlook.com>
+
+ * ast/rust-ast.cc (MetaItemLitExpr::check_cfg_predicate): Make error.
+
+2025-11-17 Lucas Ly Ba <lucas.ly-ba@outlook.com>
+
+ * ast/rust-ast.cc (Attribute::check_cfg_predicate): add cfg path in condition
+
+2025-11-17 Lucas Ly Ba <lucas.ly-ba@outlook.com>
+
+ * ast/rust-ast.cc (Attribute::check_cfg_predicate):
+ Make error.
+
+2025-11-17 Philip Herron <herron.philip@googlemail.com>
+
+ * backend/rust-compile-resolve-path.cc: handle const param values
+ * typecheck/rust-hir-type-check-item.cc: generate const infer vars when required
+ * typecheck/rust-type-util.cc (unify_site_and): handle a null param cleanup
+ * typecheck/rust-tyty-util.cc (TyVar::get_implicit_const_infer_var): helper interface
+ * typecheck/rust-tyty-util.h: update header prototypes
+ * typecheck/rust-tyty.cc (BaseType::is_concrete): correctly handle const types
+ (ConstParamType::get_name): emit the specified type
+ (ConstParamType::is_equal): fix recursion loop
+ * typecheck/rust-unify.cc (UnifyRules::go): const infer vars need cleanup too
+ * typecheck/rust-unify.h: support base generics
+
+2025-11-17 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * backend/rust-compile-pattern.cc(compilePatternCheckExpr::visit(RangePattern)):
+ Add E0579 check to ensure that lower bound is always below upper bound.
+
+2025-11-17 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * backend/rust-compile-pattern.cc (compile_range_pattern_bound): Set litexpr
+ to negative if has_minus is present in the RangePatternBoundLiteral param.
+
+2025-11-17 vishruth-thimmaiah <vishruththimmaiah@gmail.com>
+
+ * parse/rust-parse-impl.h (Parser::parse_generic_params): Emit
+ an error when const generics with a default value is not
+ trailing.
+
+2025-11-17 Yap Zhi Heng <yapzhhg@gmail.com>
+
+ * parse/rust-parse-impl.h (parse_literal_or_range_pattern): Parse minus sign
+ properly for LiteralPattern.
+ * ast/rust-pattern.h (LiteralPattern): Add has_minus boolean for LiteralPattern.
+ * hir/tree/rust-hir-pattern.h (LiteralPattern): Ditto.
+ * ast/rust-pattern.cc (LiteralPattern::as_string): Update to include minus sign
+ if present.
+ * hir/tree/rust-hir.cc (LiteralPattern::as_string): Ditto.
+ * hir/rust-ast-lower-pattern.cc (visit(LiteralPattern)): Pass has_minus boolean
+ from AST to HIR.
+ * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit(LiteralPattern)):
+ Compile litexpr as negative if minus sign is present.
+
+2025-11-17 Lucas Ly Ba <lucas.ly-ba@outlook.fr>
+
+ * metadata/rust-export-metadata.cc (ExportContext::emit_macro):
+ Change method argument NodeId to AST::MacroRulesDefinition.
+ * metadata/rust-export-metadata.h:
+ Likewise.
+ * util/rust-hir-map.cc (Mappings::insert_exported_macro):
+ Insert AST::MacroRulesDefinition instead of NodeId.
+ * util/rust-hir-map.h:
+ Change methods declarations of exported macros.
+
+2025-11-12 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-fmt.h: Simplify diagnostic avoidance.
+
+2025-11-12 Arthur Cohen <arthur.cohen@embecosm.com>
+ Thomas Schwinge <tschwinge@gcc.gnu.org>
+
+ PR rust/122498
+ * ast/rust-fmt.h: Add -Warray-bounds pragma to avoid the issue during
+ bootstraps
+
2025-10-30 Owen Avery <powerboat9.gamer@gmail.com>
* ast/rust-ast-pointer-visitor.cc (PointerVisitor::visit):
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 337a338..851f7ea 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -248,7 +248,7 @@ Attribute::as_string () const
bool
Attribute::is_derive () const
{
- return has_attr_input () && get_path () == Values::Attributes::DERIVE;
+ return has_attr_input () && get_path () == Values::Attributes::DERIVE_ATTR;
}
/**
@@ -3050,6 +3050,18 @@ TraitItemType::as_string () const
str += "\ntype " + name.as_string ();
+ if (has_generics ())
+ {
+ str += "<";
+ for (size_t i = 0; i < generic_params.size (); i++)
+ {
+ if (i > 0)
+ str += ", ";
+ str += generic_params[i]->as_string ();
+ }
+ str += ">";
+ }
+
str += "\n Type param bounds: ";
if (!has_type_param_bounds ())
{
@@ -3834,6 +3846,9 @@ MetaItemLitExpr::check_cfg_predicate (const Session &) const
{
/* as far as I can tell, a literal expr can never be a valid cfg body, so
* false */
+ rust_error_at (this->get_locus (), "'%s' predicate key cannot be a literal",
+ this->as_string ().c_str ());
+
return false;
}
@@ -4160,16 +4175,10 @@ Attribute::check_cfg_predicate (const Session &session) const
auto string_path = path.as_string ();
/* assume that cfg predicate actually can exist, i.e. attribute has cfg or
* cfg_attr path */
- if (!has_attr_input ()
- || (string_path != Values::Attributes::CFG
- && string_path != Values::Attributes::CFG_ATTR))
+ if (!has_attr_input ())
{
- // DEBUG message
- rust_debug (
- "tried to check cfg predicate on attr that either has no input "
- "or invalid path. attr: '%s'",
- as_string ().c_str ());
-
+ rust_error_at (path.get_locus (), "%qs is not followed by parentheses",
+ string_path.c_str ());
return false;
}
@@ -4178,11 +4187,18 @@ Attribute::check_cfg_predicate (const Session &session) const
return false;
auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input);
- if (meta_item.get_items ().empty ()
- && string_path == Values::Attributes::CFG_ATTR)
+ if (meta_item.get_items ().empty ())
+ {
+ rust_error_at (path.get_locus (), "malformed %<%s%> attribute input",
+ string_path.c_str ());
+ return false;
+ }
+
+ if (string_path == Values::Attributes::CFG
+ && meta_item.get_items ().size () != 1)
{
- rust_error_at (path.get_locus (),
- "malformed %<cfg_attr%> attribute input");
+ rust_error_at (path.get_locus (), "multiple %qs predicates are specified",
+ path.as_string ().c_str ());
return false;
}
return meta_item.get_items ().front ()->check_cfg_predicate (session);
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 8a7e618..8610ade 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1891,7 +1891,6 @@ public:
{
parsed_items = std::move (new_items);
}
- // TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items ()
{
return parsed_items;
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index e59bed3..13dc7be 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -22,6 +22,9 @@
#include "rust-system.h"
#include "optional.h"
+// PR122498 "rust-enabled bootstrap is broken after r16-4897"
+#pragma GCC diagnostic warning "-Warray-bounds"
+
namespace Rust {
namespace Fmt {
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 7aea763..3e3735c 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -2726,21 +2726,28 @@ class TraitItemType : public TraitItem
Identifier name;
+ // Generic parameters for GATs (Generic Associated Types)
+ std::vector<std::unique_ptr<GenericParam>> generic_params;
+
// bool has_type_param_bounds;
// TypeParamBounds type_param_bounds;
std::vector<std::unique_ptr<TypeParamBound>>
type_param_bounds; // inlined form
public:
+ bool has_generics () const { return !generic_params.empty (); }
+
// Returns whether trait item type has type param bounds.
bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
TraitItemType (Identifier name,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
std::vector<Attribute> outer_attrs, Visibility vis,
location_t locus)
: TraitItem (vis, locus), outer_attrs (std::move (outer_attrs)),
- name (std::move (name)), type_param_bounds (std::move (type_param_bounds))
+ name (std::move (name)), generic_params (std::move (generic_params)),
+ type_param_bounds (std::move (type_param_bounds))
{}
// Copy constructor with vector clone
@@ -2749,6 +2756,9 @@ public:
name (other.name)
{
node_id = other.node_id;
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -2763,6 +2773,9 @@ public:
locus = other.locus;
node_id = other.node_id;
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -2786,7 +2799,15 @@ public:
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
- // TODO: mutable getter seems kinda dodgy
+ std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
+ {
+ return generic_params;
+ }
+ const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
+ {
+ return generic_params;
+ }
+
std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
{
return type_param_bounds;
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 4165075..71de8f0 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -993,6 +993,10 @@ public:
return ident.as_string () + " = \"" + str + "\"";
}
+ const Identifier &get_name () const { return ident; }
+
+ const std::string &get_value () const { return str; }
+
void accept_vis (ASTVisitor &vis) override;
// HACK: used to simplify parsing - creates a copy of this
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index a2fe5d5..80189d3 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -48,7 +48,7 @@ tokenid_to_rangekind (TokenId id)
std::string
LiteralPattern::as_string () const
{
- return lit.as_string ();
+ return (has_minus ? "-" : "") + lit.as_string ();
}
std::string
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 0da1981..3b1bd1c 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -30,6 +30,7 @@ class LiteralPattern : public Pattern
Literal lit;
location_t locus;
NodeId node_id;
+ bool has_minus;
public:
std::string as_string () const override;
@@ -37,17 +38,34 @@ public:
// Constructor for a literal pattern
LiteralPattern (Literal lit, location_t locus)
: lit (std::move (lit)), locus (locus),
- node_id (Analysis::Mappings::get ().get_next_node_id ())
+ node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ has_minus (false)
+ {}
+
+ LiteralPattern (Literal lit, location_t locus, bool has_minus)
+ : lit (std::move (lit)), locus (locus),
+ node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ has_minus (has_minus)
{}
LiteralPattern (std::string val, Literal::LitType type, location_t locus,
PrimitiveCoreType type_hint)
: lit (Literal (std::move (val), type, type_hint)), locus (locus),
- node_id (Analysis::Mappings::get ().get_next_node_id ())
+ node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ has_minus (false)
+ {}
+
+ LiteralPattern (std::string val, Literal::LitType type, location_t locus,
+ PrimitiveCoreType type_hint, bool has_minus)
+ : lit (Literal (std::move (val), type, type_hint)), locus (locus),
+ node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ has_minus (has_minus)
{}
location_t get_locus () const override final { return locus; }
+ bool get_has_minus () const { return has_minus; }
+
void accept_vis (ASTVisitor &vis) override;
NodeId get_node_id () const override { return node_id; }
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 014963f..38a3474 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -177,7 +177,6 @@ public:
void accept_vis (ASTVisitor &vis) override;
- // TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds ()
{
return type_param_bounds;
@@ -250,7 +249,6 @@ public:
bool is_dyn () const { return has_dyn; }
- // TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds ()
{
return type_param_bounds;
@@ -463,7 +461,6 @@ public:
void accept_vis (ASTVisitor &vis) override;
- // TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<Type> > &get_elems () { return elems; }
const std::vector<std::unique_ptr<Type> > &get_elems () const
{
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 0a627f3..9a9c315 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -175,7 +175,7 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
}
auto receiver_tmp = NULL_TREE;
- auto receiver
+ Bvariable *receiver
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
TREE_TYPE (lhs), lhs, true,
expr.get_locus (), &receiver_tmp);
@@ -214,7 +214,7 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
if (ctx->in_fn () && !ctx->const_context_p ())
{
auto tmp = NULL_TREE;
- auto receiver
+ Bvariable *receiver
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
TREE_TYPE (lhs), lhs, true,
expr.get_locus (), &tmp);
@@ -1712,6 +1712,8 @@ CompileExpr::compile_float_literal (const HIR::LiteralExpr &expr,
rust_error_at (expr.get_locus (), "bad number in literal");
return error_mark_node;
}
+ if (expr.is_negative ())
+ mpfr_neg (fval, fval, MPFR_RNDN);
// taken from:
// see go/gofrontend/expressions.cc:check_float_type
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index b72e70d..d908710 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -109,6 +109,17 @@ CompileItem::visit (HIR::ConstantItem &constant)
// canonical path
Resolver::CanonicalPath canonical_path
= nr_ctx.to_canonical_path (mappings.get_nodeid ());
+ if (constant_type->is<const TyTy::FnType> ())
+ {
+ if (concrete == nullptr)
+ return;
+
+ rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
+
+ concrete_fnty->override_context ();
+ constant_type = expr_type = concrete_fnty->get_return_type ();
+ }
ctx->push_const_context ();
tree const_expr
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index 82333dc..af5f453 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -87,6 +87,8 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
auto litexpr = std::make_unique<HIR::LiteralExpr> (
HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
pattern.get_locus (), std::vector<AST::Attribute> ()));
+ if (pattern.get_has_minus ())
+ litexpr->set_negative ();
// Note: Floating point literals are currently accepted but will likely be
// forbidden in LiteralPatterns in a future version of Rust.
@@ -119,6 +121,8 @@ compile_range_pattern_bound (HIR::RangePatternBound &bound,
HIR::LiteralExpr litexpr (mappings, ref.get_literal (), locus,
std::vector<AST::Attribute> ());
+ if (ref.get_has_minus ())
+ litexpr.set_negative ();
result = CompileExpr::Compile (litexpr, ctx);
}
@@ -159,6 +163,30 @@ CompilePatternCheckExpr::visit (HIR::RangePattern &pattern)
pattern.get_mappings (),
pattern.get_locus (), ctx);
+ rust_assert (
+ (TREE_CODE (upper) == REAL_CST && TREE_CODE (lower) == REAL_CST)
+ || (TREE_CODE (upper) == INTEGER_CST && TREE_CODE (lower) == INTEGER_CST));
+
+ bool error_E0579 = false;
+ if (TREE_CODE (upper) == REAL_CST)
+ {
+ const REAL_VALUE_TYPE *upper_r = TREE_REAL_CST_PTR (upper);
+ const REAL_VALUE_TYPE *lower_r = TREE_REAL_CST_PTR (lower);
+ if (real_compare (GE_EXPR, lower_r, upper_r))
+ error_E0579 = true;
+ }
+ else if (TREE_CODE (upper) == INTEGER_CST)
+ {
+ auto upper_wi = wi::to_wide (upper).to_shwi ();
+ auto lower_wi = wi::to_wide (lower).to_shwi ();
+ if (lower_wi >= upper_wi)
+ error_E0579 = true;
+ }
+
+ if (error_E0579)
+ rust_error_at (pattern.get_locus (), ErrorCode::E0579,
+ "lower range bound must be less than upper");
+
ComparisonOperator upper_cmp = pattern.is_inclusive_range ()
? ComparisonOperator::LESS_OR_EQUAL
: ComparisonOperator::LESS_THAN;
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index c33d0b0..5f30662 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -132,10 +132,8 @@ ResolvePathRef::resolve_with_node_id (
tl::optional<HirId> hid
= ctx->get_mappings ().lookup_node_to_hir (resolved_node_id);
if (!hid.has_value ())
- {
- rust_error_at (expr_locus, "reverse call path lookup failure");
- return error_mark_node;
- }
+ return error_mark_node;
+
auto ref = hid.value ();
// might be a constant
@@ -189,6 +187,17 @@ ResolvePathRef::resolve_with_node_id (
}
}
+ // possibly a const expr value
+ if (lookup->get_kind () == TyTy::TypeKind::CONST)
+ {
+ auto d = lookup->destructure ();
+ rust_assert (d->get_kind () == TyTy::TypeKind::CONST);
+ auto c = d->as_const_type ();
+ rust_assert (c->const_kind () == TyTy::BaseConstType::ConstKind::Value);
+ auto val = static_cast<TyTy::ConstValueType *> (c);
+ return val->get_value ();
+ }
+
// Handle unit struct
tree resolved_item = error_mark_node;
if (lookup->get_kind () == TyTy::TypeKind::ADT)
@@ -203,9 +212,7 @@ ResolvePathRef::resolve_with_node_id (
resolved_item = query_compile (ref, lookup, final_segment, mappings,
expr_locus, is_qualified_path);
if (resolved_item != error_mark_node)
- {
- TREE_USED (resolved_item) = 1;
- }
+ TREE_USED (resolved_item) = 1;
return resolved_item;
}
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index d04f864..e32ba3a 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -3137,7 +3137,7 @@ eval_binary_expression (const constexpr_ctx *ctx, tree t, bool lval,
{
tree lmem = PTRMEM_CST_MEMBER (lhs);
tree rmem = PTRMEM_CST_MEMBER (rhs);
- bool eq;
+ bool eq = false;
if (TREE_CODE (lmem) == TREE_CODE (rmem)
&& TREE_CODE (lmem) == FIELD_DECL
&& TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE
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/feature/rust-feature-gate.cc b/gcc/rust/checks/errors/feature/rust-feature-gate.cc
index 44007f9..9df822b 100644
--- a/gcc/rust/checks/errors/feature/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/feature/rust-feature-gate.h b/gcc/rust/checks/errors/feature/rust-feature-gate.h
index f1011e5..8ff491c 100644
--- a/gcc/rust/checks/errors/feature/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
index 071d3f8..1a967aa 100644
--- a/gcc/rust/checks/errors/feature/rust-feature.cc
+++ b/gcc/rust/checks/errors/feature/rust-feature.cc
@@ -20,79 +20,81 @@
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 ();
- }
-}
+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 = {
- {"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},
+#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)
{
- if (Feature::name_hash_map.count (name))
- return Feature::name_hash_map.at (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)); });
+}
- return tl::nullopt;
+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
index e7cb0af..8686cf4 100644
--- a/gcc/rust/checks/errors/feature/rust-feature.h
+++ b/gcc/rust/checks/errors/feature/rust-feature.h
@@ -29,59 +29,55 @@ class Feature
public:
enum class State
{
- ACCEPTED,
- ACTIVE,
- REMOVED,
- STABILIZED,
+ ACCEPTED, // stabilized
+ ACTIVE, // unstable
+ REMOVED, // removed
+ STABILIZED, // removed after stabilization
};
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,
+#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 () { 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; }
+ 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 Feature create (Name 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 *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)
+ 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)
{}
- State m_state;
Name m_name;
+ State m_state;
std::string m_name_str;
- std::string m_rustc_since;
+ std::string m_rust_since;
tl::optional<unsigned> m_issue;
tl::optional<Edition> edition;
- std::string m_description; // TODO: Switch to optional?
+ tl::optional<const char *> m_reason;
+ static Feature feature_list[];
static const std::map<std::string, Name> name_hash_map;
};
diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index 55147df..2777f07 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -25,6 +25,7 @@
#include "rust-derive-ord.h"
#include "rust-derive-partial-eq.h"
#include "rust-derive-hash.h"
+#include "rust-system.h"
namespace Rust {
namespace AST {
@@ -39,6 +40,16 @@ DeriveVisitor::derive (Item &item, const Attribute &attr,
{
auto loc = attr.get_locus ();
+ using Kind = AST::Item::Kind;
+ auto item_kind = item.get_item_kind ();
+ if (item_kind != Kind::Enum && item_kind != Kind::Struct
+ && item_kind != Kind::Union)
+ {
+ rust_error_at (loc,
+ "derive may only be applied to structs, enums and unions");
+ return {};
+ }
+
switch (to_derive)
{
case BuiltinMacro::Clone:
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index 4593cc3..6e98a5c 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -18,6 +18,7 @@
#include "rust-expand-visitor.h"
#include "rust-ast-fragment.h"
+#include "rust-hir-map.h"
#include "rust-item.h"
#include "rust-proc-macro.h"
#include "rust-attributes.h"
@@ -48,7 +49,10 @@ static std::vector<std::unique_ptr<AST::Item>>
builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
BuiltinMacro to_derive)
{
- return AST::DeriveVisitor::derive (item, derive, to_derive);
+ auto items = AST::DeriveVisitor::derive (item, derive, to_derive);
+ for (auto &item : items)
+ Analysis::Mappings::get ().add_derived_node (item->get_node_id ());
+ return items;
}
static std::vector<std::unique_ptr<AST::Item>>
@@ -64,6 +68,8 @@ derive_item (AST::Item &item, AST::SimplePath &to_derive,
switch (node.get_kind ())
{
case AST::SingleASTNode::Kind::Item:
+ Analysis::Mappings::get ().add_derived_node (
+ node.get_item ()->get_node_id ());
result.push_back (node.take_item ());
break;
default:
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 52f8e2b..b47e43a 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -962,12 +962,10 @@ transcribe_expression (Parser<MacroInvocLexer> &parser)
auto attrs = parser.parse_outer_attributes ();
auto expr = parser.parse_expr (std::move (attrs));
- if (expr == nullptr)
- {
- for (auto error : parser.get_errors ())
- error.emit ();
- return AST::Fragment::create_error ();
- }
+ for (auto error : parser.get_errors ())
+ error.emit ();
+ if (!expr)
+ return AST::Fragment::create_error ();
// FIXME: make this an error for some edititons
if (parser.peek_current_token ()->get_id () == SEMICOLON)
@@ -997,6 +995,8 @@ transcribe_type (Parser<MacroInvocLexer> &parser)
auto type = parser.parse_type (true);
for (auto err : parser.get_errors ())
err.emit ();
+ if (!type)
+ return AST::Fragment::create_error ();
auto end = lexer.get_offs ();
@@ -1018,6 +1018,9 @@ transcribe_pattern (Parser<MacroInvocLexer> &parser)
for (auto err : parser.get_errors ())
err.emit ();
+ if (!pattern)
+ return AST::Fragment::create_error ();
+
auto end = lexer.get_offs ();
return AST::Fragment ({std::move (pattern)},
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index c3d5e7d..0e79466 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -358,7 +358,7 @@ struct MacroExpander
*
* @param parser Parser to use for matching
* @param rep Repetition to try and match
- * @param match_amount Reference in which to store the ammount of succesful
+ * @param match_amount Reference in which to store the amount of successful
* and valid matches
*
* @param lo_bound Lower bound of the matcher. When specified, the matcher
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index 1c8e5b6..8984c98 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -820,9 +820,17 @@ void
ASTLoweringBase::handle_doc_item_attribute (const ItemWrapper &,
const AST::Attribute &attr)
{
- auto simple_doc_comment = attr.has_attr_input ()
- && attr.get_attr_input ().get_attr_input_type ()
- == AST::AttrInput::AttrInputType::LITERAL;
+ if (!attr.has_attr_input ())
+ {
+ rust_error_at (attr.get_locus (),
+ "attribute must be of the form %qs or %qs",
+ "#[doc(hidden|inline|...)]", "#[doc = string]");
+ return;
+ }
+
+ auto simple_doc_comment = attr.get_attr_input ().get_attr_input_type ()
+ == AST::AttrInput::AttrInputType::LITERAL;
+
if (simple_doc_comment)
return;
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc
index 8fd9d16..87f1e01 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.cc
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -55,11 +55,11 @@ ASTLowerImplItem::translate (AST::AssociatedItem &item, HirId parent_impl_id)
void
ASTLowerImplItem::visit (AST::TypeAlias &alias)
{
- std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+ std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = translate_visibility (alias.get_visibility ());
- std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+ std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
if (alias.has_generics ())
generic_params = lower_generic_params (alias.get_generic_params ());
@@ -110,7 +110,7 @@ void
ASTLowerImplItem::visit (AST::Function &function)
{
// ignore for now and leave empty
- std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+ std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
for (auto &item : function.get_where_clause ().get_items ())
{
HIR::WhereClauseItem *i
@@ -124,7 +124,7 @@ ASTLowerImplItem::visit (AST::Function &function)
HIR::Visibility vis = translate_visibility (function.get_visibility ());
// need
- std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+ std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
if (function.has_generics ())
{
generic_params = lower_generic_params (function.get_generic_params ());
@@ -233,12 +233,12 @@ ASTLowerTraitItem::translate (AST::AssociatedItem &item)
void
ASTLowerTraitItem::visit (AST::Function &func)
{
- std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+ std::vector<std::unique_ptr<HIR::WhereClauseItem>> where_clause_items;
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::FunctionQualifiers qualifiers
= lower_qualifiers (func.get_qualifiers ());
- std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+ std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
if (func.has_generics ())
generic_params = lower_generic_params (func.get_generic_params ());
@@ -342,7 +342,24 @@ ASTLowerTraitItem::visit (AST::ConstantItem &constant)
void
ASTLowerTraitItem::visit (AST::TraitItemType &type)
{
- std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds;
+ // Lower generic parameters (for GATs)
+ std::vector<std::unique_ptr<HIR::GenericParam>> generic_params;
+ for (auto &param : type.get_generic_params ())
+ {
+ auto lowered_param = ASTLowerGenericParam::translate (*param.get ());
+ generic_params.push_back (
+ std::unique_ptr<HIR::GenericParam> (lowered_param));
+ }
+
+ // Lower type parameter bounds
+ std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
+ for (auto &bound : type.get_type_param_bounds ())
+ {
+ auto lowered_bound = lower_bound (*bound.get ());
+ type_param_bounds.push_back (
+ std::unique_ptr<HIR::TypeParamBound> (lowered_bound));
+ }
+
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings.get_next_hir_id (crate_num),
@@ -350,6 +367,7 @@ ASTLowerTraitItem::visit (AST::TraitItemType &type)
HIR::TraitItemType *trait_item
= new HIR::TraitItemType (mapping, type.get_identifier (),
+ std::move (generic_params),
std::move (type_param_bounds),
type.get_outer_attrs (), type.get_locus ());
translated = trait_item;
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 4250adb..c941a5c 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -280,7 +280,8 @@ ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
HIR::Literal l = lower_literal (pattern.get_literal ());
translated
- = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus ());
+ = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus (),
+ pattern.get_has_minus ());
}
void
diff --git a/gcc/rust/hir/tree/rust-hir-item.cc b/gcc/rust/hir/tree/rust-hir-item.cc
index 1406e7a..268b09b 100644
--- a/gcc/rust/hir/tree/rust-hir-item.cc
+++ b/gcc/rust/hir/tree/rust-hir-item.cc
@@ -716,17 +716,21 @@ TraitItemConst::operator= (TraitItemConst const &other)
TraitItemType::TraitItemType (
Analysis::NodeMapping mappings, Identifier name,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
AST::AttrVec outer_attrs, location_t locus)
: TraitItem (mappings), outer_attrs (std::move (outer_attrs)),
- name (std::move (name)), type_param_bounds (std::move (type_param_bounds)),
- locus (locus)
+ name (std::move (name)), generic_params (std::move (generic_params)),
+ type_param_bounds (std::move (type_param_bounds)), locus (locus)
{}
TraitItemType::TraitItemType (TraitItemType const &other)
: TraitItem (other.mappings), outer_attrs (other.outer_attrs),
name (other.name), locus (other.locus)
{
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
type_param_bounds.push_back (e->clone_type_param_bound ());
@@ -741,6 +745,9 @@ TraitItemType::operator= (TraitItemType const &other)
locus = other.locus;
mappings = other.mappings;
+ generic_params.reserve (other.generic_params.size ());
+ for (const auto &e : other.generic_params)
+ generic_params.push_back (e->clone_generic_param ());
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
type_param_bounds.push_back (e->clone_type_param_bound ());
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index eb9cec7..7629406 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -2121,15 +2121,20 @@ class TraitItemType : public TraitItem
AST::AttrVec outer_attrs;
Identifier name;
+ // Generic parameters for GATs (Generic Associated Types)
+ std::vector<std::unique_ptr<GenericParam>> generic_params;
std::vector<std::unique_ptr<TypeParamBound>>
type_param_bounds; // inlined form
location_t locus;
public:
+ bool has_generics () const { return !generic_params.empty (); }
+
// Returns whether trait item type has type param bounds.
bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
TraitItemType (Analysis::NodeMapping mappings, Identifier name,
+ std::vector<std::unique_ptr<GenericParam>> generic_params,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
AST::AttrVec outer_attrs, location_t locus);
@@ -2152,6 +2157,15 @@ public:
Identifier get_name () const { return name; }
+ std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
+ {
+ return generic_params;
+ }
+ const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
+ {
+ return generic_params;
+ }
+
std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
{
return type_param_bounds;
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index 89b9cc6..a2c408f 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -32,19 +32,27 @@ class LiteralPattern : public Pattern
Literal lit;
location_t locus;
Analysis::NodeMapping mappings;
+ bool has_minus;
public:
std::string as_string () const override;
// Constructor for a literal pattern
LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus)
- : lit (std::move (lit)), locus (locus), mappings (mappings)
+ : lit (std::move (lit)), locus (locus), mappings (mappings),
+ has_minus (false)
+ {}
+
+ LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus,
+ bool has_minus)
+ : lit (std::move (lit)), locus (locus), mappings (mappings),
+ has_minus (has_minus)
{}
LiteralPattern (Analysis::NodeMapping mappings, std::string val,
Literal::LitType type, location_t locus)
: lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
- locus (locus), mappings (mappings)
+ locus (locus), mappings (mappings), has_minus (false)
{}
location_t get_locus () const override { return locus; }
@@ -65,6 +73,8 @@ public:
Literal &get_literal () { return lit; }
const Literal &get_literal () const { return lit; }
+ bool get_has_minus () const { return has_minus; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index ce10b02..614fec7 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -2634,7 +2634,7 @@ StructPattern::as_string () const
std::string
LiteralPattern::as_string () const
{
- return lit.as_string ();
+ return (has_minus ? "-" : "") + lit.as_string ();
}
std::string
@@ -3582,6 +3582,18 @@ TraitItemType::as_string () const
str += "\ntype " + name.as_string ();
+ if (has_generics ())
+ {
+ str += "<";
+ for (size_t i = 0; i < generic_params.size (); i++)
+ {
+ if (i > 0)
+ str += ", ";
+ str += generic_params[i]->as_string ();
+ }
+ str += ">";
+ }
+
str += "\n Type param bounds: ";
if (!has_type_param_bounds ())
{
diff --git a/gcc/rust/lang.opt.urls b/gcc/rust/lang.opt.urls
index 33a54b4..09cfede 100644
--- a/gcc/rust/lang.opt.urls
+++ b/gcc/rust/lang.opt.urls
@@ -1,7 +1,7 @@
; Autogenerated by regenerate-opt-urls.py from gcc/rust/lang.opt and generated HTML
I
-UrlSuffix(gcc/Directory-Options.html#index-I) LangUrlSuffix_D(gdc/Directory-Options.html#index-I)
+UrlSuffix(gcc/Directory-Options.html#index-I) LangUrlSuffix_D(gdc/Directory-Options.html#index-I) LangUrlSuffix_Algol68(ga68/Directory-options.html#index-I)
L
UrlSuffix(gcc/Directory-Options.html#index-L) LangUrlSuffix_D(gdc/Directory-Options.html#index-L)
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index 214161f..a99b5ed 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -2639,37 +2639,37 @@ void
rust_input_source_test ()
{
// ASCII
- std::string src = u8"_abcde\tXYZ\v\f";
- std::vector<uint32_t> expected
- = {'_', 'a', 'b', 'c', 'd', 'e', '\t', 'X', 'Y', 'Z', '\v', '\f'};
+ std::string src = (const char *) u8"_abcde\tXYZ\v\f";
+ std::vector<uint32_t> expected = {u'_', u'a', u'b', u'c', u'd', u'e',
+ u'\t', u'X', u'Y', u'Z', u'\v', u'\f'};
test_buffer_input_source (src, expected);
// BOM
- src = u8"\xef\xbb\xbfOK";
- expected = {'O', 'K'};
+ src = (const char *) u8"\xef\xbb\xbfOK";
+ expected = {u'O', u'K'};
test_buffer_input_source (src, expected);
// Russian
- src = u8"приве́т";
- expected = {L'п',
- L'р',
- L'и',
- L'в',
+ src = (const char *) u8"приве́т";
+ expected = {u'п',
+ u'р',
+ u'и',
+ u'в',
0x0435 /* CYRILLIC SMALL LETTER IE е */,
0x301 /* COMBINING ACUTE ACCENT ́ */,
- L'т'};
+ u'т'};
test_buffer_input_source (src, expected);
- src = u8"❤️🦀";
+ src = (const char *) u8"❤️🦀";
expected = {0x2764 /* HEAVY BLACK HEART */,
- 0xfe0f /* VARIATION SELECTOR-16 */, L'🦀'};
+ 0xfe0f /* VARIATION SELECTOR-16 */, U'🦀'};
test_buffer_input_source (src, expected);
- src = u8"こんにちは";
- expected = {L'こ', L'ん', L'に', L'ち', L'は'};
+ src = (const char *) u8"こんにちは";
+ expected = {u'こ', u'ん', u'に', u'ち', u'は'};
test_file_input_source (src, expected);
- src = u8"👮‍♂👩‍⚕";
+ src = (const char *) u8"👮‍♂👩‍⚕";
expected
= {0x1f46e /* POLICE OFFICER */, 0x200d /* ZERO WIDTH JOINER */,
0x2642 /* MALE SIGN */, 0x1f469 /* WOMAN */,
diff --git a/gcc/rust/metadata/rust-export-metadata.cc b/gcc/rust/metadata/rust-export-metadata.cc
index 4dfc280..a8d4af1 100644
--- a/gcc/rust/metadata/rust-export-metadata.cc
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -23,6 +23,7 @@
#include "rust-ast-dump.h"
#include "rust-abi.h"
#include "rust-item.h"
+#include "rust-macro.h"
#include "rust-object-export.h"
#include "md5.h"
@@ -111,14 +112,12 @@ ExportContext::emit_function (const HIR::Function &fn)
}
void
-ExportContext::emit_macro (NodeId macro)
+ExportContext::emit_macro (AST::MacroRulesDefinition &macro)
{
std::stringstream oss;
AST::Dump dumper (oss);
- AST::Item *item = mappings.lookup_ast_item (macro).value ();
-
- dumper.go (*item);
+ dumper.go (macro);
public_interface_buffer += oss.str ();
}
@@ -195,7 +194,7 @@ PublicInterface::gather_export_data ()
vis_item.accept_vis (visitor);
}
- for (const auto &macro : mappings.get_exported_macros ())
+ for (auto &macro : mappings.get_exported_macros ())
context.emit_macro (macro);
}
diff --git a/gcc/rust/metadata/rust-export-metadata.h b/gcc/rust/metadata/rust-export-metadata.h
index ee006cd..7747d95 100644
--- a/gcc/rust/metadata/rust-export-metadata.h
+++ b/gcc/rust/metadata/rust-export-metadata.h
@@ -48,7 +48,7 @@ public:
* directly refer to them using their NodeId. There's no need to keep an HIR
* node for them.
*/
- void emit_macro (NodeId macro);
+ void emit_macro (AST::MacroRulesDefinition &macro);
const std::string &get_interface_buffer () const;
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index ec4c1c1..6cb8f0e 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -431,10 +431,6 @@ Parser<ManagedTokenSource>::parse_items ()
std::unique_ptr<AST::Item> item = parse_item (false);
if (item == nullptr)
{
- Error error (lexer.peek_token ()->get_locus (),
- "failed to parse item in crate");
- add_error (std::move (error));
-
// TODO: should all items be cleared?
items = std::vector<std::unique_ptr<AST::Item>> ();
break;
@@ -982,16 +978,7 @@ Parser<ManagedTokenSource>::parse_delim_token_tree ()
std::unique_ptr<AST::TokenTree> tok_tree = parse_token_tree ();
if (tok_tree == nullptr)
- {
- // TODO: is this error handling appropriate?
- Error error (
- t->get_locus (),
- "failed to parse token tree in delimited token tree - found %qs",
- t->get_token_description ());
- add_error (std::move (error));
-
- return AST::DelimTokenTree::create_empty ();
- }
+ return AST::DelimTokenTree::create_empty ();
token_trees_in_tree.push_back (std::move (tok_tree));
@@ -1079,11 +1066,12 @@ Parser<ManagedTokenSource>::parse_token_tree ()
case RIGHT_SQUARE:
case RIGHT_CURLY:
// error - should not be called when this a token
- add_error (
- Error (t->get_locus (),
- "unexpected closing delimiter %qs - token tree requires "
- "either paired delimiters or non-delimiter tokens",
- t->get_token_description ()));
+ add_error (Error (t->get_locus (), "unexpected closing delimiter %qs",
+ t->get_token_description ()));
+
+ add_error (Error (Error::Kind::Hint, t->get_locus (),
+ "token tree requires either paired delimiters or "
+ "non-delimiter tokens"));
lexer.skip_token ();
return nullptr;
@@ -1861,20 +1849,13 @@ Parser<ManagedTokenSource>::parse_macro_invocation_semi (
t = lexer.peek_token ();
// parse token trees until the initial delimiter token is found again
- while (!token_id_matches_delims (t->get_id (), delim_type))
+ while (!token_id_matches_delims (t->get_id (), delim_type)
+ && t->get_id () != END_OF_FILE)
{
std::unique_ptr<AST::TokenTree> tree = parse_token_tree ();
if (tree == nullptr)
- {
- Error error (t->get_locus (),
- "failed to parse token tree for macro invocation semi "
- "- found %qs",
- t->get_token_description ());
- add_error (std::move (error));
-
- return nullptr;
- }
+ return nullptr;
token_trees.push_back (std::move (tree));
@@ -3010,8 +2991,9 @@ Parser<ManagedTokenSource>::parse_function (AST::Visibility vis,
else
{
std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr ();
- if (block_expr != nullptr)
- body = std::move (block_expr);
+ if (block_expr == nullptr)
+ return nullptr;
+ body = std::move (block_expr);
}
return std::unique_ptr<AST::Function> (
@@ -3262,8 +3244,12 @@ Parser<ManagedTokenSource>::parse_generic_params (EndTokenPred is_end_token)
// Did we parse a generic type param yet
auto type_seen = false;
+ // Did we parse a const param with a default value yet
+ auto const_with_default_seen = false;
// Did the user write a lifetime parameter after a type one
auto order_error = false;
+ // Did the user write a const param with a default value after a type one
+ auto const_with_default_order_error = false;
// parse lifetime params
while (!is_end_token (lexer.peek_token ()->get_id ()))
@@ -3271,12 +3257,29 @@ Parser<ManagedTokenSource>::parse_generic_params (EndTokenPred is_end_token)
auto param = parse_generic_param (is_end_token);
if (param)
{
- // TODO: Handle `Const` here as well if necessary
if (param->get_kind () == AST::GenericParam::Kind::Type)
- type_seen = true;
+ {
+ type_seen = true;
+ if (const_with_default_seen)
+ const_with_default_order_error = true;
+ }
else if (param->get_kind () == AST::GenericParam::Kind::Lifetime
&& type_seen)
- order_error = true;
+ {
+ order_error = true;
+ if (const_with_default_seen)
+ const_with_default_order_error = true;
+ }
+ else if (param->get_kind () == AST::GenericParam::Kind::Const)
+ {
+ type_seen = true;
+ AST::ConstGenericParam *const_param
+ = static_cast<AST::ConstGenericParam *> (param.get ());
+ if (const_param->has_default_value ())
+ const_with_default_seen = true;
+ else if (const_with_default_seen)
+ const_with_default_order_error = true;
+ }
generic_params.emplace_back (std::move (param));
maybe_skip_token (COMMA);
@@ -3293,6 +3296,13 @@ Parser<ManagedTokenSource>::parse_generic_params (EndTokenPred is_end_token)
"must be declared prior to type and const parameters");
add_error (std::move (error));
}
+ if (const_with_default_order_error)
+ {
+ Error error (generic_params.front ()->get_locus (),
+ "invalid order for generic parameters: generic parameters "
+ "with a default must be trailing");
+ add_error (std::move (error));
+ }
generic_params.shrink_to_fit ();
return generic_params;
@@ -5193,6 +5203,13 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs,
Identifier ident{ident_tok};
+ // Parse optional generic parameters for GATs (Generic Associated Types)
+ std::vector<std::unique_ptr<AST::GenericParam>> generic_params;
+ if (lexer.peek_token ()->get_id () == LEFT_ANGLE)
+ {
+ generic_params = parse_generic_params_in_angles ();
+ }
+
std::vector<std::unique_ptr<AST::TypeParamBound>> bounds;
// parse optional colon
@@ -5213,8 +5230,9 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs,
}
return std::unique_ptr<AST::TraitItemType> (
- new AST::TraitItemType (std::move (ident), std::move (bounds),
- std::move (outer_attrs), vis, locus));
+ new AST::TraitItemType (std::move (ident), std::move (generic_params),
+ std::move (bounds), std::move (outer_attrs), vis,
+ locus));
}
// Parses a constant trait item.
@@ -6201,10 +6219,6 @@ Parser<ManagedTokenSource>::parse_let_stmt (AST::AttrVec outer_attrs,
expr = parse_expr ();
if (expr == nullptr)
{
- Error error (lexer.peek_token ()->get_locus (),
- "failed to parse expression in let statement");
- add_error (std::move (error));
-
skip_after_semicolon ();
return nullptr;
}
@@ -7231,11 +7245,7 @@ Parser<ManagedTokenSource>::parse_block_expr (
ExprOrStmt expr_or_stmt = parse_stmt_or_expr ();
if (expr_or_stmt.is_error ())
{
- Error error (
- t->get_locus (),
- "failed to parse statement or expression in block expression");
- add_error (std::move (error));
-
+ skip_after_end_block ();
return nullptr;
}
@@ -7758,14 +7768,7 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec outer_attrs,
// parse required block expr
std::unique_ptr<AST::BlockExpr> if_body = parse_block_expr ();
if (if_body == nullptr)
- {
- Error error (lexer.peek_token ()->get_locus (),
- "failed to parse if body block expression in if expression");
- add_error (std::move (error));
-
- // skip somewhere?
- return nullptr;
- }
+ return nullptr;
// branch to parse end or else (and then else, else if, or else if let)
if (lexer.peek_token ()->get_id () != ELSE)
@@ -8088,13 +8091,7 @@ Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs,
// parse loop body, which is required
std::unique_ptr<AST::BlockExpr> loop_body = parse_block_expr ();
if (loop_body == nullptr)
- {
- Error error (lexer.peek_token ()->get_locus (),
- "could not parse loop body in (infinite) loop expression");
- add_error (std::move (error));
-
- return nullptr;
- }
+ return nullptr;
return std::unique_ptr<AST::LoopExpr> (
new AST::LoopExpr (std::move (loop_body), locus, std::move (label),
@@ -8206,7 +8203,14 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (
// parse predicate patterns
std::vector<std::unique_ptr<AST::Pattern>> predicate_patterns
= parse_match_arm_patterns (EQUAL);
- // TODO: have to ensure that there is at least 1 pattern?
+ // ensure that there is at least 1 pattern
+ if (predicate_patterns.empty ())
+ {
+ Error error (lexer.peek_token ()->get_locus (),
+ "should be at least 1 pattern");
+ add_error (std::move (error));
+ return nullptr;
+ }
if (!skip_token (EQUAL))
{
@@ -10345,7 +10349,7 @@ Parser<ManagedTokenSource>::parse_literal_or_range_pattern ()
return std::unique_ptr<AST::LiteralPattern> (
new AST::LiteralPattern (range_lower->get_str (), type,
range_lower->get_locus (),
- range_lower->get_type_hint ()));
+ range_lower->get_type_hint (), has_minus));
}
}
@@ -12166,6 +12170,8 @@ Parser<ManagedTokenSource>::parse_expr (int right_binding_power,
// parse null denotation (unary part of expression)
std::unique_ptr<AST::Expr> expr
= null_denotation ({}, null_denotation_restrictions);
+ if (expr == nullptr)
+ return nullptr;
return left_denotations (std::move (expr), right_binding_power,
std::move (outer_attrs), restrictions);
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 95ca7a9..99496e6 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -349,18 +349,18 @@ void global_variable_set_init (Bvariable *, tree);
// the function, as otherwise the variable would be on the heap).
// LOCATION is where the variable is defined. For each local variable
// the frontend will call init_statement to set the initial value.
-Bvariable *local_variable (tree function, GGC::Ident name, tree type,
- Bvariable *decl_var, location_t location);
+LocalVariable local_variable (tree function, GGC::Ident name, tree type,
+ Bvariable *decl_var, location_t location);
// Create a function parameter. This is an incoming parameter, not
// a result parameter (result parameters are treated as local
// variables). The arguments are as for local_variable.
-Bvariable *parameter_variable (tree function, GGC::Ident name, tree type,
- location_t location);
+LocalVariable parameter_variable (tree function, GGC::Ident name, tree type,
+ location_t location);
// Create a static chain parameter. This is the closure parameter.
-Bvariable *static_chain_variable (tree function, GGC::Ident name, tree type,
- location_t location);
+LocalVariable static_chain_variable (tree function, GGC::Ident name, tree type,
+ location_t location);
// Create a temporary variable. A temporary variable has no name,
// just a type. We pass in FUNCTION and BLOCK in case they are
@@ -373,9 +373,9 @@ Bvariable *static_chain_variable (tree function, GGC::Ident name, tree type,
// variable, and may not be very useful. This function should
// return a variable which can be referenced later and should set
// *PSTATEMENT to a statement which initializes the variable.
-Bvariable *temporary_variable (tree fndecl, tree bind_tree, tree type,
- tree init, bool address_is_taken,
- location_t location, tree *pstatement);
+LocalVariable temporary_variable (tree fndecl, tree bind_tree, tree type,
+ tree init, bool address_is_taken,
+ location_t location, tree *pstatement);
// Labels.
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 8f950d17..750c392 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -83,6 +83,23 @@ Bvariable::error_variable ()
return new Bvariable (error_mark_node);
}
+// Get the tree of a variable for use as an expression
+tree
+LocalVariable::get_tree (location_t location) const
+{
+ if (error_operand_p (t))
+ return error_mark_node;
+
+ TREE_USED (t) = 1;
+ return t;
+}
+
+LocalVariable
+LocalVariable::error_variable ()
+{
+ return LocalVariable (error_mark_node);
+}
+
// This file implements the interface between the Rust frontend proper
// and the gcc IR. This implements specific instantiations of
// abstract classes defined by the Rust frontend proper. The Rust
@@ -2014,12 +2031,12 @@ global_variable_set_init (Bvariable *var, tree expr_tree)
// Make a local variable.
-Bvariable *
+LocalVariable
local_variable (tree function, GGC::Ident name, tree type_tree,
Bvariable *decl_var, location_t location)
{
if (error_operand_p (type_tree))
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
tree decl = build_decl (location, VAR_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = function;
@@ -2029,33 +2046,33 @@ local_variable (tree function, GGC::Ident name, tree type_tree,
SET_DECL_VALUE_EXPR (decl, decl_var->get_decl ());
}
rust_preserve_from_gc (decl);
- return new Bvariable (decl);
+ return LocalVariable (decl);
}
// Make a function parameter variable.
-Bvariable *
+LocalVariable
parameter_variable (tree function, GGC::Ident name, tree type_tree,
location_t location)
{
if (error_operand_p (type_tree))
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
tree decl = build_decl (location, PARM_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = function;
DECL_ARG_TYPE (decl) = type_tree;
rust_preserve_from_gc (decl);
- return new Bvariable (decl);
+ return LocalVariable (decl);
}
// Make a static chain variable.
-Bvariable *
+LocalVariable
static_chain_variable (tree fndecl, GGC::Ident name, tree type_tree,
location_t location)
{
if (error_operand_p (type_tree))
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
tree decl = build_decl (location, PARM_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = fndecl;
DECL_ARG_TYPE (decl) = type_tree;
@@ -2076,12 +2093,12 @@ static_chain_variable (tree fndecl, GGC::Ident name, tree type_tree,
DECL_STATIC_CHAIN (fndecl) = 1;
rust_preserve_from_gc (decl);
- return new Bvariable (decl);
+ return LocalVariable (decl);
}
// Make a temporary variable.
-Bvariable *
+LocalVariable
temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
bool is_address_taken, location_t location,
tree *pstatement)
@@ -2091,7 +2108,7 @@ temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
|| error_operand_p (fndecl))
{
*pstatement = error_mark_node;
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
}
tree var;
@@ -2141,7 +2158,7 @@ temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
|| TREE_TYPE (init_tree) == void_type_node))
*pstatement = compound_statement (init_tree, *pstatement);
- return new Bvariable (var);
+ return LocalVariable (var);
}
// Make a label.
diff --git a/gcc/rust/rust-gcc.h b/gcc/rust/rust-gcc.h
index b3f0325..1ff7c5b 100644
--- a/gcc/rust/rust-gcc.h
+++ b/gcc/rust/rust-gcc.h
@@ -59,4 +59,28 @@ private:
tree orig_type_;
};
+// like Bvariable, but orig_type_ == nullptr always holds
+// could be any variable which isn't a zero-sized global
+class LocalVariable
+{
+public:
+ LocalVariable (tree t) : t (t) {}
+
+ // Get the tree for use as an expression.
+ tree get_tree (location_t) const;
+
+ // Get the actual decl;
+ tree get_decl () const { return t; }
+
+ // Create an error variable. This is used for cases which should
+ // not occur in a correct program, in order to keep the compilation
+ // going without crashing.
+ static LocalVariable error_variable ();
+
+ operator Bvariable * () const { return new Bvariable (t); }
+
+private:
+ tree t;
+};
+
#endif // RUST_GCC
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 7885dfc..1c00fd96 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -53,10 +53,19 @@ TypeCheckExpr::Resolve (HIR::Expr &expr)
if (resolver.infered == nullptr)
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
- auto ref = expr.get_mappings ().get_hirid ();
- resolver.infered->set_ref (ref);
+ if (resolver.infered->get_kind () != TyTy::TypeKind::CONST)
+ {
+ auto ref = expr.get_mappings ().get_hirid ();
+ resolver.infered->set_ref (ref);
+ }
resolver.context->insert_type (expr.get_mappings (), resolver.infered);
+ if (auto fn = resolver.infered->try_as<const TyTy::FnType> ())
+ {
+ if (fn->is_syn_constant ())
+ resolver.infered = fn->get_return_type ();
+ }
+
return resolver.infered;
}
@@ -2358,7 +2367,12 @@ bool
TypeCheckExpr::validate_arithmetic_type (
const TyTy::BaseType *tyty, HIR::ArithmeticOrLogicalExpr::ExprType expr_type)
{
- const TyTy::BaseType *type = tyty->destructure ();
+ auto type = tyty->destructure ();
+ if (type->get_kind () == TyTy::TypeKind::CONST)
+ {
+ auto base_const = type->as_const_type ();
+ type = base_const->get_specified_type ();
+ }
// https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators
// this will change later when traits are added
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index e7f6632..8df8a18 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -391,8 +391,32 @@ TypeCheckImplItem::visit (HIR::ConstantItem &constant)
TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
constant.get_locus ());
- context->insert_type (constant.get_mappings (), unified);
- result = unified;
+
+ if (substitutions.empty ())
+ {
+ context->insert_type (constant.get_mappings (), unified);
+ result = unified;
+ return;
+ }
+
+ // special case when this is a generic constant
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+ CanonicalPath canonical_path
+ = nr_ctx.to_canonical_path (constant.get_mappings ().get_nodeid ());
+ RustIdent ident{canonical_path, constant.get_locus ()};
+ auto fnType = new TyTy::FnType (
+ constant.get_mappings ().get_hirid (),
+ constant.get_mappings ().get_defid (),
+ constant.get_identifier ().as_string (), ident,
+ TyTy::FnType::FNTYPE_IS_SYN_CONST_FLAG, ABI::RUST, {}, unified,
+ std::move (substitutions),
+ TyTy::SubstitutionArgumentMappings::empty (
+ context->get_lifetime_resolver ().get_num_bound_regions ()),
+ {});
+
+ context->insert_type (constant.get_mappings (), fnType);
+ result = fnType;
}
void
@@ -495,6 +519,12 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
void
TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
{
+ auto binder_pin = context->push_lifetime_binder ();
+
+ if (type.has_generics ())
+ resolve_generic_params (HIR::Item::ItemKind::TypeAlias, type.get_locus (),
+ type.get_generic_params (), substitutions);
+
// normal resolution of the item
TyTy::BaseType *lookup
= TypeCheckImplItem::Resolve (parent, type, self, substitutions);
@@ -558,6 +588,8 @@ TypeCheckImplItemWithTrait::visit (HIR::Function &function)
// normal resolution of the item
TyTy::BaseType *lookup
= TypeCheckImplItem::Resolve (parent, function, self, substitutions);
+ if (lookup == nullptr)
+ return;
// map the impl item to the associated trait item
const auto tref = trait_reference.get ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 4987c88a..ee5c4e9 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -112,17 +112,27 @@ TypeCheckItem::ResolveImplBlockSelfWithInference (
std::vector<TyTy::SubstitutionArg> args;
for (auto &p : substitutions)
{
- if (p.needs_substitution ())
+ auto param = p.get_param_ty ();
+ if (!p.needs_substitution ())
{
- TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
- args.emplace_back (&p, infer_var.get_tyty ());
+ auto resolved = param->destructure ();
+ args.emplace_back (&p, resolved);
+
+ continue;
+ }
+
+ TyTy::BaseType *argument = nullptr;
+ if (param->get_kind () == TyTy::TypeKind::CONST)
+ {
+ auto i = TyTy::TyVar::get_implicit_const_infer_var (locus);
+ argument = i.get_tyty ();
}
else
{
- auto param = p.get_param_ty ();
- auto resolved = param->destructure ();
- args.emplace_back (&p, resolved);
+ auto i = TyTy::TyVar::get_implicit_infer_var (locus);
+ argument = i.get_tyty ();
}
+ args.emplace_back (&p, argument);
}
// create argument mappings
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 799efc8..ca7ef47 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -704,7 +704,6 @@ TypeCheckType::visit (HIR::ArrayType &type)
TyTy::BaseType *expected_ty = nullptr;
bool ok = context->lookup_builtin ("usize", &expected_ty);
rust_assert (ok);
- context->insert_type (type.get_size_expr ().get_mappings (), expected_ty);
TyTy::BaseConstType *const_type = nullptr;
if (capacity_type->get_kind () == TyTy::TypeKind::CONST)
@@ -745,7 +744,7 @@ TypeCheckType::visit (HIR::ArrayType &type)
translated
= new TyTy::ArrayType (type.get_mappings ().get_hirid (), type.get_locus (),
TyTy::TyVar (
- const_type->as_base_type ()->get_ty_ref ()),
+ const_type->as_base_type ()->get_ref ()),
TyTy::TyVar (element_type->get_ref ()));
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 64f4314..3215f434 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -237,19 +237,20 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
: Mutability::Mut;
rust_assert (self_param.has_lifetime ());
+ auto region = TyTy::Region::make_anonymous ();
auto maybe_region = context->lookup_and_resolve_lifetime (
self_param.get_lifetime ());
-
- if (!maybe_region.has_value ())
+ if (maybe_region.has_value ())
+ region = maybe_region.value ();
+ else
{
rust_error_at (self_param.get_locus (),
"failed to resolve lifetime");
- return get_error ();
}
+
self_type = new TyTy::ReferenceType (
self_param.get_mappings ().get_hirid (),
- TyTy::TyVar (self->get_ref ()), mutability,
- maybe_region.value ());
+ TyTy::TyVar (self->get_ref ()), mutability, region);
}
break;
diff --git a/gcc/rust/typecheck/rust-type-util.cc b/gcc/rust/typecheck/rust-type-util.cc
index 6f30ebf..a6b9966 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -221,13 +221,13 @@ unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
}
else if (cleanup)
{
- // FIXME
- // reset the get_next_hir_id
-
for (auto &i : infers)
{
- i.param->set_ref (i.pref);
- i.param->set_ty_ref (i.ptyref);
+ if (i.param != nullptr)
+ {
+ i.param->set_ref (i.pref);
+ i.param->set_ty_ref (i.ptyref);
+ }
// remove the inference variable
context.clear_type (i.infer);
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.h b/gcc/rust/typecheck/rust-tyty-bounds.h
deleted file mode 100644
index 6392af1..0000000
--- a/gcc/rust/typecheck/rust-tyty-bounds.h
+++ /dev/null
@@ -1,66 +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_TYTY_BOUNDS_H
-#define RUST_TYTY_BOUNDS_H
-
-#include "rust-location.h"
-#include "rust-mapping-common.h"
-
-namespace Rust {
-
-namespace Resolver {
-class TraitReference;
-class TraitItemReference;
-class AssociatedImplTrait;
-} // namespace Resolver
-
-namespace TyTy {
-
-class BaseType;
-class TypeBoundPredicate;
-class TypeBoundsMappings
-{
-protected:
- TypeBoundsMappings (std::vector<TypeBoundPredicate> specified_bounds);
-
-public:
- std::vector<TypeBoundPredicate> &get_specified_bounds ();
-
- const std::vector<TypeBoundPredicate> &get_specified_bounds () const;
-
- TypeBoundPredicate lookup_predicate (DefId id);
-
- size_t num_specified_bounds () const;
-
- std::string raw_bounds_as_string () const;
-
- std::string bounds_as_string () const;
-
- std::string raw_bounds_as_name () const;
-
-protected:
- void add_bound (TypeBoundPredicate predicate);
-
- std::vector<TypeBoundPredicate> specified_bounds;
-};
-
-} // namespace TyTy
-} // namespace Rust
-
-#endif // RUST_TYTY_BOUNDS_H
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index c1bc96a..d09e180 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -22,7 +22,6 @@
#include "rust-system.h"
#include "rust-location.h"
#include "rust-hir-full-decls.h"
-#include "rust-tyty-bounds.h"
#include "rust-tyty-region.h"
#include "rust-ast.h"
#include "optional.h"
diff --git a/gcc/rust/typecheck/rust-tyty-util.cc b/gcc/rust/typecheck/rust-tyty-util.cc
index 72761d9..b780eaa 100644
--- a/gcc/rust/typecheck/rust-tyty-util.cc
+++ b/gcc/rust/typecheck/rust-tyty-util.cc
@@ -62,14 +62,15 @@ TyVar::get_implicit_infer_var (location_t locus)
}
TyVar
-TyVar::get_implicit_const_infer_var (location_t locus)
+TyVar::get_implicit_const_infer_var (location_t locus, TyVar *implicit_type)
{
auto &mappings = Analysis::Mappings::get ();
auto context = Resolver::TypeCheckContext::get ();
- TyVar ty_infer = get_implicit_infer_var (locus);
+ TyVar it = (implicit_type != nullptr) ? *implicit_type
+ : get_implicit_infer_var (locus);
HirId next = mappings.get_next_hir_id ();
- auto infer = new ConstInferType (ty_infer.get_tyty (), next, next, {});
+ auto infer = new ConstInferType (it.get_tyty (), next, next, {});
context->insert_implicit_type (infer->get_ref (), infer);
mappings.insert_location (infer->get_ref (), locus);
diff --git a/gcc/rust/typecheck/rust-tyty-util.h b/gcc/rust/typecheck/rust-tyty-util.h
index 26101fd..b132487 100644
--- a/gcc/rust/typecheck/rust-tyty-util.h
+++ b/gcc/rust/typecheck/rust-tyty-util.h
@@ -43,7 +43,8 @@ public:
static TyVar get_implicit_infer_var (location_t locus);
- static TyVar get_implicit_const_infer_var (location_t locus);
+ static TyVar get_implicit_const_infer_var (location_t locus,
+ TyVar *implicit_type = nullptr);
static TyVar subst_covariant_var (TyTy::BaseType *orig,
TyTy::BaseType *subst);
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index da5c350..5386b72 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -785,11 +785,18 @@ BaseType::is_concrete () const
{
const TyTy::BaseType *x = destructure ();
- if (x->is<ParamType> () || x->is<ProjectionType> ()
- || x->is<ConstParamType> ())
+ if (x->is<ParamType> () || x->is<ProjectionType> ())
{
return false;
}
+ else if (x->get_kind () == TyTy::TypeKind::CONST)
+ {
+ auto p = x->as_const_type ();
+ if (p->const_kind () == BaseConstType::ConstKind::Decl)
+ return false;
+
+ return true;
+ }
// placeholder is a special case for this case when it is not resolvable
// it means we its just an empty placeholder associated type which is
// concrete
@@ -883,7 +890,7 @@ BaseType::is_concrete () const
bool
BaseType::has_substitutions_defined () const
{
- const TyTy::BaseType *x = destructure ();
+ const auto x = this;
switch (x->get_kind ())
{
case INFER:
@@ -3633,9 +3640,8 @@ ConstParamType::get_name () const
return get_symbol ();
BaseType *lookup = resolve ();
- // Avoid infinite recursion if resolve() returns this same type
if (lookup == this->as_base_type ())
- return get_symbol ();
+ return get_symbol () + ":" + get_specified_type ()->get_name ();
return lookup->get_name ();
}
@@ -3660,9 +3666,25 @@ ConstParamType::is_equal (const BaseType &other) const
return false;
if (can_resolve ())
- return Resolver::types_compatable (TyTy::TyWithLocation (resolve ()),
- TyTy::TyWithLocation (other2.resolve ()),
- ident.locus, false);
+ {
+ // Compare the resolved ty_ref values to avoid infinite recursion
+ // through types_compatable/unification
+ BaseType *lhs = resolve ();
+ BaseType *rhs = other2.resolve ();
+
+ // If they resolve to the same type (same ty_ref), they're equal
+ if (lhs->get_ty_ref () == rhs->get_ty_ref ())
+ return true;
+
+ // Otherwise check if the resolved types are equal
+ // Avoid recursion by checking if we'd be comparing ConstParamTypes again
+ if (lhs->get_kind () == TypeKind::CONST
+ && lhs->as_const_type ()->const_kind ()
+ == BaseConstType::ConstKind::Decl)
+ return false; // Would cause recursion, so not equal
+
+ return lhs->is_equal (*rhs);
+ }
return get_symbol ().compare (other2.get_symbol ()) == 0;
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 3236bf3..50f6347 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -24,7 +24,6 @@
#include "rust-common.h"
#include "rust-identifier.h"
#include "rust-abi.h"
-#include "rust-tyty-bounds.h"
#include "rust-tyty-util.h"
#include "rust-tyty-subst.h"
#include "rust-tyty-region.h"
@@ -92,6 +91,127 @@ public:
class TyVisitor;
class TyConstVisitor;
class BaseConstType;
+
+class TypeBoundPredicate : public SubstitutionRef
+{
+public:
+ TypeBoundPredicate (const Resolver::TraitReference &trait_reference,
+ BoundPolarity polarity, location_t locus);
+
+ TypeBoundPredicate (DefId reference,
+ std::vector<SubstitutionParamMapping> substitutions,
+ BoundPolarity polarity, location_t locus);
+
+ TypeBoundPredicate (const TypeBoundPredicate &other);
+
+ virtual ~TypeBoundPredicate () {}
+
+ TypeBoundPredicate &operator= (const TypeBoundPredicate &other);
+
+ static TypeBoundPredicate error ();
+
+ std::string as_string () const;
+
+ std::string as_name () const;
+
+ const Resolver::TraitReference *get () const;
+
+ location_t get_locus () const { return locus; }
+
+ std::string get_name () const;
+
+ // check that this is object-safe see:
+ // https://doc.rust-lang.org/reference/items/traits.html#object-safety
+ bool is_object_safe (bool emit_error, location_t locus) const;
+
+ void apply_generic_arguments (HIR::GenericArgs *generic_args,
+ bool has_associated_self, bool is_super_trait);
+
+ void apply_argument_mappings (SubstitutionArgumentMappings &arguments,
+ bool is_super_trait);
+
+ bool contains_item (const std::string &search) const;
+
+ tl::optional<TypeBoundPredicateItem>
+ lookup_associated_item (const std::string &search) const;
+
+ tl::optional<TypeBoundPredicateItem>
+ lookup_associated_item (const Resolver::TraitItemReference *ref) const;
+
+ // WARNING THIS WILL ALWAYS RETURN NULLPTR
+ BaseType *
+ handle_substitions (SubstitutionArgumentMappings &mappings) override final;
+
+ bool is_error () const;
+
+ bool requires_generic_args () const;
+
+ bool contains_associated_types () const;
+
+ DefId get_id () const { return reference; }
+
+ BoundPolarity get_polarity () const { return polarity; }
+
+ std::vector<TypeBoundPredicateItem> get_associated_type_items ();
+
+ size_t get_num_associated_bindings () const override final;
+
+ TypeBoundPredicateItem
+ lookup_associated_type (const std::string &search) override final;
+
+ bool is_equal (const TypeBoundPredicate &other) const;
+
+ bool validate_type_implements_super_traits (TyTy::BaseType &self,
+ HIR::Type &impl_type,
+ HIR::Type &trait) const;
+
+ bool validate_type_implements_this (TyTy::BaseType &self,
+ HIR::Type &impl_type,
+ HIR::Type &trait) const;
+
+private:
+ struct mark_is_error
+ {
+ };
+
+ TypeBoundPredicate (mark_is_error);
+
+ void get_trait_hierachy (
+ std::function<void (const Resolver::TraitReference &)> callback) const;
+
+ DefId reference;
+ location_t locus;
+ bool error_flag;
+ BoundPolarity polarity;
+ std::vector<TyTy::TypeBoundPredicate> super_traits;
+};
+
+class TypeBoundsMappings
+{
+protected:
+ TypeBoundsMappings (std::vector<TypeBoundPredicate> specified_bounds);
+
+public:
+ std::vector<TypeBoundPredicate> &get_specified_bounds ();
+
+ const std::vector<TypeBoundPredicate> &get_specified_bounds () const;
+
+ TypeBoundPredicate lookup_predicate (DefId id);
+
+ size_t num_specified_bounds () const;
+
+ std::string raw_bounds_as_string () const;
+
+ std::string bounds_as_string () const;
+
+ std::string raw_bounds_as_name () const;
+
+protected:
+ void add_bound (TypeBoundPredicate predicate);
+
+ std::vector<TypeBoundPredicate> specified_bounds;
+};
+
class BaseType : public TypeBoundsMappings
{
public:
@@ -671,100 +791,6 @@ private:
std::vector<TyVar> fields;
};
-class TypeBoundPredicate : public SubstitutionRef
-{
-public:
- TypeBoundPredicate (const Resolver::TraitReference &trait_reference,
- BoundPolarity polarity, location_t locus);
-
- TypeBoundPredicate (DefId reference,
- std::vector<SubstitutionParamMapping> substitutions,
- BoundPolarity polarity, location_t locus);
-
- TypeBoundPredicate (const TypeBoundPredicate &other);
-
- virtual ~TypeBoundPredicate () {}
-
- TypeBoundPredicate &operator= (const TypeBoundPredicate &other);
-
- static TypeBoundPredicate error ();
-
- std::string as_string () const;
-
- std::string as_name () const;
-
- const Resolver::TraitReference *get () const;
-
- location_t get_locus () const { return locus; }
-
- std::string get_name () const;
-
- // check that this is object-safe see:
- // https://doc.rust-lang.org/reference/items/traits.html#object-safety
- bool is_object_safe (bool emit_error, location_t locus) const;
-
- void apply_generic_arguments (HIR::GenericArgs *generic_args,
- bool has_associated_self, bool is_super_trait);
-
- void apply_argument_mappings (SubstitutionArgumentMappings &arguments,
- bool is_super_trait);
-
- bool contains_item (const std::string &search) const;
-
- tl::optional<TypeBoundPredicateItem>
- lookup_associated_item (const std::string &search) const;
-
- tl::optional<TypeBoundPredicateItem>
- lookup_associated_item (const Resolver::TraitItemReference *ref) const;
-
- // WARNING THIS WILL ALWAYS RETURN NULLPTR
- BaseType *
- handle_substitions (SubstitutionArgumentMappings &mappings) override final;
-
- bool is_error () const;
-
- bool requires_generic_args () const;
-
- bool contains_associated_types () const;
-
- DefId get_id () const { return reference; }
-
- BoundPolarity get_polarity () const { return polarity; }
-
- std::vector<TypeBoundPredicateItem> get_associated_type_items ();
-
- size_t get_num_associated_bindings () const override final;
-
- TypeBoundPredicateItem
- lookup_associated_type (const std::string &search) override final;
-
- bool is_equal (const TypeBoundPredicate &other) const;
-
- bool validate_type_implements_super_traits (TyTy::BaseType &self,
- HIR::Type &impl_type,
- HIR::Type &trait) const;
-
- bool validate_type_implements_this (TyTy::BaseType &self,
- HIR::Type &impl_type,
- HIR::Type &trait) const;
-
-private:
- struct mark_is_error
- {
- };
-
- TypeBoundPredicate (mark_is_error);
-
- void get_trait_hierachy (
- std::function<void (const Resolver::TraitReference &)> callback) const;
-
- DefId reference;
- location_t locus;
- bool error_flag;
- BoundPolarity polarity;
- std::vector<TyTy::TypeBoundPredicate> super_traits;
-};
-
class TypeBoundPredicateItem
{
public:
@@ -1050,6 +1076,7 @@ public:
static const uint8_t FNTYPE_IS_METHOD_FLAG = 0x01;
static const uint8_t FNTYPE_IS_EXTERN_FLAG = 0x02;
static const uint8_t FNTYPE_IS_VARADIC_FLAG = 0X04;
+ static const uint8_t FNTYPE_IS_SYN_CONST_FLAG = 0X08;
FnType (HirId ref, DefId id, std::string identifier, RustIdent ident,
uint8_t flags, ABI abi, std::vector<FnParam> params, BaseType *type,
@@ -1111,6 +1138,11 @@ public:
bool is_variadic () const { return (flags & FNTYPE_IS_VARADIC_FLAG) != 0; }
+ bool is_syn_constant () const
+ {
+ return (flags & FNTYPE_IS_SYN_CONST_FLAG) != 0;
+ }
+
DefId get_id () const { return id; }
// get the Self type for the method
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 43dd6dc..36dbc0e 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -18,8 +18,8 @@
#include "rust-unify.h"
#include "fold-const.h"
+#include "rust-tyty-util.h"
#include "rust-tyty.h"
-#include "tree.h"
namespace Rust {
namespace Resolver {
@@ -302,35 +302,67 @@ UnifyRules::go ()
else if (ltype->get_kind () == TyTy::TypeKind::CONST
&& rtype->get_kind () == TyTy::TypeKind::CONST)
{
- const auto &lhs = *ltype->as_const_type ();
- const auto &rhs = *rtype->as_const_type ();
+ auto lhs = ltype->as_const_type ();
+ auto rhs = rtype->as_const_type ();
bool both_are_decls
- = lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl
- && rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl;
+ = lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ && rhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl;
bool have_decls
- = lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl
- || rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl;
+ = lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ || rhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl;
if (have_decls && !both_are_decls)
{
- if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
+ if (lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl)
{
- TyTy::TyVar iv = TyTy::TyVar::get_implicit_const_infer_var (
- lhs.as_base_type ()->get_locus ());
- ltype = iv.get_tyty ();
+ auto l = lhs->as_base_type ()->get_locus ();
+ auto p = static_cast<TyTy::ConstParamType *> (lhs);
+ auto it = TyTy::TyVar::get_implicit_infer_var (l);
+ auto iv = TyTy::TyVar::get_implicit_const_infer_var (l, &it);
+ auto ivt = iv.get_tyty ();
+
+ infers.emplace_back (0, 0, nullptr, it.get_tyty ());
+ infers.emplace_back (ltype->get_ref (), ltype->get_ty_ref (),
+ p, ivt);
+
+ ltype = ivt;
+ p->set_ty_ref (ltype->get_ref ());
}
- else if (rhs.const_kind ()
+ else if (rhs->const_kind ()
== TyTy::BaseConstType::ConstKind::Decl)
{
- TyTy::TyVar iv = TyTy::TyVar::get_implicit_const_infer_var (
- rhs.as_base_type ()->get_locus ());
- rtype = iv.get_tyty ();
+ auto l = rhs->as_base_type ()->get_locus ();
+ auto p = static_cast<TyTy::ConstParamType *> (rhs);
+ auto it = TyTy::TyVar::get_implicit_infer_var (l);
+ auto iv = TyTy::TyVar::get_implicit_const_infer_var (l, &it);
+ auto ivt = iv.get_tyty ();
+
+ infers.emplace_back (0, 0, nullptr, it.get_tyty ());
+ infers.emplace_back (rtype->get_ref (), rtype->get_ty_ref (),
+ p, ivt);
+
+ rtype = ivt;
+ p->set_ty_ref (rtype->get_ref ());
}
}
}
}
+ if (ltype->get_kind () != TyTy::TypeKind::CONST
+ && rtype->get_kind () == TyTy::TypeKind::CONST)
+ {
+ auto *rc = rtype->as_const_type ();
+ rtype = rc->get_specified_type ();
+ }
+
+ if (ltype->get_kind () == TyTy::TypeKind::CONST
+ && rtype->get_kind () != TyTy::TypeKind::CONST)
+ {
+ auto *lc = ltype->as_const_type ();
+ ltype = lc->get_specified_type ();
+ }
+
switch (ltype->get_kind ())
{
case TyTy::INFER:
diff --git a/gcc/rust/typecheck/rust-unify.h b/gcc/rust/typecheck/rust-unify.h
index 4bed24c..2b772fe 100644
--- a/gcc/rust/typecheck/rust-unify.h
+++ b/gcc/rust/typecheck/rust-unify.h
@@ -30,15 +30,15 @@ class UnifyRules
public:
struct InferenceSite
{
- InferenceSite (HirId pref, HirId ptyref, TyTy::ParamType *param,
- TyTy::InferType *infer)
+ InferenceSite (HirId pref, HirId ptyref, TyTy::BaseGeneric *param,
+ TyTy::BaseType *infer)
: pref (pref), ptyref (ptyref), param (param), infer (infer)
{}
HirId pref;
HirId ptyref;
- TyTy::ParamType *param;
- TyTy::InferType *infer;
+ TyTy::BaseGeneric *param;
+ TyTy::BaseType *infer;
};
struct CommitSite
{
diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h
index a22664a..0f35f56 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -49,8 +49,6 @@ public:
static constexpr auto &PROC_MACRO_DERIVE = "proc_macro_derive";
static constexpr auto &PROC_MACRO_ATTRIBUTE = "proc_macro_attribute";
- static constexpr auto &DERIVE = "derive";
-
static constexpr auto &TARGET_FEATURE = "target_feature";
// From now on, these are reserved by the compiler and gated through
// #![feature(rustc_attrs)]
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 9621100..70f26e7 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -90,8 +90,6 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::PROC_MACRO, EXPANSION},
{Attrs::PROC_MACRO_DERIVE, EXPANSION},
{Attrs::PROC_MACRO_ATTRIBUTE, EXPANSION},
-
- {Attrs::DERIVE, EXPANSION},
// FIXME: This is not implemented yet, see
// https://github.com/Rust-GCC/gccrs/issues/1475
{Attrs::TARGET_FEATURE, CODE_GENERATION},
@@ -101,7 +99,6 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
{Attrs::STABLE, STATIC_ANALYSIS},
{Attrs::UNSTABLE, STATIC_ANALYSIS},
-
// assuming we keep these for static analysis
{Attrs::RUSTC_PROMOTABLE, CODE_GENERATION},
{Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
@@ -114,23 +111,22 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK},
{Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK},
{Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK},
-
{Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION},
-
// TODO: be careful about calling functions marked with this?
{Attrs::RUSTC_ARGS_REQUIRED_CONST, CODE_GENERATION},
-
{Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
-
{Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS},
{Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS},
-
{Attrs::FUNDAMENTAL, TYPE_CHECK},
{Attrs::NON_EXHAUSTIVE, TYPE_CHECK},
{Attrs::RUSTFMT, EXTERNAL},
-
{Attrs::TEST, CODE_GENERATION}};
+static const std::set<std::string> __outer_attributes
+ = {Attrs::INLINE, Attrs::DERIVE_ATTR, Attrs::ALLOW_INTERNAL_UNSTABLE,
+ Attrs::LANG, Attrs::REPR, Attrs::PATH,
+ Attrs::TARGET_FEATURE, Attrs::TEST};
+
BuiltinAttributeMappings *
BuiltinAttributeMappings::get ()
{
@@ -327,6 +323,26 @@ check_proc_macro_non_root (AST::AttrVec attributes, location_t loc)
}
void
+AttributeChecker::check_inner_attribute (const AST::Attribute &attribute)
+{
+ BuiltinAttrDefinition result;
+
+ if (!is_builtin (attribute, result))
+ return;
+
+ if (__outer_attributes.find (result.name) != __outer_attributes.end ())
+ rust_error_at (attribute.get_locus (),
+ "attribute cannot be used at crate level");
+}
+
+void
+AttributeChecker::check_inner_attributes (const AST::AttrVec &attributes)
+{
+ for (auto &attr : attributes)
+ check_inner_attribute (attr);
+}
+
+void
AttributeChecker::check_attribute (const AST::Attribute &attribute)
{
if (!attribute.empty_input ())
@@ -357,15 +373,6 @@ AttributeChecker::check_attribute (const AST::Attribute &attribute)
}
void
-AttributeChecker::check_inner_attributes (const AST::AttrVec &attributes)
-{
- for (auto &attr : attributes)
- if (attr.is_derive ())
- rust_error_at (attr.get_locus (),
- "derive attribute cannot be used at crate level");
-}
-
-void
AttributeChecker::check_attributes (const AST::AttrVec &attributes)
{
for (auto &attr : attributes)
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index b10a080..f4a2d38 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -102,12 +102,14 @@ public:
private:
using AST::DefaultASTVisitor::visit;
+
+ /* Check the validity of an inner attribute */
+ void check_inner_attribute (const AST::Attribute &attribute);
+ /* Check the validy of all inner attributes */
+ void check_inner_attributes (const AST::AttrVec &attributes);
/* Check the validity of a given attribute */
void check_attribute (const AST::Attribute &attribute);
-
/* Check the validity of all given attributes */
-
- void check_inner_attributes (const AST::AttrVec &attributes);
void check_attributes (const AST::AttrVec &attributes);
// rust-ast.h
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 4629e6a..a6d323e 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -925,10 +925,10 @@ Mappings::lookup_macro_invocation (AST::MacroInvocation &invoc)
void
Mappings::insert_exported_macro (AST::MacroRulesDefinition &def)
{
- exportedMacros.emplace_back (def.get_node_id ());
+ exportedMacros.emplace_back (def);
}
-std::vector<NodeId> &
+std::vector<AST::MacroRulesDefinition>
Mappings::get_exported_macros ()
{
return exportedMacros;
@@ -1358,5 +1358,17 @@ Mappings::lookup_captures (NodeId closure)
return cap->second;
}
+void
+Mappings::add_derived_node (NodeId node_id)
+{
+ derived_nodes.insert (node_id);
+}
+
+bool
+Mappings::is_derived_node (NodeId node_id)
+{
+ return derived_nodes.find (node_id) != derived_nodes.end ();
+}
+
} // namespace Analysis
} // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index c8fafa4..60066d6 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -279,7 +279,7 @@ public:
lookup_macro_invocation (AST::MacroInvocation &invoc);
void insert_exported_macro (AST::MacroRulesDefinition &def);
- std::vector<NodeId> &get_exported_macros ();
+ std::vector<AST::MacroRulesDefinition> get_exported_macros ();
void insert_derive_proc_macros (CrateNum num,
std::vector<CustomDeriveProcMacro> macros);
@@ -350,6 +350,9 @@ public:
void add_capture (NodeId closure, NodeId definition);
tl::optional<std::vector<NodeId>> lookup_captures (NodeId closure);
+ void add_derived_node (NodeId node_id);
+ bool is_derived_node (NodeId node_id);
+
private:
Mappings ();
@@ -408,7 +411,7 @@ private:
std::map<NodeId, std::pair<AST::MacroRulesDefinition *, CrateNum>>
macroMappings;
std::map<NodeId, AST::MacroRulesDefinition *> macroInvocations;
- std::vector<NodeId> exportedMacros;
+ std::vector<AST::MacroRulesDefinition> exportedMacros;
// Procedural macros
std::map<CrateNum, std::vector<CustomDeriveProcMacro>>
@@ -443,6 +446,8 @@ private:
// Closure AST NodeId -> vector of Definition node ids
std::unordered_map<NodeId, std::vector<NodeId>> captures;
+
+ std::set<NodeId> derived_nodes;
};
} // namespace Analysis