From c4f1a7aa81feee7fe227bb61ef014eabba06a5d3 Mon Sep 17 00:00:00 2001 From: Nym Seddon Date: Wed, 23 Dec 2020 09:16:20 +0000 Subject: Fix minor typo in visibility as_string --- gcc/rust/hir/tree/rust-hir-full-test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc index 0a87d25..2e30b59 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -286,7 +286,7 @@ Visibility::as_string () const case NONE: return std::string ("pub"); case CRATE: - return std::string ("ub(crate)"); + return std::string ("pub(crate)"); case SELF: return std::string ("pub(self)"); case SUPER: -- cgit v1.1 From a4e20cf765364221946200c8e7f96c2041f827a5 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Tue, 22 Dec 2020 23:06:19 +0000 Subject: Shadowing rules are done as part of name resolution. When a new name is defined the name resolver freezes the previous declartion such that all new references point to the latest decl. This patch fixes a crash when we shadow and get a type mismatch and the combination of types fails. See the failure test case for the crash. --- gcc/rust/typecheck/rust-tyty-resolver.h | 10 ++++++++-- gcc/testsuite/rust.test/compilable/shadow1.rs | 5 +++++ gcc/testsuite/rust.test/fail_compilation/shadow1.rs | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/rust.test/compilable/shadow1.rs create mode 100644 gcc/testsuite/rust.test/fail_compilation/shadow1.rs (limited to 'gcc') diff --git a/gcc/rust/typecheck/rust-tyty-resolver.h b/gcc/rust/typecheck/rust-tyty-resolver.h index 1ee533e..b971e66 100644 --- a/gcc/rust/typecheck/rust-tyty-resolver.h +++ b/gcc/rust/typecheck/rust-tyty-resolver.h @@ -87,12 +87,18 @@ public: auto resolved_tyty = resolved_type; for (auto it : gathered_types) - resolved_tyty = resolved_tyty->combine (it); + { + auto combined = resolved_tyty->combine (it); + if (combined == nullptr) + break; + + resolved_tyty = combined; + } // something is not inferred we need to look at all references now if (resolved_tyty == nullptr || resolved_tyty->is_unit ()) { - rust_error_at (decl->get_locus_slow (), "failed to resolve type"); + rust_fatal_error (decl->get_locus_slow (), "failed to resolve type"); return false; } diff --git a/gcc/testsuite/rust.test/compilable/shadow1.rs b/gcc/testsuite/rust.test/compilable/shadow1.rs new file mode 100644 index 0000000..3cb1ec5 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/shadow1.rs @@ -0,0 +1,5 @@ +fn main() { + let mut x = 5; + let mut x; + x = true; +} diff --git a/gcc/testsuite/rust.test/fail_compilation/shadow1.rs b/gcc/testsuite/rust.test/fail_compilation/shadow1.rs new file mode 100644 index 0000000..18c5c58 --- /dev/null +++ b/gcc/testsuite/rust.test/fail_compilation/shadow1.rs @@ -0,0 +1,6 @@ +fn main() { + let mut x = 5; + let mut x; + x = true; + x = x + 2; +} -- cgit v1.1 From b021811ab700156e1e3d56200d585b3180264f4f Mon Sep 17 00:00:00 2001 From: Nym Seddon Date: Wed, 23 Dec 2020 09:13:57 +0000 Subject: Add missing license text Add GPL license text to files without the header --- gcc/rust/ast/clone-test.h | 18 ++++++++++++++++++ gcc/rust/ast/rust-ast-containers.h | 18 ++++++++++++++++++ gcc/rust/ast/rust-ast-full.h | 20 +++++++++++++++++++- gcc/rust/ast/rust-ast-visitor.h | 18 ++++++++++++++++++ gcc/rust/ast/rust-cond-compilation.h | 18 ++++++++++++++++++ gcc/rust/ast/rust-macro.h | 18 ++++++++++++++++++ gcc/rust/ast/rust-path.h | 18 ++++++++++++++++++ gcc/rust/ast/rust-pattern.h | 18 ++++++++++++++++++ gcc/rust/ast/rust-stmt.h | 18 ++++++++++++++++++ gcc/rust/ast/rust-type.h | 18 ++++++++++++++++++ gcc/rust/backend/cscope.h | 18 ++++++++++++++++++ gcc/rust/expand/rust-macro-expand.cc | 18 ++++++++++++++++++ gcc/rust/expand/rust-macro-expand.h | 18 ++++++++++++++++++ gcc/rust/lex/rust-codepoint.h | 18 ++++++++++++++++++ gcc/rust/lex/rust-lex.cc | 18 ++++++++++++++++++ gcc/rust/lex/rust-token.cc | 18 ++++++++++++++++++ gcc/rust/lex/rust-token.h | 18 ++++++++++++++++++ gcc/rust/parse/rust-parse-impl.h | 16 ++++++++++++++++ gcc/rust/parse/rust-parse.cc | 16 ++++++++++++++++ gcc/rust/parse/rust-parse.h | 16 ++++++++++++++++ gcc/rust/rust-backend.h | 18 ++++++++++++++++++ gcc/rust/rust-buffered-queue.h | 18 ++++++++++++++++++ gcc/rust/rust-diagnostics.h | 18 ++++++++++++++++++ gcc/rust/rust-gcc-diagnostics.cc | 18 ++++++++++++++++++ gcc/rust/rust-lang.cc | 18 ++++++++++++++++++ gcc/rust/rust-linemap.cc | 18 ++++++++++++++++++ gcc/rust/rust-location.h | 18 ++++++++++++++++++ gcc/rust/rust-object-export.h | 18 ++++++++++++++++++ 28 files changed, 499 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/rust/ast/clone-test.h b/gcc/rust/ast/clone-test.h index 7d530d2..78a0662 100644 --- a/gcc/rust/ast/clone-test.h +++ b/gcc/rust/ast/clone-test.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef CLONE_TEST_H #define CLONE_TEST_H // Potential fancy deep cloning test for use with unique_ptr diff --git a/gcc/rust/ast/rust-ast-containers.h b/gcc/rust/ast/rust-ast-containers.h index fa400f1..b01255e 100644 --- a/gcc/rust/ast/rust-ast-containers.h +++ b/gcc/rust/ast/rust-ast-containers.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_CONTAINERS_H #define RUST_AST_CONTAINERS_H // crappy redefined AST maybe. may move diff --git a/gcc/rust/ast/rust-ast-full.h b/gcc/rust/ast/rust-ast-full.h index 5378236..8366f78 100644 --- a/gcc/rust/ast/rust-ast-full.h +++ b/gcc/rust/ast/rust-ast-full.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_FULL_H #define RUST_AST_FULL_H // Use as a fast way of including all aspects of the AST (i.e. all headers) @@ -10,4 +28,4 @@ #include "rust-type.h" #include "rust-macro.h" -#endif \ No newline at end of file +#endif diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index b48e8f3..a2b505b 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_VISITOR_H #define RUST_AST_VISITOR_H // Visitor base for AST diff --git a/gcc/rust/ast/rust-cond-compilation.h b/gcc/rust/ast/rust-cond-compilation.h index cef8ebb..77d1d4d 100644 --- a/gcc/rust/ast/rust-cond-compilation.h +++ b/gcc/rust/ast/rust-cond-compilation.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_CONDCOMPILATION #define RUST_AST_CONDCOMPILATION // Conditional compilation-related AST stuff diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 2cae0f9..98051cec 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_MACRO_H #define RUST_AST_MACRO_H diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index bd3b0f0..d1be6f3 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_PATH_H #define RUST_AST_PATH_H /* "Path" (identifier within namespaces, essentially) handling. Required include diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h index dc4d48c..79beebb 100644 --- a/gcc/rust/ast/rust-pattern.h +++ b/gcc/rust/ast/rust-pattern.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_PATTERN_H #define RUST_AST_PATTERN_H diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h index faea905..c2ce387 100644 --- a/gcc/rust/ast/rust-stmt.h +++ b/gcc/rust/ast/rust-stmt.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_STATEMENT_H #define RUST_AST_STATEMENT_H diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h index 8c175d3..0dfeb07 100644 --- a/gcc/rust/ast/rust-type.h +++ b/gcc/rust/ast/rust-type.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_AST_TYPE_H #define RUST_AST_TYPE_H diff --git a/gcc/rust/backend/cscope.h b/gcc/rust/backend/cscope.h index ee4f955..3ba837c 100644 --- a/gcc/rust/backend/cscope.h +++ b/gcc/rust/backend/cscope.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #pragma once #include "rust-system.h" diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 79e74ac..1647909 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #include "rust-macro-expand.h" #include "rust-ast-full.h" // is full really required? diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index a0c1a076..1102565 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_MACRO_EXPAND_H #define RUST_MACRO_EXPAND_H diff --git a/gcc/rust/lex/rust-codepoint.h b/gcc/rust/lex/rust-codepoint.h index d95bfdf..836f819 100644 --- a/gcc/rust/lex/rust-codepoint.h +++ b/gcc/rust/lex/rust-codepoint.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_CODEPOINT_H #define RUST_CODEPOINT_H diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc index 64aad25..b97eea1 100644 --- a/gcc/rust/lex/rust-lex.cc +++ b/gcc/rust/lex/rust-lex.cc @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #include "rust-lex.h" #include "rust-system.h" // for rust_assert and rust_unreachable diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc index e47692c..abaa71b 100644 --- a/gcc/rust/lex/rust-token.cc +++ b/gcc/rust/lex/rust-token.cc @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #include "rust-token.h" #include "rust-diagnostics.h" // for error_at diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h index 2193181..fab736a 100644 --- a/gcc/rust/lex/rust-token.h +++ b/gcc/rust/lex/rust-token.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_TOKEN_H #define RUST_TOKEN_H diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 187f821..a58bff6 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -1,3 +1,19 @@ +/* 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 +. */ + /* Template implementation for Rust::Parser. Previously in rust-parse.cc (before * Parser was template). Separated from rust-parse.h for readability. */ diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc index 883735f..62076ee 100644 --- a/gcc/rust/parse/rust-parse.cc +++ b/gcc/rust/parse/rust-parse.cc @@ -1,3 +1,19 @@ +/* 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-parse.h" #include "rust-linemap.h" #include "rust-diagnostics.h" diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 7218ebc..2778ec7 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -1,3 +1,19 @@ +/* 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 +. */ + #ifndef RUST_PARSE_H #define RUST_PARSE_H diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h index a907fe4..bc8ca96 100644 --- a/gcc/rust/rust-backend.h +++ b/gcc/rust/rust-backend.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_BACKEND_H #define RUST_BACKEND_H diff --git a/gcc/rust/rust-buffered-queue.h b/gcc/rust/rust-buffered-queue.h index ae002c0..7cca024 100644 --- a/gcc/rust/rust-buffered-queue.h +++ b/gcc/rust/rust-buffered-queue.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_BUFFERED_QUEUE_H #define RUST_BUFFERED_QUEUE_H diff --git a/gcc/rust/rust-diagnostics.h b/gcc/rust/rust-diagnostics.h index 04d48c8..fc80303 100644 --- a/gcc/rust/rust-diagnostics.h +++ b/gcc/rust/rust-diagnostics.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + // rust-diagnostics.h -- interface to diagnostic reporting -*- C++ -*- #ifndef RUST_DIAGNOSTICS_H diff --git a/gcc/rust/rust-gcc-diagnostics.cc b/gcc/rust/rust-gcc-diagnostics.cc index fd9c63d..7553d74 100644 --- a/gcc/rust/rust-gcc-diagnostics.cc +++ b/gcc/rust/rust-gcc-diagnostics.cc @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + // rust-gcc-diagnostics.cc -- GCC implementation of rust diagnostics interface. #include "rust-system.h" diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc index 2752497..c4ccbab 100644 --- a/gcc/rust/rust-lang.cc +++ b/gcc/rust/rust-lang.cc @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #include "config.h" #include "system.h" #include "coretypes.h" diff --git a/gcc/rust/rust-linemap.cc b/gcc/rust/rust-linemap.cc index 5ee76bd..caa8383 100644 --- a/gcc/rust/rust-linemap.cc +++ b/gcc/rust/rust-linemap.cc @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + // rust-linemap.cc -- GCC implementation of Linemap. #include "rust-linemap.h" diff --git a/gcc/rust/rust-location.h b/gcc/rust/rust-location.h index 575fa83..9345762 100644 --- a/gcc/rust/rust-location.h +++ b/gcc/rust/rust-location.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + // rust-location.h -- GCC specific Location declaration. -*- C++ -*- #ifndef RUST_LOCATION_H diff --git a/gcc/rust/rust-object-export.h b/gcc/rust/rust-object-export.h index 5ec63e8..345217f 100644 --- a/gcc/rust/rust-object-export.h +++ b/gcc/rust/rust-object-export.h @@ -1,3 +1,21 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + #ifndef RUST_OBJECT_EXPORT_H #define RUST_OBJECT_EXPORT_H -- cgit v1.1 From aa2fbb5e48f6218035d7bde1336345cebf120d3e Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Mon, 21 Dec 2020 18:32:15 +0000 Subject: Bring conditionals back since the HIR change. --- gcc/rust/ast/rust-expr.h | 4 + gcc/rust/backend/rust-compile-block.h | 112 ++++++++++++++++++++++ gcc/rust/backend/rust-compile-expr.h | 26 +++++ gcc/rust/backend/rust-compile-stmt.h | 12 +++ gcc/rust/backend/rust-compile.cc | 109 +++++++++++++++++++++ gcc/rust/hir/rust-ast-lower-block.h | 132 ++++++++++++++++++++++++++ gcc/rust/hir/rust-ast-lower-expr.h | 105 ++++++++++++++++++-- gcc/rust/hir/rust-ast-lower-item.h | 30 +----- gcc/rust/hir/rust-ast-lower-stmt.h | 19 ++++ gcc/rust/hir/rust-ast-lower.cc | 91 ++++++++++++++++++ gcc/rust/hir/tree/rust-hir-expr.h | 6 ++ gcc/rust/hir/tree/rust-hir-stmt.h | 6 +- gcc/rust/resolve/rust-ast-resolve-expr.h | 34 +++++++ gcc/rust/resolve/rust-ast-resolve-stmt.h | 5 + gcc/rust/resolve/rust-ast-resolve.cc | 25 ++++- gcc/rust/typecheck/rust-hir-type-check-expr.h | 40 ++++++++ gcc/rust/typecheck/rust-hir-type-check-stmt.h | 5 + gcc/rust/typecheck/rust-hir-type-check.cc | 11 +++ gcc/rust/util/rust-hir-map.cc | 2 - 19 files changed, 733 insertions(+), 41 deletions(-) create mode 100644 gcc/rust/backend/rust-compile-block.h create mode 100644 gcc/rust/hir/rust-ast-lower-block.h (limited to 'gcc') diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index de011c1..8e60557 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -550,6 +550,8 @@ public: return right_expr; } + ExprType get_kind () { return expr_type; } + /* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2) * maybe? */ protected: @@ -628,6 +630,8 @@ public: return right_expr; } + ExprType get_kind () { return expr_type; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h new file mode 100644 index 0000000..b17fb05 --- /dev/null +++ b/gcc/rust/backend/rust-compile-block.h @@ -0,0 +1,112 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +#ifndef RUST_COMPILE_BLOCK +#define RUST_COMPILE_BLOCK + +#include "rust-compile-base.h" +#include "rust-compile-tyty.h" + +namespace Rust { +namespace Compile { + +class CompileBlock : public HIRCompileBase +{ +public: + static Bblock *compile (HIR::BlockExpr *expr, Context *ctx) + { + CompileBlock compiler (ctx); + expr->accept_vis (compiler); + return compiler.translated; + } + + ~CompileBlock () {} + + void visit (HIR::BlockExpr &expr); + +private: + CompileBlock (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} + + Bblock *translated; +}; + +class CompileConditionalBlocks : public HIRCompileBase +{ +public: + static Bstatement *compile (HIR::IfExpr *expr, Context *ctx) + { + CompileConditionalBlocks resolver (ctx); + expr->accept_vis (resolver); + return resolver.translated; + } + + ~CompileConditionalBlocks () {} + + void visit (HIR::IfExpr &expr); + + void visit (HIR::IfExprConseqElse &expr); + + void visit (HIR::IfExprConseqIf &expr); + +private: + CompileConditionalBlocks (Context *ctx) + : HIRCompileBase (ctx), translated (nullptr) + {} + + Bstatement *translated; +}; + +class CompileExprWithBlock : public HIRCompileBase +{ +public: + static Bstatement *compile (HIR::ExprWithBlock *expr, Context *ctx) + { + CompileExprWithBlock resolver (ctx); + expr->accept_vis (resolver); + return resolver.translated; + } + + ~CompileExprWithBlock () {} + + void visit (HIR::IfExpr &expr) + { + translated = CompileConditionalBlocks::compile (&expr, ctx); + } + + void visit (HIR::IfExprConseqElse &expr) + { + translated = CompileConditionalBlocks::compile (&expr, ctx); + } + + void visit (HIR::IfExprConseqIf &expr) + { + translated = CompileConditionalBlocks::compile (&expr, ctx); + } + +private: + CompileExprWithBlock (Context *ctx) + : HIRCompileBase (ctx), translated (nullptr) + {} + + Bstatement *translated; +}; + +} // namespace Compile +} // namespace Rust + +#endif // RUST_COMPILE_BLOCK diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 7808af2..854fe5e 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -22,6 +22,7 @@ #include "rust-compile-base.h" #include "rust-compile-tyty.h" #include "rust-compile-resolve-path.h" +#include "rust-compile-block.h" namespace Rust { namespace Compile { @@ -273,6 +274,31 @@ public: expr.get_locus ()); } + void visit (HIR::IfExpr &expr) + { + auto stmt = CompileConditionalBlocks::compile (&expr, ctx); + ctx->add_statement (stmt); + } + + void visit (HIR::IfExprConseqElse &expr) + { + auto stmt = CompileConditionalBlocks::compile (&expr, ctx); + ctx->add_statement (stmt); + } + + void visit (HIR::IfExprConseqIf &expr) + { + auto stmt = CompileConditionalBlocks::compile (&expr, ctx); + ctx->add_statement (stmt); + } + + void visit (HIR::BlockExpr &expr) + { + auto code_block = CompileBlock::compile (&expr, ctx); + auto block_stmt = ctx->get_backend ()->block_statement (code_block); + ctx->add_statement (block_stmt); + } + private: CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h index 0a08130..5f7decb 100644 --- a/gcc/rust/backend/rust-compile-stmt.h +++ b/gcc/rust/backend/rust-compile-stmt.h @@ -38,6 +38,18 @@ public: virtual ~CompileStmt () {} + void visit (HIR::ExprStmtWithBlock &stmt) + { + ok = true; + auto translated = CompileExpr::Compile (stmt.get_expr (), ctx); + + // these can be null + if (translated == nullptr) + return; + + gcc_unreachable (); + } + void visit (HIR::ExprStmtWithoutBlock &stmt) { ok = true; diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 11c380b..02fa3a0 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -18,6 +18,7 @@ #include "rust-compile.h" #include "rust-compile-item.h" +#include "rust-compile-expr.h" namespace Rust { namespace Compile { @@ -43,5 +44,113 @@ CompileCrate::go () CompileItem::compile (it->get (), ctx); } +// rust-compile-block.h + +void +CompileBlock::visit (HIR::BlockExpr &expr) +{ + fncontext fnctx = ctx->peek_fn (); + Bfunction *fndecl = fnctx.fndecl; + Location start_location = expr.get_locus (); + Location end_location = expr.get_closing_locus (); + auto body_mappings = expr.get_mappings (); + + Resolver::Rib *rib = nullptr; + if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (), &rib)) + { + rust_fatal_error (expr.get_locus (), "failed to setup locals per block"); + return; + } + + std::vector locals; + rib->iterate_decls ([&] (NodeId n) mutable -> bool { + Resolver::Definition d; + bool ok = ctx->get_resolver ()->lookup_definition (n, &d); + rust_assert (ok); + + HIR::Stmt *decl = nullptr; + ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl); + rust_assert (ok); + + Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx); + locals.push_back (compiled); + + return true; + }); + + Bblock *enclosing_scope = ctx->peek_enclosing_scope (); + Bblock *new_block + = ctx->get_backend ()->block (fndecl, enclosing_scope, locals, + start_location, end_location); + ctx->push_block (new_block); + + expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool { + CompileStmt::Compile (s, ctx); + return true; + }); + + ctx->pop_block (); + translated = new_block; +} + +void +CompileConditionalBlocks::visit (HIR::IfExpr &expr) +{ + fncontext fnctx = ctx->peek_fn (); + Bfunction *fndecl = fnctx.fndecl; + Bexpression *condition_expr + = CompileExpr::Compile (expr.get_if_condition (), ctx); + Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx); + + translated + = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block, + NULL, expr.get_locus ()); +} + +void +CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr) +{ + fncontext fnctx = ctx->peek_fn (); + Bfunction *fndecl = fnctx.fndecl; + Bexpression *condition_expr + = CompileExpr::Compile (expr.get_if_condition (), ctx); + Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx); + Bblock *else_block = CompileBlock::compile (expr.get_else_block (), ctx); + + translated + = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block, + else_block, expr.get_locus ()); +} + +void +CompileConditionalBlocks::visit (HIR::IfExprConseqIf &expr) +{ + fncontext fnctx = ctx->peek_fn (); + Bfunction *fndecl = fnctx.fndecl; + Bexpression *condition_expr + = CompileExpr::Compile (expr.get_if_condition (), ctx); + Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx); + + // else block + std::vector locals; + Location start_location = expr.get_conseq_if_expr ()->get_locus (); + Location end_location = expr.get_conseq_if_expr ()->get_locus (); // FIXME + Bblock *enclosing_scope = ctx->peek_enclosing_scope (); + Bblock *else_block + = ctx->get_backend ()->block (fndecl, enclosing_scope, locals, + start_location, end_location); + ctx->push_block (else_block); + + Bstatement *else_stmt_decl + = CompileConditionalBlocks::compile (expr.get_conseq_if_expr (), ctx); + ctx->add_statement (else_stmt_decl); + + ctx->pop_block (); + + translated + = ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block, + else_block, expr.get_locus ()); +} + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h new file mode 100644 index 0000000..11f1ab8 --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-block.h @@ -0,0 +1,132 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +#ifndef RUST_AST_LOWER_BLOCK +#define RUST_AST_LOWER_BLOCK + +#include "rust-diagnostics.h" +#include "rust-ast-lower-base.h" + +namespace Rust { +namespace HIR { + +class ASTLoweringBlock : public ASTLoweringBase +{ +public: + static HIR::BlockExpr *translate (AST::BlockExpr *expr) + { + ASTLoweringBlock resolver; + expr->accept_vis (resolver); + if (resolver.translated != nullptr) + { + resolver.mappings->insert_hir_expr ( + resolver.translated->get_mappings ().get_crate_num (), + resolver.translated->get_mappings ().get_hirid (), + resolver.translated); + } + + return resolver.translated; + } + + ~ASTLoweringBlock () {} + + void visit (AST::BlockExpr &expr); + +private: + ASTLoweringBlock () : ASTLoweringBase (), translated (nullptr) {} + + HIR::BlockExpr *translated; +}; + +class ASTLoweringIfBlock : public ASTLoweringBase +{ +public: + static HIR::IfExpr *translate (AST::IfExpr *expr) + { + ASTLoweringIfBlock resolver; + expr->accept_vis (resolver); + if (resolver.translated != nullptr) + { + resolver.mappings->insert_hir_expr ( + resolver.translated->get_mappings ().get_crate_num (), + resolver.translated->get_mappings ().get_hirid (), + resolver.translated); + } + + return resolver.translated; + } + + ~ASTLoweringIfBlock () {} + + void visit (AST::IfExpr &expr); + + void visit (AST::IfExprConseqElse &expr); + + void visit (AST::IfExprConseqIf &expr); + +private: + ASTLoweringIfBlock () : ASTLoweringBase (), translated (nullptr) {} + + HIR::IfExpr *translated; +}; + +class ASTLoweringExprWithBlock : public ASTLoweringBase +{ +public: + static HIR::ExprWithBlock *translate (AST::ExprWithBlock *expr) + { + ASTLoweringExprWithBlock resolver; + expr->accept_vis (resolver); + if (resolver.translated != nullptr) + { + resolver.mappings->insert_hir_expr ( + resolver.translated->get_mappings ().get_crate_num (), + resolver.translated->get_mappings ().get_hirid (), + resolver.translated); + } + + return resolver.translated; + } + + ~ASTLoweringExprWithBlock () {} + + void visit (AST::IfExpr &expr) + { + translated = ASTLoweringIfBlock::translate (&expr); + } + + void visit (AST::IfExprConseqElse &expr) + { + translated = ASTLoweringIfBlock::translate (&expr); + } + + void visit (AST::IfExprConseqIf &expr) + { + translated = ASTLoweringIfBlock::translate (&expr); + } + +private: + ASTLoweringExprWithBlock () : ASTLoweringBase (), translated (nullptr) {} + + HIR::ExprWithBlock *translated; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_AST_LOWER_BLOCK diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 50e67a8..19d599a 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -20,8 +20,8 @@ #define RUST_AST_LOWER_EXPR #include "rust-diagnostics.h" - #include "rust-ast-lower-base.h" +#include "rust-ast-lower-block.h" namespace Rust { namespace HIR { @@ -33,19 +33,42 @@ public: { ASTLoweringExpr resolver; expr->accept_vis (resolver); - if (resolver.translated != nullptr) + if (resolver.translated == nullptr) { - resolver.mappings->insert_hir_expr ( - resolver.translated->get_mappings ().get_crate_num (), - resolver.translated->get_mappings ().get_hirid (), - resolver.translated); + rust_fatal_error (expr->get_locus_slow (), "Failed to lower expr: [%s]", + expr->as_string ().c_str ()); + return nullptr; } + resolver.mappings->insert_hir_expr ( + resolver.translated->get_mappings ().get_crate_num (), + resolver.translated->get_mappings ().get_hirid (), resolver.translated); + return resolver.translated; } virtual ~ASTLoweringExpr () {} + void visit (AST::IfExpr &expr) + { + translated = ASTLoweringIfBlock::translate (&expr); + } + + void visit (AST::IfExprConseqElse &expr) + { + translated = ASTLoweringIfBlock::translate (&expr); + } + + void visit (AST::IfExprConseqIf &expr) + { + translated = ASTLoweringIfBlock::translate (&expr); + } + + void visit (AST::BlockExpr &expr) + { + translated = ASTLoweringBlock::translate (&expr); + } + void visit (AST::PathInExpression &expr) { std::vector path_segments; @@ -230,6 +253,76 @@ public: kind, expr.get_locus ()); } + void visit (AST::ComparisonExpr &expr) + { + HIR::ComparisonExpr::ExprType kind; + switch (expr.get_kind ()) + { + case AST::ComparisonExpr::ExprType::EQUAL: + kind = HIR::ComparisonExpr::ExprType::EQUAL; + break; + case AST::ComparisonExpr::ExprType::NOT_EQUAL: + kind = HIR::ComparisonExpr::ExprType::NOT_EQUAL; + break; + case AST::ComparisonExpr::ExprType::GREATER_THAN: + kind = HIR::ComparisonExpr::ExprType::GREATER_THAN; + break; + case AST::ComparisonExpr::ExprType::LESS_THAN: + kind = HIR::ComparisonExpr::ExprType::LESS_THAN; + break; + case AST::ComparisonExpr::ExprType::GREATER_OR_EQUAL: + kind = HIR::ComparisonExpr::ExprType::GREATER_OR_EQUAL; + break; + case AST::ComparisonExpr::ExprType::LESS_OR_EQUAL: + kind = HIR::ComparisonExpr::ExprType::LESS_OR_EQUAL; + break; + } + + HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ()); + rust_assert (lhs != nullptr); + HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ()); + rust_assert (rhs != nullptr); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::ComparisonExpr (mapping, std::unique_ptr (lhs), + std::unique_ptr (rhs), kind, + expr.get_locus ()); + } + + void visit (AST::LazyBooleanExpr &expr) + { + HIR::LazyBooleanExpr::ExprType kind; + switch (expr.get_kind ()) + { + case AST::LazyBooleanExpr::ExprType::LOGICAL_AND: + kind = HIR::LazyBooleanExpr::ExprType::LOGICAL_AND; + break; + case AST::LazyBooleanExpr::ExprType::LOGICAL_OR: + kind = HIR::LazyBooleanExpr::ExprType::LOGICAL_OR; + break; + } + + HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ()); + rust_assert (lhs != nullptr); + HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ()); + rust_assert (rhs != nullptr); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::LazyBooleanExpr (mapping, std::unique_ptr (lhs), + std::unique_ptr (rhs), kind, + expr.get_locus ()); + } + private: ASTLoweringExpr () : translated (nullptr) {} diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h index e6c86b8..f57ac86 100644 --- a/gcc/rust/hir/rust-ast-lower-item.h +++ b/gcc/rust/hir/rust-ast-lower-item.h @@ -25,6 +25,7 @@ #include "rust-ast-lower-type.h" #include "rust-ast-lower-stmt.h" #include "rust-ast-lower-pattern.h" +#include "rust-ast-lower-block.h" namespace Rust { namespace HIR { @@ -83,7 +84,7 @@ public: std::unique_ptr function_body = std::unique_ptr ( - translate (function.get_definition ().get ())); + ASTLoweringBlock::translate (function.get_definition ().get ())); auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, function.get_node_id (), @@ -116,33 +117,6 @@ public: translated = fn; } - // Helpers - - HIR::BlockExpr *translate (AST::BlockExpr *function_body) - { - std::vector > block_stmts; - std::unique_ptr block_expr; - std::vector inner_attribs; - std::vector outer_attribs; - - function_body->iterate_stmts ([&] (AST::Stmt *s) mutable -> bool { - auto translated_stmt = ASTLoweringStmt::translate (s); - block_stmts.push_back (std::unique_ptr (translated_stmt)); - return true; - }); - - auto crate_num = mappings->get_current_crate (); - Analysis::NodeMapping mapping (crate_num, function_body->get_node_id (), - mappings->get_next_hir_id (crate_num), - UNKNOWN_LOCAL_DEFID); - - return new HIR::BlockExpr (mapping, std::move (block_stmts), - std::move (block_expr), - std::move (inner_attribs), - std::move (outer_attribs), - function_body->get_locus ()); - } - private: ASTLoweringItem () : translated (nullptr) {} diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h index c57d14f..f4ecd8e 100644 --- a/gcc/rust/hir/rust-ast-lower-stmt.h +++ b/gcc/rust/hir/rust-ast-lower-stmt.h @@ -23,6 +23,7 @@ #include "rust-ast-lower-base.h" #include "rust-ast-lower-type.h" +#include "rust-ast-lower-block.h" #include "rust-ast-lower-expr.h" #include "rust-ast-lower-pattern.h" @@ -46,6 +47,24 @@ public: virtual ~ASTLoweringStmt () {} + void visit (AST::ExprStmtWithBlock &stmt) + { + HIR::ExprWithBlock *expr + = ASTLoweringExprWithBlock::translate (stmt.get_expr ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + translated + = new HIR::ExprStmtWithBlock (mapping, + std::unique_ptr (expr), + stmt.get_locus ()); + mappings->insert_location (crate_num, mapping.get_hirid (), + stmt.get_locus ()); + mappings->insert_hir_stmt (crate_num, mapping.get_hirid (), translated); + } + void visit (AST::ExprStmtWithoutBlock &stmt) { HIR::Expr *expr = ASTLoweringExpr::translate (stmt.get_expr ().get ()); diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index 8a514ce..93288c3 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -18,6 +18,8 @@ #include "rust-ast-lower.h" #include "rust-ast-lower-item.h" +#include "rust-ast-lower-expr.h" +#include "rust-ast-lower-block.h" namespace Rust { namespace HIR { @@ -58,5 +60,94 @@ ASTLowering::go () has_utf8bom, has_shebang); } +// rust-ast-lower-block.h +void +ASTLoweringBlock::visit (AST::BlockExpr &expr) +{ + std::vector > block_stmts; + std::unique_ptr block_expr; + std::vector inner_attribs; + std::vector outer_attribs; + + expr.iterate_stmts ([&] (AST::Stmt *s) mutable -> bool { + auto translated_stmt = ASTLoweringStmt::translate (s); + block_stmts.push_back (std::unique_ptr (translated_stmt)); + return true; + }); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::BlockExpr (mapping, std::move (block_stmts), + std::move (block_expr), std::move (inner_attribs), + std::move (outer_attribs), expr.get_locus ()); +} + +void +ASTLoweringIfBlock::visit (AST::IfExpr &expr) +{ + HIR::Expr *condition + = ASTLoweringExpr::translate (expr.get_condition_expr ().get ()); + HIR::BlockExpr *block + = ASTLoweringBlock::translate (expr.get_if_block ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::IfExpr (mapping, std::unique_ptr (condition), + std::unique_ptr (block), + expr.get_locus ()); +} + +void +ASTLoweringIfBlock::visit (AST::IfExprConseqElse &expr) +{ + HIR::Expr *condition + = ASTLoweringExpr::translate (expr.get_condition_expr ().get ()); + HIR::BlockExpr *if_block + = ASTLoweringBlock::translate (expr.get_if_block ().get ()); + HIR::BlockExpr *else_block + = ASTLoweringBlock::translate (expr.get_else_block ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::IfExprConseqElse (mapping, + std::unique_ptr (condition), + std::unique_ptr (if_block), + std::unique_ptr (else_block), + expr.get_locus ()); +} + +void +ASTLoweringIfBlock::visit (AST::IfExprConseqIf &expr) +{ + HIR::Expr *condition + = ASTLoweringExpr::translate (expr.get_condition_expr ().get ()); + HIR::BlockExpr *block + = ASTLoweringBlock::translate (expr.get_if_block ().get ()); + HIR::IfExpr *conseq_if_expr + = ASTLoweringIfBlock::translate (expr.get_conseq_if_expr ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::IfExprConseqIf (mapping, std::unique_ptr (condition), + std::unique_ptr (block), + std::unique_ptr (conseq_if_expr), + expr.get_locus ()); +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 36c2085..7e1c76b 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -538,6 +538,8 @@ public: Expr *get_lhs () { return main_or_left_expr.get (); } Expr *get_rhs () { return right_expr.get (); } + ExprType get_kind () { return expr_type; } + /* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2) * maybe? */ protected: @@ -3647,6 +3649,8 @@ public: void vis_else_block (HIRVisitor &vis) { else_block->accept_vis (vis); } + BlockExpr *get_else_block () { return else_block.get (); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3715,6 +3719,8 @@ public: conseq_if_expr->accept_vis (vis); } + IfExpr *get_conseq_if_expr () { return conseq_if_expr.get (); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h index 9a0e0f2..be4ff7d 100644 --- a/gcc/rust/hir/tree/rust-hir-stmt.h +++ b/gcc/rust/hir/tree/rust-hir-stmt.h @@ -192,13 +192,11 @@ protected: // Statement containing an expression with a block class ExprStmtWithBlock : public ExprStmt { -public: std::unique_ptr expr; +public: std::string as_string () const override; - std::vector locals; - ExprStmtWithBlock (Analysis::NodeMapping mappings, std::unique_ptr expr, Location locus) : ExprStmt (std::move (mappings), locus), expr (std::move (expr)) @@ -224,6 +222,8 @@ public: void accept_vis (HIRVisitor &vis) override; + ExprWithBlock *get_expr () { return expr.get (); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 9e98fda..3316b2a 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -95,6 +95,40 @@ public: ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); } + void visit (AST::ComparisonExpr &expr) + { + ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); + } + + void visit (AST::LazyBooleanExpr &expr) + { + ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); + } + + void visit (AST::IfExpr &expr) + { + ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ()); + } + + void visit (AST::IfExprConseqElse &expr) + { + ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_else_block ().get (), expr.get_node_id ()); + } + + void visit (AST::IfExprConseqIf &expr) + { + ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_conseq_if_expr ().get (), expr.get_node_id ()); + } + + void visit (AST::BlockExpr &expr); + private: ResolveExpr (NodeId parent) : ResolverBase (parent) {} }; diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index 20d40f1..87b3cf3 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -39,6 +39,11 @@ public: ~ResolveStmt () {} + void visit (AST::ExprStmtWithBlock &stmt) + { + ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ()); + } + void visit (AST::ExprStmtWithoutBlock &stmt) { ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ()); diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index ba4ee21..8370a5b 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -17,10 +17,11 @@ // . #include "rust-ast-resolve.h" -#include "rust-ast-resolve-toplevel.h" -#include "rust-ast-resolve-item.h" #include "rust-ast-full.h" #include "rust-tyty.h" +#include "rust-ast-resolve-toplevel.h" +#include "rust-ast-resolve-item.h" +#include "rust-ast-resolve-expr.h" #define MKBUILTIN_TYPE(_X, _R, _TY) \ do \ @@ -250,5 +251,25 @@ NameResolution::go (AST::Crate &crate) ResolveItem::go (it->get ()); } +// rust-ast-resolve-expr.h + +void +ResolveExpr::visit (AST::BlockExpr &expr) +{ + NodeId scope_node_id = expr.get_node_id (); + resolver->get_name_scope ().push (scope_node_id); + resolver->get_type_scope ().push (scope_node_id); + resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); + resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); + + expr.iterate_stmts ([&] (AST::Stmt *s) mutable -> bool { + ResolveStmt::go (s, s->get_node_id ()); + return true; + }); + + resolver->get_name_scope ().pop (); + resolver->get_type_scope ().pop (); +} + } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index c9a0fde..8be2dbf 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -179,6 +179,46 @@ public: infered = lhs->combine (rhs); } + void visit (HIR::ComparisonExpr &expr) + { + auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ()); + auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ()); + + infered = lhs->combine (rhs); + // FIXME this will need to turn into bool + } + + void visit (HIR::LazyBooleanExpr &expr) + { + auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ()); + auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ()); + + infered = lhs->combine (rhs); + // FIXME this will need to turn into bool + } + + void visit (HIR::IfExpr &expr) + { + TypeCheckExpr::Resolve (expr.get_if_condition ()); + TypeCheckExpr::Resolve (expr.get_if_block ()); + } + + void visit (HIR::IfExprConseqElse &expr) + { + TypeCheckExpr::Resolve (expr.get_if_condition ()); + TypeCheckExpr::Resolve (expr.get_if_block ()); + TypeCheckExpr::Resolve (expr.get_else_block ()); + } + + void visit (HIR::IfExprConseqIf &expr) + { + TypeCheckExpr::Resolve (expr.get_if_condition ()); + TypeCheckExpr::Resolve (expr.get_if_block ()); + TypeCheckExpr::Resolve (expr.get_conseq_if_expr ()); + } + + void visit (HIR::BlockExpr &expr); + private: TypeCheckExpr () : TypeCheckBase (), infered (nullptr) {} diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h index ccf1138..d3189cc 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h @@ -36,6 +36,11 @@ public: stmt->accept_vis (resolver); } + void visit (HIR::ExprStmtWithBlock &stmt) + { + TypeCheckExpr::Resolve (stmt.get_expr ()); + } + void visit (HIR::ExprStmtWithoutBlock &stmt) { TypeCheckExpr::Resolve (stmt.get_expr ()); diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index f9dbe49..79e0190 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -20,6 +20,7 @@ #include "rust-hir-full.h" #include "rust-hir-type-check-toplevel.h" #include "rust-hir-type-check-item.h" +#include "rust-hir-type-check-expr.h" namespace Rust { namespace Resolver { @@ -34,5 +35,15 @@ TypeResolution::Resolve (HIR::Crate &crate) TypeCheckItem::Resolve (it->get ()); } +// RUST_HIR_TYPE_CHECK_EXPR +void +TypeCheckExpr::visit (HIR::BlockExpr &expr) +{ + expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool { + TypeCheckStmt::Resolve (s); + return true; + }); +} + } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index bdf487e..238689c 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -260,8 +260,6 @@ Mappings::lookup_hir_item (CrateNum crateNum, HirId id) void Mappings::insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr) { - rust_assert (lookup_hir_expr (crateNum, id) == nullptr); - hirExprMappings[crateNum][id] = expr; nodeIdToHirMappings[crateNum][expr->get_mappings ().get_nodeid ()] = id; insert_location (crateNum, id, expr->get_locus_slow ()); -- cgit v1.1 From f701ad5352c7bc8dad53a1ee7f666c8365b35307 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Sun, 20 Dec 2020 23:58:33 +0000 Subject: This brings arrays back into the new framework. It resolves ArrayType ArrayExpr, ArrayExprElems and ArrayIndexExpr. Still need to do ArrayElemsCopied. I expect there to be some changes to cleanup the rust-tyty-resolver this code is to resolve all ribs within a scope but its getting a bit hairy in there now. --- gcc/rust/ast/rust-expr.h | 17 +++---- gcc/rust/backend/rust-compile-context.h | 16 ++++-- gcc/rust/backend/rust-compile-expr.h | 43 ++++++++++++++++ gcc/rust/hir/rust-ast-lower-expr.h | 60 ++++++++++++++++++++++- gcc/rust/hir/rust-ast-lower-type.h | 22 +++++++++ gcc/rust/hir/tree/rust-hir-expr.h | 13 ++--- gcc/rust/resolve/rust-ast-resolve-expr.h | 25 ++++++++++ gcc/rust/resolve/rust-ast-resolve-type.h | 7 ++- gcc/rust/rust-backend.h | 2 + gcc/rust/typecheck/rust-hir-type-check-expr.h | 56 ++++++++++++++++++++- gcc/rust/typecheck/rust-hir-type-check-stmt.h | 11 ++++- gcc/rust/typecheck/rust-hir-type-check-type.h | 53 +++++++++++++++++++- gcc/rust/typecheck/rust-tyty-resolver.h | 50 +++++++++++++++++-- gcc/rust/typecheck/rust-tyty-rules.h | 46 +++++++++++++++++ gcc/rust/typecheck/rust-tyty-visitor.h | 1 + gcc/rust/typecheck/rust-tyty.cc | 19 +++++++ gcc/rust/typecheck/rust-tyty.h | 22 +++++++++ gcc/testsuite/rust.test/compilable/type_infer4.rs | 9 ++++ 18 files changed, 442 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/rust.test/compilable/type_infer4.rs (limited to 'gcc') diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 8e60557..cc87498 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -952,9 +952,15 @@ public: virtual void accept_vis (ASTVisitor &vis) = 0; + NodeId get_node_id () const { return node_id; } + protected: + ArrayElems () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {} + // pure virtual clone implementation virtual ArrayElems *clone_array_elems_impl () const = 0; + + NodeId node_id; }; // Value array elements @@ -966,7 +972,7 @@ class ArrayElemsValues : public ArrayElems public: ArrayElemsValues (std::vector > elems) - : values (std::move (elems)) + : ArrayElems (), values (std::move (elems)) {} // copy constructor with vector clone @@ -1032,7 +1038,7 @@ public: // Constructor requires pointers for polymorphism ArrayElemsCopied (std::unique_ptr copied_elem, std::unique_ptr copy_amount) - : elem_to_copy (std::move (copied_elem)), + : ArrayElems (), elem_to_copy (std::move (copied_elem)), num_copies (std::move (copy_amount)) {} @@ -1091,10 +1097,6 @@ class ArrayExpr : public ExprWithoutBlock // TODO: find another way to store this to save memory? bool marked_for_strip = false; - // this is a reference to what the inferred type is based on - // this init expression - Type *inferredType; - public: std::string as_string () const override; @@ -1159,9 +1161,6 @@ public: return internal_elements; } - Type *get_inferred_type () { return inferredType; } - void set_inferred_type (Type *type) { inferredType = type; } - protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 1924b52..5736bf2 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -211,6 +211,19 @@ public: void visit (TyTy::FnType &type) override { gcc_unreachable (); } + void visit (TyTy::ArrayType &type) override + { + mpz_t ival; + mpz_init_set_ui (ival, type.get_capacity ()); + + Btype *capacity_type = ctx->get_backend ()->integer_type (true, 32); + Bexpression *length + = ctx->get_backend ()->integer_constant_expression (capacity_type, ival); + + Btype *element_type = TyTyResolveCompile::compile (ctx, type.get_type ()); + translated = ctx->get_backend ()->array_type (element_type, length); + } + void visit (TyTy::BoolType &type) override { ::Btype *compiled_type = nullptr; @@ -221,9 +234,6 @@ public: void visit (TyTy::IntType &type) override { - printf ("type [%s] has ref: %u\n", type.as_string ().c_str (), - type.get_ref ()); - ::Btype *compiled_type = nullptr; bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); rust_assert (ok); diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 854fe5e..6ea97ee 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -169,6 +169,48 @@ public: ctx->add_statement (assignment); } + void visit (HIR::ArrayIndexExpr &expr) + { + Bexpression *array = CompileExpr::Compile (expr.get_array_expr (), ctx); + Bexpression *index = CompileExpr::Compile (expr.get_index_expr (), ctx); + translated + = ctx->get_backend ()->array_index_expression (array, index, + expr.get_locus ()); + } + + void visit (HIR::ArrayExpr &expr) + { + TyTy::TyBase *tyty = nullptr; + if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), + &tyty)) + { + rust_fatal_error (expr.get_locus (), + "did not resolve type for this array expr"); + return; + } + + Btype *array_type = TyTyResolveCompile::compile (ctx, tyty); + + expr.get_internal_elements ()->accept_vis (*this); + std::vector indexes; + for (size_t i = 0; i < constructor.size (); i++) + indexes.push_back (i); + + translated + = ctx->get_backend ()->array_constructor_expression (array_type, indexes, + constructor, + expr.get_locus ()); + } + + void visit (HIR::ArrayElemsValues &elems) + { + elems.iterate ([&] (HIR::Expr *e) mutable -> bool { + Bexpression *translated_expr = CompileExpr::Compile (e, ctx); + constructor.push_back (translated_expr); + return true; + }); + } + void visit (HIR::ArithmeticOrLogicalExpr &expr) { Operator op; @@ -303,6 +345,7 @@ private: CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} Bexpression *translated; + std::vector constructor; }; } // namespace Compile diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 19d599a..b919905 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -156,6 +156,63 @@ public: = new HIR::IdentifierExpr (mapping, expr.as_string (), expr.get_locus ()); } + void visit (AST::ArrayExpr &expr) + { + std::vector outer_attribs; + std::vector inner_attribs; + + expr.get_array_elems ()->accept_vis (*this); + rust_assert (translated_array_elems != nullptr); + HIR::ArrayElems *elems = translated_array_elems; + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::ArrayExpr (mapping, std::unique_ptr (elems), + inner_attribs, outer_attribs, expr.get_locus ()); + } + + void visit (AST::ArrayIndexExpr &expr) + { + std::vector outer_attribs; + HIR::Expr *array_expr + = ASTLoweringExpr::translate (expr.get_array_expr ().get ()); + HIR::Expr *array_index_expr + = ASTLoweringExpr::translate (expr.get_index_expr ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::ArrayIndexExpr (mapping, + std::unique_ptr (array_expr), + std::unique_ptr (array_index_expr), + outer_attribs, expr.get_locus ()); + } + + void visit (AST::ArrayElemsValues &elems) + { + std::vector > elements; + elems.iterate ([&] (AST::Expr *elem) mutable -> bool { + HIR::Expr *translated_elem = ASTLoweringExpr::translate (elem); + elements.push_back (std::unique_ptr (translated_elem)); + return true; + }); + + translated_array_elems = new HIR::ArrayElemsValues (std::move (elements)); + } + + void visit (AST::ArrayElemsCopied &elems) + { + // TODO + gcc_unreachable (); + } + void visit (AST::LiteralExpr &expr) { HIR::Literal::LitType type = HIR::Literal::LitType::CHAR; @@ -324,9 +381,10 @@ public: } private: - ASTLoweringExpr () : translated (nullptr) {} + ASTLoweringExpr () : translated (nullptr), translated_array_elems (nullptr) {} HIR::Expr *translated; + HIR::ArrayElems *translated_array_elems; }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h index 4193415..2e14ad2 100644 --- a/gcc/rust/hir/rust-ast-lower-type.h +++ b/gcc/rust/hir/rust-ast-lower-type.h @@ -21,6 +21,7 @@ #include "rust-ast-lower-base.h" #include "rust-diagnostics.h" +#include "rust-ast-lower-expr.h" namespace Rust { namespace HIR { @@ -77,6 +78,27 @@ public: translated); } + void visit (AST::ArrayType &type) + { + HIR::Type *translated_type + = ASTLoweringType::translate (type.get_elem_type ().get ()); + HIR::Expr *array_size + = ASTLoweringExpr::translate (type.get_size_expr ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, type.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + translated + = new HIR::ArrayType (mapping, + std::unique_ptr (translated_type), + std::unique_ptr (array_size), + type.get_locus ()); + mappings->insert_hir_type (mapping.get_crate_num (), mapping.get_hirid (), + translated); + } + private: ASTLoweringType () : translated (nullptr) {} diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 7e1c76b..7c32ac2 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -912,6 +912,8 @@ public: virtual void accept_vis (HIRVisitor &vis) = 0; + virtual size_t get_num_elements () const = 0; + protected: // pure virtual clone implementation virtual ArrayElems *clone_array_elems_impl () const = 0; @@ -955,7 +957,7 @@ public: void accept_vis (HIRVisitor &vis) override; - size_t get_num_values () const { return values.size (); } + size_t get_num_elements () const override { return values.size (); } void iterate (std::function cb) { @@ -1012,6 +1014,8 @@ public: void accept_vis (HIRVisitor &vis) override; + size_t get_num_elements () const override { return 0; } + protected: ArrayElemsCopied *clone_array_elems_impl () const override { @@ -1027,10 +1031,6 @@ class ArrayExpr : public ExprWithoutBlock Location locus; - // this is a reference to what the inferred type is based on - // this init expression - Type *inferredType; - public: std::string as_string () const override; @@ -1082,9 +1082,6 @@ public: ArrayElems *get_internal_elements () { return internal_elements.get (); }; - Type *get_inferred_type () { return inferredType; } - void set_inferred_type (Type *type) { inferredType = type; } - protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 3316b2a..54d33a8 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -129,6 +129,31 @@ public: void visit (AST::BlockExpr &expr); + void visit (AST::ArrayElemsValues &elems) + { + elems.iterate ([&] (AST::Expr *elem) mutable -> bool { + ResolveExpr::go (elem, elems.get_node_id ()); + return true; + }); + } + + void visit (AST::ArrayExpr &expr) + { + expr.get_array_elems ()->accept_vis (*this); + } + + void visit (AST::ArrayIndexExpr &expr) + { + ResolveExpr::go (expr.get_array_expr ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_index_expr ().get (), expr.get_node_id ()); + } + + void visit (AST::ArrayElemsCopied &elems) + { + // TODO + gcc_unreachable (); + } + private: ResolveExpr (NodeId parent) : ResolverBase (parent) {} }; diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 3cffa77..9d408a9 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -42,7 +42,7 @@ public: ~ResolveType () {} - virtual void visit (AST::TypePath &path) + void visit (AST::TypePath &path) { // this will need changed to handle mod/crate/use globs and look // at the segments in granularity @@ -56,6 +56,11 @@ public: } } + void visit (AST::ArrayType &type) + { + type.get_elem_type ()->accept_vis (*this); + } + private: ResolveType (NodeId parent) : ResolverBase (parent) {} }; diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h index bc8ca96..210eff3 100644 --- a/gcc/rust/rust-backend.h +++ b/gcc/rust/rust-backend.h @@ -23,6 +23,8 @@ #include #include +#include "rust-location.h" +#include "rust-linemap.h" #include "operator.h" extern bool diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 8be2dbf..999523f 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -23,6 +23,7 @@ #include "rust-hir-full.h" #include "rust-tyty.h" #include "rust-tyty-call.h" +#include "rust-tyty-resolver.h" namespace Rust { namespace Resolver { @@ -219,10 +220,63 @@ public: void visit (HIR::BlockExpr &expr); + void visit (HIR::ArrayIndexExpr &expr) + { + // check the index + TyTy::IntType size_ty (expr.get_index_expr ()->get_mappings ().get_hirid (), + TyTy::IntType::I32); + auto resolved + = size_ty.combine (TypeCheckExpr::Resolve (expr.get_index_expr ())); + context->insert_type (expr.get_index_expr ()->get_mappings ().get_hirid (), + resolved); + + expr.get_array_expr ()->accept_vis (*this); + rust_assert (infered != nullptr); + printf ("Resolved array-index 1 [%u] -> %s\n", + expr.get_mappings ().get_hirid (), infered->as_string ().c_str ()); + // extract the element type out now from the base type + infered = TyTyExtractorArray::ExtractElementTypeFromArray (infered); + + printf ("Resolved array-index 2 [%u] -> %s\n", + expr.get_mappings ().get_hirid (), infered->as_string ().c_str ()); + printf ("array-expr node [%u]\n", + expr.get_array_expr ()->get_mappings ().get_hirid ()); + } + + void visit (HIR::ArrayExpr &expr) + { + HIR::ArrayElems *elements = expr.get_internal_elements (); + size_t num_elems = elements->get_num_elements (); + + elements->accept_vis (*this); + rust_assert (infered_array_elems != nullptr); + + infered = new TyTy::ArrayType (expr.get_mappings ().get_hirid (), num_elems, + infered_array_elems); + } + + void visit (HIR::ArrayElemsValues &elems) + { + std::vector types; + elems.iterate ([&] (HIR::Expr *e) mutable -> bool { + types.push_back (TypeCheckExpr::Resolve (e)); + return true; + }); + + infered_array_elems = types[0]; + for (size_t i = 1; i < types.size (); i++) + { + infered_array_elems = infered_array_elems->combine (types.at (i)); + } + } + private: - TypeCheckExpr () : TypeCheckBase (), infered (nullptr) {} + TypeCheckExpr () + : TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr) + {} TyTy::TyBase *infered; + TyTy::TyBase *infered_array_elems; }; } // namespace Resolver diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h index d3189cc..dbf6583 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h @@ -59,8 +59,15 @@ public: // let x:i32 = 123; if (specified_ty != nullptr && init_expr_ty != nullptr) { - context->insert_type (stmt.get_mappings ().get_hirid (), - specified_ty->combine (init_expr_ty)); + auto combined = specified_ty->combine (init_expr_ty); + if (combined == nullptr) + { + rust_fatal_error (stmt.get_locus (), + "failure in setting up let stmt type"); + return; + } + + context->insert_type (stmt.get_mappings ().get_hirid (), combined); } else { diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index beab77a..21d6c23 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -25,6 +25,42 @@ namespace Rust { namespace Resolver { +class ArrayCapacityConstant : public TypeCheckBase +{ +public: + static bool fold (HIR::Expr *expr, size_t *folded_result) + { + ArrayCapacityConstant folder; + expr->accept_vis (folder); + *folded_result = folder.result; + return folder.ok; + } + + virtual ~ArrayCapacityConstant () {} + + void visit (HIR::LiteralExpr &expr) + { + switch (expr.get_lit_type ()) + { + case HIR::Literal::LitType::INT: { + ok = true; + std::stringstream ss (expr.as_string ()); + ss >> result; + } + break; + + default: + return; + } + } + +private: + ArrayCapacityConstant () : TypeCheckBase (), ok (false), result (-1) {} + + bool ok; + size_t result; +}; // namespace Resolver + class TypeCheckType : public TypeCheckBase { public: @@ -40,7 +76,7 @@ public: return resolver.translated; } - virtual void visit (HIR::TypePath &path) + void visit (HIR::TypePath &path) { // check if this is already defined or not if (context->lookup_type (path.get_mappings ().get_hirid (), &translated)) @@ -70,6 +106,21 @@ public: gcc_unreachable (); } + void visit (HIR::ArrayType &type) + { + size_t capacity; + if (!ArrayCapacityConstant::fold (type.get_size_expr (), &capacity)) + { + rust_error_at (type.get_size_expr ()->get_locus_slow (), + "non-constant value"); + return; + } + + TyTy::TyBase *base = TypeCheckType::Resolve (type.get_element_type ()); + translated + = new TyTy::ArrayType (type.get_mappings ().get_hirid (), capacity, base); + } + private: TypeCheckType () : TypeCheckBase (), translated (nullptr) {} diff --git a/gcc/rust/typecheck/rust-tyty-resolver.h b/gcc/rust/typecheck/rust-tyty-resolver.h index b971e66..2851a1e 100644 --- a/gcc/rust/typecheck/rust-tyty-resolver.h +++ b/gcc/rust/typecheck/rust-tyty-resolver.h @@ -25,6 +25,7 @@ #include "rust-name-resolver.h" #include "rust-hir-type-check.h" #include "rust-hir-full.h" +#include "rust-tyty-visitor.h" namespace Rust { namespace Resolver { @@ -63,9 +64,25 @@ public: TyTy::TyBase *resolved = nullptr; if (!context->lookup_type (hir_node_ref, &resolved)) { - rust_fatal_error (mappings->lookup_location (hir_node_ref), - "failed to lookup type for reference"); - return false; + // this could be an array/adt type + Definition d; + bool ok = resolver->lookup_definition (ref_node, &d); + rust_assert (ok); + + ok = mappings->lookup_node_to_hir (mappings->get_current_crate (), + d.parent, &hir_node_ref); + rust_assert (ok); + + printf ("failed lets try [%u]\n", hir_node_ref); + + if (!context->lookup_type (hir_node_ref, &resolved)) + { + rust_fatal_error ( + mappings->lookup_location (hir_node_ref), + "failed to lookup type for reference at node [%u]", + hir_node_ref); + return false; + } } gathered_types.push_back (resolved); @@ -85,6 +102,11 @@ public: &resolved_type); rust_assert (ok); + if (!resolved_type->is_unit ()) + { + return true; + } + auto resolved_tyty = resolved_type; for (auto it : gathered_types) { @@ -120,8 +142,28 @@ private: TypeCheckContext *context; }; -} // namespace Resolver +class TyTyExtractorArray : public TyTy::TyVisitor +{ +public: + static TyTy::TyBase *ExtractElementTypeFromArray (TyTy::TyBase *base) + { + TyTyExtractorArray e; + base->accept_vis (e); + rust_assert (e.extracted != nullptr); + return e.extracted; + } + + virtual ~TyTyExtractorArray () {} + + void visit (TyTy::ArrayType &type) override { extracted = type.get_type (); } + +private: + TyTyExtractorArray () : extracted (nullptr) {} + + TyTy::TyBase *extracted; +}; +} // namespace Resolver } // namespace Rust #endif // RUST_TYTY_RESOLVER diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index 205ef44..97ee895 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -60,6 +60,13 @@ public: type.as_string ().c_str ()); } + virtual void visit (ArrayType &type) override + { + Location locus = mappings->lookup_location (type.get_ref ()); + rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), + type.as_string ().c_str ()); + } + virtual void visit (BoolType &type) override { Location locus = mappings->lookup_location (type.get_ref ()); @@ -181,6 +188,45 @@ private: TyBase *resolved; }; +class ArrayRules : protected BaseRules +{ +public: + ArrayRules (ArrayType *base) + : BaseRules (base), base (base), resolved (nullptr) + {} + + ~ArrayRules () {} + + TyBase *combine (TyBase *other) + { + other->accept_vis (*this); + return resolved; + } + + void visit (ArrayType &type) override + { + // check base type + auto base_resolved = base->get_type ()->combine (type.get_type ()); + if (base_resolved == nullptr) + return; + + // need to check the base types and capacity + if (type.get_capacity () != base->get_capacity ()) + { + Location locus = mappings->lookup_location (type.get_ref ()); + rust_error_at (locus, "mismatch in array capacity"); + return; + } + + resolved + = new ArrayType (type.get_ref (), type.get_capacity (), base_resolved); + } + +private: + ArrayType *base; + TyBase *resolved; +}; + class BoolRules : protected BaseRules { public: diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index 68a8a43..427190f 100644 --- a/gcc/rust/typecheck/rust-tyty-visitor.h +++ b/gcc/rust/typecheck/rust-tyty-visitor.h @@ -31,6 +31,7 @@ public: virtual void visit (InferType &type) {} virtual void visit (FnType &type) {} virtual void visit (ParamType &type) {} + virtual void visit (ArrayType &type) {} virtual void visit (BoolType &type) {} virtual void visit (IntType &type) {} virtual void visit (UintType &type) {} diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 4a36d4f..2023523 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -110,6 +110,25 @@ ParamType::combine (TyBase *other) } void +ArrayType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +std::string +ArrayType::as_string () const +{ + return "[" + type->as_string () + ":" + std::to_string (capacity) + "]"; +} + +TyBase * +ArrayType::combine (TyBase *other) +{ + ArrayRules r (this); + return r.combine (other); +} + +void BoolType::accept_vis (TyVisitor &vis) { vis.visit (*this); diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 4e04490..b9dc268 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -143,6 +143,28 @@ private: TyBase *type; }; +class ArrayType : public TyBase +{ +public: + ArrayType (HirId ref, size_t capacity, TyBase *type) + : TyBase (ref, TypeKind::ARRAY), capacity (capacity), type (type) + {} + + void accept_vis (TyVisitor &vis) override; + + std::string as_string () const override; + + TyBase *combine (TyBase *other) override; + + size_t get_capacity () const { return capacity; } + + TyBase *get_type () { return type; } + +private: + size_t capacity; + TyBase *type; +}; + class BoolType : public TyBase { public: diff --git a/gcc/testsuite/rust.test/compilable/type_infer4.rs b/gcc/testsuite/rust.test/compilable/type_infer4.rs new file mode 100644 index 0000000..8e123e2 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/type_infer4.rs @@ -0,0 +1,9 @@ +fn main() { + let xs: [i32; 5] = [1, 2, 3, 4, 5]; + let xy = [6, 7, 8]; + + let a = xs[0]; + let b = xy[2]; + let mut c; + c = xs[0]; +} -- cgit v1.1 From d1afbb7ead51347a84da62a6be9f98b0742538de Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Mon, 21 Dec 2020 15:52:23 +0000 Subject: Implement compilation of ArrayElemsCopied to GIMPLE let mut array = [123; 5] --- gcc/rust/backend/rust-compile-expr.h | 9 ++++ gcc/rust/hir/rust-ast-lower-expr.h | 55 +++++++++++++++++++++- gcc/rust/hir/tree/rust-hir-expr.h | 15 ++++-- gcc/rust/resolve/rust-ast-resolve-expr.h | 4 +- gcc/rust/typecheck/rust-hir-type-check-expr.h | 13 +++-- gcc/testsuite/rust.test/compilable/arrays2.rs | 7 +++ .../rust.test/compilable/arrays_index1.rs | 8 ++++ 7 files changed, 96 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/rust.test/compilable/arrays2.rs create mode 100644 gcc/testsuite/rust.test/compilable/arrays_index1.rs (limited to 'gcc') diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 6ea97ee..5c3206a 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -211,6 +211,15 @@ public: }); } + void visit (HIR::ArrayElemsCopied &elems) + { + Bexpression *translated_expr + = CompileExpr::Compile (elems.get_elem_to_copy (), ctx); + + for (size_t i = 0; i < elems.get_num_elements (); ++i) + constructor.push_back (translated_expr); + } + void visit (HIR::ArithmeticOrLogicalExpr &expr) { Operator op; diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index b919905..a165eaf 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -26,6 +26,42 @@ namespace Rust { namespace HIR { +class ArrayCapacityConstant : public ASTLoweringBase +{ +public: + static bool fold (AST::Expr *expr, size_t *folded_result) + { + ArrayCapacityConstant folder; + expr->accept_vis (folder); + *folded_result = folder.result; + return folder.ok; + } + + virtual ~ArrayCapacityConstant () {} + + void visit (AST::LiteralExpr &expr) + { + switch (expr.get_lit_type ()) + { + case AST::Literal::LitType::INT: { + ok = true; + std::stringstream ss (expr.as_string ()); + ss >> result; + } + break; + + default: + return; + } + } + +private: + ArrayCapacityConstant () : ok (false), result (-1) {} + + bool ok; + size_t result; +}; // namespace Resolver + class ASTLoweringExpr : public ASTLoweringBase { public: @@ -209,8 +245,23 @@ public: void visit (AST::ArrayElemsCopied &elems) { - // TODO - gcc_unreachable (); + HIR::Expr *element + = ASTLoweringExpr::translate (elems.get_elem_to_copy ().get ()); + HIR::Expr *num_copies + = ASTLoweringExpr::translate (elems.get_num_copies ().get ()); + + size_t folded; + if (!ArrayCapacityConstant::fold (elems.get_num_copies ().get (), &folded)) + { + rust_fatal_error (elems.get_num_copies ()->get_locus_slow (), + "failed to fold capacity constant"); + return; + } + + translated_array_elems + = new HIR::ArrayElemsCopied (std::unique_ptr (element), + std::unique_ptr (num_copies), + folded); } void visit (AST::LiteralExpr &expr) diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 7c32ac2..1110f98 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -980,21 +980,25 @@ class ArrayElemsCopied : public ArrayElems { std::unique_ptr elem_to_copy; std::unique_ptr num_copies; + size_t folded_copy_amount; // TODO: should this store location data? public: // Constructor requires pointers for polymorphism ArrayElemsCopied (std::unique_ptr copied_elem, - std::unique_ptr copy_amount) + std::unique_ptr copy_amount, + size_t folded_copy_amount) : elem_to_copy (std::move (copied_elem)), - num_copies (std::move (copy_amount)) + num_copies (std::move (copy_amount)), + folded_copy_amount (folded_copy_amount) {} // Copy constructor required due to unique_ptr - uses custom clone ArrayElemsCopied (ArrayElemsCopied const &other) : elem_to_copy (other.elem_to_copy->clone_expr ()), - num_copies (other.num_copies->clone_expr ()) + num_copies (other.num_copies->clone_expr ()), + folded_copy_amount (other.folded_copy_amount) {} // Overloaded assignment operator for deep copying @@ -1002,6 +1006,7 @@ public: { elem_to_copy = other.elem_to_copy->clone_expr (); num_copies = other.num_copies->clone_expr (); + folded_copy_amount = other.folded_copy_amount; return *this; } @@ -1014,7 +1019,9 @@ public: void accept_vis (HIRVisitor &vis) override; - size_t get_num_elements () const override { return 0; } + size_t get_num_elements () const override { return folded_copy_amount; } + + Expr *get_elem_to_copy () { return elem_to_copy.get (); } protected: ArrayElemsCopied *clone_array_elems_impl () const override diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 54d33a8..d86866c 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -150,8 +150,8 @@ public: void visit (AST::ArrayElemsCopied &elems) { - // TODO - gcc_unreachable (); + ResolveExpr::go (elems.get_num_copies ().get (), elems.get_node_id ()); + ResolveExpr::go (elems.get_elem_to_copy ().get (), elems.get_node_id ()); } private: diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 999523f..116fab7 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -232,15 +232,9 @@ public: expr.get_array_expr ()->accept_vis (*this); rust_assert (infered != nullptr); - printf ("Resolved array-index 1 [%u] -> %s\n", - expr.get_mappings ().get_hirid (), infered->as_string ().c_str ()); + // extract the element type out now from the base type infered = TyTyExtractorArray::ExtractElementTypeFromArray (infered); - - printf ("Resolved array-index 2 [%u] -> %s\n", - expr.get_mappings ().get_hirid (), infered->as_string ().c_str ()); - printf ("array-expr node [%u]\n", - expr.get_array_expr ()->get_mappings ().get_hirid ()); } void visit (HIR::ArrayExpr &expr) @@ -270,6 +264,11 @@ public: } } + void visit (HIR::ArrayElemsCopied &elems) + { + infered_array_elems = TypeCheckExpr::Resolve (elems.get_elem_to_copy ()); + } + private: TypeCheckExpr () : TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr) diff --git a/gcc/testsuite/rust.test/compilable/arrays2.rs b/gcc/testsuite/rust.test/compilable/arrays2.rs new file mode 100644 index 0000000..a3c8523 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/arrays2.rs @@ -0,0 +1,7 @@ +fn main() { + let mut array: [i32; 3] = [0; 3]; + + let a = array[0]; + let mut c; + c = array[2]; +} diff --git a/gcc/testsuite/rust.test/compilable/arrays_index1.rs b/gcc/testsuite/rust.test/compilable/arrays_index1.rs new file mode 100644 index 0000000..8dd1c04 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/arrays_index1.rs @@ -0,0 +1,8 @@ +fn main() { + let mut array: [i32; 3] = [0; 3]; + + let a = array[0]; + let x = 0; + let mut c; + c = array[x+1]; +} -- cgit v1.1 From a56656e26e64a2a20bd5b9907eac6d016510b3e1 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 23 Dec 2020 14:16:42 +0000 Subject: Remove impl_block test. This is part of the next milestone and we want to turn on CI build failure if any test fails and this will block that change until the next milestone if not removed. --- gcc/testsuite/rust.test/compilable/impl_block.rs | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 gcc/testsuite/rust.test/compilable/impl_block.rs (limited to 'gcc') diff --git a/gcc/testsuite/rust.test/compilable/impl_block.rs b/gcc/testsuite/rust.test/compilable/impl_block.rs deleted file mode 100644 index 51ed74b..0000000 --- a/gcc/testsuite/rust.test/compilable/impl_block.rs +++ /dev/null @@ -1,14 +0,0 @@ -struct Foo { - one: i32, - two: i32, -} - -impl Foo { - fn new(a: i32, b: i32) -> Foo { - return Foo { one: a, two: b }; - } -} - -fn main() { - let cake = Foo::new(3, 4); -} -- cgit v1.1