public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-4661] gccrs: Add const checker
@ 2022-12-13 13:19 Arthur Cohen
  0 siblings, 0 replies; only message in thread
From: Arthur Cohen @ 2022-12-13 13:19 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5215235f01665062fbe182bb0c3c49539d882ad7

commit r13-4661-g5215235f01665062fbe182bb0c3c49539d882ad7
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date:   Tue Aug 23 16:31:55 2022 +0100

    gccrs: Add const checker
    
    Similarly to the unsafe checker, constant evaluation can only be performed
    in a few contexts and include restrictions on the Rust language. Should
    the user fail to uphold those conditions, errors will be reported and the
    compilation pipeline interrupted.
    
    These contexts are as follow:
    
    - Array type length expressions
    - Array repeat length expressions
    - Constants
    - Statics
    - Enum discriminants
    - Const generic arguments
    
    In these contexts, the user is restricted to calling only functions marked
    as `const` or perform arithmetic operations only on certain types, among
    other restrictions.
    
            gcc/rust/
            * checks/errors/rust-const-checker.cc: New.
            * checks/errors/rust-const-checker.h: New.

Diff:
---
 gcc/rust/checks/errors/rust-const-checker.cc | 844 +++++++++++++++++++++++++++
 gcc/rust/checks/errors/rust-const-checker.h  | 189 ++++++
 2 files changed, 1033 insertions(+)

diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
new file mode 100644
index 00000000000..35c61fe03f0
--- /dev/null
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -0,0 +1,844 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-const-checker.h"
+#include "rust-hir.h"
+#include "rust-hir-expr.h"
+#include "rust-hir-stmt.h"
+#include "rust-hir-item.h"
+
+namespace Rust {
+namespace HIR {
+
+ConstChecker::ConstChecker ()
+  : resolver (*Resolver::Resolver::get ()),
+    mappings (*Analysis::Mappings::get ())
+{}
+
+void
+ConstChecker::go (HIR::Crate &crate)
+{
+  for (auto &item : crate.items)
+    item->accept_vis (*this);
+}
+
+bool
+ConstChecker::is_const_extern_fn (HIR::ExternalFunctionItem &fn)
+{
+  // FIXME: Is it really how we want to handle `rustc_const_stable`
+  // and `rustc_const_unstable`?
+  // TODO: Add these attributes to the attribute check and handle
+  // `stable` and `unstable` as well
+  return std::any_of (
+    fn.get_outer_attrs ().begin (), fn.get_outer_attrs ().end (),
+    [] (const AST::Attribute &attr) {
+      // `starts_with` in C++11...
+      return attr.get_path ().as_string ().rfind ("rustc_const_", 0) == 0;
+    });
+}
+
+void
+ConstChecker::visit (Lifetime &lifetime)
+{}
+
+void
+ConstChecker::visit (LifetimeParam &lifetime_param)
+{}
+
+void
+ConstChecker::visit (PathInExpression &path)
+{}
+
+void
+ConstChecker::visit (TypePathSegment &segment)
+{}
+
+void
+ConstChecker::visit (TypePathSegmentGeneric &segment)
+{}
+
+void
+ConstChecker::visit (TypePathSegmentFunction &segment)
+{}
+
+void
+ConstChecker::visit (TypePath &path)
+{}
+
+void
+ConstChecker::visit (QualifiedPathInExpression &path)
+{}
+
+void
+ConstChecker::visit (QualifiedPathInType &path)
+{}
+
+void
+ConstChecker::visit (LiteralExpr &expr)
+{}
+
+void
+ConstChecker::visit (BorrowExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (DereferenceExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ErrorPropagationExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (NegationExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArithmeticOrLogicalExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ComparisonExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (LazyBooleanExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (TypeCastExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (AssignmentExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (CompoundAssignmentExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (GroupedExpr &expr)
+{
+  expr.get_expr_in_parens ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArrayElemsValues &elems)
+{
+  for (auto &elem : elems.get_values ())
+    elem->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArrayElemsCopied &elems)
+{
+  elems.get_elem_to_copy ()->accept_vis (*this);
+
+  const_context.enter (elems.get_mappings ().get_hirid ());
+
+  elems.get_num_copies_expr ()->accept_vis (*this);
+
+  const_context.exit ();
+}
+
+void
+ConstChecker::visit (ArrayExpr &expr)
+{
+  expr.get_internal_elements ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArrayIndexExpr &expr)
+{
+  expr.get_array_expr ()->accept_vis (*this);
+  expr.get_index_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (TupleExpr &expr)
+{
+  for (auto &elem : expr.get_tuple_elems ())
+    elem->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (TupleIndexExpr &expr)
+{
+  expr.get_tuple_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (StructExprStruct &expr)
+{}
+
+void
+ConstChecker::visit (StructExprFieldIdentifier &field)
+{}
+
+void
+ConstChecker::visit (StructExprFieldIdentifierValue &field)
+{
+  field.get_value ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (StructExprFieldIndexValue &field)
+{
+  field.get_value ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (StructExprStructFields &expr)
+{
+  for (auto &field : expr.get_fields ())
+    field->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (StructExprStructBase &expr)
+{}
+
+void
+ConstChecker::check_function_call (HirId fn_id, Location locus)
+{
+  if (!const_context.is_in_context ())
+    return;
+
+  auto maybe_fn = mappings.lookup_hir_item (fn_id);
+  if (maybe_fn && maybe_fn->get_item_kind () != Item::ItemKind::Function)
+    return;
+
+  // There are const extern functions (intrinsics)
+  // TODO: Should we check the ABI is only "rust intrinsics"? Is that handled
+  // elsewhere?
+  HirId parent_block;
+  auto maybe_extern_item
+    = mappings.lookup_hir_extern_item (fn_id, &parent_block);
+  if (maybe_extern_item
+      && maybe_extern_item->get_extern_kind ()
+	   != ExternalItem::ExternKind::Function)
+    return;
+
+  auto is_error = false;
+  if (maybe_fn)
+    {
+      auto fn = static_cast<Function *> (maybe_fn);
+      if (!fn->get_qualifiers ().is_const ())
+	is_error = true;
+    }
+
+  if (maybe_extern_item)
+    {
+      {
+	auto fn = static_cast<ExternalFunctionItem *> (maybe_extern_item);
+	if (!is_const_extern_fn (*fn))
+	  is_error = true;
+      }
+    }
+
+  if (is_error)
+    rust_error_at (locus, "only functions marked as %<const%> are allowed to "
+			  "be called from constant contexts");
+}
+
+void
+ConstChecker::visit (CallExpr &expr)
+{
+  auto fn = expr.get_fnexpr ();
+  if (!fn)
+    return;
+
+  NodeId ast_node_id = fn->get_mappings ().get_nodeid ();
+  NodeId ref_node_id;
+  HirId definition_id;
+
+  // We don't care about types here
+  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+    return;
+
+  rust_assert (mappings.lookup_node_to_hir (ref_node_id, &definition_id));
+
+  check_function_call (definition_id, expr.get_locus ());
+
+  for (auto &arg : expr.get_arguments ())
+    arg->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (MethodCallExpr &expr)
+{
+  expr.get_receiver ()->accept_vis (*this);
+
+  for (auto &arg : expr.get_arguments ())
+    arg->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (FieldAccessExpr &expr)
+{
+  expr.get_receiver_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ClosureExprInner &expr)
+{}
+
+void
+ConstChecker::visit (BlockExpr &expr)
+{
+  for (auto &stmt : expr.get_statements ())
+    stmt->accept_vis (*this);
+
+  if (expr.has_expr ())
+    expr.get_final_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ClosureExprInnerTyped &expr)
+{}
+
+void
+ConstChecker::visit (ContinueExpr &expr)
+{}
+
+void
+ConstChecker::visit (BreakExpr &expr)
+{
+  if (expr.has_break_expr ())
+    expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (RangeFromToExpr &expr)
+{
+  expr.get_from_expr ()->accept_vis (*this);
+  expr.get_to_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (RangeFromExpr &expr)
+{
+  expr.get_from_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (RangeToExpr &expr)
+{
+  expr.get_to_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (RangeFullExpr &expr)
+{}
+
+void
+ConstChecker::visit (RangeFromToInclExpr &expr)
+{
+  expr.get_from_expr ()->accept_vis (*this);
+  expr.get_to_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (RangeToInclExpr &expr)
+{
+  // FIXME: Visit to_expr
+}
+
+void
+ConstChecker::visit (ReturnExpr &expr)
+{
+  if (expr.has_return_expr ())
+    expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (UnsafeBlockExpr &expr)
+{
+  expr.get_block_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (LoopExpr &expr)
+{
+  expr.get_loop_block ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (WhileLoopExpr &expr)
+{
+  expr.get_predicate_expr ()->accept_vis (*this);
+  expr.get_loop_block ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (WhileLetLoopExpr &expr)
+{
+  expr.get_cond ()->accept_vis (*this);
+  expr.get_loop_block ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ForLoopExpr &expr)
+{
+  expr.get_iterator_expr ()->accept_vis (*this);
+  expr.get_loop_block ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (IfExpr &expr)
+{
+  expr.get_if_condition ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (IfExprConseqElse &expr)
+{
+  expr.get_if_condition ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_else_block ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (IfExprConseqIf &expr)
+{
+  expr.get_if_condition ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_conseq_if_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (IfExprConseqIfLet &expr)
+{
+  expr.get_if_condition ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+
+  // TODO: Visit conseq if let expression
+}
+
+void
+ConstChecker::visit (IfLetExpr &expr)
+{
+  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (IfLetExprConseqElse &expr)
+{
+  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+
+  // TODO: Visit else expression
+}
+
+void
+ConstChecker::visit (IfLetExprConseqIf &expr)
+{
+  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (IfLetExprConseqIfLet &expr)
+{
+  expr.get_scrutinee_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+
+  // TODO: Visit conseq if let expression
+}
+
+void
+ConstChecker::visit (MatchExpr &expr)
+{
+  expr.get_scrutinee_expr ()->accept_vis (*this);
+
+  for (auto &match_arm : expr.get_match_cases ())
+    match_arm.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (AwaitExpr &expr)
+{
+  // TODO: Visit expression
+}
+
+void
+ConstChecker::visit (AsyncBlockExpr &expr)
+{
+  // TODO: Visit block expression
+}
+
+void
+ConstChecker::visit (TypeParam &param)
+{}
+
+void
+ConstChecker::visit (ConstGenericParam &param)
+{}
+
+void
+ConstChecker::visit (LifetimeWhereClauseItem &item)
+{}
+
+void
+ConstChecker::visit (TypeBoundWhereClauseItem &item)
+{}
+
+void
+ConstChecker::visit (Module &module)
+{
+  for (auto &item : module.get_items ())
+    item->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ExternCrate &crate)
+{}
+
+void
+ConstChecker::visit (UseTreeGlob &use_tree)
+{}
+
+void
+ConstChecker::visit (UseTreeList &use_tree)
+{}
+
+void
+ConstChecker::visit (UseTreeRebind &use_tree)
+{}
+
+void
+ConstChecker::visit (UseDeclaration &use_decl)
+{}
+
+void
+ConstChecker::visit (Function &function)
+{
+  auto const_fn = function.get_qualifiers ().is_const ();
+  if (const_fn)
+    const_context.enter (function.get_mappings ().get_hirid ());
+
+  for (auto &param : function.get_function_params ())
+    param.get_type ()->accept_vis (*this);
+
+  function.get_definition ()->accept_vis (*this);
+
+  if (const_fn)
+    const_context.exit ();
+}
+
+void
+ConstChecker::visit (TypeAlias &type_alias)
+{}
+
+void
+ConstChecker::visit (StructStruct &struct_item)
+{}
+
+void
+ConstChecker::visit (TupleStruct &tuple_struct)
+{}
+
+void
+ConstChecker::visit (EnumItem &item)
+{}
+
+void
+ConstChecker::visit (EnumItemTuple &item)
+{}
+
+void
+ConstChecker::visit (EnumItemStruct &item)
+{}
+
+void
+ConstChecker::visit (EnumItemDiscriminant &item)
+{
+  const_context.enter (item.get_mappings ().get_hirid ());
+
+  item.get_discriminant_expression ()->accept_vis (*this);
+
+  const_context.exit ();
+}
+
+void
+ConstChecker::visit (Enum &enum_item)
+{}
+
+void
+ConstChecker::visit (Union &union_item)
+{}
+
+void
+ConstChecker::visit (ConstantItem &const_item)
+{
+  const_context.enter (const_item.get_mappings ().get_hirid ());
+
+  const_item.get_expr ()->accept_vis (*this);
+
+  const_context.exit ();
+}
+
+void
+ConstChecker::visit (StaticItem &static_item)
+{
+  const_context.enter (static_item.get_mappings ().get_hirid ());
+
+  static_item.get_expr ()->accept_vis (*this);
+
+  const_context.exit ();
+}
+
+void
+ConstChecker::visit (TraitItemFunc &item)
+{
+  if (item.has_block_defined ())
+    item.get_block_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (TraitItemConst &item)
+{
+  if (item.has_expr ())
+    item.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (TraitItemType &item)
+{}
+
+void
+ConstChecker::visit (Trait &trait)
+{
+  for (auto &item : trait.get_trait_items ())
+    item->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ImplBlock &impl)
+{
+  for (auto &item : impl.get_impl_items ())
+    item->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ExternalStaticItem &item)
+{}
+
+void
+ConstChecker::visit (ExternalFunctionItem &item)
+{}
+
+void
+ConstChecker::visit (ExternBlock &block)
+{
+  // FIXME: Do we need to do this?
+  for (auto &item : block.get_extern_items ())
+    item->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (LiteralPattern &pattern)
+{}
+
+void
+ConstChecker::visit (IdentifierPattern &pattern)
+{}
+
+void
+ConstChecker::visit (WildcardPattern &pattern)
+{}
+
+void
+ConstChecker::visit (RangePatternBoundLiteral &bound)
+{}
+
+void
+ConstChecker::visit (RangePatternBoundPath &bound)
+{}
+
+void
+ConstChecker::visit (RangePatternBoundQualPath &bound)
+{}
+
+void
+ConstChecker::visit (RangePattern &pattern)
+{}
+
+void
+ConstChecker::visit (ReferencePattern &pattern)
+{}
+
+void
+ConstChecker::visit (StructPatternFieldTuplePat &field)
+{}
+
+void
+ConstChecker::visit (StructPatternFieldIdentPat &field)
+{}
+
+void
+ConstChecker::visit (StructPatternFieldIdent &field)
+{}
+
+void
+ConstChecker::visit (StructPattern &pattern)
+{}
+
+void
+ConstChecker::visit (TupleStructItemsNoRange &tuple_items)
+{}
+
+void
+ConstChecker::visit (TupleStructItemsRange &tuple_items)
+{}
+
+void
+ConstChecker::visit (TupleStructPattern &pattern)
+{}
+
+void
+ConstChecker::visit (TuplePatternItemsMultiple &tuple_items)
+{}
+
+void
+ConstChecker::visit (TuplePatternItemsRanged &tuple_items)
+{}
+
+void
+ConstChecker::visit (TuplePattern &pattern)
+{}
+
+void
+ConstChecker::visit (GroupedPattern &pattern)
+{}
+
+void
+ConstChecker::visit (SlicePattern &pattern)
+{}
+
+void
+ConstChecker::visit (EmptyStmt &stmt)
+{}
+
+void
+ConstChecker::visit (LetStmt &stmt)
+{
+  if (stmt.has_init_expr ())
+    stmt.get_init_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ExprStmtWithoutBlock &stmt)
+{
+  stmt.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ExprStmtWithBlock &stmt)
+{
+  stmt.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (TraitBound &bound)
+{}
+
+void
+ConstChecker::visit (ImplTraitType &type)
+{}
+
+void
+ConstChecker::visit (TraitObjectType &type)
+{}
+
+void
+ConstChecker::visit (ParenthesisedType &type)
+{}
+
+void
+ConstChecker::visit (ImplTraitTypeOneBound &type)
+{}
+
+void
+ConstChecker::visit (TupleType &type)
+{}
+
+void
+ConstChecker::visit (NeverType &type)
+{}
+
+void
+ConstChecker::visit (RawPointerType &type)
+{}
+
+void
+ConstChecker::visit (ReferenceType &type)
+{}
+
+void
+ConstChecker::visit (ArrayType &type)
+{
+  const_context.enter (type.get_mappings ().get_hirid ());
+
+  type.get_size_expr ()->accept_vis (*this);
+
+  const_context.exit ();
+}
+
+void
+ConstChecker::visit (SliceType &type)
+{}
+
+void
+ConstChecker::visit (InferredType &type)
+{}
+
+void
+ConstChecker::visit (BareFunctionType &type)
+{}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h
new file mode 100644
index 00000000000..50838d18996
--- /dev/null
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -0,0 +1,189 @@
+// Copyright (C) 2020-2022 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_CONST_CHECKER_H
+#define RUST_CONST_CHECKER_H
+
+#include "rust-hir-visitor.h"
+#include "rust-hir-type-check.h"
+#include "rust-stacked-contexts.h"
+#include "rust-name-resolver.h"
+
+namespace Rust {
+namespace HIR {
+class ConstChecker : public HIRFullVisitor
+{
+public:
+  ConstChecker ();
+
+  void go (HIR::Crate &crate);
+
+  /**
+   * Check if an item is a const extern item or not
+   * TODO: Move this to a const compilation context class or an attribute
+   * checking class
+   */
+  static bool is_const_extern_fn (HIR::ExternalFunctionItem &fn);
+
+private:
+  /**
+   * Check that only const functions are called in const contexts
+   */
+  void check_function_call (HirId fn_id, Location locus);
+
+  StackedContexts<HirId> const_context;
+  Resolver::Resolver &resolver;
+  Analysis::Mappings &mappings;
+
+  virtual void visit (Lifetime &lifetime) override;
+  virtual void visit (LifetimeParam &lifetime_param) override;
+  virtual void visit (PathInExpression &path) override;
+  virtual void visit (TypePathSegment &segment) override;
+  virtual void visit (TypePathSegmentGeneric &segment) override;
+  virtual void visit (TypePathSegmentFunction &segment) override;
+  virtual void visit (TypePath &path) override;
+  virtual void visit (QualifiedPathInExpression &path) override;
+  virtual void visit (QualifiedPathInType &path) override;
+  virtual void visit (LiteralExpr &expr) override;
+  virtual void visit (BorrowExpr &expr) override;
+  virtual void visit (DereferenceExpr &expr) override;
+  virtual void visit (ErrorPropagationExpr &expr) override;
+  virtual void visit (NegationExpr &expr) override;
+  virtual void visit (ArithmeticOrLogicalExpr &expr) override;
+  virtual void visit (ComparisonExpr &expr) override;
+  virtual void visit (LazyBooleanExpr &expr) override;
+  virtual void visit (TypeCastExpr &expr) override;
+  virtual void visit (AssignmentExpr &expr) override;
+  virtual void visit (CompoundAssignmentExpr &expr) override;
+  virtual void visit (GroupedExpr &expr) override;
+  virtual void visit (ArrayElemsValues &elems) override;
+  virtual void visit (ArrayElemsCopied &elems) override;
+  virtual void visit (ArrayExpr &expr) override;
+  virtual void visit (ArrayIndexExpr &expr) override;
+  virtual void visit (TupleExpr &expr) override;
+  virtual void visit (TupleIndexExpr &expr) override;
+  virtual void visit (StructExprStruct &expr) override;
+  virtual void visit (StructExprFieldIdentifier &field) override;
+  virtual void visit (StructExprFieldIdentifierValue &field) override;
+  virtual void visit (StructExprFieldIndexValue &field) override;
+  virtual void visit (StructExprStructFields &expr) override;
+  virtual void visit (StructExprStructBase &expr) override;
+  virtual void visit (CallExpr &expr) override;
+  virtual void visit (MethodCallExpr &expr) override;
+  virtual void visit (FieldAccessExpr &expr) override;
+  virtual void visit (ClosureExprInner &expr) override;
+  virtual void visit (BlockExpr &expr) override;
+  virtual void visit (ClosureExprInnerTyped &expr) override;
+  virtual void visit (ContinueExpr &expr) override;
+  virtual void visit (BreakExpr &expr) override;
+  virtual void visit (RangeFromToExpr &expr) override;
+  virtual void visit (RangeFromExpr &expr) override;
+  virtual void visit (RangeToExpr &expr) override;
+  virtual void visit (RangeFullExpr &expr) override;
+  virtual void visit (RangeFromToInclExpr &expr) override;
+  virtual void visit (RangeToInclExpr &expr) override;
+  virtual void visit (ReturnExpr &expr) override;
+  virtual void visit (UnsafeBlockExpr &expr) override;
+  virtual void visit (LoopExpr &expr) override;
+  virtual void visit (WhileLoopExpr &expr) override;
+  virtual void visit (WhileLetLoopExpr &expr) override;
+  virtual void visit (ForLoopExpr &expr) override;
+  virtual void visit (IfExpr &expr) override;
+  virtual void visit (IfExprConseqElse &expr) override;
+  virtual void visit (IfExprConseqIf &expr) override;
+  virtual void visit (IfExprConseqIfLet &expr) override;
+  virtual void visit (IfLetExpr &expr) override;
+  virtual void visit (IfLetExprConseqElse &expr) override;
+  virtual void visit (IfLetExprConseqIf &expr) override;
+  virtual void visit (IfLetExprConseqIfLet &expr) override;
+  virtual void visit (MatchExpr &expr) override;
+  virtual void visit (AwaitExpr &expr) override;
+  virtual void visit (AsyncBlockExpr &expr) override;
+  virtual void visit (TypeParam &param) override;
+  virtual void visit (ConstGenericParam &param) override;
+  virtual void visit (LifetimeWhereClauseItem &item) override;
+  virtual void visit (TypeBoundWhereClauseItem &item) override;
+  virtual void visit (Module &module) override;
+  virtual void visit (ExternCrate &crate) override;
+  virtual void visit (UseTreeGlob &use_tree) override;
+  virtual void visit (UseTreeList &use_tree) override;
+  virtual void visit (UseTreeRebind &use_tree) override;
+  virtual void visit (UseDeclaration &use_decl) override;
+  virtual void visit (Function &function) override;
+  virtual void visit (TypeAlias &type_alias) override;
+  virtual void visit (StructStruct &struct_item) override;
+  virtual void visit (TupleStruct &tuple_struct) override;
+  virtual void visit (EnumItem &item) override;
+  virtual void visit (EnumItemTuple &item) override;
+  virtual void visit (EnumItemStruct &item) override;
+  virtual void visit (EnumItemDiscriminant &item) override;
+  virtual void visit (Enum &enum_item) override;
+  virtual void visit (Union &union_item) override;
+  virtual void visit (ConstantItem &const_item) override;
+  virtual void visit (StaticItem &static_item) override;
+  virtual void visit (TraitItemFunc &item) override;
+  virtual void visit (TraitItemConst &item) override;
+  virtual void visit (TraitItemType &item) override;
+  virtual void visit (Trait &trait) override;
+  virtual void visit (ImplBlock &impl) override;
+  virtual void visit (ExternalStaticItem &item) override;
+  virtual void visit (ExternalFunctionItem &item) override;
+  virtual void visit (ExternBlock &block) override;
+  virtual void visit (LiteralPattern &pattern) override;
+  virtual void visit (IdentifierPattern &pattern) override;
+  virtual void visit (WildcardPattern &pattern) override;
+  virtual void visit (RangePatternBoundLiteral &bound) override;
+  virtual void visit (RangePatternBoundPath &bound) override;
+  virtual void visit (RangePatternBoundQualPath &bound) override;
+  virtual void visit (RangePattern &pattern) override;
+  virtual void visit (ReferencePattern &pattern) override;
+  virtual void visit (StructPatternFieldTuplePat &field) override;
+  virtual void visit (StructPatternFieldIdentPat &field) override;
+  virtual void visit (StructPatternFieldIdent &field) override;
+  virtual void visit (StructPattern &pattern) override;
+  virtual void visit (TupleStructItemsNoRange &tuple_items) override;
+  virtual void visit (TupleStructItemsRange &tuple_items) override;
+  virtual void visit (TupleStructPattern &pattern) override;
+  virtual void visit (TuplePatternItemsMultiple &tuple_items) override;
+  virtual void visit (TuplePatternItemsRanged &tuple_items) override;
+  virtual void visit (TuplePattern &pattern) override;
+  virtual void visit (GroupedPattern &pattern) override;
+  virtual void visit (SlicePattern &pattern) override;
+  virtual void visit (EmptyStmt &stmt) override;
+  virtual void visit (LetStmt &stmt) override;
+  virtual void visit (ExprStmtWithoutBlock &stmt) override;
+  virtual void visit (ExprStmtWithBlock &stmt) override;
+  virtual void visit (TraitBound &bound) override;
+  virtual void visit (ImplTraitType &type) override;
+  virtual void visit (TraitObjectType &type) override;
+  virtual void visit (ParenthesisedType &type) override;
+  virtual void visit (ImplTraitTypeOneBound &type) override;
+  virtual void visit (TupleType &type) override;
+  virtual void visit (NeverType &type) override;
+  virtual void visit (RawPointerType &type) override;
+  virtual void visit (ReferenceType &type) override;
+  virtual void visit (ArrayType &type) override;
+  virtual void visit (SliceType &type) override;
+  virtual void visit (InferredType &type) override;
+  virtual void visit (BareFunctionType &type) override;
+};
+
+} // namespace HIR
+} // namespace Rust
+
+#endif /* !RUST_CONST_CHECKER_H */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-12-13 13:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-13 13:19 [gcc r13-4661] gccrs: Add const checker Arthur Cohen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).