[COMMITTED] gccrs: session-manager: Add ast-pretty-expanded dump

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Allow the dump of 
prettified AST
(Session::dump_ast_pretty): New
* rust-session-manager.h: Add new output file for pretty AST dump

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/rust-session-manager.cc | 10 --
 gcc/rust/rust-session-manager.h  |  2 +-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 2b33ddfa601..157f5099155 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -58,6 +58,7 @@ namespace Rust {
 const char *kLexDumpFile = "gccrs.lex.dump";
 const char *kASTDumpFile = "gccrs.ast.dump";
 const char *kASTPrettyDumpFile = "gccrs.ast-pretty.dump";
+const char *kASTPrettyDumpFileExpanded = "gccrs.ast-pretty-expanded.dump";
 const char *kASTExpandedDumpFile = "gccrs.ast-expanded.dump";
 const char *kHIRDumpFile = "gccrs.hir.dump";
 const char *kHIRPrettyDumpFile = "gccrs.hir-pretty.dump";
@@ -531,6 +532,7 @@ Session::compile_crate (const char *filename)
   // dump AST with expanded stuff
   rust_debug ("BEGIN POST-EXPANSION AST DUMP");
   dump_ast_expanded (parser, parsed_crate);
+  dump_ast_pretty (parsed_crate, true);
   rust_debug ("END POST-EXPANSION AST DUMP");
 }
 
@@ -832,10 +834,14 @@ Session::dump_ast (Parser &parser, AST::Crate 
&crate) const
 }
 
 void
-Session::dump_ast_pretty (AST::Crate &crate) const
+Session::dump_ast_pretty (AST::Crate &crate, bool expanded) const
 {
   std::ofstream out;
-  out.open (kASTPrettyDumpFile);
+  if (expanded)
+out.open (kASTPrettyDumpFileExpanded);
+  else
+out.open (kASTPrettyDumpFile);
+
   if (out.fail ())
 {
   rust_error_at (Linemap::unknown_location (), "cannot open %s:%m; 
ignored",
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 055aea6b7e6..db915991809 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -319,7 +319,7 @@ private:
 
   void dump_lex (Parser &parser) const;
   void dump_ast (Parser &parser, AST::Crate &crate) const;
-  void dump_ast_pretty (AST::Crate &crate) const;
+  void dump_ast_pretty (AST::Crate &crate, bool expanded = false) const;
   void dump_ast_expanded (Parser &parser, AST::Crate &crate) const;
   void dump_hir (HIR::Crate &crate) const;
   void dump_hir_pretty (HIR::Crate &crate) const;
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Desugar double borrows into two HIR:BorrowExpr's

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

We simply hit a gcc_unreachable() on double borrows but it seems reasonable
to just desugar the AST into a borrow of a borrow to foo. Instead of a
borrow expression with a flag to be respected.

Fixes #1506

gcc/rust/ChangeLog:

* hir/rust-ast-lower-expr.h: Lower double borrow expressions to two
`HIR::BorrowExpr`s.
* hir/tree/rust-hir-expr.h: Remove `is_double_borrow` field from
`HIR::BorrowExpr`.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Remove
call to `gcc_unreachable` on double borrow expressions.

gcc/testsuite/ChangeLog:

* rust/compile/torture/issue-1506.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/hir/rust-ast-lower-expr.h| 27 ---
 gcc/rust/hir/tree/rust-hir-expr.h |  5 ++--
 .../typecheck/rust-hir-type-check-expr.cc |  6 -
 .../rust/compile/torture/issue-1506.rs|  3 +++
 4 files changed, 28 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/torture/issue-1506.rs

diff --git a/gcc/rust/hir/rust-ast-lower-expr.h 
b/gcc/rust/hir/rust-ast-lower-expr.h
index 92773b6f3a1..b0ab409646d 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -643,10 +643,29 @@ public:
   mappings->get_next_hir_id (crate_num),
   UNKNOWN_LOCAL_DEFID);
 
-translated = new HIR::BorrowExpr (
-  mapping, std::unique_ptr (borrow_lvalue),
-  expr.get_is_mut () ? Mutability::Mut : Mutability::Imm,
-  expr.get_is_double_borrow (), expr.get_outer_attrs (), expr.get_locus 
());
+HIR::BorrowExpr *borrow_expr
+  = new HIR::BorrowExpr (mapping,
+std::unique_ptr (borrow_lvalue),
+expr.get_is_mut () ? Mutability::Mut
+   : Mutability::Imm,
+expr.get_outer_attrs (), expr.get_locus ());
+
+if (expr.get_is_double_borrow ())
+  {
+   NodeId artifical_bouble_borrow_id = mappings->get_next_node_id ();
+   Analysis::NodeMapping mapping (crate_num, artifical_bouble_borrow_id,
+  mappings->get_next_hir_id (crate_num),
+  UNKNOWN_LOCAL_DEFID);
+
+   borrow_expr
+ = new HIR::BorrowExpr (mapping,
+std::unique_ptr (borrow_expr),
+expr.get_is_mut () ? Mutability::Mut
+   : Mutability::Imm,
+expr.get_outer_attrs (), expr.get_locus ());
+  }
+
+translated = borrow_expr;
   }
 
   void visit (AST::DereferenceExpr &expr) override
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h 
b/gcc/rust/hir/tree/rust-hir-expr.h
index 5a1e9768526..564d5215724 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -192,10 +192,10 @@ public:
 
   BorrowExpr (Analysis::NodeMapping mappings,
  std::unique_ptr borrow_lvalue, Mutability mut,
- bool is_double_borrow, AST::AttrVec outer_attribs, Location locus)
+ AST::AttrVec outer_attribs, Location locus)
 : OperatorExpr (std::move (mappings), std::move (borrow_lvalue),
std::move (outer_attribs), locus),
-  mut (mut), double_borrow (is_double_borrow)
+  mut (mut)
   {}
 
   void accept_vis (HIRFullVisitor &vis) override;
@@ -203,7 +203,6 @@ public:
 
   Mutability get_mut () const { return mut; }
   bool is_mut () const { return mut == Mutability::Mut; }
-  bool get_is_double_borrow () const { return double_borrow; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 41c8cd1f19b..c415ae98a7a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1209,12 +1209,6 @@ TypeCheckExpr::visit (HIR::BorrowExpr &expr)
}
 }
 
-  if (expr.get_is_double_borrow ())
-{
-  // FIXME double_reference
-  gcc_unreachable ();
-}
-
   infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
 TyTy::TyVar (resolved_base->get_ref ()),
 expr.get_mut ());
diff --git a/gcc/testsuite/rust/compile/torture/issue-1506.rs 
b/gcc/testsuite/rust/compile/torture/issue-1506.rs
new file mode 100644
index 000..a38f23144ed
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1506.rs
@@ -0,0 +1,3 @@
+pub fn main() {
+let _: &i32 = 1;
+}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: builtins: Add add_overflow builtin and refactor class

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* backend/rust-builtins.h: Refactor builtin context class and add
overflow builtins.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-builtins.h | 51 ++--
 1 file changed, 36 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/backend/rust-builtins.h b/gcc/rust/backend/rust-builtins.h
index 2bfa6c6cdf7..5cd84010723 100644
--- a/gcc/rust/backend/rust-builtins.h
+++ b/gcc/rust/backend/rust-builtins.h
@@ -18,8 +18,9 @@
 #define RUST_BUILTINS_H
 
 #include "rust-system.h"
-#include "tree.h"
+#include "rust-tree.h"
 #include "langhooks.h"
+#include "tree.h"
 
 namespace Rust {
 namespace Compile {
@@ -99,16 +100,34 @@ private:
 
   BuiltinsContext () { setup (); }
 
-  void setup ()
+  void setup_overflow_fns ()
+  {
+tree overflow_type
+  = build_varargs_function_type_list (boolean_type_node, NULL_TREE);
+
+define_builtin ("add_overflow", BUILT_IN_ADD_OVERFLOW,
+   "__builtin_add_overflow", "add_overflow", overflow_type, 0);
+define_builtin ("sub_overflow", BUILT_IN_SUB_OVERFLOW,
+   "__builtin_sub_overflow", "sub_overflow", overflow_type, 0);
+define_builtin ("mul_overflow", BUILT_IN_MUL_OVERFLOW,
+   "__builtin_mul_overflow", "mul_overflow", overflow_type, 0);
+  }
+
+  void setup_math_fns ()
   {
 tree math_function_type_f32
   = build_function_type_list (float_type_node, float_type_node, NULL_TREE);
 
 define_builtin ("sinf32", BUILT_IN_SINF, "__builtin_sinf", "sinf",
math_function_type_f32, builtin_const);
-
 define_builtin ("sqrtf32", BUILT_IN_SQRTF, "__builtin_sqrtf", "sqrtf",
math_function_type_f32, builtin_const);
+  }
+
+  void setup ()
+  {
+setup_math_fns ();
+setup_overflow_fns ();
 
 define_builtin ("unreachable", BUILT_IN_UNREACHABLE,
"__builtin_unreachable", NULL,
@@ -132,6 +151,16 @@ private:
   0);
   }
 
+  static void handle_flags (tree decl, int flags)
+  {
+if (flags & builtin_const)
+  TREE_READONLY (decl) = 1;
+if (flags & builtin_noreturn)
+  TREE_READONLY (decl) = 1;
+if (flags & builtin_novops)
+  DECL_IS_NOVOPS (decl) = 1;
+  }
+
   // Define a builtin function.  BCODE is the builtin function code
   // defined by builtins.def.  NAME is the name of the builtin function.
   // LIBNAME is the name of the corresponding library function, and is
@@ -144,24 +173,16 @@ private:
   {
 tree decl = add_builtin_function (name, fntype, bcode, BUILT_IN_NORMAL,
  libname, NULL_TREE);
-if ((flags & builtin_const) != 0)
-  TREE_READONLY (decl) = 1;
-if ((flags & builtin_noreturn) != 0)
-  TREE_THIS_VOLATILE (decl) = 1;
-if ((flags & builtin_novops) != 0)
-  DECL_IS_NOVOPS (decl) = 1;
+handle_flags (decl, flags);
 set_builtin_decl (bcode, decl, true);
+
 this->builtin_functions_[name] = decl;
 if (libname != NULL)
   {
decl = add_builtin_function (libname, fntype, bcode, BUILT_IN_NORMAL,
 NULL, NULL_TREE);
-   if ((flags & builtin_const) != 0)
- TREE_READONLY (decl) = 1;
-   if ((flags & builtin_noreturn) != 0)
- TREE_THIS_VOLATILE (decl) = 1;
-   if ((flags & builtin_novops) != 0)
- DECL_IS_NOVOPS (decl) = 1;
+   handle_flags (decl, flags);
+
this->builtin_functions_[libname] = decl;
   }
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: rustc_attrs: Allow `rustc_inherit_overflow_checks` as a builtin..

2023-01-31 Thread Arthur Cohen
..attribute. We cannot yet handle this attribute, but we should not reject it 
either

gcc/rust/ChangeLog:

* util/rust-attributes.cc: Add `rustc_inherit_overflow_checks` to list
of builtin attributes.

gcc/testsuite/ChangeLog:

* rust/compile/rustc_attr1.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/util/rust-attributes.cc  | 32 ---
 gcc/testsuite/rust/compile/rustc_attr1.rs | 13 +
 2 files changed, 30 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/rustc_attr1.rs

diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 2cefdb247d1..9db77b40dfb 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -26,21 +26,23 @@ namespace Rust {
 namespace Analysis {
 
 // 
https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
-static const BuiltinAttrDefinition __definitions[] = {
-  {"inline", CODE_GENERATION},
-  {"cold", CODE_GENERATION},
-  {"cfg", EXPANSION},
-  {"cfg_attr", EXPANSION},
-  {"deprecated", STATIC_ANALYSIS},
-  {"allow", STATIC_ANALYSIS},
-  {"doc", HIR_LOWERING},
-  {"must_use", STATIC_ANALYSIS},
-  {"lang", HIR_LOWERING},
-  {"link_section", CODE_GENERATION},
-  {"no_mangle", CODE_GENERATION},
-  {"repr", CODE_GENERATION},
-  {"path", EXPANSION},
-};
+static const BuiltinAttrDefinition __definitions[]
+  = {{"inline", CODE_GENERATION},
+ {"cold", CODE_GENERATION},
+ {"cfg", EXPANSION},
+ {"cfg_attr", EXPANSION},
+ {"deprecated", STATIC_ANALYSIS},
+ {"allow", STATIC_ANALYSIS},
+ {"doc", HIR_LOWERING},
+ {"must_use", STATIC_ANALYSIS},
+ {"lang", HIR_LOWERING},
+ {"link_section", CODE_GENERATION},
+ {"no_mangle", CODE_GENERATION},
+ {"repr", CODE_GENERATION},
+ {"path", EXPANSION},
+ // From now on, these are reserved by the compiler and gated through
+ // #![feature(rustc_attrs)]
+ {"rustc_inherit_overflow_checks", CODE_GENERATION}};
 
 BuiltinAttributeMappings *
 BuiltinAttributeMappings::get ()
diff --git a/gcc/testsuite/rust/compile/rustc_attr1.rs 
b/gcc/testsuite/rust/compile/rustc_attr1.rs
new file mode 100644
index 000..4bc7d5e3553
--- /dev/null
+++ b/gcc/testsuite/rust/compile/rustc_attr1.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-w" }
+
+#![feature(rustc_attrs)]
+
+pub struct NotI8(i8);
+
+impl NotI8 {
+#[inline]
+#[rustc_inherit_overflow_checks]
+pub fn add(self, other: NotI8) -> NotI8 {
+NotI8(self.0 + other.0)
+}
+}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: backend: Add overflow checks to every arithmetic operation

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit): Insert overflow
checks logic.
(CompileExpr::array_copied_expr): Insert overflow checks logic.
* backend/rust-compile-item.cc (CompileItem::visit): Insert overflow
checks logic.
* backend/rust-compile-type.cc (TyTyResolveCompile::visit): Insert
overflow checks logic.
* rust-gcc.cc (Gcc_backend::arithmetic_or_logical_expression): 
Differentiate
existing function from `arithmetic_or_logical_expression_checked`.
This function does insert perform overflow checks.
(Gcc_backend::arithmetic_or_logical_expression_checked): New
function.
(is_overflowing_expr): New function. Check if an expression is an
overflowing one (ADD, SUB, MUL).
(fetch_overflow_builtins): New function.
* rust-backend.h: Declare `arithmetic_or_logical_expression_checked` in
abstract `Backend` class.

gcc/testsuite/ChangeLog:

* rust/debug/win64-abi.rs: Fix assertion to take into account
overflow builtins
* rust/compile/torture/macro-issue1426.rs: Moved to...
* rust/execute/torture/macro-issue1426.rs: ...here.
* rust/execute/torture/overflow1.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-expr.cc |  55 +--
 gcc/rust/backend/rust-compile-item.cc |   6 +
 gcc/rust/backend/rust-compile-type.cc |   4 +
 gcc/rust/rust-backend.h   |  19 ++-
 gcc/rust/rust-gcc.cc  | 140 --
 gcc/testsuite/rust/debug/win64-abi.rs |   8 +-
 .../torture/macro-issue1426.rs|   9 +-
 .../rust/execute/torture/overflow1.rs |  20 +++
 8 files changed, 223 insertions(+), 38 deletions(-)
 rename gcc/testsuite/rust/{compile => execute}/torture/macro-issue1426.rs (68%)
 create mode 100644 gcc/testsuite/rust/execute/torture/overflow1.rs

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 9db14a238a7..ea146731cbe 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -26,6 +26,7 @@
 #include "rust-compile-block.h"
 #include "rust-compile-implitem.h"
 #include "rust-constexpr.h"
+#include "rust-gcc.h"
 
 #include "fold-const.h"
 #include "realmpfr.h"
@@ -146,9 +147,26 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
   return;
 }
 
-  translated
-= ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
-expr.get_locus ());
+  if (ctx->in_fn () && !ctx->const_context_p ())
+{
+  auto receiver_tmp = NULL_TREE;
+  auto receiver
+   = ctx->get_backend ()->temporary_variable (ctx->peek_fn ().fndecl,
+  NULL_TREE, TREE_TYPE (lhs),
+  lhs, true, expr.get_locus (),
+  &receiver_tmp);
+  auto check
+   = ctx->get_backend ()->arithmetic_or_logical_expression_checked (
+ op, lhs, rhs, expr.get_locus (), receiver);
+
+  ctx->add_statement (check);
+  translated = receiver->get_tree (expr.get_locus ());
+}
+  else
+{
+  translated = ctx->get_backend ()->arithmetic_or_logical_expression (
+   op, lhs, rhs, expr.get_locus ());
+}
 }
 
 void
@@ -176,13 +194,27 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
   return;
 }
 
-  auto operator_expr
-= ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
-expr.get_locus ());
-  tree assignment
-= ctx->get_backend ()->assignment_statement (lhs, operator_expr,
-expr.get_locus ());
-  ctx->add_statement (assignment);
+  if (ctx->in_fn () && !ctx->const_context_p ())
+{
+  auto tmp = NULL_TREE;
+  auto receiver
+   = ctx->get_backend ()->temporary_variable (ctx->peek_fn ().fndecl,
+  NULL_TREE, TREE_TYPE (lhs),
+  lhs, true, expr.get_locus (),
+  &tmp);
+  auto check
+   = ctx->get_backend ()->arithmetic_or_logical_expression_checked (
+ op, lhs, rhs, expr.get_locus (), receiver);
+  ctx->add_statement (check);
+
+  translated = ctx->get_backend ()->assignment_statement (
+   lhs, receiver->get_tree (expr.get_locus ()), expr.get_locus ());
+}
+  else
+{
+  translated = ctx->get_backend ()->arithmetic_or_logical_expression (
+   op, lhs, rhs, expr.get_locus ());
+}
 }
 
 void
@@ -2383,7 +2415,10 @@ CompileExpr::array_copied_expr (Location expr_locus,
   return error_mark_node;
 }
 
+  ctx->push_const_c

[COMMITTED] gccrs: dump: Add AST debugging using the AST::Dump class

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-ast-dump.h: Add shorthand `AST::Dump::debug` function to
dump an AST node on `stderr`.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/ast/rust-ast-dump.h | 16 
 1 file changed, 16 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 4fa4db9265f..955dbc0bebc 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -52,6 +52,22 @@ public:
   void go (AST::Crate &crate);
   void go (AST::Item &item);
 
+  /**
+   * Use the AST Dump as a debugging tool
+   */
+  template  static void debug (T &instance)
+  {
+auto dump = Dump (std::cerr);
+
+std::cerr << '\n';
+instance.accept_vis (dump);
+std::cerr << '\n';
+  }
+  template  static void debug (std::unique_ptr &instance)
+  {
+debug (*instance);
+  }
+
 private:
   std::ostream &stream;
   Indent indentation;
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: transcriber: Do not infinite loop if the current parsed node is an error

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* expand/rust-macro-expand.cc (parse_many): Return early from parsing
loop if we encounter an error, and emit that error in the meantime.

Co-authored-by: philberty 

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/expand/rust-macro-expand.cc | 8 
 1 file changed, 8 insertions(+)

diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index df258bd96ec..ed1b838c987 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -731,6 +731,14 @@ parse_many (Parser &parser, TokenId 
&delimiter,
break;
 
   auto node = parse_fn ();
+  if (node.is_error ())
+   {
+ for (auto err : parser.get_errors ())
+   err.emit_error ();
+
+ return AST::ASTFragment::create_error ();
+   }
+
   nodes.emplace_back (std::move (node));
 }
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: ast: Only expand expressions and types if the kind is right

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-ast.h: Add assertions and accessors for fragment nodes.
* expand/rust-attribute-visitor.cc (AttrVisitor::visit): Fix expansion
context typo when visiting `InherentImpl` items.
(AttrVisitor::maybe_expand_expr): Use new Fragment accessor to fetch
properly typed node.
(AttrVisitor::maybe_expand_type): Likewise.
* expand/rust-macro-expand.cc (transcribe_type): Emit parse errors
when trying to parse a type.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/ast/rust-ast.h   | 15 +++
 gcc/rust/expand/rust-attribute-visitor.cc | 11 +++
 gcc/rust/expand/rust-macro-expand.cc  |  4 +++-
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 213208efb56..58fe2674479 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -24,6 +24,7 @@
 #include "rust-hir-map.h"
 #include "rust-token.h"
 #include "rust-location.h"
+#include "rust-diagnostics.h"
 
 namespace Rust {
 // TODO: remove typedefs and make actual types for these
@@ -1868,6 +1869,10 @@ private:
*/
 
   bool is_single_fragment () const { return nodes.size () == 1; }
+  bool is_single_fragment (SingleASTNode::NodeType expected) const
+  {
+return is_single_fragment () && nodes[0].get_kind () == expected;
+  }
 
   bool is_single_fragment_kind (SingleASTNode::NodeType kind) const
   {
@@ -1913,6 +1918,16 @@ public:
 
   bool should_expand () const { return !is_error (); }
 
+  bool is_expression_fragment () const
+  {
+return is_single_fragment (SingleASTNode::NodeType::EXPRESSION);
+  }
+
+  bool is_type_fragment () const
+  {
+return is_single_fragment (SingleASTNode::NodeType::TYPE);
+  }
+
   std::unique_ptr take_expression_fragment ()
   {
 rust_assert (is_single_fragment_kind 
(SingleASTNode::NodeType::EXPRESSION));
diff --git a/gcc/rust/expand/rust-attribute-visitor.cc 
b/gcc/rust/expand/rust-attribute-visitor.cc
index 15aedbfa668..673f0432a30 100644
--- a/gcc/rust/expand/rust-attribute-visitor.cc
+++ b/gcc/rust/expand/rust-attribute-visitor.cc
@@ -2662,7 +2662,7 @@ AttrVisitor::visit (AST::InherentImpl &impl)
   for (auto ¶m : impl.get_generic_params ())
 param->accept_vis (*this);
 
-  expander.push_context (MacroExpander::ContextType::TYPE);
+  expander.push_context (MacroExpander::ContextType::ITEM);
 
   auto &type = impl.get_type ();
   type->accept_vis (*this);
@@ -2706,7 +2706,7 @@ AttrVisitor::visit (AST::TraitImpl &impl)
   for (auto ¶m : impl.get_generic_params ())
 param->accept_vis (*this);
 
-  expander.push_context (MacroExpander::ContextType::TYPE);
+  expander.push_context (MacroExpander::ContextType::ITEM);
 
   auto &type = impl.get_type ();
   type->accept_vis (*this);
@@ -3427,11 +3427,13 @@ AttrVisitor::visit (AST::BareFunctionType &type)
 
   // no where clause, apparently
 }
+
 void
 AttrVisitor::maybe_expand_expr (std::unique_ptr &expr)
 {
   auto final_fragment = expand_macro_fragment_recursive ();
-  if (final_fragment.should_expand ())
+  if (final_fragment.should_expand ()
+  && final_fragment.is_expression_fragment ())
 expr = final_fragment.take_expression_fragment ();
 }
 
@@ -3439,7 +3441,8 @@ void
 AttrVisitor::maybe_expand_type (std::unique_ptr &type)
 {
   auto final_fragment = expand_macro_fragment_recursive ();
-  if (final_fragment.should_expand ())
+  if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
 type = final_fragment.take_type_fragment ();
 }
+
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index ed1b838c987..c68faba86ad 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -864,7 +864,9 @@ transcribe_expression (Parser &parser)
 static AST::ASTFragment
 transcribe_type (Parser &parser)
 {
-  auto type = parser.parse_type ();
+  auto type = parser.parse_type (true);
+  for (auto err : parser.get_errors ())
+err.emit_error ();
 
   return AST::ASTFragment ({std::move (type)});
 }
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: ast: Add better assertion on AST fragments

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-ast.h: Improve assertions within ASTFragment API.

Co-authored-by: philberty 

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/ast/rust-ast.h | 47 ++---
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 58fe2674479..9e1b8b11373 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1819,7 +1819,7 @@ public:
 return true;
   }
 
-  std::string as_string ()
+  std::string as_string () const
   {
 switch (kind)
   {
@@ -1869,14 +1869,45 @@ private:
*/
 
   bool is_single_fragment () const { return nodes.size () == 1; }
-  bool is_single_fragment (SingleASTNode::NodeType expected) const
+
+  bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const
   {
 return is_single_fragment () && nodes[0].get_kind () == expected;
   }
 
-  bool is_single_fragment_kind (SingleASTNode::NodeType kind) const
+  void assert_single_fragment (SingleASTNode::NodeType expected) const
   {
-return is_single_fragment () && nodes[0].get_kind () == kind;
+static const std::map str_map = {
+  {SingleASTNode::NodeType::IMPL, "impl"},
+  {SingleASTNode::NodeType::ITEM, "item"},
+  {SingleASTNode::NodeType::TYPE, "type"},
+  {SingleASTNode::NodeType::EXPRESSION, "expr"},
+  {SingleASTNode::NodeType::STMT, "stmt"},
+  {SingleASTNode::NodeType::EXTERN, "extern"},
+  {SingleASTNode::NodeType::TRAIT, "trait"},
+  {SingleASTNode::NodeType::TRAIT_IMPL, "trait impl"},
+};
+
+auto actual = nodes[0].get_kind ();
+auto fail = false;
+
+if (!is_single_fragment ())
+  {
+   rust_error_at (Location (), "fragment is not single");
+   fail = true;
+  }
+
+if (actual != expected)
+  {
+   rust_error_at (
+ Location (),
+ "invalid fragment operation: expected %qs node, got %qs node",
+ str_map.find (expected)->second,
+ str_map.find (nodes[0].get_kind ())->second);
+   fail = true;
+  }
+
+rust_assert (!fail);
   }
 
 public:
@@ -1920,23 +1951,23 @@ public:
 
   bool is_expression_fragment () const
   {
-return is_single_fragment (SingleASTNode::NodeType::EXPRESSION);
+return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION);
   }
 
   bool is_type_fragment () const
   {
-return is_single_fragment (SingleASTNode::NodeType::TYPE);
+return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE);
   }
 
   std::unique_ptr take_expression_fragment ()
   {
-rust_assert (is_single_fragment_kind 
(SingleASTNode::NodeType::EXPRESSION));
+assert_single_fragment (SingleASTNode::NodeType::EXPRESSION);
 return nodes[0].take_expr ();
   }
 
   std::unique_ptr take_type_fragment ()
   {
-rust_assert (is_single_fragment_kind (SingleASTNode::NodeType::TYPE));
+assert_single_fragment (SingleASTNode::NodeType::TYPE);
 return nodes[0].take_type ();
   }
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Create canonical process of compiling constant items

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

In order to compile a block expression constant, the simplest way for us
was to reuse what code we have and to generate an artifical function which
does not get added to the translation unit. The constant then becomes
a CALL_EXPR to this artifical function which we can pass to the constexpr
evaluator to resolve the result of this artifical 'CALL_EXPR'.

Before this patch we seperated the difference between block expressions
and non block expressions in constants. So for non block expressions we
simply compiled them as if it was a simple constant but this is not
guaranteed to be the case in rust, for example coercion sites can generate
temporaries during autoderef which we let the constant evaluator resolve
for us. This makes all constants handled in the same way to simplify the
logic here.

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc: Improve compilation pipeline and 
simplify
function.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-base.cc | 103 ++
 1 file changed, 55 insertions(+), 48 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index e1506b377ce..568abf9ca2c 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -652,65 +652,72 @@ HIRCompileBase::compile_constant_item (
   bool is_block_expr
 = const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block;
 
-  // compile the expression
-  tree folded_expr = error_mark_node;
-  if (!is_block_expr)
-{
-  tree value = CompileExpr::Compile (const_value_expr, ctx);
-  folded_expr = fold_expr (value);
-}
-  else
-{
-  // in order to compile a block expr we want to reuse as much existing
-  // machineary that we already have. This means the best approach is to
-  // make a _fake_ function with a block so it can hold onto temps then
-  // use our constexpr code to fold it completely or error_mark_node
-  Backend::typed_identifier receiver;
-  tree compiled_fn_type = ctx->get_backend ()->function_type (
-   receiver, {}, {Backend::typed_identifier ("_", const_type, locus)},
-   NULL, locus);
-
-  tree fndecl
-   = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
-  TREE_READONLY (fndecl) = 1;
+  // in order to compile a block expr we want to reuse as much existing
+  // machineary that we already have. This means the best approach is to
+  // make a _fake_ function with a block so it can hold onto temps then
+  // use our constexpr code to fold it completely or error_mark_node
+  Backend::typed_identifier receiver;
+  tree compiled_fn_type = ctx->get_backend ()->function_type (
+receiver, {}, {Backend::typed_identifier ("_", const_type, locus)}, NULL,
+locus);
+
+  tree fndecl
+= ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
+  TREE_READONLY (fndecl) = 1;
+
+  tree enclosing_scope = NULL_TREE;
 
-  tree enclosing_scope = NULL_TREE;
+  Location start_location = const_value_expr->get_locus ();
+  Location end_location = const_value_expr->get_locus ();
+  if (is_block_expr)
+{
   HIR::BlockExpr *function_body
= static_cast (const_value_expr);
-  Location start_location = function_body->get_locus ();
-  Location end_location = function_body->get_end_locus ();
+  start_location = function_body->get_locus ();
+  end_location = function_body->get_end_locus ();
+}
 
-  tree code_block
-   = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
- start_location, end_location);
-  ctx->push_block (code_block);
+  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
+   start_location, end_location);
+  ctx->push_block (code_block);
 
-  bool address_is_taken = false;
-  tree ret_var_stmt = NULL_TREE;
-  Bvariable *return_address
-   = ctx->get_backend ()->temporary_variable (fndecl, code_block,
-  const_type, NULL,
-  address_is_taken, locus,
-  &ret_var_stmt);
+  bool address_is_taken = false;
+  tree ret_var_stmt = NULL_TREE;
+  Bvariable *return_address
+= ctx->get_backend ()->temporary_variable (fndecl, code_block, const_type,
+  NULL, address_is_taken, locus,
+  &ret_var_stmt);
 
-  ctx->add_statement (ret_var_stmt);
-  ctx->push_fn (fndecl, return_address);
+  ctx->add_statement (ret_var_stmt);
+  ctx->push_fn (fndecl, return_address);
 
+  if (is_block_expr)
+{
+  HIR::BlockExpr *function_body
+   = static_cast (const_value_expr);
   compile_function_body (ctx, fndecl, *function_body, true);
- 

[COMMITTED] gccrs: macros: Handle matchers properly in repetitions

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* expand/rust-macro-expand.cc (MacroExpander::match_matcher): Handle
fragments differently based on whether or not we are currently trying
to match a matcher in a repetition context.
(MacroExpander::match_n_matches): Use new `in_repetition` argument
properly when calling `match_matcher`.
* expand/rust-macro-expand.h (MacroExpander::match_matcher): Allow
passing extra `in_repetition` bool argument

gcc/testsuite/ChangeLog:

* rust/compile/macro43.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/expand/rust-macro-expand.cc  | 14 +++---
 gcc/rust/expand/rust-macro-expand.h   |  2 +-
 gcc/testsuite/rust/compile/macro43.rs | 64 +++
 3 files changed, 74 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/macro43.rs

diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index a214ca906bf..df258bd96ec 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -435,7 +435,7 @@ MacroExpander::match_fragment (Parser 
&parser,
 
 bool
 MacroExpander::match_matcher (Parser &parser,
- AST::MacroMatcher &matcher)
+ AST::MacroMatcher &matcher, bool in_repetition)
 {
   if (depth_exceeds_recursion_limit ())
 {
@@ -485,8 +485,12 @@ MacroExpander::match_matcher (Parser 
&parser,
 
// matched fragment get the offset in the token stream
size_t offs_end = source.get_offs ();
-   sub_stack.insert_metavar (
- MatchedFragment (fragment->get_ident (), offs_begin, offs_end));
+   if (in_repetition)
+ sub_stack.append_fragment (
+   MatchedFragment (fragment->get_ident (), offs_begin, offs_end));
+   else
+ sub_stack.insert_metavar (
+   MatchedFragment (fragment->get_ident (), offs_begin, offs_end));
  }
  break;
 
@@ -509,7 +513,7 @@ MacroExpander::match_matcher (Parser 
&parser,
AST::MacroMatcher *m
  = static_cast (match.get ());
expansion_depth++;
-   if (!match_matcher (parser, *m))
+   if (!match_matcher (parser, *m, in_repetition))
  {
expansion_depth--;
return false;
@@ -619,7 +623,7 @@ MacroExpander::match_n_matches (Parser 
&parser,
  case AST::MacroMatch::MacroMatchType::Matcher: {
AST::MacroMatcher *m
  = static_cast (match.get ());
-   valid_current_match = match_matcher (parser, *m);
+   valid_current_match = match_matcher (parser, *m, true);
  }
  break;
}
diff --git a/gcc/rust/expand/rust-macro-expand.h 
b/gcc/rust/expand/rust-macro-expand.h
index 97a02692d1f..bef140236b3 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -273,7 +273,7 @@ struct MacroExpander
 AST::MacroMatchRepetition &rep);
 
   bool match_matcher (Parser &parser,
- AST::MacroMatcher &matcher);
+ AST::MacroMatcher &matcher, bool in_repetition = false);
 
   /**
* Match any amount of matches
diff --git a/gcc/testsuite/rust/compile/macro43.rs 
b/gcc/testsuite/rust/compile/macro43.rs
new file mode 100644
index 000..c7bf50a030e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro43.rs
@@ -0,0 +1,64 @@
+macro_rules! nonzero_integers {
+( $( $Ty: ident($Int: ty); )+ ) => {
+$(
+/// An integer that is known not to equal zero.
+///
+/// This enables some memory layout optimization.
+/// For example, `Option` is the same size as `u32`:
+///
+/// ```rust
+/// use std::mem::size_of;
+/// assert_eq!(size_of::>(), 
size_of::());
+/// ```
+#[stable(feature = "nonzero", since = "1.28.0")]
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[repr(transparent)]
+pub struct $Ty(NonZero<$Int>);
+
+impl $Ty {
+/// Create a non-zero without checking the value.
+///
+/// # Safety
+///
+/// The value must not be zero.
+#[stable(feature = "nonzero", since = "1.28.0")]
+#[inline]
+pub const unsafe fn new_unchecked(n: $Int) -> Self {
+$Ty(NonZero(n))
+}
+
+/// Create a non-zero if the given value is not zero.
+#[stable(feature = "nonzero", since = "1.28.0")]
+#[inline]
+pub fn new(n: $Int) -> Option {
+if n != 0 {
+Some($Ty(NonZero(n)))
+} else {
+   

[COMMITTED] gccrs: Remove param_use_canonical_types checks ported from c++ front-end

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

We are not fully setting TYPE_CANONICAL yet but we don't need to be as
strict as the C++ front-end yet. param_use_canonical_types is a command
line option we are not using either.

gcc/rust/ChangeLog:

* backend/rust-tree.cc (comptypes): Remove some C++ specific checks in
Rust const folder for now.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-tree.cc | 22 +-
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index d79cd96f011..d2ddcfd2957 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -2916,27 +2916,7 @@ comptypes (tree t1, tree t2, int strict)
   perform a deep check. */
return structural_comptypes (t1, t2, strict);
 
-  if (flag_checking && param_use_canonical_types)
-   {
- bool result = structural_comptypes (t1, t2, strict);
-
- if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
-   /* The two types are structurally equivalent, but their
-  canonical types were different. This is a failure of the
-  canonical type propagation code.*/
-   internal_error (
- "canonical types differ for identical types %qT and %qT", t1, t2);
- else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
-   /* Two types are structurally different, but the canonical
-  types are the same. This means we were over-eager in
-  assigning canonical types. */
-   internal_error (
- "same canonical type node for different types %qT and %qT", t1,
- t2);
-
- return result;
-   }
-  if (!flag_checking && param_use_canonical_types)
+  if (!flag_checking)
return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
   else
return structural_comptypes (t1, t2, strict);
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Add extra debugging for method call expressions

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Add
more calls to `rust_debug` for development.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc | 12 
 1 file changed, 12 insertions(+)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index a0eb1a596f7..bea5eb8cb0b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1024,6 +1024,11 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
   return;
 }
 
+  rust_debug_loc (expr.get_method_name ().get_locus (),
+ "resolved method to: {%u} {%s}",
+ candidate.candidate.ty->get_ref (),
+ candidate.candidate.ty->debug_str ().c_str ());
+
   // Get the adjusted self
   Adjuster adj (receiver_tyty);
   TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
@@ -1120,6 +1125,9 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
   // apply any remaining generic arguments
   if (expr.get_method_name ().has_generic_args ())
 {
+  rust_debug_loc (expr.get_method_name ().get_generic_args ().get_locus (),
+ "applying generic arguments to method_call: {%s}",
+ lookup->debug_str ().c_str ());
   HIR::GenericArgs &args = expr.get_method_name ().get_generic_args ();
   lookup
= SubstMapper::Resolve (lookup, expr.get_method_name ().get_locus (),
@@ -1129,10 +1137,14 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
 }
   else if (lookup->needs_generic_substitutions ())
 {
+  rust_debug ("method needs inference: {%s}",
+ lookup->debug_str ().c_str ());
   lookup = SubstMapper::InferSubst (lookup,
expr.get_method_name ().get_locus ());
 }
 
+  rust_debug ("type-checking method_call: {%s}", lookup->debug_str ().c_str 
());
+
   TyTy::BaseType *function_ret_tyty
 = TyTy::TypeCheckMethodCallExpr::go (lookup, expr, adjusted_self, context);
   if (function_ret_tyty == nullptr
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Add guards against getting data from an empty vector

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

gcc/rust/ChangeLog:

* typecheck/rust-tyctx.cc (TypeCheckContext::pop_return_type): Add
guards around `std::vector.pop_back()`.
(TypeCheckContext::peek_context): Likewise for `std::vector.back()`.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/typecheck/rust-tyctx.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/typecheck/rust-tyctx.cc b/gcc/rust/typecheck/rust-tyctx.cc
index ad5f67cc1dd..af86b064c6c 100644
--- a/gcc/rust/typecheck/rust-tyctx.cc
+++ b/gcc/rust/typecheck/rust-tyctx.cc
@@ -142,12 +142,14 @@ TypeCheckContext::push_return_type (TypeCheckContextItem 
item,
 void
 TypeCheckContext::pop_return_type ()
 {
+  rust_assert (!return_type_stack.empty ());
   return_type_stack.pop_back ();
 }
 
 TypeCheckContextItem &
 TypeCheckContext::peek_context ()
 {
+  rust_assert (!return_type_stack.empty ());
   return return_type_stack.back ().first;
 }
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Add missing location info to coercions

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-base.cc (TypeCheckBase::TypeCheckBase):
Remove constructor.
(TypeCheckBase::coercion_site): Add `Location` argument to function.
* typecheck/rust-hir-type-check-base.h: Use 
`TypeCheckBase::coercion_site`
function with location argument.
* typecheck/rust-hir-type-check-enumitem.cc (TypeCheckEnumItem::visit): 
Likewise.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): 
Likewise.
* typecheck/rust-hir-type-check-expr.h (class TypeCheckExpr): Likewise.
* typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): 
Likewise.
* typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::visit): 
Likewise.
* typecheck/rust-hir-type-check-toplevel.cc (TypeCheckTopLevel::visit): 
Likewise.
* typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Likewise.
(TypeCheckMethodCallExpr::visit): Likewise.
* typecheck/rust-tyty.h: Add missing locus field.
* typecheck/rust-tyty.cc (StructFieldType::clone): Use locus field.
(StructFieldType::monomorphized_clone): Likewise.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../typecheck/rust-hir-type-check-base.cc | 12 +-
 gcc/rust/typecheck/rust-hir-type-check-base.h | 10 ++---
 .../typecheck/rust-hir-type-check-enumitem.cc |  6 ++-
 .../typecheck/rust-hir-type-check-expr.cc |  4 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.h |  2 +-
 .../typecheck/rust-hir-type-check-stmt.cc | 24 +++
 .../typecheck/rust-hir-type-check-struct.cc   | 29 ++---
 .../typecheck/rust-hir-type-check-toplevel.cc |  9 ++--
 gcc/rust/typecheck/rust-tyty-call.cc  | 41 +++
 gcc/rust/typecheck/rust-tyty.cc   |  5 ++-
 gcc/rust/typecheck/rust-tyty.h| 11 +++--
 11 files changed, 109 insertions(+), 44 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc 
b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index f75266b2160..b809ac33108 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -25,6 +25,11 @@
 namespace Rust {
 namespace Resolver {
 
+TypeCheckBase::TypeCheckBase ()
+  : mappings (Analysis::Mappings::get ()), resolver (Resolver::get ()),
+context (TypeCheckContext::get ())
+{}
+
 bool
 TypeCheckBase::check_for_unconstrained (
   const std::vector ¶ms_to_constrain,
@@ -332,9 +337,12 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, Location locus)
 }
 
 TyTy::BaseType *
-TypeCheckBase::coercion_site (HirId id, TyTy::BaseType *expected,
- TyTy::BaseType *expr, Location locus)
+TypeCheckBase::coercion_site (HirId id, TyTy::TyWithLocation lhs,
+ TyTy::TyWithLocation rhs, Location locus)
 {
+  TyTy::BaseType *expected = lhs.get_ty ();
+  TyTy::BaseType *expr = rhs.get_ty ();
+
   rust_debug ("coercion_site id={%u} expected={%s} expr={%s}", id,
  expected->debug_str ().c_str (), expr->debug_str ().c_str ());
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h 
b/gcc/rust/typecheck/rust-hir-type-check-base.h
index d5b12705f63..acdf55713d5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -24,7 +24,6 @@
 #include "rust-name-resolver.h"
 #include "rust-hir-visitor.h"
 #include "rust-hir-map.h"
-#include "rust-backend.h"
 
 namespace Rust {
 namespace Resolver {
@@ -35,8 +34,8 @@ class TypeCheckBase
 public:
   virtual ~TypeCheckBase () {}
 
-  static TyTy::BaseType *coercion_site (HirId id, TyTy::BaseType *lhs,
-   TyTy::BaseType *rhs,
+  static TyTy::BaseType *coercion_site (HirId id, TyTy::TyWithLocation lhs,
+   TyTy::TyWithLocation rhs,
Location coercion_locus);
 
   static TyTy::BaseType *cast_site (HirId id, TyTy::TyWithLocation from,
@@ -44,10 +43,7 @@ public:
Location cast_locus);
 
 protected:
-  TypeCheckBase ()
-: mappings (Analysis::Mappings::get ()), resolver (Resolver::get ()),
-  context (TypeCheckContext::get ())
-  {}
+  TypeCheckBase ();
 
   TraitReference *resolve_trait_path (HIR::TypePath &);
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
index e7a7f08853b..0a99d444060 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
@@ -129,7 +129,8 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
= TypeCheckType::Resolve (field.get_field_type ().get ());
   TyTy::StructFieldType *ty_field
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
-std::to_string (idx), field_type);
+

[COMMITTED] gccrs: remove bad assertion

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

gcc/rust/ChangeLog:

* backend/rust-tree.cc (rs_type_quals): Comment out bad assertion

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-tree.cc | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index d2ddcfd2957..47506d6792a 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -974,9 +974,10 @@ rs_type_quals (const_tree type)
 return TYPE_UNQUALIFIED;
   quals = TYPE_QUALS (type);
   /* METHOD and REFERENCE_TYPEs should never have quals.  */
-  gcc_assert (
-(TREE_CODE (type) != METHOD_TYPE && !TYPE_REF_P (type))
-|| ((quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) == TYPE_UNQUALIFIED));
+  // gcc_assert (
+  //   (TREE_CODE (type) != METHOD_TYPE && !TYPE_REF_P (type))
+  //   || ((quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) ==
+  //   TYPE_UNQUALIFIED));
   return quals;
 }
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: attributes: Add #[macro_use] as builtin

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* util/rust-attributes.cc: Add `macro_use` to list of builtin
attributes.

gcc/testsuite/ChangeLog:

* rust/compile/macro_export_1.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/util/rust-attributes.cc | 1 +
 gcc/testsuite/rust/compile/macro_export_1.rs | 2 ++
 2 files changed, 3 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/macro_export_1.rs

diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 9db77b40dfb..1c85273e541 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -40,6 +40,7 @@ static const BuiltinAttrDefinition __definitions[]
  {"no_mangle", CODE_GENERATION},
  {"repr", CODE_GENERATION},
  {"path", EXPANSION},
+ {"macro_use", NAME_RESOLUTION},
  // From now on, these are reserved by the compiler and gated through
  // #![feature(rustc_attrs)]
  {"rustc_inherit_overflow_checks", CODE_GENERATION}};
diff --git a/gcc/testsuite/rust/compile/macro_export_1.rs 
b/gcc/testsuite/rust/compile/macro_export_1.rs
new file mode 100644
index 000..f87df083624
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro_export_1.rs
@@ -0,0 +1,2 @@
+#[macro_use]
+mod foo {}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Refactor unify to hit a unify_site

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

This allows us to enforce better error handling on unify sites

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-base.cc (TypeCheckBase::unify_site): Add
better unification function with debug calls.
* typecheck/rust-autoderef.cc (AutoderefCycle::cycle): Add more debug
calls and use new unify API.
* typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion): Likewise.
(TypeCoercionRules::coerce_borrowed_pointer): Likewise.
(TypeCoercionRules::select): Likewise.
* typecheck/rust-hir-dot-operator.cc (MethodResolver::select): Likewise.
* typecheck/rust-hir-trait-resolve.cc 
(TraitItemReference::resolve_item): Likewise.
(TypeCheckBase::coercion_site): Likewise.
(TypeCheckBase::cast_site): Likewise.
* typecheck/rust-hir-type-check-base.h: Likewise.
* typecheck/rust-hir-type-check-enumitem.cc (TypeCheckEnumItem::visit): 
Likewise.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): 
Likewise.
* typecheck/rust-hir-type-check-implitem.cc 
(TypeCheckTopLevelImplItem::visit): Likewise.
(TypeCheckImplItem::visit): Likewise.
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): 
Likewise.
* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_segments): Likewise.
* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): 
Likewise.
* typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): 
Likewise.
* typecheck/rust-hir-type-check-struct.cc 
(TypeCheckStructExpr::resolve): Likewise.
* typecheck/rust-hir-type-check-toplevel.cc (TypeCheckTopLevel::visit): 
Likewise.
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): 
Likewise.
* typecheck/rust-hir-type-check.cc (TypeResolution::Resolve): Likewise.
* typecheck/rust-tyctx.cc (TypeCheckContext::peek_return_type): 
Likewise.
* typecheck/rust-tyty-call.cc (TypeCheckMethodCallExpr::visit): 
Likewise.
* typecheck/rust-tyty-cmp.h: Likewise.
* typecheck/rust-tyty-rules.h: Likewise.
* typecheck/rust-tyty.cc (BaseType::mappings_str): Likewise.
(BaseType::debug): Print type name more clearly.
(BaseType::debug_str): Add new function to print type pointer and name.
(TupleType::get_name): Improve type name fetching function.
(ReferenceType::get_name): Likewise.
(PointerType::get_name): Likewise.
* typecheck/rust-tyty.h: Refactor definitions outside of the header.

gcc/testsuite/ChangeLog:

* rust/compile/issue-1152.rs: Fix dejagnu assertion.
* rust/compile/tuple1.rs: Likewise.
* rust/compile/type-alias1.rs: Likewise.
* rust/execute/torture/operator_overload_9.rs: Likewise.
* rust/execute/torture/slice1.rs: Rework test to use new parsing
capability and stick to the original implementation.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/typecheck/rust-autoderef.cc  |  15 +-
 gcc/rust/typecheck/rust-coercion.cc   |  62 +++-
 gcc/rust/typecheck/rust-hir-dot-operator.cc   |  15 +
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |  24 +-
 .../typecheck/rust-hir-type-check-base.cc |  42 ++-
 gcc/rust/typecheck/rust-hir-type-check-base.h |   4 +
 .../typecheck/rust-hir-type-check-enumitem.cc |   6 +-
 .../typecheck/rust-hir-type-check-expr.cc | 170 ---
 .../typecheck/rust-hir-type-check-implitem.cc |  17 +-
 .../typecheck/rust-hir-type-check-item.cc |  11 +-
 .../typecheck/rust-hir-type-check-path.cc |   5 +-
 .../typecheck/rust-hir-type-check-pattern.cc  |   4 +-
 .../typecheck/rust-hir-type-check-stmt.cc |  15 +-
 .../typecheck/rust-hir-type-check-struct.cc   |  12 +-
 .../typecheck/rust-hir-type-check-toplevel.cc |  15 +-
 .../typecheck/rust-hir-type-check-type.cc |   8 +-
 gcc/rust/typecheck/rust-hir-type-check.cc |  12 +-
 gcc/rust/typecheck/rust-tyctx.cc  |   1 +
 gcc/rust/typecheck/rust-tyty-call.cc  |   5 +-
 gcc/rust/typecheck/rust-tyty-cmp.h|   4 +-
 gcc/rust/typecheck/rust-tyty-rules.h  | 264 ++
 gcc/rust/typecheck/rust-tyty.cc   |  61 +++-
 gcc/rust/typecheck/rust-tyty.h|  36 +--
 gcc/testsuite/rust/compile/issue-1152.rs  |   2 -
 gcc/testsuite/rust/compile/tuple1.rs  |   2 +-
 gcc/testsuite/rust/compile/type-alias1.rs |   2 +-
 .../execute/torture/operator_overload_9.rs|   2 +-
 gcc/testsuite/rust/execute/torture/slice1.rs  |   7 +-
 28 files changed, 460 insertions(+), 363 deletions(-)

diff --git a/gcc/rust/typecheck/rust-autoderef.cc 
b/gcc/rust/typecheck/rust-autoderef.cc
index 71d39cff3de..ca43f847e98 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -255,7 +255,12 @@ resolve_operator_overload_fn (
  lookup = fn->infer_substitions (Location 

[COMMITTED] gccrs: Add testcase for const-eval issue from rust-blog

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

see:
https://blog.rust-lang.org/2022/09/15/const-eval-safety-rule-revision.html

gcc/testsuite/ChangeLog:

* rust/compile/rust-const-blog-issue.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/testsuite/rust/compile/rust-const-blog-issue.rs | 12 
 1 file changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/rust-const-blog-issue.rs

diff --git a/gcc/testsuite/rust/compile/rust-const-blog-issue.rs 
b/gcc/testsuite/rust/compile/rust-const-blog-issue.rs
new file mode 100644
index 000..a5ea2ebacb9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/rust-const-blog-issue.rs
@@ -0,0 +1,12 @@
+// { dg-excess-errors "accessing value of"  }
+mod mem {
+extern "rust-intrinsic" {
+#[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+fn transmute(_: T) -> U;
+}
+}
+
+pub static FOO: () = unsafe {
+let illegal_ptr2int: usize = mem::transmute(&());
+let _copy = illegal_ptr2int;
+};
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Unit structs are not concrete when they need substitutions

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

Fixes #1518

gcc/rust/ChangeLog:

* typecheck/rust-tyty.h: Fix `is_concrete` for unit types with
substitutions.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/typecheck/rust-tyty.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 24efc7aa54c..43460d2dd2f 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1362,6 +1362,11 @@ public:
 
   bool is_concrete () const override final
   {
+if (is_unit ())
+  {
+   return !needs_substitution ();
+  }
+
 for (auto &variant : variants)
   {
for (auto &field : variant->get_fields ())
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Add new check for contains_associated_types

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

We don't need to setup associated types when a trait does not contain any
associated types.

gcc/rust/ChangeLog:

* typecheck/rust-tyty-bounds.cc 
(TypeBoundPredicate::contains_associated_types):
Check if a type bound predicate contains assocated types.
* typecheck/rust-tyty.h: Declare the above mentioned function.
* typecheck/rust-hir-trait-resolve.cc: Use `contains_associated_types`
function.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc |  3 +++
 gcc/rust/typecheck/rust-tyty-bounds.cc   | 15 +++
 gcc/rust/typecheck/rust-tyty.h   |  2 ++
 3 files changed, 20 insertions(+)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index c14a6c3a9be..22398b1fa8a 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -368,6 +368,9 @@ void
 AssociatedImplTrait::setup_associated_types (
   const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound)
 {
+  if (!bound.contains_associated_types ())
+return;
+
   // compute the constrained impl block generic arguments based on self and the
   // higher ranked trait bound
   TyTy::BaseType *receiver = self->clone ();
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 8dfd692f345..69376aaa373 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -374,6 +374,21 @@ TypeBoundPredicate::requires_generic_args () const
   return substitutions.size () > 1;
 }
 
+bool
+TypeBoundPredicate::contains_associated_types () const
+{
+  auto trait_ref = get ();
+  for (const auto &trait_item : trait_ref->get_trait_items ())
+{
+  bool is_associated_type
+   = trait_item.get_trait_item_type ()
+ == Resolver::TraitItemReference::TraitItemType::TYPE;
+  if (is_associated_type)
+   return true;
+}
+  return false;
+}
+
 // trait item reference
 
 const Resolver::TraitItemReference *
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 14868f2bb81..24efc7aa54c 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1057,6 +1057,8 @@ public:
 
   bool requires_generic_args () const;
 
+  bool contains_associated_types () const;
+
 private:
   DefId reference;
   Location locus;
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: bugfix: initialize slice from array in const context

2023-01-31 Thread Arthur Cohen
From: Faisal Abbas <90.abbasfai...@gmail.com>

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): Turn
constant item typechecking into a coercion site instead of a unify
site.

gcc/testsuite/ChangeLog:

* rust/compile/const6.rs: New test.

Signed-off-by: Faisal Abbas <90.abbasfai...@gmail.com>

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/typecheck/rust-hir-type-check-stmt.cc | 2 +-
 gcc/testsuite/rust/compile/const6.rs   | 4 
 2 files changed, 5 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/const6.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc 
b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
index e82dd8e5300..a55cf22ba23 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc
@@ -68,7 +68,7 @@ TypeCheckStmt::visit (HIR::ConstantItem &constant)
   TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
   TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
 
-  infered = unify_site (
+  infered = coercion_site (
 constant.get_mappings ().get_hirid (),
 TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
 TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
diff --git a/gcc/testsuite/rust/compile/const6.rs 
b/gcc/testsuite/rust/compile/const6.rs
new file mode 100644
index 000..8f0dc320129
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const6.rs
@@ -0,0 +1,4 @@
+fn main() {
+const array:[i32; 1] = [1];
+const slice:&[i32] = &array;
+}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: testsuite/rust: add a testcase for testing ...

2023-01-31 Thread Arthur Cohen
From: liushuyu 

... builtin macro and decl macro mixed expansion

gcc/testsuite/ChangeLog:

* rust/compile/builtin_macro_recurse.rs: New test.

Signed-off-by: Zixing Liu 

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../rust/compile/builtin_macro_recurse.rs | 21 +++
 1 file changed, 21 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/builtin_macro_recurse.rs

diff --git a/gcc/testsuite/rust/compile/builtin_macro_recurse.rs 
b/gcc/testsuite/rust/compile/builtin_macro_recurse.rs
new file mode 100644
index 000..0b516fd93a9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/builtin_macro_recurse.rs
@@ -0,0 +1,21 @@
+// { dg-additional-options "-fdump-tree-gimple" }
+
+#[rustc_builtin_macro]
+macro_rules! concat {
+() => {{}};
+}
+
+macro_rules! a {
+() => { "test" };
+}
+
+macro_rules! b {
+() => { "canary" };
+}
+
+fn main() {
+// { dg-final { scan-tree-dump-times {"test1canary"} 1 gimple } }
+let _ = concat!(a!(), 1, b!());
+// should not error
+concat!(a!(), true, b!(),);
+}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Cleanup formatting of backend expression visitor

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

gcc/rust/ChangeLog:

* backend/rust-compile-expr.h: Formatting.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-expr.h | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.h 
b/gcc/rust/backend/rust-compile-expr.h
index 83293a40b44..845511f9f43 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -68,24 +68,31 @@ public:
   void visit (HIR::RangeFullExpr &expr) override;
   void visit (HIR::RangeFromToInclExpr &expr) override;
 
-  // Empty visit for unused Expression HIR nodes.
+  // TODO
   void visit (HIR::ClosureExprInner &) override {}
   void visit (HIR::ClosureExprInnerTyped &) override {}
-  void visit (HIR::StructExprFieldIdentifier &) override {}
-  void visit (HIR::StructExprFieldIdentifierValue &) override {}
-  void visit (HIR::StructExprFieldIndexValue &) override {}
   void visit (HIR::ErrorPropagationExpr &) override {}
   void visit (HIR::RangeToInclExpr &) override {}
-  void visit (HIR::WhileLetLoopExpr &) override {}
   void visit (HIR::ForLoopExpr &) override {}
+
+  // TODO
+  // these need to be sugared in the HIR to if statements and a match
+  void visit (HIR::WhileLetLoopExpr &) override {}
   void visit (HIR::IfExprConseqIfLet &) override {}
   void visit (HIR::IfLetExpr &) override {}
   void visit (HIR::IfLetExprConseqElse &) override {}
   void visit (HIR::IfLetExprConseqIf &) override {}
   void visit (HIR::IfLetExprConseqIfLet &) override {}
+
+  // lets not worry about async yet
   void visit (HIR::AwaitExpr &) override {}
   void visit (HIR::AsyncBlockExpr &) override {}
 
+  // nothing to do for these
+  void visit (HIR::StructExprFieldIdentifier &) override {}
+  void visit (HIR::StructExprFieldIdentifierValue &) override {}
+  void visit (HIR::StructExprFieldIndexValue &) override {}
+
 protected:
   tree get_fn_addr_from_dyn (const TyTy::DynamicObjectType *dyn,
 TyTy::BaseType *receiver, TyTy::FnType *fntype,
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Make constexpr constructors type-checking more permissive

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

gcc/rust/ChangeLog:

* backend/rust-constexpr.cc (eval_store_expression): Remove invalid
assertion on constexpr constructors.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-constexpr.cc | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/backend/rust-constexpr.cc 
b/gcc/rust/backend/rust-constexpr.cc
index 8efb4301d09..8623816236c 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2953,14 +2953,14 @@ eval_store_expression (const constexpr_ctx *ctx, tree 
t, bool lval,
   TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
   CONSTRUCTOR_NO_CLEARING (*valp) = CONSTRUCTOR_NO_CLEARING (init);
 }
-  else if (TREE_CODE (init) == CONSTRUCTOR
-  && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
- type))
-{
-  /* See above on initialization of empty bases.  */
-  gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
-  return init;
-}
+  // else if (TREE_CODE (init) == CONSTRUCTOR
+  //  && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
+  // type))
+  //   {
+  // /* See above on initialization of empty bases.  */
+  // // gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
+  // return init;
+  //   }
   else
 *valp = init;
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: backend: correctly formulate the exit condition ...

2023-01-31 Thread Arthur Cohen
From: liushuyu 

... previously the exit condition was treated the same as the loop
condition (which is the inverse condition of the exit condition). Now
this is corrected.

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit): Properly formulate
exit condition when compiling while loops.

Signed-off-by: Zixing Liu 

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-expr.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index ea146731cbe..d58e2258947 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -727,8 +727,11 @@ CompileExpr::visit (HIR::WhileLoopExpr &expr)
 
   tree condition
 = CompileExpr::Compile (expr.get_predicate_expr ().get (), ctx);
+  tree exit_condition
+= fold_build1_loc (expr.get_locus ().gcc_location (), TRUTH_NOT_EXPR,
+  boolean_type_node, condition);
   tree exit_expr
-= ctx->get_backend ()->exit_expression (condition, expr.get_locus ());
+= ctx->get_backend ()->exit_expression (exit_condition, expr.get_locus ());
   ctx->add_statement (exit_expr);
 
   tree code_block_stmt
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: add testcase to test component_ref and constructor codes in eval_constant_expression()

2023-01-31 Thread Arthur Cohen
From: Faisal Abbas <90.abbasfai...@gmail.com>

gcc/testsuite/ChangeLog:

* rust/compile/const7.rs: New test.

Signed-off-by: Faisal Abbas <90.abbasfai...@gmail.com>

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/testsuite/rust/compile/const7.rs | 12 
 1 file changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/const7.rs

diff --git a/gcc/testsuite/rust/compile/const7.rs 
b/gcc/testsuite/rust/compile/const7.rs
new file mode 100644
index 000..a7431c0c4d2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const7.rs
@@ -0,0 +1,12 @@
+// { dg-options "-w -O0 -fdump-tree-gimple" }
+struct Foo(usize, usize);
+
+const A:Foo = Foo(123, 4546);
+
+const B:usize = A.0;
+
+fn main() {
+// { dg-final { scan-tree-dump-times {b = 123} 1 gimple } }
+let b = B;
+}
+
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: const generics: Make sure const generic types are visited properly

2023-01-31 Thread Arthur Cohen
...in all contexts.

gcc/testsuite/ChangeLog:

* rust/compile/const_generics_7.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/testsuite/rust/compile/const_generics_7.rs | 17 +
 1 file changed, 17 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/const_generics_7.rs

diff --git a/gcc/testsuite/rust/compile/const_generics_7.rs 
b/gcc/testsuite/rust/compile/const_generics_7.rs
new file mode 100644
index 000..2c128db92ea
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_7.rs
@@ -0,0 +1,17 @@
+struct S;
+
+pub fn foo() {} // { dg-error "failed to resolve" }
+type Foo = S; // { dg-error "failed to resolve" }
+struct Foo2; // { dg-error "failed to resolve" }
+enum Foo3 { // { dg-error "failed to resolve" }
+Foo,
+Bar,
+}
+union Foo4 { // { dg-error "failed to resolve" }
+a: usize,
+b: i32,
+}
+trait Fooable {} // { dg-error "failed to resolve" }
+
+trait Traitable {}
+impl Traitable for Foo2 {} // { dg-error "failed to 
resolve" }
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: add testcase with struct to test component_ref and constructor codes..

2023-01-31 Thread Arthur Cohen
From: Faisal Abbas <90.abbasfai...@gmail.com>

..in eval_constant_expression()

gcc/testsuite/ChangeLog:

* rust/compile/const8.rs: New test.

Signed-off-by: Faisal Abbas <90.abbasfai...@gmail.com>

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/testsuite/rust/compile/const8.rs | 40 
 1 file changed, 40 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/const8.rs

diff --git a/gcc/testsuite/rust/compile/const8.rs 
b/gcc/testsuite/rust/compile/const8.rs
new file mode 100644
index 000..94c4268ec8c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const8.rs
@@ -0,0 +1,40 @@
+// { dg-options "-w -O0 -fdump-tree-gimple" }
+struct Foo {
+First: i32,
+Second: f32
+}
+
+struct Bar {
+First: i32,
+Second: f32
+}
+
+struct Baz {
+First: i32,
+Second: f32
+}
+const A:Foo = Foo { First: 1, Second: 1.0 };
+const B:Bar = Bar { First: 2, Second: 2.0 };
+const C:Baz = Baz { First: 3, Second: 2.0 };
+
+const fn test() -> f32 {
+if (A.First == 2) {
+return A.Second;
+}
+else if (B.First == 2) {
+return B.Second;
+}
+else if (C.First == 2) {
+return C.Second;
+}
+
+return 0.0;
+}
+
+const D:f32 = test();
+
+fn main() {
+// { dg-final { scan-tree-dump-times {d = 2.0} 1 gimple } }
+let d = D;
+}
+
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Statics are a coercion site

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

Statics can be assigned to a block expression meaning they need to behave
similarly to constant items.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-toplevel.cc (TypeCheckTopLevel::visit):
Make static items behave more similarly to const items.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/typecheck/rust-hir-type-check-toplevel.cc | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc 
b/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc
index b0ee292df10..594e527fdcf 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc
@@ -261,11 +261,11 @@ TypeCheckTopLevel::visit (HIR::StaticItem &var)
   TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
 
   TyTy::BaseType *unified
-= unify_site (var.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (type, var.get_type ()->get_locus ()),
- TyTy::TyWithLocation (expr_type,
-   var.get_expr ()->get_locus ()),
- var.get_locus ());
+= coercion_site (var.get_mappings ().get_hirid (),
+TyTy::TyWithLocation (type, var.get_type ()->get_locus ()),
+TyTy::TyWithLocation (expr_type,
+  var.get_expr ()->get_locus ()),
+var.get_locus ());
   context->insert_type (var.get_mappings (), unified);
 }
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: testsuite: add loop condition execution test

2023-01-31 Thread Arthur Cohen
From: liushuyu 

gcc/testsuite/ChangeLog:

* rust/execute/torture/loop-condition-eval.rs: New test.

Signed-off-by: Zixing Liu 

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../execute/torture/loop-condition-eval.rs| 21 +++
 1 file changed, 21 insertions(+)
 create mode 100644 gcc/testsuite/rust/execute/torture/loop-condition-eval.rs

diff --git a/gcc/testsuite/rust/execute/torture/loop-condition-eval.rs 
b/gcc/testsuite/rust/execute/torture/loop-condition-eval.rs
new file mode 100644
index 000..008965917ab
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/loop-condition-eval.rs
@@ -0,0 +1,21 @@
+// { dg-output "1\n" }
+pub fn test() -> u64 {
+let mut n = 113383; // #20 in https://oeis.org/A006884
+while n != 1 {
+n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 };
+}
+n
+}
+
+pub fn test_1() -> u64 {
+test()
+}
+
+extern "C" {
+fn printf(fmt: *const i8, ...);
+}
+
+fn main() -> i32 {
+unsafe { printf("%lu\n" as *const str as *const i8, test_1()) }
+0
+}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: rust: Add -frust-compile-until option

2023-01-31 Thread Arthur Cohen
This option helps ensure that we do not introduce regressions on various
parts of the compilation pipeline. For example, a testcase (or testsuite
from the `testing` project) might pass attribute checking, expansion and
lowering, but fail during typechecking. Should a change suddenly make
that testcase fail expansion, we would not be able to notice it. By
generating tests that run up until expansion, typechecking, compilation
and so forth we ensure that no regressions are added accidentally to
already failing tests/testsuites.

gcc/rust/ChangeLog:

* lang.opt: Add new ``-frust-compile-until` option.
* rust-session-manager.cc (Session::compile_crate): Add stops around
various compilation steps in the pipeline.
* rust-session-manager.h (struct CompileOptions): Add `CompileStep` enum
and field.

gcc/testsuite/ChangeLog:

* rust/compile/frust-compile-until.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/lang.opt | 42 +++
 gcc/rust/rust-session-manager.cc  | 36 +++-
 gcc/rust/rust-session-manager.h   | 25 ++-
 .../rust/compile/frust-compile-until.rs   |  7 
 4 files changed, 107 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/frust-compile-until.rs

diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
index 3e6826954da..40aafaf34d2 100644
--- a/gcc/rust/lang.opt
+++ b/gcc/rust/lang.opt
@@ -117,6 +117,48 @@ Rust Joined RejectNegative
 
 o
 Rust Joined Separate
+
+frust-compile-until=
+Rust Joined RejectNegative Enum(frust_compile_until) 
Var(flag_rust_compile_until)
+-frust-compile-until=[ast|attributecheck|expansion|nameresolution|lowering|typecheck|privacy|unsafety|const|copimlation|end]
 When to stop in the pipeline when compiling Rust code
+
+Enum
+Name(frust_compile_until) Type(int) UnknownError(unknown rust compile-until 
%qs)
+
+EnumValue
+Enum(frust_compile_until) String(ast) Value(0)
+
+EnumValue
+Enum(frust_compile_until) String(attributecheck) Value(1)
+
+EnumValue
+Enum(frust_compile_until) String(expansion) Value(2)
+
+EnumValue
+Enum(frust_compile_until) String(nameresolution) Value(3)
+
+EnumValue
+Enum(frust_compile_until) String(lowering) Value(4)
+
+EnumValue
+Enum(frust_compile_until) String(typecheck) Value(5)
+
+EnumValue
+Enum(frust_compile_until) String(privacy) Value(6)
+
+EnumValue
+Enum(frust_compile_until) String(unsafety) Value(7)
+
+EnumValue
+Enum(frust_compile_until) String(const) Value(8)
+
+EnumValue
+Enum(frust_compile_until) String(compilation) Value(9)
+
+EnumValue
+Enum(frust_compile_until) String(end) Value(10)
+
+
 ; Documented in common.opt
 
 ; This comment is to ensure we retain the blank line above.
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 157f5099155..4ee7175b48b 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -223,7 +223,9 @@ Session::handle_option (
 case OPT_frust_edition_:
   options.set_edition (flag_rust_edition);
   break;
-
+case OPT_frust_compile_until_:
+  options.set_compile_step (flag_rust_compile_until);
+  break;
 case OPT_frust_metadata_output_:
   options.set_metadata_output (arg);
   break;
@@ -447,6 +449,8 @@ Session::compile_crate (const char *filename)
   return;
 }
 
+  auto last_step = options.get_compile_until ();
+
   // parse file here
   /* create lexer and parser - these are file-specific and so aren't instance
* variables */
@@ -503,7 +507,7 @@ Session::compile_crate (const char *filename)
 
   // If -fsyntax-only was passed, we can just skip the remaining passes.
   // Parsing errors are already emitted in `parse_crate()`
-  if (flag_syntax_only)
+  if (flag_syntax_only || last_step == CompileOptions::CompileStep::Ast)
 return;
 
   // register plugins pipeline stage
@@ -522,8 +526,14 @@ Session::compile_crate (const char *filename)
   // TODO: what do I dump here? injected crate names?
 }
 
+  if (last_step == CompileOptions::CompileStep::AttributeCheck)
+return;
+
   Analysis::AttributeChecker ().go (parsed_crate);
 
+  if (last_step == CompileOptions::CompileStep::Expansion)
+return;
+
   // expansion pipeline stage
   expansion (parsed_crate);
   rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
@@ -536,6 +546,9 @@ Session::compile_crate (const char *filename)
   rust_debug ("END POST-EXPANSION AST DUMP");
 }
 
+  if (last_step == CompileOptions::CompileStep::NameResolution)
+return;
+
   // resolution pipeline stage
   Resolver::NameResolution::Resolve (parsed_crate);
   if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP))
@@ -546,6 +559,9 @@ Session::compile_crate (const char *filename)
   if (saw_errors ())
 return;
 
+  if (last_step == CompileOptions::CompileStep::Lowering)
+return;
+
   // lower AST to HIR
   std::uniq

[COMMITTED] gccrs: const generics: Forbid default values in Functions, Traits and Impls

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* checks/errors/rust-const-checker.cc (ConstChecker::ctx_to_str): Allow
getting an error string from a specific constant context.
(ConstChecker::ctx_allows_default): New function, check if a context
allows default values for Const generics.
(ConstChecker::visit): Call into `ctx_allows_default`.
* checks/errors/rust-const-checker.h: Declare `ctx_allows_default`.

gcc/testsuite/ChangeLog:

* rust/compile/const_generics_8.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/checks/errors/rust-const-checker.cc  | 97 +--
 gcc/rust/checks/errors/rust-const-checker.h   | 25 +
 .../rust/compile/const_generics_8.rs  | 12 +++
 3 files changed, 128 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/const_generics_8.rs

diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
index 0c1b743cfaf..2fa9614abf1 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -52,6 +52,67 @@ ConstChecker::is_const_extern_fn (HIR::ExternalFunctionItem 
&fn)
 });
 }
 
+const char *
+ConstChecker::ctx_to_str (ConstGenericCtx ctx)
+{
+  switch (ctx)
+{
+case ConstGenericCtx::Function:
+  return "function";
+case ConstGenericCtx::TypeAlias:
+  return "type alias";
+case ConstGenericCtx::Struct:
+  return "struct";
+case ConstGenericCtx::Enum:
+  return "enum";
+case ConstGenericCtx::Union:
+  return "union";
+case ConstGenericCtx::Trait:
+  return "trait";
+case ConstGenericCtx::Impl:
+  return "impl";
+default:
+  gcc_unreachable ();
+}
+}
+
+bool
+ConstChecker::ctx_allows_default (ConstGenericCtx ctx)
+{
+  switch (ctx)
+{
+case ConstGenericCtx::TypeAlias:
+case ConstGenericCtx::Struct:
+case ConstGenericCtx::Enum:
+case ConstGenericCtx::Trait:
+  return true;
+default:
+  return false;
+}
+}
+
+void
+ConstChecker::check_default_const_generics (
+  std::vector> ¶ms, ConstGenericCtx context)
+{
+  if (ctx_allows_default (context))
+return;
+
+  for (auto ¶m : params)
+{
+  if (param->get_kind () == GenericParam::GenericKind::CONST)
+   {
+ auto const_param = static_cast (param.get ());
+ if (const_param->has_default_expression ())
+   rust_error_at (
+ param->get_locus (),
+ "default values for const generic parameters are not "
+ "allowed in %qs items",
+ ctx_to_str (context));
+   }
+}
+}
+
 void
 ConstChecker::visit (Lifetime &lifetime)
 {}
@@ -560,6 +621,9 @@ ConstChecker::visit (Function &function)
   if (const_fn)
 const_context.enter (function.get_mappings ().get_hirid ());
 
+  check_default_const_generics (function.get_generic_params (),
+   ConstGenericCtx::Function);
+
   for (auto ¶m : function.get_function_params ())
 param.get_type ()->accept_vis (*this);
 
@@ -571,18 +635,27 @@ ConstChecker::visit (Function &function)
 
 void
 ConstChecker::visit (TypeAlias &type_alias)
-{}
+{
+  check_default_const_generics (type_alias.get_generic_params (),
+   ConstGenericCtx::TypeAlias);
+}
 
 void
 ConstChecker::visit (StructStruct &struct_item)
-{}
+{
+  check_default_const_generics (struct_item.get_generic_params (),
+   ConstGenericCtx::Struct);
+}
 
 void
 ConstChecker::visit (TupleStruct &tuple_struct)
-{}
+{
+  check_default_const_generics (tuple_struct.get_generic_params (),
+   ConstGenericCtx::Struct);
+}
 
 void
-ConstChecker::visit (EnumItem &item)
+ConstChecker::visit (EnumItem &enum_item)
 {}
 
 void
@@ -605,11 +678,17 @@ ConstChecker::visit (EnumItemDiscriminant &item)
 
 void
 ConstChecker::visit (Enum &enum_item)
-{}
+{
+  check_default_const_generics (enum_item.get_generic_params (),
+   ConstGenericCtx::Enum);
+}
 
 void
 ConstChecker::visit (Union &union_item)
-{}
+{
+  check_default_const_generics (union_item.get_generic_params (),
+   ConstGenericCtx::Union);
+}
 
 void
 ConstChecker::visit (ConstantItem &const_item)
@@ -652,6 +731,9 @@ ConstChecker::visit (TraitItemType &item)
 void
 ConstChecker::visit (Trait &trait)
 {
+  check_default_const_generics (trait.get_generic_params (),
+   ConstGenericCtx::Trait);
+
   for (auto &item : trait.get_trait_items ())
 item->accept_vis (*this);
 }
@@ -659,6 +741,9 @@ ConstChecker::visit (Trait &trait)
 void
 ConstChecker::visit (ImplBlock &impl)
 {
+  check_default_const_generics (impl.get_generic_params (),
+   ConstGenericCtx::Impl);
+
   for (auto &item : impl.get_impl_items ())
 item->accept_vis (*this);
 }
diff --git a/gcc/rust/checks/errors/rust-const-checker.h 
b/gc

[COMMITTED] gccrs: expand: eager evaluate macros inside builtin macros

2023-01-31 Thread Arthur Cohen
From: liushuyu 

gcc/rust/ChangeLog:

* ast/rust-ast.h (class MacroInvocData): Store expander as
member of the class.
(class Expr): Add `is_literal` virtual method
* ast/rust-expr.h: Override `is_literal` for `LiteralExpr`s.
* expand/rust-macro-builtins.cc (try_expand_macro_expression): New 
function.
(try_extract_string_literal_from_fragment): Likewise.
(try_expand_single_string_literal): Likewise.
(try_expand_many_expr): Likewise.
(parse_single_string_literal): Add macro expander as argument.
(MacroBuiltin::include_bytes): Pass expander as argument to
`parse_single_string_literal`.
(MacroBuiltin::include_str): Likewise.
(MacroBuiltin::compile_error): Likewise.
(MacroBuiltin::include): Likewise.
(MacroBuiltin::concat): Likewise and add better error handling.
(MacroBuiltin::env): Likewise.
* expand/rust-macro-expand.cc (MacroExpander::expand_invoc): Expand
invocations recursively.

gcc/testsuite/ChangeLog:

* rust/compile/builtin_macro_concat.rs: Fix test error messages.
* rust/compile/builtin_macro_env.rs: Likewise.

Signed-off-by: Zixing Liu 

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/ast/rust-ast.h   |  12 +
 gcc/rust/ast/rust-expr.h  |   2 +
 gcc/rust/expand/rust-macro-builtins.cc| 206 ++
 gcc/rust/expand/rust-macro-expand.cc  |   1 +
 .../rust/compile/builtin_macro_concat.rs  |   8 +-
 .../rust/compile/builtin_macro_env.rs |   4 +-
 6 files changed, 182 insertions(+), 51 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 9e1b8b11373..ccabccd6aff 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -31,6 +31,7 @@ namespace Rust {
 typedef std::string Identifier;
 typedef int TupleIndex;
 struct Session;
+struct MacroExpander;
 
 namespace AST {
 // foward decl: ast visitor
@@ -951,6 +952,8 @@ public:
 
   virtual Location get_locus () const = 0;
 
+  virtual bool is_literal () const { return false; }
+
   // HACK: strictly not needed, but faster than full downcast clone
   virtual bool is_expr_without_block () const = 0;
 
@@ -1471,6 +1474,7 @@ private:
   // One way of parsing the macro. Probably not applicable for all macros.
   std::vector > parsed_items;
   bool parsed_to_meta_item = false;
+  MacroExpander *expander = nullptr;
 
 public:
   std::string as_string () const;
@@ -1495,6 +1499,7 @@ public:
 path = other.path;
 token_tree = other.token_tree;
 parsed_to_meta_item = other.parsed_to_meta_item;
+expander = other.expander;
 
 parsed_items.reserve (other.parsed_items.size ());
 for (const auto &e : other.parsed_items)
@@ -1523,6 +1528,13 @@ public:
   SimplePath &get_path () { return path; }
   const SimplePath &get_path () const { return path; }
 
+  void set_expander (MacroExpander *new_expander) { expander = new_expander; }
+  MacroExpander *get_expander ()
+  {
+rust_assert (expander);
+return expander;
+  }
+
   void
   set_meta_item_output (std::vector > new_items)
   {
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 1966a590c94..c764f9c4c66 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -67,6 +67,8 @@ public:
 
   Location get_locus () const override final { return locus; }
 
+  bool is_literal () const override final { return true; }
+
   Literal get_literal () const { return literal; }
 
   void accept_vis (ASTVisitor &vis) override;
diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index f5e3e188423..606f33c65bc 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -17,12 +17,14 @@
 // .
 
 #include "rust-macro-builtins.h"
+#include "rust-ast.h"
 #include "rust-diagnostics.h"
 #include "rust-expr.h"
 #include "rust-session-manager.h"
 #include "rust-macro-invoc-lexer.h"
 #include "rust-lex.h"
 #include "rust-parse.h"
+#include "rust-attribute-visitor.h"
 
 namespace Rust {
 namespace {
@@ -61,13 +63,119 @@ macro_end_token (AST::DelimTokenTree &invoc_token_tree,
   return last_token_id;
 }
 
+/* Expand and extract an expression from the macro */
+
+static inline AST::ASTFragment
+try_expand_macro_expression (AST::Expr *expr, MacroExpander *expander)
+{
+  rust_assert (expander);
+
+  auto vis = Rust::AttrVisitor (*expander);
+  expr->accept_vis (vis);
+  return expander->take_expanded_fragment (vis);
+}
+
+/* Expand and then extract a string literal from the macro */
+
+static std::unique_ptr
+try_extract_string_literal_from_fragment (const Location &parent_locus,
+ std::unique_ptr &node)
+{
+  auto maybe_lit = static_cast (node.get ());
+  if (!node || !node->is_literal ()
+  || maybe_lit->get_lit_type () != AST::Literal::STRING)
+

[COMMITTED] gccrs: module lowering: Do not append null pointers as items

2023-01-31 Thread Arthur Cohen
Some module items do not need to get lowered to HIR such as `macro_rules!` 
definitions. Hence, module lowering should act the same as crate lowering: Only 
emplace back the lowered item if it is a valid pointer

gcc/rust/ChangeLog:

* hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Do not lower
null items within modules.

gcc/testsuite/ChangeLog:

* rust/compile/macro44.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/hir/rust-ast-lower-item.cc   |  5 +++-
 gcc/testsuite/rust/compile/macro44.rs | 34 +++
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/macro44.rs

diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index 8aec68d9458..411cc4be855 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -59,7 +59,10 @@ ASTLoweringItem::visit (AST::Module &module)
   for (auto &item : module.get_items ())
 {
   auto transitem = translate (item.get ());
-  items.push_back (std::unique_ptr (transitem));
+  // The item may be null if it doesn't need to live in the HIR - for
+  // example, macro rules definitions
+  if (transitem)
+   items.push_back (std::unique_ptr (transitem));
 }
 
   // should be lowered/copied from module.get_in/outer_attrs()
diff --git a/gcc/testsuite/rust/compile/macro44.rs 
b/gcc/testsuite/rust/compile/macro44.rs
new file mode 100644
index 000..84b2cdbb506
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro44.rs
@@ -0,0 +1,34 @@
+mod foo {
+mod bar {
+mod baz {
+macro_rules! baz {
+() => {{}};
+}
+}
+}
+
+macro_rules! foo {
+() => {{}};
+}
+
+fn foo_f() { // { dg-warning "function is never used" }
+foo!();
+}
+
+fn bar_f() { // { dg-warning "function is never used" }
+baz!();
+}
+}
+
+mod foo2 {
+#[macro_export]
+macro_rules! bar1 {
+() => {};
+}
+
+macro_rules! bar2 {
+() => {};
+}
+}
+
+fn main() {}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Refactor TypeResolution to be a simple query based system

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

This patch refactors the type resolution system to introduce a new
interface

  bool query_type (HirId, TyTy::BaseType** result)

This is needed in order to properly support forward declared items. Our
name resolution system has two parts:

  1. Toplevel scan
  2. Item resolution

The toplevel scan gathers all the nesseacry 'names' into their respective
namespace by doing a full toplevel scan and generate canonical paths for
each item. The second pass is responsible for drilling down into each
structure or function to resolve each field or variable etc. This means
our name resolution system supports forward decalred items but our type
resolution system did not.

This patch removes the toplevel scan from our type resolution pass which
is not able to handle all cases such as a function with return type and
the type is decalred after the fact or a type alias to a type declared
after the fact. The name resolution mappings are resolved so when errors
occured here we got errors such as unable to lookup HirId 1234, which meant
yes we have 'resolved' this reference to this HirId but we are unable to
find any type information for it. This means we needed a new way to figure
out the type in a query based way.

This is where the new query_type inferface comes in so when we have an
HirId we want to resolve the mappings class allows us to figure out what
item this is such as:

  1. HIR::Item (normal HIR::Function, Struct, TypeAlias, ...)
  2. HIR::ImplItem (function, constant, ... within an impl-block)
  3. HIR::ImplBlock (Self type on an impl-block)
  4. HIR::ExternalItem (extern-block item)

The mappings class allows us to simply lookup these HIR nodes and then
call the relevant resolver class to compute the type. This patch does not
add support for self-referencial types but is the starting point to be able
to support such types.

Fixes #1455

gcc/rust/ChangeLog:

* Make-lang.in: Remove `rust-hir-typecheck-toplevel` object and add
`rust-hir-path-probe` one.
* typecheck/rust-hir-dot-operator.cc (MethodResolver::MethodResolver):
Remove no longer used `context` and `mapping` fields, and use new
`query_type` API.
(MethodResolver::MethodResolver): Likewise.
(MethodResolver::select): Use new `query_type` API.
* typecheck/rust-hir-path-probe.h: New header.
* typecheck/rust-hir-path-probe.cc: New file.
* typecheck/rust-hir-dot-operator.h (class MethodResolver): Remove no
longer used `context` and `mapping` fields, and use new `query_type` 
API.
* typecheck/rust-hir-type-check-base.cc (TypeCheckBase::query_type): 
New function.
* typecheck/rust-hir-type-check-base.h: Declare `query_type` function.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Add 
debug print.
* typecheck/rust-hir-type-check-implitem.cc 
(TypeCheckTopLevelExternItem::Resolve):
Refactor and make use of new query system.
(TypeCheckTopLevelExternItem::Resolve): Likewise.
(TypeCheckTopLevelExternItem::visit): Likewise.
(TypeCheckTopLevelImplItem::visit): Likewise.
(TypeCheckImplItem::visit): Likewise.
(TypeCheckImplItem::TypeCheckImplItem): Likewise.
(TypeCheckImplItem::Resolve): Likewise.
(TypeCheckImplItemWithTrait::visit): Likewise.
* typecheck/rust-hir-type-check-implitem.h (class 
TypeCheckTopLevelImplItem): Likewise.
(class TypeCheckImplItemWithTrait): Likewise.
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::TypeCheckItem): 
Likewise.
(TypeCheckItem::Resolve): Likewise.
(TypeCheckItem::ResolveImplItem): Likewise.
(TypeCheckItem::ResolveImplBlockSelf): Likewise.
(TypeCheckItem::visit): Likewise.
(TypeCheckItem::resolve_impl_item): Likewise.
(TypeCheckItem::resolve_impl_block_substitutions): Likewise.
(TypeCheckItem::resolve_impl_block_self): Likewise.
* typecheck/rust-hir-type-check-item.h: Likewise.
* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_root_path): Likewise.
(TypeCheckExpr::resolve_segments): Likewise.
* typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): 
Likewise.
* typecheck/rust-hir-type-check-stmt.h: Likewise.
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::Resolve): 
Likewise.
(TypeCheckType::visit): Likewise.
(TypeCheckType::resolve_root_path): Likewise.
* typecheck/rust-hir-type-check.cc (TypeResolution::Resolve): Likewise.
* typecheck/rust-hir-type-check.h: Likewise.
* typecheck/rust-substitution-mapper.h: Likewise.
* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): Likewise.
(TypeCheckBase::get_predicate_from_bound): Likewise.
(TypeBoundsMappings::add_bound): Likewise.
* typecheck/rust-tyty-cmp.h: Likewise.
* typecheck/rust-tyty.h: Likewise.
* typecheck/ru

[COMMITTED] gccrs: Static Items must be const evaluated

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

Statics like constants need to have a singular value they are not functions
to be lazy evaluated. So to evaluate a block expr we can just reuse our
const code to resolve this to a singular value.

gcc/rust/ChangeLog:

* backend/rust-compile-item.cc (CompileItem::visit): Const evaluate
static item expressions.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-item.cc | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/backend/rust-compile-item.cc 
b/gcc/rust/backend/rust-compile-item.cc
index 634b983a771..d1cdc3b6698 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -43,13 +43,18 @@ CompileItem::visit (HIR::StaticItem &var)
   rust_assert (ok);
 
   tree type = TyTyResolveCompile::compile (ctx, resolved_type);
-  tree value = CompileExpr::Compile (var.get_expr (), ctx);
 
   const Resolver::CanonicalPath *canonical_path = nullptr;
   ok = ctx->get_mappings ()->lookup_canonical_path (
 var.get_mappings ().get_nodeid (), &canonical_path);
   rust_assert (ok);
 
+  HIR::Expr *const_value_expr = var.get_expr ();
+  ctx->push_const_context ();
+  tree value = compile_constant_item (ctx, resolved_type, canonical_path,
+ const_value_expr, var.get_locus ());
+  ctx->pop_const_context ();
+
   std::string name = canonical_path->get ();
   std::string asm_name = ctx->mangle_item (resolved_type, *canonical_path);
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Fix duplicated function generation on higher ranked trait bounds

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

Deuplicate function elimination can fail when we compile helpers during
higher ranked trait bound monomorphization. This because the
TyTy::BaseType info can be lost/reset during the compilation process. This
adds a second mechanism to match based on the manged names which is a bit
more reliable. This patch is required since the query based refactor of
the type system so this issue was likely hidden to to using duplicated type
info for higher ranked trait bounds.

gcc/rust/ChangeLog:

* backend/rust-compile-context.h: Add new optional `asm_name` string
argument to `lookup_function_decl`.
* backend/rust-compile-item.cc (CompileItem::visit): Compute assembly
name and pass it to `lookup_function_decl` when calling it.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-context.h | 21 -
 gcc/rust/backend/rust-compile-item.cc   | 14 --
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-context.h 
b/gcc/rust/backend/rust-compile-context.h
index 2d379c2a5fa..49f78e19b20 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -148,7 +148,8 @@ public:
   }
 
   bool lookup_function_decl (HirId id, tree *fn, DefId dId = UNKNOWN_DEFID,
-const TyTy::BaseType *ref = nullptr)
+const TyTy::BaseType *ref = nullptr,
+const std::string &asm_name = std::string ())
   {
 // for for any monomorphized fns
 if (ref != nullptr)
@@ -163,11 +164,29 @@ public:
  {
const TyTy::BaseType *r = e.first;
tree f = e.second;
+
if (ref->is_equal (*r))
  {
*fn = f;
return true;
  }
+
+   if (DECL_ASSEMBLER_NAME_SET_P (f) && !asm_name.empty ())
+ {
+   tree raw = DECL_ASSEMBLER_NAME_RAW (f);
+   const char *rptr = IDENTIFIER_POINTER (raw);
+
+   bool lengths_match_p
+ = IDENTIFIER_LENGTH (raw) == asm_name.size ();
+   if (lengths_match_p
+   && strncmp (rptr, asm_name.c_str (),
+   IDENTIFIER_LENGTH (raw))
+== 0)
+ {
+   *fn = f;
+   return true;
+ }
+ }
  }
return false;
   }
diff --git a/gcc/rust/backend/rust-compile-item.cc 
b/gcc/rust/backend/rust-compile-item.cc
index d1cdc3b6698..b2e9b3fbf6d 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -134,11 +134,18 @@ CompileItem::visit (HIR::Function &function)
}
 }
 
+  const Resolver::CanonicalPath *canonical_path = nullptr;
+  bool ok = ctx->get_mappings ()->lookup_canonical_path (
+function.get_mappings ().get_nodeid (), &canonical_path);
+  rust_assert (ok);
+
+  const std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+
   // items can be forward compiled which means we may not need to invoke this
   // code. We might also have already compiled this generic function as well.
   tree lookup = NULL_TREE;
   if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-fntype->get_id (), fntype))
+fntype->get_id (), fntype, asm_name))
 {
   // has this been added to the list then it must be finished
   if (ctx->function_completed (lookup))
@@ -160,11 +167,6 @@ CompileItem::visit (HIR::Function &function)
   fntype->override_context ();
 }
 
-  const Resolver::CanonicalPath *canonical_path = nullptr;
-  bool ok = ctx->get_mappings ()->lookup_canonical_path (
-function.get_mappings ().get_nodeid (), &canonical_path);
-  rust_assert (ok);
-
   if (function.get_qualifiers ().is_const ())
 ctx->push_const_context ();
 
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Add testcase to show forward declared items work

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

Fixes #1006

gcc/testsuite/ChangeLog:

* rust/compile/issue-1006.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/testsuite/rust/compile/issue-1006.rs | 10 ++
 1 file changed, 10 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-1006.rs

diff --git a/gcc/testsuite/rust/compile/issue-1006.rs 
b/gcc/testsuite/rust/compile/issue-1006.rs
new file mode 100644
index 000..7f565deaef3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1006.rs
@@ -0,0 +1,10 @@
+// { dg-options "-w" }
+union B {
+a: A,
+b: f32,
+}
+
+struct A {
+data: i32,
+len: usize,
+}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: Add testcase to show forward declared items work via TypeAlias

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

Fixes #1073

gcc/testsuite/ChangeLog:

* rust/compile/issue-1073.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/testsuite/rust/compile/issue-1073.rs | 4 
 1 file changed, 4 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-1073.rs

diff --git a/gcc/testsuite/rust/compile/issue-1073.rs 
b/gcc/testsuite/rust/compile/issue-1073.rs
new file mode 100644
index 000..ac887c02b4d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1073.rs
@@ -0,0 +1,4 @@
+// { dg-options "-w" }
+type A = B;
+
+struct B;
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: backend: Expose Bvariable class through rust-gcc header

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* rust-gcc.cc (class Bvariable): Move class to `rust-gcc.h` header.
* rust-gcc.h: New file.

Tested on x86_64-pc-linux-gnu, committed on master.


Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/rust-gcc.cc | 30 +--
 gcc/rust/rust-gcc.h  | 58 
 2 files changed, 59 insertions(+), 29 deletions(-)
 create mode 100644 gcc/rust/rust-gcc.h

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index e3331d60e32..82b2d33977d 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -50,38 +50,10 @@
 #include "rust-linemap.h"
 #include "rust-backend.h"
 #include "rust-object-export.h"
+#include "rust-gcc.h"
 
 #include "backend/rust-tree.h"
 
-// TODO: this will have to be significantly modified to work with Rust
-
-// Bvariable is a bit more complicated, because of zero-sized types.
-// The GNU linker does not permit dynamic variables with zero size.
-// When we see such a variable, we generate a version of the type with
-// non-zero size.  However, when referring to the global variable, we
-// want an expression of zero size; otherwise, if, say, the global
-// variable is passed to a function, we will be passing a
-// non-zero-sized value to a zero-sized value, which can lead to a
-// miscompilation.
-
-class Bvariable
-{
-public:
-  Bvariable (tree t) : t_ (t), orig_type_ (NULL) {}
-
-  Bvariable (tree t, tree orig_type) : t_ (t), orig_type_ (orig_type) {}
-
-  // Get the tree for use as an expression.
-  tree get_tree (Location) const;
-
-  // Get the actual decl;
-  tree get_decl () const { return this->t_; }
-
-private:
-  tree t_;
-  tree orig_type_;
-};
-
 // Get the tree of a variable for use as an expression.  If this is a
 // zero-sized global, create an expression that refers to the decl but
 // has zero size.
diff --git a/gcc/rust/rust-gcc.h b/gcc/rust/rust-gcc.h
new file mode 100644
index 000..085c16d0f3b
--- /dev/null
+++ b/gcc/rust/rust-gcc.h
@@ -0,0 +1,58 @@
+// rust-gcc.cc -- Rust frontend to gcc IR.
+// Copyright (C) 2011-2022 Free Software Foundation, Inc.
+// Contributed by Ian Lance Taylor, Google.
+// forked from gccgo
+
+// 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
+// .
+
+#include "rust-system.h"
+
+// This has to be included outside of extern "C", so we have to
+// include it here before tree.h includes it later.
+#include 
+
+#include "tree.h"
+#include "rust-location.h"
+
+// TODO: this will have to be significantly modified to work with Rust
+
+// Bvariable is a bit more complicated, because of zero-sized types.
+// The GNU linker does not permit dynamic variables with zero size.
+// When we see such a variable, we generate a version of the type with
+// non-zero size.  However, when referring to the global variable, we
+// want an expression of zero size; otherwise, if, say, the global
+// variable is passed to a function, we will be passing a
+// non-zero-sized value to a zero-sized value, which can lead to a
+// miscompilation.
+
+class Bvariable
+{
+public:
+  Bvariable (tree t) : t_ (t), orig_type_ (NULL) {}
+
+  Bvariable (tree t, tree orig_type) : t_ (t), orig_type_ (orig_type) {}
+
+  // Get the tree for use as an expression.
+  tree get_tree (Location) const;
+
+  // Get the actual decl;
+  tree get_decl () const { return this->t_; }
+
+private:
+  tree t_;
+  tree orig_type_;
+};
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: lint: Do not emit unused warnings for public items

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* checks/lints/rust-lint-scan-deadcode.h: Do not report public items
as dead code.

gcc/testsuite/ChangeLog:

* rust/compile/issue-1031.rs: Remove extraneous dead code warnings.
* rust/compile/issue-1289.rs: Likewise.
* rust/compile/test_mod.rs: Likewise.
* rust/compile/torture/raw_identifiers.rs: Likewise.
* rust/compile/torture/raw_identifiers_keywords.rs: Likewise.
* rust/compile/privacy7.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/checks/lints/rust-lint-scan-deadcode.h  | 9 +
 gcc/testsuite/rust/compile/issue-1031.rs | 2 --
 gcc/testsuite/rust/compile/issue-1289.rs | 2 --
 gcc/testsuite/rust/compile/privacy7.rs   | 9 +
 gcc/testsuite/rust/compile/test_mod.rs   | 1 -
 gcc/testsuite/rust/compile/torture/raw_identifiers.rs| 4 ++--
 .../rust/compile/torture/raw_identifiers_keywords.rs | 4 ++--
 7 files changed, 18 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/privacy7.rs

diff --git a/gcc/rust/checks/lints/rust-lint-scan-deadcode.h 
b/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
index 3289b7d759b..63a308949c3 100644
--- a/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
+++ b/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
@@ -53,7 +53,7 @@ public:
   void visit (HIR::Function &function) override
   {
 HirId hirId = function.get_mappings ().get_hirid ();
-if (should_warn (hirId))
+if (should_warn (hirId) && !function.get_visibility ().is_public ())
   {
if (mappings->is_impl_item (hirId))
  {
@@ -78,7 +78,7 @@ public:
   void visit (HIR::StructStruct &stct) override
   {
 HirId hirId = stct.get_mappings ().get_hirid ();
-if (should_warn (hirId))
+if (should_warn (hirId) && !stct.get_visibility ().is_public ())
   {
bool name_starts_underscore = stct.get_identifier ().at (0) == '_';
if (!name_starts_underscore)
@@ -92,7 +92,8 @@ public:
for (auto &field : stct.get_fields ())
  {
HirId field_hir_id = field.get_mappings ().get_hirid ();
-   if (should_warn (field_hir_id))
+   if (should_warn (field_hir_id)
+   && !field.get_visibility ().is_public ())
  {
rust_warning_at (field.get_locus (), 0,
 "field is never read: %<%s%>",
@@ -106,7 +107,7 @@ public:
   {
 // only warn tuple struct unconstructed, and ignoring unused field
 HirId hirId = stct.get_mappings ().get_hirid ();
-if (should_warn (hirId))
+if (should_warn (hirId) && !stct.get_visibility ().is_public ())
   {
rust_warning_at (stct.get_locus (), 0,
 "struct is never constructed: %<%s%>",
diff --git a/gcc/testsuite/rust/compile/issue-1031.rs 
b/gcc/testsuite/rust/compile/issue-1031.rs
index 939f0f981e0..5ba8f7a267b 100644
--- a/gcc/testsuite/rust/compile/issue-1031.rs
+++ b/gcc/testsuite/rust/compile/issue-1031.rs
@@ -6,12 +6,10 @@ extern "rust-intrinsic" {
 #[lang = "const_ptr"]
 impl *const T {
 pub const unsafe fn offset(self, count: isize) -> *const T {
-// { dg-warning "associated function is never used" "" { target *-*-* 
} .-1 }
 unsafe { offset(self, count) }
 }
 
 pub const unsafe fn add(self, count: usize) -> Self {
-// { dg-warning "associated function is never used" "" { target *-*-* 
} .-1 }
 unsafe { self.offset(count as isize) }
 }
 }
diff --git a/gcc/testsuite/rust/compile/issue-1289.rs 
b/gcc/testsuite/rust/compile/issue-1289.rs
index 343aaab078b..eb41af0a75b 100644
--- a/gcc/testsuite/rust/compile/issue-1289.rs
+++ b/gcc/testsuite/rust/compile/issue-1289.rs
@@ -23,12 +23,10 @@ impl *mut T {
 #[lang = "const_ptr"]
 impl *const T {
 pub const unsafe fn offset(self, count: isize) -> *mut T {
-// { dg-warning "associated function is never used" "" { target *-*-* 
} .-1 }
 unsafe { intrinsics::offset(self, count) as *mut T }
 }
 
 pub const unsafe fn add(self, count: usize) -> Self {
-// { dg-warning "associated function is never used" "" { target *-*-* 
} .-1 }
 unsafe { self.offset(count as isize) }
 }
 }
diff --git a/gcc/testsuite/rust/compile/privacy7.rs 
b/gcc/testsuite/rust/compile/privacy7.rs
new file mode 100644
index 000..00fa0ef8f11
--- /dev/null
+++ b/gcc/testsuite/rust/compile/privacy7.rs
@@ -0,0 +1,9 @@
+pub struct Foo(i8);
+struct Bar(pub i8); // { dg-warning "struct is never constructed: .Bar." }
+pub struct Baz {
+a: i32, // { dg-warning "field is never read: .a." }
+pub b: i32,
+}
+
+pub fn foo() {}
+fn bar() {} // { dg-warning "function is never used: .bar." }
diff --git a/gcc/testsuite/rust/compile/test_mod.rs 
b/gcc/testsuite/rust/compile/test_mod.rs
index 4b3c000236b..6e9c19b3fa4 100644
--- a/gcc/testsuite/rust/compile/test_mod.rs
+

[COMMITTED] gccrs: parser: Parse RangeFullExpr without erroring out

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* parse/rust-parse-impl.h: Allow parsing full range expressions without
erroring out.

gcc/testsuite/ChangeLog:

* rust/compile/parse_range.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/parse/rust-parse-impl.h  | 6 +-
 gcc/testsuite/rust/compile/parse_range.rs | 9 +
 2 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/parse_range.rs

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index fe628647653..72207a1bc22 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -14112,9 +14112,13 @@ std::unique_ptr
 Parser::parse_nud_range_exclusive_expr (
   const_TokenPtr tok, AST::AttrVec outer_attrs ATTRIBUTE_UNUSED)
 {
+  auto restrictions = ParseRestrictions ();
+  restrictions.expr_can_be_null = true;
+
   // FIXME: this probably parses expressions accidently or whatever
   // try parsing RHS (as tok has already been consumed in parse_expression)
-  std::unique_ptr right = parse_expr (LBP_DOT_DOT, AST::AttrVec ());
+  std::unique_ptr right
+= parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
 
   Location locus = tok->get_locus ();
 
diff --git a/gcc/testsuite/rust/compile/parse_range.rs 
b/gcc/testsuite/rust/compile/parse_range.rs
new file mode 100644
index 000..03469b1f8d5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/parse_range.rs
@@ -0,0 +1,9 @@
+// { dg-additional-options "-fsyntax-only" }
+
+fn main() {
+let a = [1, 2, 3, 4];
+let _ = a[0..];
+let _ = a[..3];
+let _ = a[0..3];
+let _ = a[..];
+}
-- 
2.39.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust