aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--gcc/ChangeLog308
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog115
-rw-r--r--gcc/config/avr/avr-log.cc1
-rw-r--r--gcc/config/avr/avr-protos.h2
-rw-r--r--gcc/config/avr/avr.cc124
-rw-r--r--gcc/config/avr/avr.h18
-rw-r--r--gcc/config/avr/avr.md35
-rw-r--r--gcc/config/avr/avr.opt4
-rw-r--r--gcc/config/avr/avr.opt.urls2
-rw-r--r--gcc/config/i386/i386.md407
-rw-r--r--gcc/config/i386/predicates.md8
-rw-r--r--gcc/config/riscv/riscv.cc4
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/doc/install.texi4
-rw-r--r--gcc/explow.cc24
-rw-r--r--gcc/expr.cc12
-rw-r--r--gcc/expr.h4
-rw-r--r--gcc/fortran/trans-array.cc19
-rw-r--r--gcc/fortran/trans-array.h1
-rw-r--r--gcc/fortran/trans-decl.cc25
-rw-r--r--gcc/fortran/trans-expr.cc2
-rw-r--r--gcc/fortran/trans-stmt.cc7
-rw-r--r--gcc/fortran/trans.cc4
-rw-r--r--gcc/function.cc4
-rw-r--r--gcc/rust/Make-lang.in3
-rw-r--r--gcc/rust/ast/rust-ast-builder-type.cc9
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc26
-rw-r--r--gcc/rust/ast/rust-ast-builder.h4
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc140
-rw-r--r--gcc/rust/ast/rust-ast-collector.h2
-rw-r--r--gcc/rust/ast/rust-ast-dump.h6
-rw-r--r--gcc/rust/ast/rust-ast-formatting.h15
-rw-r--r--gcc/rust/ast/rust-ast-full-decls.h3
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc48
-rw-r--r--gcc/rust/ast/rust-ast-visitor.h4
-rw-r--r--gcc/rust/ast/rust-ast.cc55
-rw-r--r--gcc/rust/ast/rust-ast.h15
-rw-r--r--gcc/rust/ast/rust-collect-lang-items.cc24
-rw-r--r--gcc/rust/ast/rust-collect-lang-items.h3
-rw-r--r--gcc/rust/ast/rust-cond-compilation.h4
-rw-r--r--gcc/rust/ast/rust-desugar-apit.cc522
-rw-r--r--gcc/rust/ast/rust-desugar-apit.h (renamed from gcc/rust/ast/rust-macro.cc)21
-rw-r--r--gcc/rust/ast/rust-expr.h194
-rw-r--r--gcc/rust/ast/rust-fmt.h7
-rw-r--r--gcc/rust/ast/rust-item.h35
-rw-r--r--gcc/rust/ast/rust-path.cc21
-rw-r--r--gcc/rust/ast/rust-path.h8
-rw-r--r--gcc/rust/ast/rust-pattern.cc4
-rw-r--r--gcc/rust/ast/rust-pattern.h29
-rw-r--r--gcc/rust/ast/rust-type.h47
-rw-r--r--gcc/rust/backend/rust-compile-base.cc5
-rw-r--r--gcc/rust/backend/rust-compile-block.cc1
-rw-r--r--gcc/rust/backend/rust-compile-block.h9
-rw-r--r--gcc/rust/backend/rust-compile-context.cc15
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc19
-rw-r--r--gcc/rust/backend/rust-compile-expr.h2
-rw-r--r--gcc/rust/backend/rust-compile-implitem.cc6
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc66
-rw-r--r--gcc/rust/backend/rust-compile-item.cc11
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc209
-rw-r--r--gcc/rust/backend/rust-compile-pattern.h20
-rw-r--r--gcc/rust/backend/rust-compile-type.cc19
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h3
-rw-r--r--gcc/rust/backend/rust-constexpr.cc193
-rw-r--r--gcc/rust/backend/rust-constexpr.h3
-rw-r--r--gcc/rust/backend/rust-mangle-v0.cc18
-rw-r--r--gcc/rust/backend/rust-mangle.h11
-rw-r--r--gcc/rust/backend/rust-tree.cc82
-rw-r--r--gcc/rust/backend/rust-tree.h183
-rw-r--r--gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h20
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc18
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h2
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h54
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h8
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc21
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h2
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-dump.cc3
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h27
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-place.h8
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-bir-visitor.h2
-rw-r--r--gcc/rust/checks/errors/borrowck/rust-function-collector.h2
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-check.cc3
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-ctx.h3
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc27
-rw-r--r--gcc/rust/checks/errors/privacy/rust-privacy-reporter.h2
-rw-r--r--gcc/rust/checks/errors/privacy/rust-reachability.cc6
-rw-r--r--gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc3
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.cc20
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.h2
-rw-r--r--gcc/rust/checks/errors/rust-hir-pattern-analysis.cc138
-rw-r--r--gcc/rust/checks/errors/rust-hir-pattern-analysis.h8
-rw-r--r--gcc/rust/checks/errors/rust-unsafe-checker.cc12
-rw-r--r--gcc/rust/checks/errors/rust-unsafe-checker.h2
-rw-r--r--gcc/rust/expand/rust-cfg-strip.cc10
-rw-r--r--gcc/rust/expand/rust-derive-clone.h10
-rw-r--r--gcc/rust/expand/rust-derive-copy.h8
-rw-r--r--gcc/rust/expand/rust-derive-default.cc5
-rw-r--r--gcc/rust/expand/rust-derive-eq.cc32
-rw-r--r--gcc/rust/expand/rust-derive-eq.h10
-rw-r--r--gcc/rust/expand/rust-derive-hash.h10
-rw-r--r--gcc/rust/expand/rust-derive-ord.cc172
-rw-r--r--gcc/rust/expand/rust-derive-ord.h74
-rw-r--r--gcc/rust/expand/rust-derive-partial-eq.cc66
-rw-r--r--gcc/rust/expand/rust-derive-partial-eq.h10
-rw-r--r--gcc/rust/expand/rust-derive.cc15
-rw-r--r--gcc/rust/expand/rust-derive.h2
-rw-r--r--gcc/rust/expand/rust-expand-format-args.cc6
-rw-r--r--gcc/rust/expand/rust-expand-visitor.cc2
-rw-r--r--gcc/rust/expand/rust-expand-visitor.h6
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.cc38
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.h32
-rw-r--r--gcc/rust/expand/rust-macro-builtins-helpers.h35
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc45
-rw-r--r--gcc/rust/expand/rust-macro-substitute-ctx.cc3
-rw-r--r--gcc/rust/expand/rust-proc-macro.h6
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc21
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.cc62
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-extern.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.cc3
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.cc11
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.cc30
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.cc62
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.h13
-rw-r--r--gcc/rust/hir/rust-ast-lower.h8
-rw-r--r--gcc/rust/hir/rust-hir-dump.cc34
-rw-r--r--gcc/rust/hir/rust-hir-dump.h5
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr-abstract.h4
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.cc66
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h85
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-decls.h3
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.cc9
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h16
-rw-r--r--gcc/rust/hir/tree/rust-hir-pattern.h18
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h6
-rw-r--r--gcc/rust/hir/tree/rust-hir.cc61
-rw-r--r--gcc/rust/lex/rust-lex.cc19
-rw-r--r--gcc/rust/lex/rust-lex.h3
-rw-r--r--gcc/rust/lex/rust-token.cc11
-rw-r--r--gcc/rust/lex/rust-token.h25
-rw-r--r--gcc/rust/metadata/rust-export-metadata.cc3
-rw-r--r--gcc/rust/metadata/rust-import-archive.cc2
-rw-r--r--gcc/rust/metadata/rust-imports.h3
-rw-r--r--gcc/rust/parse/rust-cfg-parser.h7
-rw-r--r--gcc/rust/parse/rust-parse-impl.h341
-rw-r--r--gcc/rust/parse/rust-parse.cc46
-rw-r--r--gcc/rust/parse/rust-parse.h16
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.cc8
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.cc38
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc34
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc27
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc11
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc3
-rw-r--r--gcc/rust/resolve/rust-default-resolver.cc249
-rw-r--r--gcc/rust/resolve/rust-default-resolver.h12
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc23
-rw-r--r--gcc/rust/resolve/rust-forever-stack.h15
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx212
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc191
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.h11
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.cc57
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h344
-rw-r--r--gcc/rust/resolve/rust-rib.h10
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc83
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h3
-rw-r--r--gcc/rust/rust-attribs.cc162
-rw-r--r--gcc/rust/rust-backend.h257
-rw-r--r--gcc/rust/rust-diagnostics.cc49
-rw-r--r--gcc/rust/rust-diagnostics.h13
-rw-r--r--gcc/rust/rust-gcc.cc3
-rw-r--r--gcc/rust/rust-lang.cc13
-rw-r--r--gcc/rust/rust-object-export.h13
-rw-r--r--gcc/rust/rust-session-manager.cc26
-rw-r--r--gcc/rust/rust-session-manager.h3
-rw-r--r--gcc/rust/rust-system.h6
-rw-r--r--gcc/rust/rust-target.h3
-rw-r--r--gcc/rust/typecheck/rust-autoderef.cc3
-rw-r--r--gcc/rust/typecheck/rust-casts.cc27
-rw-r--r--gcc/rust/typecheck/rust-coercion.cc26
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc9
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc30
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-enumitem.cc8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc58
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.cc24
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.cc26
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.cc38
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-struct.cc3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc15
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h4
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc2
-rw-r--r--gcc/rust/typecheck/rust-type-util.cc6
-rw-r--r--gcc/rust/typecheck/rust-type-util.h39
-rw-r--r--gcc/rust/typecheck/rust-typecheck-context.cc67
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc6
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.cc17
-rw-r--r--gcc/rust/typecheck/rust-tyty-cmp.h6
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.cc21
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.h1
-rw-r--r--gcc/rust/typecheck/rust-tyty-variance-analysis.h7
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc131
-rw-r--r--gcc/rust/typecheck/rust-tyty.h9
-rw-r--r--gcc/rust/typecheck/rust-unify.cc347
-rw-r--r--gcc/rust/typecheck/rust-unify.h3
-rw-r--r--gcc/rust/util/rust-abi.h6
-rw-r--r--gcc/rust/util/rust-attributes.cc3
-rw-r--r--gcc/rust/util/rust-base62.h3
-rw-r--r--gcc/rust/util/rust-canonical-path.h13
-rw-r--r--gcc/rust/util/rust-dir-owner.h3
-rw-r--r--gcc/rust/util/rust-edition.h3
-rw-r--r--gcc/rust/util/rust-punycode.h6
-rw-r--r--gcc/rust/util/rust-token-converter.cc8
-rw-r--r--gcc/rust/util/rust-token-converter.h9
-rw-r--r--gcc/rust/util/rust-unicode.h27
-rw-r--r--gcc/rust/util/rust-unwrap-segment.h9
-rw-r--r--gcc/testsuite/ChangeLog190
-rw-r--r--gcc/testsuite/c-c++-common/cpp/va-opt-6.c10
-rw-r--r--gcc/testsuite/g++.dg/DRs/dr2579.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-using6.C20
-rw-r--r--gcc/testsuite/gcc.dg/bitintext.h22
-rw-r--r--gcc/testsuite/gcc.dg/c23-attr-syntax-6.c4
-rw-r--r--gcc/testsuite/gcc.dg/cpp/paste12-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/paste12.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/paste14-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/cpp/paste14.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr121370.c25
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr121382.c23
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr59984.c4
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr118591-1.c2
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr118591-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c1
-rw-r--r--gcc/testsuite/lib/rust.exp5
-rw-r--r--gcc/testsuite/rust/compile/bad-rpit1.rs26
-rw-r--r--gcc/testsuite/rust/compile/const_generics_3.rs2
-rw-r--r--gcc/testsuite/rust/compile/impl_trait_diag.rs17
-rw-r--r--gcc/testsuite/rust/compile/impl_trait_generic_arg.rs24
-rw-r--r--gcc/testsuite/rust/compile/issue-1485.rs16
-rw-r--r--gcc/testsuite/rust/compile/issue-1487.rs15
-rw-r--r--gcc/testsuite/rust/compile/issue-2015.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3454.rs20
-rw-r--r--gcc/testsuite/rust/compile/issue-3618.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-3660.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3661.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3671.rs2
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/meta-param.rs7
-rw-r--r--gcc/testsuite/rust/compile/match-identifierpattern.rs9
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude16
-rw-r--r--gcc/testsuite/rust/compile/pub_restricted_1.rs8
-rw-r--r--gcc/testsuite/rust/compile/pub_restricted_2.rs10
-rw-r--r--gcc/testsuite/rust/compile/same_field_name.rs (renamed from gcc/testsuite/rust/execute/same_field_name.rs)2
-rw-r--r--gcc/testsuite/rust/compile/self-in-impl.rs17
-rw-r--r--gcc/testsuite/rust/compile/torture/extern_mod2.rs6
-rw-r--r--gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs6
-rw-r--r--gcc/testsuite/rust/compile/traits9.rs3
-rw-r--r--gcc/testsuite/rust/compile/unify-errors1.rs49
-rw-r--r--gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs176
-rw-r--r--gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs184
-rw-r--r--gcc/testsuite/rust/execute/torture/builtin_abort.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/const_block1.rs9
-rw-r--r--gcc/testsuite/rust/execute/torture/derive-partialeq2.rs66
-rw-r--r--gcc/testsuite/rust/execute/torture/for-loop1.rs38
-rw-r--r--gcc/testsuite/rust/execute/torture/for-loop2.rs38
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_desugar-2.rs32
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_desugar.rs32
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit1.rs28
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit2.rs36
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit3.rs25
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait1.rs31
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait2.rs31
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait3.rs46
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait4.rs31
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1482.rs23
-rw-r--r--gcc/testsuite/rust/execute/torture/iter1.rs38
-rw-r--r--gcc/testsuite/rust/execute/torture/match-identifierpattern.rs10
-rw-r--r--gcc/testsuite/rust/execute/torture/struct-pattern-match.rs13
-rw-r--r--gcc/testsuite/rust/execute/torture/struct_pattern1.rs19
-rw-r--r--gcc/tree-scalar-evolution.cc11
-rw-r--r--gcc/tree-ssa-loop-ivopts.cc20
-rw-r--r--gcc/tree-vect-data-refs.cc11
-rw-r--r--gcc/tree-vect-loop.cc13
-rw-r--r--gcc/tree-vect-slp.cc265
-rw-r--r--gcc/tree-vect-stmts.cc10
-rw-r--r--gcc/tree-vectorizer.cc2
-rw-r--r--gcc/tree-vectorizer.h28
-rw-r--r--libcpp/ChangeLog6
-rw-r--r--libcpp/macro.cc2
-rw-r--r--libgrust/libproc_macro_internal/ffistring.h6
-rw-r--r--libgrust/libproc_macro_internal/ident.h12
-rw-r--r--libgrust/libproc_macro_internal/literal.h3
-rw-r--r--libgrust/libproc_macro_internal/proc_macro.h3
-rw-r--r--libgrust/libproc_macro_internal/tokenstream.h18
-rw-r--r--libstdc++-v3/ChangeLog24
-rw-r--r--libstdc++-v3/src/c++23/std.cc.in2
301 files changed, 7023 insertions, 3110 deletions
diff --git a/.gitignore b/.gitignore
index 7150fc3..f044fe1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,6 +71,3 @@ stamp-*
/gmp*
/isl*
/gettext*
-
-# ADDITIONS from GCCRS front-end
-libgrust/*/target/
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d73ba82..4b6bc90 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,311 @@
+2025-08-04 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * defaults.h (MAX_FIXED_MODE_SIZE): Default to 2 * BITS_PER_WORD
+ for larger-than-32-bitters.
+ * doc/tm.texi.in (MAX_FIXED_MODE_SIZE): Adjust accordingly. Tweak
+ wording.
+ * doc/tm.texi: Regenerate.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ * dump-context.h: Convert "enum optinfo_item_kind" into
+ "enum class kind" within class optinfo_item.
+ * dumpfile.cc: Likewise. Use "auto" in a few places.
+ Convert "enum optinfo_kind" to "enum class kind" within
+ class optinfo.
+ * opt-problem.cc: Likewise.
+ * optinfo-emit-json.cc: Likewise.
+ * optinfo.cc: Likewise.
+ * optinfo.h: Likewise.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ PR diagnostics/116253
+ * diagnostics/context.cc (context::set_nesting_level): New.
+ * diagnostics/context.h (context::set_nesting_level): New decl.
+ * doc/libgdiagnostics/topics/compatibility.rst
+ (LIBGDIAGNOSTICS_ABI_5): New.
+ * doc/libgdiagnostics/topics/physical-locations.rst
+ (diagnostic_manager_set_debug_physical_locations): New.
+ * libgdiagnostics++.h (manager::set_debug_physical_locations):
+ New.
+ * libgdiagnostics-private.h
+ (private_diagnostic_set_nesting_level): New decl.
+ * libgdiagnostics.cc (diagnostic_manager::diagnostic_manager):
+ Initialize m_debug_physical_locations.
+ (diagnostic_manager::new_location_from_file_and_line): Add debug
+ printing.
+ (diagnostic_manager::new_location_from_file_line_column):
+ Likewise.
+ (diagnostic_manager::new_location_from_range): Likewise.
+ (diagnostic_manager::set_debug_physical_locations): New.
+ (diagnostic_manager::ensure_linemap_for_file_and_line): Avoid
+ redundant calls to linemap_add.
+ (diagnostic_manager::new_location): Add debug printing.
+ (diagnostic_manager::m_debug_physical_locations): New field.
+ (diagnostic::diagnostic): Initialize m_nesting_level.
+ (diagnostic::get_nesting_level): New accessor.
+ (diagnostic::set_nesting_level): New.
+ (diagnostic::m_nesting_level): New field.
+ (diagnostic_manager::emit_va): Set and reset the nesting level
+ of the context from that of the diagnostic.
+ (diagnostic_manager_set_debug_physical_locations): New.
+ (private_diagnostic_set_nesting_level): New.
+ * libgdiagnostics.h
+ (diagnostic_manager_set_debug_physical_locations): New decl.
+ * libgdiagnostics.map (LIBGDIAGNOSTICS_ABI_5): New.
+ * libsarifreplay.cc (sarif_replayer::handle_result_obj): Support
+ the "nestingLevel" property.
+ * libsarifreplay.h (replay_options::m_debug_physical_locations):
+ New field.
+ * sarif-replay.cc: Add -fdebug-physical-locations.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ PR diagnostics/116792
+ * diagnostics/html-sink.cc
+ (html_builder::make_element_for_diagnostic): Don't add the
+ metadata element if it's empty.
+ (html_builder::make_element_for_metadata): Return null rather than
+ an empty element.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostics/context.h: Move struct counters to its own header
+ and include it.
+ * diagnostics/counters.h: New file, from the above.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostics/context.h: Split struct source_printing_options out
+ into "diagnostics/source-printing-options.h" and include it.
+ * diagnostics/source-printing-options.h: New file, from the above.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostics/context.cc: Update for renaming of option_manager to
+ option_id_manager and of context::m_option_mgr to
+ context::m_option_id_mgr.
+ * diagnostics/context.h: Likewise, moving class declaration to a
+ new diagnostics/option-id-manager.h.
+ * diagnostics/lazy-paths.cc: Likewise.
+ * diagnostics/option-id-manager.h: New file, from material in
+ diagnostics/context.h.
+ * lto-wrapper.cc: Update for renaming of option_manager to
+ option_id_manager.
+ * opts-common.cc: Likewise.
+ * opts-diagnostic.h: Likewise.
+ * opts.cc: Likewise.
+ * toplev.cc: Likewise.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostics/buffering.h: Update comment to refer to output sinks
+ rather than output formats.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ * gimple-warn-recursion.cc (pass_warn_recursion::execute): Add
+ missing auto_diagnostic_group.
+
+2025-08-04 Konstantinos Eleftheriou <konstantinos.eleftheriou@vrull.eu>
+
+ PR rtl-optimization/121303
+ * avoid-store-forwarding.cc (is_store_forwarding): Add check
+ for `off_val` in `is_store_forwarding`.
+
+2025-08-04 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.cc (vect_analyze_slp): When analyzing a loop
+ and slp instance discovery fails, immediately fail the whole
+ process.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve-builtins.cc
+ (function_expander::expand): Assert that the return value
+ has an appropriate mode.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-protos.h
+ (aarch64_convert_sve_data_to_pred): Remove the mode argument.
+ * config/aarch64/aarch64.cc
+ (aarch64_sve_emit_int_cmp): Allow PRED_MODE to be VNx16BI or
+ the natural predicate mode for the data mode.
+ (aarch64_convert_sve_data_to_pred): Remove the mode argument
+ and instead always create a VNx16BI result.
+ (aarch64_expand_sve_const_pred): Update call accordingly.
+ * config/aarch64/aarch64-sve-builtins-base.cc
+ (svdupq_impl::expand): Likewise, ensuring that the result
+ has mode VNx16BI.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-protos.h
+ (aarch64_emit_sve_pred_vec_duplicate): Declare.
+ * config/aarch64/aarch64.cc
+ (aarch64_emit_sve_pred_vec_duplicate): New function.
+ * config/aarch64/aarch64-sve.md (vec_duplicate<PRED_ALL:mode>): Use it.
+ * config/aarch64/aarch64-sve-builtins-base.cc
+ (svdup_impl::expand): Handle boolean values specially. Check for
+ constants and fall back on aarch64_emit_sve_pred_vec_duplicate
+ for the variable case, ensuring that the result has mode VNx16BI.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (PNEXT_ONLY): New int iterator.
+ * config/aarch64/aarch64-sve.md
+ (@aarch64_sve_<sve_pred_op><mode>): Restrict SVE_PITER pattern
+ to VNx16BI_ONLY.
+ (@aarch64_sve_<sve_pred_op><mode>): New PNEXT_ONLY pattern for
+ PRED_HSD.
+ (*aarch64_sve_<sve_pred_op><mode>): Likewise.
+ (*aarch64_sve_<sve_pred_op><mode>_cc): Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve2.md (@aarch64_pred_<sve_int_op><mode>):
+ Split SVE2_MATCH pattern into a VNx16QI_ONLY define_ins and a
+ VNx8HI_ONLY define_expand. Use a VNx16BI destination for the latter.
+ (*aarch64_pred_<sve_int_op><mode>): New SVE2_MATCH pattern for
+ VNx8HI_ONLY.
+ (*aarch64_pred_<sve_int_op><mode>_cc): Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (@aarch64_pred_fac<cmp_op><mode>):
+ Replace with...
+ (@aarch64_pred_fac<cmp_op><mode>_acle): ...this new expander.
+ (*aarch64_pred_fac<cmp_op><mode>_strict_acle): New pattern.
+ * config/aarch64/aarch64-sve-builtins-base.cc
+ (svac_impl::expand): Update accordingly.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (@aarch64_pred_fcm<cmp_op><mode>_acle)
+ (*aarch64_pred_fcm<cmp_op><mode>_acle, @aarch64_pred_fcmuo<mode>_acle)
+ (*aarch64_pred_fcmuo<mode>_acle): New patterns.
+ * config/aarch64/aarch64-sve-builtins-base.cc
+ (svcmp_impl::expand, svcmpuo_impl::expand): Use them.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (@aarch64_pred_cmp<cmp_op><mode>_wide):
+ Split into VNx16QI_ONLY and SVE_FULL_HSI patterns. Use VNx16BI
+ results for both.
+ (*aarch64_pred_cmp<cmp_op><mode>_wide): New pattern.
+ (*aarch64_pred_cmp<cmp_op><mode>_wide_cc): Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md
+ (*aarch64_pred_cmp<cmp_op><mode>_wide_cc): Turn into a
+ define_insn_and_rewrite and rewrite the governing predicate
+ of the comparison so that it is identical to the PTEST's.
+ (*aarch64_pred_cmp<cmp_op><mode>_wide_ptest): Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (@aarch64_pred_cmp<cmp_op><mode>_wide)
+ (*aarch64_pred_cmp<cmp_op><mode>_wide_cc): Use <VPRED> instead of
+ VNx16BI for the governing predicate.
+ (*aarch64_pred_cmp<cmp_op><mode>_wide_ptest): Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (@aarch64_pred_cmp<cmp_op><mode>_acle)
+ (*aarch64_pred_cmp<cmp_op><mode>_acle, *cmp<cmp_op><mode>_acle_cc)
+ (*cmp<cmp_op><mode>_acle_and): New patterns that yield VNx16BI
+ results for all element types.
+ * config/aarch64/aarch64-sve-builtins-base.cc
+ (svcmp_impl::expand): Use them.
+ (svcmp_wide_impl::expand): Likewise when implementing an svcmp_wide
+ against an in-range constant.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (@aarch64_sve_punpk<perm_hilo>_acle)
+ (*aarch64_sve_punpk<perm_hilo>_acle): New patterns.
+ * config/aarch64/aarch64-sve-builtins-base.cc
+ (svunpk_impl::expand): Use them for boolean svunpk*.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/121294
+ * config/aarch64/aarch64.md (UNSPEC_REV_PRED): New unspec.
+ * config/aarch64/aarch64-sve.md (@aarch64_sve_rev<mode>_acle)
+ (*aarch64_sve_rev<mode>_acle): New patterns.
+ * config/aarch64/aarch64-sve-builtins-base.cc
+ (svrev_impl::expand): Use the new patterns for boolean svrev.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/121294
+ * config/aarch64/iterators.md (UNSPEC_TRN1_CONV): Delete.
+ (UNSPEC_PERMUTE_PRED): New unspec.
+ * config/aarch64/aarch64-sve.md (@aarch64_sve_trn1_conv<mode>):
+ Replace with...
+ (@aarch64_sve_<perm_insn><mode>_acle)
+ (*aarch64_sve_<perm_insn><mode>_acle): ...these new patterns.
+ * config/aarch64/aarch64.cc (aarch64_expand_sve_const_pred_trn):
+ Update accordingly.
+ * config/aarch64/aarch64-sve-builtins-functions.h
+ (binary_permute::expand): Use the new _acle patterns for
+ predicate operations.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR testsuite/121118
+ * config/aarch64/iterators.md (VNx16BI_ONLY): New mode iterator.
+ * config/aarch64/predicates.md (aarch64_ptrue_all_operand): New
+ predicate.
+ * config/aarch64/aarch64-sve.md
+ (@aarch64_sve_while_<while_optab_cmp><GPI:mode><VNx16BI_ONLY:mode>_acle)
+ (@aarch64_sve_while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle)
+ (*aarch64_sve_while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle)
+ (*while_<while_optab_cmp><GPI:mode><PRED_HSD:mode>_acle_cc): New
+ patterns.
+ * config/aarch64/aarch64-sve-builtins-functions.h
+ (while_comparison::expand): Use the new _acle patterns that
+ always return a VNx16BI.
+ * config/aarch64/aarch64-sve-builtins-sve2.cc
+ (svwhilerw_svwhilewr_impl::expand): Likewise.
+ * config/aarch64/aarch64.cc
+ (aarch64_sve_move_pred_via_while): Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/121293
+ * config/aarch64/aarch64-sve-builtins-base.cc (svdupq_lane::expand):
+ Use aarch64_sve_reinterpret instead of subregs. Explicitly
+ reinterpret the result back to the required mode, rather than
+ leaving the caller to take a subreg.
+
+2025-08-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/121362
+ * tree-ssa-sccvn.cc (vn_reference_lookup_3): Generalize
+ aggregate copy handling.
+
+2025-08-04 Filip Kastl <fkastl@suse.cz>
+
+ * doc/invoke.texi: Add remark about -options being documented
+ under -fdump-tree. Remove remark about -graph working only for
+ RTL.
+
+2025-08-04 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/120941
+ * config/i386/i386-features.cc (x86_cse_kind): Moved before
+ ix86_place_single_vector_set.
+ (redundant_load): Likewise.
+ (ix86_place_single_vector_set): Replace the last argument to the
+ pointer to redundant_load. For X86_CSE_VEC_DUP, don't place the
+ vector set outside of the loop to avoid extra spills.
+ (remove_redundant_vector_load): Pass load to
+ ix86_place_single_vector_set.
+
2025-08-03 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.md (define_insn_and_split) [reload_completed]:
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 85faa76..3724f15 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250804
+20250805
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 85464e3..063d6a7 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,118 @@
+2025-08-04 Viljar Indus <indus@adacore.com>
+
+ * contracts.adb: Use Is_Ignored_In_Codegen instead of just
+ using Is_Ignored.
+ * exp_ch6.adb: Likewise.
+ * exp_prag.adb: Likewise.
+ * exp_util.adb: Likewise.
+ * frontend.adb: Avoid removal of ignored nodes in GNATProve_Mode.
+ * gnat1drv.adb: Avoid forcing Assertions_Enabled in GNATProve_Mode.
+ * lib-writ.adb (Write_With_File_Names): Avoid early exit
+ with ignored entities in GNATProve_Mode.
+ * lib-xref.adb: Likewise.
+ * opt.adb: Remove check for Assertions_Enabled.
+ * sem_attr.adb: Use Is_Ignored_In_Codegen instead of Is_Ignored.
+ * sem_ch13.adb: Likewise. Additionally always add predicates in
+ GNATProve_Mode.
+ * sem_prag.adb: Likewise. Additionally remove modifications
+ to applied policies in GNATProve_Mode.
+ * sem_util.adb (Is_Ignored_In_Codegen): New function that overrides
+ Is_Ignored in GNATProve_Mode and Codepeer_Mode.
+ (Is_Ignored_Ghost_Pragma_In_Codegen): Likewise for
+ Is_Ignored_Ghost_Pragma.
+ (Is_Ignored_Ghost_Entity_In_Codegen): Likewise for
+ Is_Ignored_Ghost_Entity.
+ (Policy_In_List): Remove overriding of policies in GNATProve_Mode.
+ * sem_util.ads: Add specs for new functions.
+ * (Predicates_Enabled): Always generate predicates in
+ GNATProve_Mode.
+
+2025-08-04 Bob Duff <duff@adacore.com>
+
+ * treepr.adb (Print_Node_Ref): Protect against
+ Entity (N) being empty before calling
+ Compile_Time_Known_Value.
+
+2025-08-04 Viljar Indus <indus@adacore.com>
+
+ * sem_prag.adb (Validate_Compile_Time_Warning_Errors):
+ Check if the original compile time pragma was replaced and
+ validate the original node instead.
+
+2025-08-04 Viljar Indus <indus@adacore.com>
+
+ * sem_prag.adb (Validate_Compile_Time_Warning_Or_Error):
+ simplify the implementation.
+
+2025-08-04 Steve Baird <baird@adacore.com>
+
+ * exp_ch6.adb (Apply_Access_Discrims_Accessibility_Check): If the
+ accessibility level being checked is known statically, then
+ statically check it against the level of the function being
+ returned from.
+
+2025-08-04 Viljar Indus <indus@adacore.com>
+
+ * atree.adb: update references to Ghost_Mode.
+ * exp_ch3.adb: use a structure type to store all of the existing
+ ghost mode related state variables.
+ * exp_disp.adb: Likewise.
+ * exp_spark.adb: Likewise.
+ * exp_util.adb: Likewise.
+ * expander.adb: Likewise.
+ * freeze.adb: Likewise and replace references to existing ghost
+ mode variables.
+ * ghost.adb (Install_Ghost_Region): install the changes of
+ the region in to the new Ghost_Config structure.
+ (Restore_Ghost_Region): Use the new Ghost_Config instead.
+ In general replace all references to the existing ghost mode
+ variables with the new structure equivalent.
+ * ghost.ads (Restore_Ghost_Region): update the spec.
+ * opt.ads (Ghost_Config_Type): A new type that has two of the
+ previous ghost code related global variables as memembers -
+ Ghost_Mode and Ignored_Ghost_Region.
+ (Ghost_Config) New variable to store the previous Ghost_Mode and
+ Ignored_Ghost_Region info.
+ * rtsfind.adb: Replace references to existing ghost mode variables.
+ * sem.adb: Likewise.
+ * sem_ch12.adb: Likewise.
+ * sem_ch13.adb: Likewise.
+ * sem_ch3.adb: Likewise.
+ * sem_ch5.adb: Likewise.
+ * sem_ch6.adb: Likewise.
+ * sem_ch7.adb: Likewise.
+ * sem_prag.adb: Likewise.
+ * sem_util.adb: Likewise.
+
+2025-08-04 Steve Baird <baird@adacore.com>
+
+ * freeze.adb (Freeze_Profile): Do not emit a warning stating that
+ a formal parameter's size is 8 if the parameter's size is not 8.
+
+2025-08-04 Viljar Indus <indus@adacore.com>
+
+ * table.adb (Max): Move variable to the body and initialize
+ it with the same value as in the Init function.
+ * table.ads (Max): Likewise.
+
+2025-08-04 Bob Duff <duff@adacore.com>
+
+ * par.adb: Move and rewrite some comments.
+ (Util): Shared code and comments for dealing with
+ defining_identifier_lists.
+ * par-util.adb (Append): Shared code for appending
+ one identifier onto Defining_Identifiers.
+ (P_Def_Ids): Shared code for parsing a defining_identifier_list.
+ Unfortunately, this is not used in all cases, because some of
+ them mix in sophisticated error recovery, which we do not
+ modify here.
+ * par-ch12.adb (P_Formal_Object_Declarations):
+ Use Defining_Identifiers and related code.
+ * par-ch3.adb (P_Identifier_Declarations): Likewise.
+ (P_Known_Discriminant_Part_Opt): Likewise.
+ (P_Component_Items): Likewise.
+ * par-ch6.adb (P_Formal_Part): Likewise.
+
2025-07-31 Eric Botcazou <ebotcazou@gcc.gnu.org>
Revert:
diff --git a/gcc/config/avr/avr-log.cc b/gcc/config/avr/avr-log.cc
index fadb3ca..972ba6b 100644
--- a/gcc/config/avr/avr-log.cc
+++ b/gcc/config/avr/avr-log.cc
@@ -373,7 +373,6 @@ avr_log_set_avr_log (void)
SET_DUMP_DETAIL (insn_addresses);
SET_DUMP_DETAIL (legitimate_address_p);
SET_DUMP_DETAIL (legitimize_address);
- SET_DUMP_DETAIL (legitimize_reload_address);
SET_DUMP_DETAIL (progmem);
SET_DUMP_DETAIL (rtx_costs);
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 9aa00d3..8ba1945 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -146,7 +146,6 @@ extern void out_shift_with_cnt (const char *templ, rtx_insn *insn,
extern enum reg_class avr_mode_code_base_reg_class (machine_mode, addr_space_t, rtx_code, rtx_code);
extern bool avr_regno_mode_code_ok_for_base_p (int, machine_mode, addr_space_t, rtx_code, rtx_code);
extern rtx avr_incoming_return_addr_rtx (void);
-extern rtx avr_legitimize_reload_address (rtx*, machine_mode, int, int, int, int, rtx (*)(rtx,int));
extern bool avr_adiw_reg_p (rtx);
extern bool avr_mem_flash_p (rtx);
extern bool avr_mem_flashx_p (rtx);
@@ -241,7 +240,6 @@ typedef struct
unsigned insn_addresses :1;
unsigned legitimate_address_p :1;
unsigned legitimize_address :1;
- unsigned legitimize_reload_address :1;
unsigned progmem :1;
unsigned rtx_costs :1;
} avr_log_t;
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 2afea95..1bfa3f5 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -453,13 +453,6 @@ avr_ld_regno_p (int regno)
}
-static bool
-ra_in_progress ()
-{
- return avropt_lra_p ? lra_in_progress : reload_in_progress;
-}
-
-
/* Set `avr_arch' as specified by `-mmcu='.
Return true on success. */
@@ -2347,8 +2340,8 @@ avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
if (avr_log.legitimate_address_p)
{
avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
- "reload_completed=%d ra_in_progress=%d %s:",
- ok, mode, strict, reload_completed, ra_in_progress (),
+ "reload_completed=%d lra_in_progress=%d %s:",
+ ok, mode, strict, reload_completed, lra_in_progress,
reg_renumber ? "(reg_renumber)" : "");
if (GET_CODE (x) == PLUS
@@ -2418,88 +2411,6 @@ avr_legitimize_address (rtx x, rtx oldx, machine_mode mode)
}
-/* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */
-/* This will allow register R26/27 to be used where it is no worse than normal
- base pointers R28/29 or R30/31. For example, if base offset is greater
- than 63 bytes or for R++ or --R addressing. */
-
-rtx
-avr_legitimize_reload_address (rtx *px, machine_mode mode, int opnum,
- int type, int addr_type, int /*ind_levels*/,
- rtx (*mk_memloc)(rtx,int))
-{
- rtx x = *px;
-
- if (avr_log.legitimize_reload_address)
- avr_edump ("\n%?:%m %r\n", mode, x);
-
- if (1 && (GET_CODE (x) == POST_INC
- || GET_CODE (x) == PRE_DEC))
- {
- push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
- POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
- opnum, RELOAD_OTHER);
-
- if (avr_log.legitimize_reload_address)
- avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
- POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
-
- return x;
- }
-
- if (GET_CODE (x) == PLUS
- && REG_P (XEXP (x, 0))
- && reg_equiv_constant (REGNO (XEXP (x, 0))) == 0
- && CONST_INT_P (XEXP (x, 1))
- && INTVAL (XEXP (x, 1)) >= 1)
- {
- bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
-
- if (fit)
- {
- if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
- {
- int regno = REGNO (XEXP (x, 0));
- rtx mem = mk_memloc (x, regno);
-
- push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
- POINTER_REGS, Pmode, VOIDmode, 0, 0,
- 1, (enum reload_type) addr_type);
-
- if (avr_log.legitimize_reload_address)
- avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
- POINTER_REGS, XEXP (mem, 0), NULL_RTX);
-
- push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
- BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
- opnum, (enum reload_type) type);
-
- if (avr_log.legitimize_reload_address)
- avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
- BASE_POINTER_REGS, mem, NULL_RTX);
-
- return x;
- }
- }
- else if (! (frame_pointer_needed
- && XEXP (x, 0) == frame_pointer_rtx))
- {
- push_reload (x, NULL_RTX, px, NULL,
- POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
- opnum, (enum reload_type) type);
-
- if (avr_log.legitimize_reload_address)
- avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
- POINTER_REGS, x, NULL_RTX);
-
- return x;
- }
- }
-
- return NULL_RTX;
-}
-
-
/* Helper function to print assembler resp. track instruction
sequence lengths. Always return "".
@@ -13959,8 +13870,8 @@ extra_constraint_Q (rtx x)
|| xx == arg_pointer_rtx);
if (avr_log.constraints)
- avr_edump ("\n%?=%d reload_completed=%d ra_in_progress=%d\n %r\n",
- ok, reload_completed, ra_in_progress (), x);
+ avr_edump ("\n%?=%d reload_completed=%d lra_in_progress=%d\n %r\n",
+ ok, reload_completed, lra_in_progress, x);
}
return ok;
@@ -14165,17 +14076,6 @@ avr_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
if (GET_MODE_SIZE (mode) == 1)
return true;
- /* FIXME: Ideally, the following test is not needed.
- However, it turned out that it can reduce the number
- of spill fails. AVR and it's poor endowment with
- address registers is extreme stress test for reload. */
-
- if (GET_MODE_SIZE (mode) >= 4
- && regno + GET_MODE_SIZE (mode) >= REG_30
- // This problem only concerned the old reload.
- && ! avropt_lra_p)
- return false;
-
/* All modes larger than 8 bits should start in an even register. */
return !(regno & 1);
@@ -14937,8 +14837,8 @@ avr_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict,
if (avr_log.legitimate_address_p)
{
avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
- "reload_completed=%d ra_in_progress=%d %s:",
- ok, mode, strict, reload_completed, ra_in_progress (),
+ "reload_completed=%d lra_in_progress=%d %s:",
+ ok, mode, strict, reload_completed, lra_in_progress,
reg_renumber ? "(reg_renumber)" : "");
if (GET_CODE (x) == PLUS
@@ -16716,15 +16616,6 @@ avr_unwind_word_mode ()
return Pmode;
}
-
-/* Implement `TARGET_LRA_P'. */
-
-static bool
-avr_use_lra_p ()
-{
- return avropt_lra_p;
-}
-
/* Initialize the GCC target structure. */
@@ -16866,9 +16757,6 @@ avr_use_lra_p ()
#undef TARGET_CONVERT_TO_TYPE
#define TARGET_CONVERT_TO_TYPE avr_convert_to_type
-#undef TARGET_LRA_P
-#define TARGET_LRA_P avr_use_lra_p
-
#undef TARGET_ADDR_SPACE_SUBSET_P
#define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index cb818c3..335f9fa5 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -309,12 +309,6 @@ enum reg_class {
#define STATIC_CHAIN_REGNUM ((AVR_TINY) ? 18 :2)
-#define RELOAD_ELIMINABLE_REGS { \
- { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
- { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \
- { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
- { FRAME_POINTER_REGNUM + 1, STACK_POINTER_REGNUM + 1 } }
-
#define ELIMINABLE_REGS \
{ \
{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
@@ -358,18 +352,6 @@ typedef struct avr_args
#define MAX_REGS_PER_ADDRESS 1
-#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_L,WIN) \
- do { \
- rtx new_x = avr_legitimize_reload_address (&(X), MODE, OPNUM, TYPE, \
- ADDR_TYPE (TYPE), \
- IND_L, make_memloc); \
- if (new_x) \
- { \
- X = new_x; \
- goto WIN; \
- } \
- } while (0)
-
/* We increase branch costs after reload in order to keep basic-block
reordering from introducing out-of-line jumps and to prefer fall-through
edges instead. The default branch costs are 0, mainly because otherwise
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 67e88c1..d4bf4da 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -5009,41 +5009,6 @@
;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
;; arithmetic shift left
-;; Work around PR120423: Transform left shift of a paradoxical subreg
-;; into left shift of the zero-extended entity.
-(define_split ; PR120423
- [(set (match_operand:HISI 0 "register_operand")
- (ashift:HISI (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand")
- 0)
- (match_operand:QI 2 "const_int_operand")))]
- "!reload_completed
- && !avropt_lra_p
- && <HISI:SIZE> > <QIPSI:SIZE>"
- [(set (match_dup 4)
- (zero_extend:HISI (match_dup 5)))
- (set (match_dup 0)
- (ashift:HISI (match_dup 4)
- (match_dup 2)))]
- {
- operands[4] = gen_reg_rtx (<HISI:MODE>mode);
- operands[5] = force_reg (<QIPSI:MODE>mode, operands[1]);
- })
-
-;; Similar happens for PR116389.
-(define_split ; PR116389
- [(set (match_operand:HISI 0 "register_operand")
- (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand")
- 0))]
- "!reload_completed
- && !avropt_lra_p
- && <HISI:SIZE> > <QIPSI:SIZE>"
- [(set (match_dup 0)
- (zero_extend:HISI (match_dup 2)))]
- {
- operands[2] = force_reg (<QIPSI:MODE>mode, operands[1]);
- })
-
-
;; "ashlqi3"
;; "ashlqq3" "ashluqq3"
(define_expand "ashl<mode>3"
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt
index 7f6f18c..2bed8ea 100644
--- a/gcc/config/avr/avr.opt
+++ b/gcc/config/avr/avr.opt
@@ -18,10 +18,6 @@
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
-mlra
-Target Var(avropt_lra_p) UInteger Init(1) Optimization Undocumented
-Usa LRA for reload instead of the old reload framework. This option is experimental, on per default, and it may be removed in future versions of the compiler.
-
mcall-prologues
Target Mask(CALL_PROLOGUES) Optimization
Optimization. Use subroutines for function prologues and epilogues.
diff --git a/gcc/config/avr/avr.opt.urls b/gcc/config/avr/avr.opt.urls
index 87c26b2..fa560bc 100644
--- a/gcc/config/avr/avr.opt.urls
+++ b/gcc/config/avr/avr.opt.urls
@@ -1,7 +1,5 @@
; Autogenerated by regenerate-opt-urls.py from gcc/config/avr/avr.opt and generated HTML
-; skipping UrlSuffix for 'mlra' due to finding no URLs
-
mcall-prologues
UrlSuffix(gcc/AVR-Options.html#index-mcall-prologues)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index a50475b..2b0dd66 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1618,10 +1618,8 @@
(compare
(match_operand:QI 0 "nonimmediate_operand" "QBn")
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))]
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)))]
"ix86_match_ccmode (insn, CCmode)"
"cmp{b}\t{%h1, %0|%0, %h1}"
[(set_attr "addr" "gpr8")
@@ -1632,10 +1630,8 @@
[(set (reg FLAGS_REG)
(compare
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 0 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 0 "int248_register_operand" "Q")]) 0)
(match_operand:QI 1 "const0_operand")))]
"ix86_match_ccmode (insn, CCNOmode)"
"test{b}\t%h0, %h0"
@@ -1657,10 +1653,8 @@
[(set (reg FLAGS_REG)
(compare
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 0 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 0 "int248_register_operand" "Q")]) 0)
(match_operand:QI 1 "general_operand" "QnBn")))]
"ix86_match_ccmode (insn, CCmode)"
"cmp{b}\t{%1, %h0|%h0, %1}"
@@ -1672,15 +1666,11 @@
[(set (reg FLAGS_REG)
(compare
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 0 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 0 "int248_register_operand" "Q")]) 0)
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))]
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)))]
"ix86_match_ccmode (insn, CCmode)"
"cmp{b}\t{%h1, %h0|%h0, %h1}"
[(set_attr "type" "icmp")
@@ -3480,10 +3470,8 @@
[(set (strict_low_part
(match_operand:QI 0 "register_operand" "+Q"))
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0))]
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
"mov{b}\t{%h1, %0|%0, %h1}"
[(set_attr "type" "imov")
@@ -3566,10 +3554,8 @@
(define_insn "*extzvqi"
[(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)]) 0))]
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q,Q")]) 0))]
""
{
switch (get_attr_type (insn))
@@ -3690,10 +3676,8 @@
(match_operand 0 "int248_register_operand" "+Q")
(const_int 8)
(const_int 8))
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]))]
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]))]
""
"mov{b}\t{%h1, %h0|%h0, %h1}"
[(set_attr "type" "imov")
@@ -5260,10 +5244,8 @@
[(set (match_operand:SWI24 0 "register_operand" "=R")
(sign_extend:SWI24
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))]
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)))]
""
"movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
[(set_attr "type" "imovx")
@@ -7009,10 +6991,8 @@
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
(plus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)
(match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
@@ -7026,8 +7006,8 @@
[(set (strict_low_part (match_dup 0))
(plus:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 2) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0)
(match_dup 0)))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -7038,29 +7018,25 @@
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
(plus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
"#"
"&& reload_completed"
[(set (strict_low_part (match_dup 0))
(subreg:QI
- (match_op_dup 4
- [(match_dup 2) (const_int 8) (const_int 8)]) 0))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0))
(parallel
[(set (strict_low_part (match_dup 0))
(plus:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 1) (const_int 8) (const_int 8)) 0)
(match_dup 0)))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -7475,10 +7451,8 @@
[(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
(plus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)
(match_operand:QI 1 "nonimmediate_operand" "0")))
(clobber (reg:CC FLAGS_REG))]
""
@@ -7491,29 +7465,25 @@
[(set (match_operand:QI 0 "register_operand" "=&Q")
(plus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)))
(clobber (reg:CC FLAGS_REG))]
""
"#"
"&& reload_completed"
[(set (match_dup 0)
(subreg:QI
- (match_op_dup 4
- [(match_dup 2) (const_int 8) (const_int 8)]) 0))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0))
(parallel
[(set (match_dup 0)
(plus:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 1) (const_int 8) (const_int 8)) 0)
(match_dup 0)))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -7543,10 +7513,8 @@
(subreg:SWI248
(plus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "0,!Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
(match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
(clobber (reg:CC FLAGS_REG))]
""
@@ -7581,8 +7549,8 @@
(subreg:SWI248
(plus:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(match_dup 2)) 0))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -7602,15 +7570,11 @@
(subreg:SWI248
(plusminus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "<comm>0,!Q")]) 0)
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)]) 0)) 0))
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)) 0))
(clobber (reg:CC FLAGS_REG))]
""
"@
@@ -7629,11 +7593,11 @@
(subreg:SWI248
(plusminus:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(subreg:QI
- (match_op_dup 4
- [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0)) 0))
(clobber (reg:CC FLAGS_REG))])]
""
[(set_attr "type" "alu")
@@ -8230,10 +8194,8 @@
(minus:QI
(match_operand:QI 1 "nonimmediate_operand" "0,!qm")
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)]) 0)))
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
"@
@@ -8247,8 +8209,8 @@
(minus:QI
(match_dup 0)
(subreg:QI
- (match_op_dup 3
- [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0)))
(clobber (reg:CC FLAGS_REG))])]
""
[(set_attr "type" "alu")
@@ -8258,30 +8220,26 @@
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
(minus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
"#"
"&& reload_completed"
[(set (strict_low_part (match_dup 0))
(subreg:QI
- (match_op_dup 3
- [(match_dup 1) (const_int 8) (const_int 8)]) 0))
+ (zero_extract:SWI248
+ (match_dup 1) (const_int 8) (const_int 8)) 0))
(parallel
[(set (strict_low_part (match_dup 0))
(minus:QI
(match_dup 0)
(subreg:QI
- (match_op_dup 4
- [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0)))
(clobber (reg:CC FLAGS_REG))])]
""
[(set_attr "type" "alu")
@@ -8332,10 +8290,8 @@
(minus:QI
(match_operand:QI 1 "nonimmediate_operand" "0")
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)))
(clobber (reg:CC FLAGS_REG))]
""
"sub{b}\t{%h2, %0|%0, %h2}"
@@ -8347,30 +8303,26 @@
[(set (match_operand:QI 0 "register_operand" "=&Q")
(minus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)))
(clobber (reg:CC FLAGS_REG))]
""
"#"
"&& reload_completed"
[(set (match_dup 0)
(subreg:QI
- (match_op_dup 3
- [(match_dup 1) (const_int 8) (const_int 8)]) 0))
+ (zero_extract:SWI248
+ (match_dup 1) (const_int 8) (const_int 8)) 0))
(parallel
[(set (match_dup 0)
(minus:QI
(match_dup 0)
(subreg:QI
- (match_op_dup 4
- [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0)))
(clobber (reg:CC FLAGS_REG))])]
""
[(set_attr "type" "alu")
@@ -8385,10 +8337,8 @@
(subreg:SWI248
(minus:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "0,!Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
(match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
(clobber (reg:CC FLAGS_REG))]
""
@@ -8407,8 +8357,8 @@
(subreg:SWI248
(minus:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(match_dup 2)) 0))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -12356,10 +12306,8 @@
(compare
(and:QI
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 0 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 0 "int248_register_operand" "Q")]) 0)
(match_operand:QI 1 "general_operand" "QnBn"))
(const_int 0)))]
"ix86_match_ccmode (insn, CCNOmode)"
@@ -12373,15 +12321,11 @@
(compare
(and:QI
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 0 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 0 "int248_register_operand" "Q")]) 0)
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0))
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0))
(const_int 0)))]
"ix86_match_ccmode (insn, CCNOmode)"
"test{b}\t{%h1, %h0|%h0, %h1}"
@@ -12970,10 +12914,8 @@
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
(any_logic:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)
(match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
@@ -12987,8 +12929,8 @@
[(set (strict_low_part (match_dup 0))
(any_logic:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 2) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0)
(match_dup 0)))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -12999,29 +12941,25 @@
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
(any_logic:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
"#"
"&& reload_completed"
[(set (strict_low_part (match_dup 0))
(subreg:QI
- (match_op_dup 4
- [(match_dup 2) (const_int 8) (const_int 8)]) 0))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0))
(parallel
[(set (strict_low_part (match_dup 0))
(any_logic:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 1) (const_int 8) (const_int 8)) 0)
(match_dup 0)))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -13224,10 +13162,8 @@
[(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
(any_logic:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)
(match_operand:QI 1 "nonimmediate_operand" "0")))
(clobber (reg:CC FLAGS_REG))]
""
@@ -13240,29 +13176,25 @@
[(set (match_operand:QI 0 "register_operand" "=&Q")
(any_logic:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "Q")]) 0)
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q")
- (const_int 8)
- (const_int 8)]) 0)))
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q")]) 0)))
(clobber (reg:CC FLAGS_REG))]
""
"#"
"&& reload_completed"
[(set (match_dup 0)
(subreg:QI
- (match_op_dup 4
- [(match_dup 2) (const_int 8) (const_int 8)]) 0))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0))
(parallel
[(set (match_dup 0)
(any_logic:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 1) (const_int 8) (const_int 8)) 0)
(match_dup 0)))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -13292,10 +13224,8 @@
(subreg:SWI248
(any_logic:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "0,!Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
(match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
(clobber (reg:CC FLAGS_REG))]
""
@@ -13314,8 +13244,8 @@
(subreg:SWI248
(any_logic:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(match_dup 2)) 0))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -13329,10 +13259,8 @@
(match_operator 5 "compare_operator"
[(any_logic:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "0,!Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
(match_operand:QI 2 "general_operand" "QnBn,QnBn"))
(const_int 0)]))
(set (zero_extract:SWI248
@@ -13342,8 +13270,8 @@
(subreg:SWI248
(any_logic:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(match_dup 2)) 0))]
"ix86_match_ccmode (insn, CCNOmode)"
"@
@@ -13359,9 +13287,9 @@
[(set (match_dup 4)
(match_op_dup 5
[(any_logic:QI
- (subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (subreg:QI
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(match_dup 2))
(const_int 0)]))
(set (zero_extract:SWI248
@@ -13369,8 +13297,8 @@
(subreg:SWI248
(any_logic:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 1) (const_int 8) (const_int 8)) 0)
(match_dup 2)) 0))])]
""
[(set_attr "addr" "gpr8")
@@ -13386,15 +13314,11 @@
(subreg:SWI248
(any_logic:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "%0,!Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "%0,!Q")]) 0)
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)]) 0)) 0))
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand" "Q,Q")]) 0)) 0))
(clobber (reg:CC FLAGS_REG))]
""
"@
@@ -13413,11 +13337,11 @@
(subreg:SWI248
(any_logic:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(subreg:QI
- (match_op_dup 4
- [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
+ (zero_extract:SWI248
+ (match_dup 2) (const_int 8) (const_int 8)) 0)) 0))
(clobber (reg:CC FLAGS_REG))])]
""
[(set_attr "type" "alu")
@@ -13429,12 +13353,10 @@
(match_operand 0 "int248_register_operand" "+Q,&Q")
(const_int 8)
(const_int 8))
- (match_operator:SWI248 3 "extract_operator"
+ (match_operator:SWI248 3 "extract_high_operator"
[(any_logic
(match_operand 1 "int248_register_operand" "%0,!Q")
- (match_operand 2 "int248_register_operand" "Q,Q"))
- (const_int 8)
- (const_int 8)]))
+ (match_operand 2 "int248_register_operand" "Q,Q"))]))
(clobber (reg:CC FLAGS_REG))]
"GET_MODE (operands[1]) == GET_MODE (operands[2])"
"@
@@ -13450,9 +13372,9 @@
(parallel
[(set (zero_extract:SWI248
(match_dup 0) (const_int 8) (const_int 8))
- (match_op_dup 3
- [(any_logic (match_dup 4) (match_dup 2))
- (const_int 8) (const_int 8)]))
+ (zero_extract:SWI248
+ (any_logic (match_dup 4) (match_dup 2))
+ (const_int 8) (const_int 8)))
(clobber (reg:CC FLAGS_REG))])]
"operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
[(set_attr "type" "alu")
@@ -14697,10 +14619,8 @@
(subreg:SWI248
(neg:QI
(subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 1 "int248_register_operand" "0,!Q")
- (const_int 8)
- (const_int 8)]) 0)) 0))
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)) 0))
(clobber (reg:CC FLAGS_REG))]
""
"@
@@ -14718,8 +14638,8 @@
(subreg:SWI248
(neg:QI
(subreg:QI
- (match_op_dup 2
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)) 0))
(clobber (reg:CC FLAGS_REG))])]
""
[(set_attr "type" "negnot")
@@ -15351,13 +15271,9 @@
(match_operand 0 "int248_register_operand" "+Q,&Q")
(const_int 8)
(const_int 8))
- (subreg:SWI248
- (not:QI
- (subreg:QI
- (match_operator:SWI248 2 "extract_operator"
- [(match_operand 1 "int248_register_operand" "0,!Q")
- (const_int 8)
- (const_int 8)]) 0)) 0))]
+ (not:SWI248
+ (match_operator:SWI248 2 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "0,!Q")])))]
""
"@
not{b}\t%h0
@@ -15370,11 +15286,8 @@
(match_dup 1) (const_int 8) (const_int 8)))
(set (zero_extract:SWI248
(match_dup 0) (const_int 8) (const_int 8))
- (subreg:SWI248
- (not:QI
- (subreg:QI
- (match_op_dup 2
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
+ (not:SWI248
+ (zero_extract:SWI248 (match_dup 0) (const_int 8) (const_int 8))))]
""
[(set_attr "type" "negnot")
(set_attr "mode" "QI")])
@@ -16721,10 +16634,8 @@
(subreg:SWI248
(ashift:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "0,!Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
(match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
(clobber (reg:CC FLAGS_REG))]
""
@@ -16758,8 +16669,8 @@
(subreg:SWI248
(ashift:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(match_dup 2)) 0))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -18005,10 +17916,8 @@
(subreg:SWI248
(any_shiftrt:QI
(subreg:QI
- (match_operator:SWI248 3 "extract_operator"
- [(match_operand 1 "int248_register_operand" "0,!Q")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 3 "extract_high_operator"
+ [(match_operand 1 "int248_register_operand" "0,!Q")]) 0)
(match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
(clobber (reg:CC FLAGS_REG))]
""
@@ -18034,8 +17943,8 @@
(subreg:SWI248
(any_shiftrt:QI
(subreg:QI
- (match_op_dup 3
- [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+ (zero_extract:SWI248
+ (match_dup 0) (const_int 8) (const_int 8)) 0)
(match_dup 2)) 0))
(clobber (reg:CC FLAGS_REG))])]
""
@@ -28252,10 +28161,8 @@
(match_operator 1 "compare_operator"
[(and:QI
(subreg:QI
- (match_operator:SWI248 4 "extract_operator"
- [(match_operand 2 "int248_register_operand")
- (const_int 8)
- (const_int 8)]) 0)
+ (match_operator:SWI248 4 "extract_high_operator"
+ [(match_operand 2 "int248_register_operand")]) 0)
(match_operand 3 "const_int_operand"))
(const_int 0)]))]
"! TARGET_PARTIAL_REG_STALL
@@ -28267,9 +28174,9 @@
(match_op_dup 1
[(and:QI
(subreg:QI
- (match_op_dup 4 [(match_dup 2)
- (const_int 8)
- (const_int 8)]) 0)
+ (zero_extract:SWI248 (match_dup 2)
+ (const_int 8)
+ (const_int 8)) 0)
(match_dup 3))
(const_int 0)]))
(set (zero_extract:SWI248 (match_dup 2)
@@ -28278,9 +28185,9 @@
(subreg:SWI248
(and:QI
(subreg:QI
- (match_op_dup 4 [(match_dup 2)
- (const_int 8)
- (const_int 8)]) 0)
+ (zero_extract:SWI248 (match_dup 2)
+ (const_int 8)
+ (const_int 8)) 0)
(match_dup 3)) 0))])])
;; Don't do logical operations with memory inputs.
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index b2d2eec..0f31090 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1740,8 +1740,12 @@
(define_predicate "compare_operator"
(match_code "compare"))
-(define_predicate "extract_operator"
- (match_code "zero_extract,sign_extract"))
+(define_predicate "extract_high_operator"
+ (match_code "zero_extract,sign_extract,ashiftrt,lshiftrt")
+{
+ return (const8_operand (XEXP (op, 1), VOIDmode)
+ && (BINARY_P (op) || const8_operand (XEXP (op, 2), VOIDmode)));
+})
;; Return true if OP is a memory operand, aligned to
;; less than its natural alignment.
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 0a9fcef..e0d8904 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -13867,9 +13867,9 @@ riscv_expand_xmode_usmul (rtx dest, rtx x, rtx y)
riscv_emit_binary (MULT, mul, x, y);
if (TARGET_64BIT)
- emit_insn (gen_usmuldi3_highpart (mulhu, x, y));
+ emit_insn (gen_umuldi3_highpart (mulhu, x, y));
else
- emit_insn (gen_usmulsi3_highpart (mulhu, x, y));
+ emit_insn (gen_umulsi3_highpart (mulhu, x, y));
riscv_emit_binary (NE, overflow_p, mulhu, CONST0_RTX (Xmode));
riscv_emit_unary (NEG, overflow_p, overflow_p);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3f76afd..3ab14f0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2025-08-04 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/121351
+ PR c++/119859
+ * class.cc (add_method): Substitute outer template arguments
+ into constraints before comparing them if the declarations are
+ from different classes.
+
+2025-08-04 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/120620
+ * constexpr.cc (cxx_dynamic_cast_fn_p): Return true only
+ for synthesized __dynamic_cast.
+
2025-08-01 Nathaniel Shead <nathanieloshead@gmail.com>
PR c++/108080
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index f3f1445..64c1217 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1887,8 +1887,8 @@ Produce code conforming to version 20191213.
In the absence of this configuration option the default version is 20191213.
@item --enable-__cxa_atexit
-Define if you want to use @code{__cxa_atexit}, rather than atexit, to
-register C++ destructors for local statics and global objects.
+Define if you want to use @code{__cxa_atexit}, rather than @code{atexit},
+to register C++ destructors for local statics and global objects.
This is essential for fully standards-compliant handling of
destructors, but requires @code{__cxa_atexit} in libc. This option is
currently only available on systems with GNU libc. When enabled, this
diff --git a/gcc/explow.cc b/gcc/explow.cc
index 7799a98..8f8ca7f 100644
--- a/gcc/explow.cc
+++ b/gcc/explow.cc
@@ -854,6 +854,18 @@ promote_function_mode (const_tree type, machine_mode mode, int *punsignedp,
switch (TREE_CODE (type))
{
+ case BITINT_TYPE:
+ if (TYPE_MODE (type) == BLKmode)
+ return mode;
+
+ struct bitint_info info;
+ bool ok;
+ ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
+ gcc_assert (ok);
+
+ if (!info.extended)
+ return mode;
+ /* FALLTHRU */
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE:
case POINTER_TYPE: case REFERENCE_TYPE:
@@ -893,6 +905,18 @@ promote_mode (const_tree type ATTRIBUTE_UNUSED, machine_mode mode,
switch (code)
{
+ case BITINT_TYPE:
+ if (TYPE_MODE (type) == BLKmode)
+ return mode;
+
+ struct bitint_info info;
+ bool ok;
+ ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
+ gcc_assert (ok);
+
+ if (!info.extended)
+ return mode;
+ /* FALLTHRU */
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE:
/* Values of these types always have scalar mode. */
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 3f2b121..3d2b253 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -76,6 +76,10 @@ along with GCC; see the file COPYING3. If not see
the same indirect address eventually. */
int cse_not_expected;
+/* Cache of the "extended" flag in the target's _BitInt description
+ for use during expand. */
+int bitint_extended = -1;
+
static bool block_move_libcall_safe_for_call_parm (void);
static bool emit_block_move_via_pattern (rtx, rtx, rtx, unsigned, unsigned,
HOST_WIDE_INT, unsigned HOST_WIDE_INT,
@@ -11280,6 +11284,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
when reading from SSA_NAMEs of vars. */
#define EXTEND_BITINT(expr) \
((TREE_CODE (type) == BITINT_TYPE \
+ && !bitint_extended \
&& reduce_bit_field \
&& mode != BLKmode \
&& modifier != EXPAND_MEMORY \
@@ -11291,6 +11296,13 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
type = TREE_TYPE (exp);
mode = TYPE_MODE (type);
unsignedp = TYPE_UNSIGNED (type);
+ if (TREE_CODE (type) == BITINT_TYPE && bitint_extended == -1)
+ {
+ struct bitint_info info;
+ bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
+ gcc_assert (ok);
+ bitint_extended = info.extended;
+ }
treeop0 = treeop1 = treeop2 = NULL_TREE;
if (!VL_EXP_CLASS_P (exp))
diff --git a/gcc/expr.h b/gcc/expr.h
index 53ab625..060151d 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -388,4 +388,8 @@ extern void expand_crc_table_based (rtx, rtx, rtx, rtx, machine_mode);
extern void expand_reversed_crc_table_based (rtx, rtx, rtx, rtx, machine_mode,
void (*) (rtx *));
+/* Cache of the "extended" flag in the target's _BitInt description
+ for use during expand. */
+extern int bitint_extended;
+
#endif /* GCC_EXPR_H */
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 990aaaf..45980d6 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -284,16 +284,6 @@ gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
}
-/* This provides address access to the data field. This should only be
- used by array allocation, passing this on to the runtime. */
-
-tree
-gfc_conv_descriptor_data_addr (tree desc)
-{
- tree field = gfc_get_descriptor_field (desc, DATA_FIELD);
- return gfc_build_addr_expr (NULL_TREE, field);
-}
-
static tree
gfc_conv_descriptor_offset (tree desc)
{
@@ -9588,9 +9578,8 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77,
new_field = gfc_conv_descriptor_dtype (new_desc);
gfc_add_modify (&se->pre, new_field, old_field);
- old_field = gfc_conv_descriptor_offset (old_desc);
- new_field = gfc_conv_descriptor_offset (new_desc);
- gfc_add_modify (&se->pre, new_field, old_field);
+ old_field = gfc_conv_descriptor_offset_get (old_desc);
+ gfc_conv_descriptor_offset_set (&se->pre, new_desc, old_field);
for (int i = 0; i < expr->rank; i++)
{
@@ -11760,8 +11749,8 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
gfc_index_zero_node);
}
- tmp = gfc_conv_descriptor_offset (desc);
- gfc_add_modify (&loop_pre_block, tmp, gfc_index_zero_node);
+ gfc_conv_descriptor_offset_set (&loop_pre_block, desc,
+ gfc_index_zero_node);
tmp = fold_build2_loc (input_location, EQ_EXPR,
logical_type_node, array1,
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 29098fd..345a975 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -173,7 +173,6 @@ void gfc_get_descriptor_offsets_for_info (const_tree, tree *, tree *, tree *, tr
tree *, tree *, tree *, tree *);
tree gfc_conv_descriptor_data_get (tree);
-tree gfc_conv_descriptor_data_addr (tree);
tree gfc_conv_descriptor_offset_get (tree);
tree gfc_conv_descriptor_span_get (tree);
tree gfc_conv_descriptor_dtype (tree);
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 3b49b18..b495f43 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5148,18 +5148,31 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
se.descriptor_only = 1;
gfc_conv_expr (&se, e);
descriptor = se.expr;
- se.expr = gfc_conv_descriptor_data_addr (se.expr);
- se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
+ se.expr = gfc_conv_descriptor_data_get (se.expr);
}
gfc_free_expr (e);
if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
{
/* Nullify when entering the scope. */
- tmp = fold_build2_loc (input_location, MODIFY_EXPR,
- TREE_TYPE (se.expr), se.expr,
- fold_convert (TREE_TYPE (se.expr),
- null_pointer_node));
+ if (sym->ts.type == BT_CLASS
+ && (CLASS_DATA (sym)->attr.dimension
+ || CLASS_DATA (sym)->attr.codimension))
+ {
+ stmtblock_t nullify;
+ gfc_init_block (&nullify);
+ gfc_conv_descriptor_data_set (&nullify, descriptor,
+ null_pointer_node);
+ tmp = gfc_finish_block (&nullify);
+ }
+ else
+ {
+ tree typed_null = fold_convert (TREE_TYPE (se.expr),
+ null_pointer_node);
+ tmp = fold_build2_loc (input_location, MODIFY_EXPR,
+ TREE_TYPE (se.expr), se.expr,
+ typed_null);
+ }
if (sym->attr.optional)
{
tree present = gfc_conv_expr_present (sym);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index ec24084..e6c3218 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -9583,8 +9583,8 @@ gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
/* Shift the lbound and ubound of temporaries to being unity,
rather than zero, based. Always calculate the offset. */
+ gfc_conv_descriptor_offset_set (&block, dest, gfc_index_zero_node);
offset = gfc_conv_descriptor_offset_get (dest);
- gfc_add_modify (&block, offset, gfc_index_zero_node);
tmp2 =gfc_create_var (gfc_array_index_type, NULL);
for (n = 0; n < expr->rank; n++)
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index b4ddf75..4f2f4da 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -2494,9 +2494,10 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
{
tmp = sym->backend_decl;
if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
- tmp = gfc_conv_descriptor_data_get (tmp);
- gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
- null_pointer_node));
+ gfc_conv_descriptor_data_set (&se.pre, tmp, null_pointer_node);
+ else
+ gfc_add_modify (&se.pre, tmp,
+ fold_convert (TREE_TYPE (tmp), null_pointer_node));
}
lhs = gfc_lval_expr_from_sym (sym);
diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index 13fd5ad..47396c3 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -1740,7 +1740,7 @@ gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
gfc_call_free (data_ptr),
build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->loop->post, tmp);
- gfc_add_modify (&se->loop->post, data_ptr, data_null);
+ gfc_conv_descriptor_data_set (&se->loop->post, desc, data_null);
}
else
{
@@ -1754,7 +1754,7 @@ gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
gfc_call_free (data_ptr),
build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->finalblock, tmp);
- gfc_add_modify (&se->finalblock, data_ptr, data_null);
+ gfc_conv_descriptor_data_set (&se->finalblock, desc, data_null);
}
}
}
diff --git a/gcc/function.cc b/gcc/function.cc
index 2b77bbd..5a054a9 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -4965,6 +4965,10 @@ prepare_function_start (void)
/* Indicate we have no need of a frame pointer yet. */
frame_pointer_needed = 0;
+
+ /* Reset the cache of the "extended" flag in the target's
+ _BitInt info struct. */
+ bitint_extended = -1;
}
void
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 835e113..c919b3d 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -100,6 +100,7 @@ GRS_OBJS = \
rust/rust-derive-default.o \
rust/rust-derive-partial-eq.o \
rust/rust-derive-eq.o \
+ rust/rust-derive-ord.o \
rust/rust-derive-hash.o \
rust/rust-proc-macro.o \
rust/rust-macro-invoc-lexer.o \
@@ -123,7 +124,6 @@ GRS_OBJS = \
rust/rust-keyword-values.o \
rust/rust-abi.o \
rust/rust-token-converter.o \
- rust/rust-macro.o \
rust/rust-ast-lower.o \
rust/rust-ast-lower-base.o \
rust/rust-ast-lower-pattern.o \
@@ -242,6 +242,7 @@ GRS_OBJS = \
rust/rust-collect-lang-items.o \
rust/rust-desugar-for-loops.o \
rust/rust-desugar-question-mark.o \
+ rust/rust-desugar-apit.o \
$(END)
# removed object files from here
diff --git a/gcc/rust/ast/rust-ast-builder-type.cc b/gcc/rust/ast/rust-ast-builder-type.cc
index 13126b4..7f8571a 100644
--- a/gcc/rust/ast/rust-ast-builder-type.cc
+++ b/gcc/rust/ast/rust-ast-builder-type.cc
@@ -62,7 +62,8 @@ ASTTypeBuilder::visit (TypePath &path)
{
switch (seg->get_type ())
{
- case TypePathSegment::REG: {
+ case TypePathSegment::REG:
+ {
const TypePathSegment &segment
= (const TypePathSegment &) (*seg.get ());
TypePathSegment *s
@@ -74,7 +75,8 @@ ASTTypeBuilder::visit (TypePath &path)
}
break;
- case TypePathSegment::GENERIC: {
+ case TypePathSegment::GENERIC:
+ {
TypePathSegmentGeneric &generic
= (TypePathSegmentGeneric &) (*seg.get ());
@@ -89,7 +91,8 @@ ASTTypeBuilder::visit (TypePath &path)
}
break;
- case TypePathSegment::FUNCTION: {
+ case TypePathSegment::FUNCTION:
+ {
rust_unreachable ();
// TODO
// const TypePathSegmentFunction &fn
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 08c52b1..fbc8f27 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -442,6 +442,14 @@ Builder::field_access (std::unique_ptr<Expr> &&instance,
new FieldAccessExpr (std::move (instance), field, {}, loc));
}
+std::unique_ptr<StructPatternField>
+Builder::struct_pattern_ident_pattern (std::string field_name,
+ std::unique_ptr<Pattern> &&pattern)
+{
+ return std::make_unique<StructPatternFieldIdentPat> (
+ field_name, std::move (pattern), std::vector<Attribute> (), loc);
+}
+
std::unique_ptr<Pattern>
Builder::wildcard () const
{
@@ -566,7 +574,8 @@ Builder::new_type_param (
{
switch (b->get_bound_type ())
{
- case TypeParamBound::TypeParamBoundType::TRAIT: {
+ case TypeParamBound::TypeParamBoundType::TRAIT:
+ {
const TraitBound &tb = (const TraitBound &) *b.get ();
const TypePath &path = tb.get_type_path ();
@@ -591,7 +600,8 @@ Builder::new_type_param (
{
switch (seg->get_type ())
{
- case TypePathSegment::REG: {
+ case TypePathSegment::REG:
+ {
const TypePathSegment &segment
= (const TypePathSegment &) (*seg.get ());
TypePathSegment *s = new TypePathSegment (
@@ -603,7 +613,8 @@ Builder::new_type_param (
}
break;
- case TypePathSegment::GENERIC: {
+ case TypePathSegment::GENERIC:
+ {
TypePathSegmentGeneric &generic
= (TypePathSegmentGeneric &) (*seg.get ());
@@ -617,7 +628,8 @@ Builder::new_type_param (
}
break;
- case TypePathSegment::FUNCTION: {
+ case TypePathSegment::FUNCTION:
+ {
rust_unreachable ();
// TODO
// const TypePathSegmentFunction &fn
@@ -639,7 +651,8 @@ Builder::new_type_param (
}
break;
- case TypeParamBound::TypeParamBoundType::LIFETIME: {
+ case TypeParamBound::TypeParamBoundType::LIFETIME:
+ {
const Lifetime &l = (const Lifetime &) *b.get ();
auto bl = new Lifetime (l.get_lifetime_type (),
@@ -692,7 +705,8 @@ Builder::new_generic_args (GenericArgs &args)
{
switch (arg.get_kind ())
{
- case GenericArg::Kind::Type: {
+ case GenericArg::Kind::Type:
+ {
std::unique_ptr<Type> ty = new_type (arg.get_type ());
GenericArg arg = GenericArg::create_type (std::move (ty));
}
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 41ce118..a5115b68 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -254,6 +254,10 @@ public:
std::unique_ptr<Expr> field_access (std::unique_ptr<Expr> &&instance,
std::string field) const;
+ std::unique_ptr<StructPatternField>
+ struct_pattern_ident_pattern (std::string field_name,
+ std::unique_ptr<Pattern> &&pattern);
+
/* Create a wildcard pattern (`_`) */
std::unique_ptr<Pattern> wildcard () const;
/* Create a reference pattern (`&pattern`) */
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index c850e96..b0e06ab 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -154,20 +154,24 @@ TokenCollector::visit (Attribute &attrib)
{
switch (attrib.get_attr_input ().get_attr_input_type ())
{
- case AST::AttrInput::AttrInputType::LITERAL: {
+ case AST::AttrInput::AttrInputType::LITERAL:
+ {
visit (static_cast<AttrInputLiteral &> (attrib.get_attr_input ()));
break;
}
- case AST::AttrInput::AttrInputType::MACRO: {
+ case AST::AttrInput::AttrInputType::MACRO:
+ {
visit (static_cast<AttrInputMacro &> (attrib.get_attr_input ()));
break;
}
- case AST::AttrInput::AttrInputType::META_ITEM: {
+ case AST::AttrInput::AttrInputType::META_ITEM:
+ {
visit (static_cast<AttrInputMetaItemContainer &> (
attrib.get_attr_input ()));
break;
}
- case AST::AttrInput::AttrInputType::TOKEN_TREE: {
+ case AST::AttrInput::AttrInputType::TOKEN_TREE:
+ {
visit (static_cast<DelimTokenTree &> (attrib.get_attr_input ()));
break;
}
@@ -634,7 +638,8 @@ TokenCollector::visit (GenericArg &arg)
case GenericArg::Kind::Type:
visit (arg.get_type ());
break;
- case GenericArg::Kind::Either: {
+ case GenericArg::Kind::Either:
+ {
auto path = arg.get_path ();
push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (path)));
}
@@ -789,7 +794,8 @@ TokenCollector::visit (Literal &lit, location_t locus)
push (Rust::Token::make_float (locus, std::move (value),
lit.get_type_hint ()));
break;
- case Literal::LitType::BOOL: {
+ case Literal::LitType::BOOL:
+ {
if (value == Values::Keywords::FALSE_LITERAL)
push (Rust::Token::make (FALSE_LITERAL, locus));
else if (value == Values::Keywords::TRUE_LITERAL)
@@ -1264,12 +1270,28 @@ TokenCollector::visit (BlockExpr &expr)
}
void
+TokenCollector::visit (AnonConst &expr)
+{
+ visit (expr.get_inner_expr ());
+}
+
+void
+TokenCollector::visit (ConstBlock &expr)
+{
+ push (Rust::Token::make (CONST, expr.get_locus ()));
+
+ // The inner expression is already a block expr, so we don't need to add
+ // curlies
+ visit (expr.get_const_expr ());
+}
+
+void
TokenCollector::visit (ClosureExprInnerTyped &expr)
{
visit_closure_common (expr);
push (Rust::Token::make (RETURN_TYPE, expr.get_locus ()));
visit (expr.get_return_type ());
- visit (expr.get_definition_block ());
+ visit (expr.get_definition_expr ());
}
void
@@ -1518,7 +1540,95 @@ TokenCollector::visit (AsyncBlockExpr &expr)
void
TokenCollector::visit (InlineAsm &expr)
-{}
+{
+ push (Rust::Token::make_identifier (expr.get_locus (), "asm"));
+ push (Rust::Token::make (EXCLAM, expr.get_locus ()));
+ push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
+
+ for (auto &template_str : expr.get_template_strs ())
+ push (Rust::Token::make_string (template_str.get_locus (),
+ std::move (template_str.symbol)));
+
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+
+ for (auto &operand : expr.get_operands ())
+ {
+ using RegisterType = AST::InlineAsmOperand::RegisterType;
+ switch (operand.get_register_type ())
+ {
+ case RegisterType::In:
+ {
+ visit (operand.get_in ().expr);
+ break;
+ }
+ case RegisterType::Out:
+ {
+ visit (operand.get_out ().expr);
+ break;
+ }
+ case RegisterType::InOut:
+ {
+ visit (operand.get_in_out ().expr);
+ break;
+ }
+ case RegisterType::SplitInOut:
+ {
+ auto split = operand.get_split_in_out ();
+ visit (split.in_expr);
+ visit (split.out_expr);
+ break;
+ }
+ case RegisterType::Const:
+ {
+ visit (operand.get_const ().anon_const.get_inner_expr ());
+ break;
+ }
+ case RegisterType::Sym:
+ {
+ visit (operand.get_sym ().expr);
+ break;
+ }
+ case RegisterType::Label:
+ {
+ visit (operand.get_label ().expr);
+ break;
+ }
+ }
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+
+ for (auto &clobber : expr.get_clobber_abi ())
+ {
+ push (Rust::Token::make_string (expr.get_locus (),
+ std::move (clobber.symbol)));
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+
+ for (auto it = expr.named_args.begin (); it != expr.named_args.end (); ++it)
+ {
+ auto &arg = *it;
+ push (
+ Rust::Token::make_identifier (expr.get_locus (), arg.first.c_str ()));
+ push (Rust::Token::make (EQUAL, expr.get_locus ()));
+ push (Rust::Token::make_identifier (expr.get_locus (),
+ std::to_string (arg.second)));
+
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+
+ push (Rust::Token::make (COLON, expr.get_locus ()));
+
+ for (auto &option : expr.get_options ())
+ {
+ push (Rust::Token::make_identifier (
+ expr.get_locus (), InlineAsm::option_to_string (option).c_str ()));
+ push (Rust::Token::make (COMMA, expr.get_locus ()));
+ }
+
+ push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
+}
void
TokenCollector::visit (LlvmInlineAsm &expr)
@@ -1695,7 +1805,8 @@ TokenCollector::visit (UseTreeGlob &use_tree)
{
switch (use_tree.get_glob_type ())
{
- case UseTreeGlob::PathType::PATH_PREFIXED: {
+ case UseTreeGlob::PathType::PATH_PREFIXED:
+ {
auto path = use_tree.get_path ();
visit (path);
push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
@@ -1715,7 +1826,8 @@ TokenCollector::visit (UseTreeList &use_tree)
{
switch (use_tree.get_path_type ())
{
- case UseTreeList::PathType::PATH_PREFIXED: {
+ case UseTreeList::PathType::PATH_PREFIXED:
+ {
auto path = use_tree.get_path ();
visit (path);
push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
@@ -1743,7 +1855,8 @@ TokenCollector::visit (UseTreeRebind &use_tree)
visit (path);
switch (use_tree.get_new_bind_type ())
{
- case UseTreeRebind::NewBindType::IDENTIFIER: {
+ case UseTreeRebind::NewBindType::IDENTIFIER:
+ {
push (Rust::Token::make (AS, UNDEF_LOCATION));
auto id = use_tree.get_identifier ().as_string ();
push (
@@ -1964,8 +2077,7 @@ TokenCollector::visit (ConstantItem &item)
}
else
{
- auto id = item.get_identifier ();
- push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
+ push (Rust::Token::make_identifier (item.get_identifier ()));
}
push (Rust::Token::make (COLON, UNDEF_LOCATION));
visit (item.get_type ());
@@ -2370,7 +2482,7 @@ TokenCollector::visit (IdentifierPattern &pattern)
auto id = pattern.get_ident ().as_string ();
push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
- if (pattern.has_pattern_to_bind ())
+ if (pattern.has_subpattern ())
{
push (Rust::Token::make (PATTERN_BIND, UNDEF_LOCATION));
visit (pattern.get_pattern_to_bind ());
diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h
index f45e3cc..cec2365 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -277,6 +277,8 @@ public:
void visit (ClosureParam &param);
void visit (ClosureExprInner &expr);
void visit (BlockExpr &expr);
+ void visit (AnonConst &expr);
+ void visit (ConstBlock &expr);
void visit (ClosureExprInnerTyped &expr);
void visit (ContinueExpr &expr);
void visit (BreakExpr &expr);
diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 02c99b7..0c3875e 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -49,7 +49,8 @@ public:
{
switch (item.get_kind ())
{
- case AST::CollectItem::Kind::Token: {
+ case AST::CollectItem::Kind::Token:
+ {
TokenPtr current = item.get_token ();
if (require_spacing (previous, current))
stream << " ";
@@ -90,7 +91,6 @@ private:
} // namespace Rust
// In the global namespace to make it easier to call from debugger
-void
-debug (Rust::AST::Visitable &v);
+void debug (Rust::AST::Visitable &v);
#endif // !RUST_AST_DUMP_H
diff --git a/gcc/rust/ast/rust-ast-formatting.h b/gcc/rust/ast/rust-ast-formatting.h
index 3dfabbc..aace93f 100644
--- a/gcc/rust/ast/rust-ast-formatting.h
+++ b/gcc/rust/ast/rust-ast-formatting.h
@@ -35,23 +35,18 @@ enum AttrMode
INNER
};
-std::string
-indent_spaces (enum indent_mode mode);
+std::string indent_spaces (enum indent_mode mode);
// Gets a string in a certain delim type.
-std::string
-get_string_in_delims (std::string str_input, DelimType delim_type);
+std::string get_string_in_delims (std::string str_input, DelimType delim_type);
-std::string
-get_mode_dump_desc (AttrMode mode);
+std::string get_mode_dump_desc (AttrMode mode);
// Adds lines below adding attributes
-std::string
-append_attributes (std::vector<Attribute> attrs, AttrMode mode);
+std::string append_attributes (std::vector<Attribute> attrs, AttrMode mode);
// Removes the beginning and end quotes of a quoted string.
-std::string
-unquote_string (std::string input);
+std::string unquote_string (std::string input);
} // namespace AST
} // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h
index 9359248..b410f3a 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -115,6 +115,8 @@ struct ClosureParam;
class ClosureExpr;
class ClosureExprInner;
class BlockExpr;
+class AnonConst;
+class ConstBlock;
class ClosureExprInnerTyped;
class ContinueExpr;
class BreakExpr;
@@ -146,7 +148,6 @@ class MatchExpr;
class AwaitExpr;
class AsyncBlockExpr;
enum class InlineAsmOption;
-struct AnonConst;
struct InlineAsmRegOrRegClass;
class InlineAsmOperand;
struct InlineAsmPlaceHolder;
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index b6833f6..02f4f16 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -456,13 +456,25 @@ DefaultASTVisitor::visit (AST::BlockExpr &expr)
}
void
+DefaultASTVisitor::visit (AST::ConstBlock &expr)
+{
+ visit (expr.get_const_expr ());
+}
+
+void
+DefaultASTVisitor::visit (AST::AnonConst &expr)
+{
+ visit (expr.get_inner_expr ());
+}
+
+void
DefaultASTVisitor::visit (AST::ClosureExprInnerTyped &expr)
{
visit_outer_attrs (expr);
for (auto &param : expr.get_params ())
visit (param);
visit (expr.get_return_type ());
- visit (expr.get_definition_block ());
+ visit (expr.get_definition_expr ());
}
void
@@ -680,33 +692,40 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr)
{
switch (operand.get_register_type ())
{
- case RegisterType::In: {
+ case RegisterType::In:
+ {
visit (operand.get_in ().expr);
break;
}
- case RegisterType::Out: {
+ case RegisterType::Out:
+ {
visit (operand.get_out ().expr);
break;
}
- case RegisterType::InOut: {
+ case RegisterType::InOut:
+ {
visit (operand.get_in_out ().expr);
break;
}
- case RegisterType::SplitInOut: {
+ case RegisterType::SplitInOut:
+ {
auto split = operand.get_split_in_out ();
visit (split.in_expr);
visit (split.out_expr);
break;
}
- case RegisterType::Const: {
- visit (operand.get_const ().anon_const.expr);
+ case RegisterType::Const:
+ {
+ visit (operand.get_const ().anon_const.get_inner_expr ());
break;
}
- case RegisterType::Sym: {
+ case RegisterType::Sym:
+ {
visit (operand.get_sym ().expr);
break;
}
- case RegisterType::Label: {
+ case RegisterType::Label:
+ {
visit (operand.get_label ().expr);
break;
}
@@ -755,7 +774,8 @@ DefaultASTVisitor::visit (AST::TypeBoundWhereClauseItem &item)
void
DefaultASTVisitor::visit (AST::Visibility &vis)
{
- visit (vis.get_path ());
+ if (vis.has_path ())
+ visit (vis.get_path ());
}
void
@@ -922,7 +942,7 @@ DefaultASTVisitor::visit (AST::EnumItem &item)
void
DefaultASTVisitor::visit (AST::EnumItemTuple &item)
{
- visit (reinterpret_cast<EnumItem &> (item));
+ DefaultASTVisitor::visit (reinterpret_cast<EnumItem &> (item));
for (auto &field : item.get_tuple_fields ())
visit (field);
}
@@ -930,7 +950,7 @@ DefaultASTVisitor::visit (AST::EnumItemTuple &item)
void
DefaultASTVisitor::visit (AST::EnumItemStruct &item)
{
- visit (reinterpret_cast<EnumItem &> (item));
+ DefaultASTVisitor::visit (reinterpret_cast<EnumItem &> (item));
for (auto &field : item.get_struct_fields ())
visit (field);
}
@@ -938,7 +958,7 @@ DefaultASTVisitor::visit (AST::EnumItemStruct &item)
void
DefaultASTVisitor::visit (AST::EnumItemDiscriminant &item)
{
- visit (reinterpret_cast<EnumItem &> (item));
+ DefaultASTVisitor::visit (reinterpret_cast<EnumItem &> (item));
visit (item.get_expr ());
}
@@ -1179,7 +1199,7 @@ DefaultASTVisitor::visit (AST::LiteralPattern &pattern)
void
DefaultASTVisitor::visit (AST::IdentifierPattern &pattern)
{
- if (pattern.has_pattern_to_bind ())
+ if (pattern.has_subpattern ())
visit (pattern.get_pattern_to_bind ());
}
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index b1fc504..22fd98b 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -104,6 +104,8 @@ public:
virtual void visit (FieldAccessExpr &expr) = 0;
virtual void visit (ClosureExprInner &expr) = 0;
virtual void visit (BlockExpr &expr) = 0;
+ virtual void visit (AnonConst &expr) = 0;
+ virtual void visit (ConstBlock &expr) = 0;
virtual void visit (ClosureExprInnerTyped &expr) = 0;
virtual void visit (ContinueExpr &expr) = 0;
virtual void visit (BreakExpr &expr) = 0;
@@ -293,6 +295,8 @@ public:
virtual void visit (AST::FieldAccessExpr &expr) override;
virtual void visit (AST::ClosureExprInner &expr) override;
virtual void visit (AST::BlockExpr &expr) override;
+ virtual void visit (AST::AnonConst &expr) override;
+ virtual void visit (AST::ConstBlock &expr) override;
virtual void visit (AST::ClosureExprInnerTyped &expr) override;
virtual void visit (AST::ContinueExpr &expr) override;
virtual void visit (AST::BreakExpr &expr) override;
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 4e82be4..916829f 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -249,27 +249,31 @@ Attribute::get_traits_to_derive ()
auto &input = get_attr_input ();
switch (input.get_attr_input_type ())
{
- case AST::AttrInput::META_ITEM: {
+ case AST::AttrInput::META_ITEM:
+ {
auto &meta = static_cast<AST::AttrInputMetaItemContainer &> (input);
for (auto &current : meta.get_items ())
{
// HACK: Find a better way to achieve the downcast.
switch (current->get_kind ())
{
- case AST::MetaItemInner::Kind::MetaItem: {
+ case AST::MetaItemInner::Kind::MetaItem:
+ {
// Let raw pointer go out of scope without freeing, it doesn't
// own the data anyway
auto meta_item
= static_cast<AST::MetaItem *> (current.get ());
switch (meta_item->get_item_kind ())
{
- case AST::MetaItem::ItemKind::Path: {
+ case AST::MetaItem::ItemKind::Path:
+ {
auto path
= static_cast<AST::MetaItemPath *> (meta_item);
result.push_back (path->get_path ());
}
break;
- case AST::MetaItem::ItemKind::Word: {
+ case AST::MetaItem::ItemKind::Word:
+ {
auto word = static_cast<AST::MetaWord *> (meta_item);
// Convert current word to path
current = std::make_unique<AST::MetaItemPath> (
@@ -620,7 +624,7 @@ ConstantItem::as_string () const
{
std::string str = VisItem::as_string ();
- str += "const " + identifier;
+ str += "const " + identifier.as_string ();
// DEBUG: null pointer check
if (type == nullptr)
@@ -782,7 +786,8 @@ UseTreeGlob::as_string () const
return "*";
case GLOBAL:
return "::*";
- case PATH_PREFIXED: {
+ case PATH_PREFIXED:
+ {
std::string path_str = path.as_string ();
return path_str + "::*";
}
@@ -805,7 +810,8 @@ UseTreeList::as_string () const
case GLOBAL:
path_str = "::{";
break;
- case PATH_PREFIXED: {
+ case PATH_PREFIXED:
+ {
path_str = path.as_string () + "::{";
break;
}
@@ -1272,6 +1278,18 @@ BlockExpr::as_string () const
}
std::string
+AnonConst::as_string () const
+{
+ return "AnonConst: " + expr->as_string ();
+}
+
+std::string
+ConstBlock::as_string () const
+{
+ return "ConstBlock: " + expr.as_string ();
+}
+
+std::string
TraitImpl::as_string () const
{
std::string str = VisItem::as_string ();
@@ -2714,7 +2732,7 @@ ImplTraitTypeOneBound::as_string () const
{
std::string str ("ImplTraitTypeOneBound: \n TraitBound: ");
- return str + trait_bound.as_string ();
+ return str + trait_bound->as_string ();
}
std::string
@@ -3653,14 +3671,16 @@ AttributeParser::parse_path_meta_item ()
switch (peek_token ()->get_id ())
{
- case LEFT_PAREN: {
+ case LEFT_PAREN:
+ {
std::vector<std::unique_ptr<MetaItemInner>> meta_items
= parse_meta_item_seq ();
return std::unique_ptr<MetaItemSeq> (
new MetaItemSeq (std::move (path), std::move (meta_items)));
}
- case EQUAL: {
+ case EQUAL:
+ {
skip_token ();
location_t locus = peek_token ()->get_locus ();
@@ -4513,6 +4533,18 @@ BlockExpr::accept_vis (ASTVisitor &vis)
}
void
+AnonConst::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+ConstBlock::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
ClosureExprInnerTyped::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
@@ -5047,7 +5079,8 @@ FormatArgs::get_outer_attrs ()
rust_unreachable ();
}
-void FormatArgs::set_outer_attrs (std::vector<Attribute>)
+void
+FormatArgs::set_outer_attrs (std::vector<Attribute>)
{
rust_unreachable ();
}
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index aa6ad50..cd586c6 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -62,13 +62,14 @@ public:
return ident == other.ident;
}
+ operator const std::string & () const { return ident; }
+
private:
std::string ident;
location_t loc;
};
-std::ostream &
-operator<< (std::ostream &os, Identifier const &i);
+std::ostream &operator<< (std::ostream &os, Identifier const &i);
namespace AST {
// foward decl: ast visitor
@@ -403,15 +404,15 @@ class SimplePath
public:
// Constructor
- SimplePath (std::vector<SimplePathSegment> path_segments,
- bool has_opening_scope_resolution = false,
- location_t locus = UNDEF_LOCATION)
+ explicit SimplePath (std::vector<SimplePathSegment> path_segments,
+ bool has_opening_scope_resolution = false,
+ location_t locus = UNDEF_LOCATION)
: opening_scope_resolution (has_opening_scope_resolution),
segments (std::move (path_segments)), locus (locus),
node_id (Analysis::Mappings::get ().get_next_node_id ())
{}
- SimplePath (Identifier ident)
+ explicit SimplePath (Identifier ident)
: opening_scope_resolution (false),
segments ({SimplePathSegment (ident.as_string (), ident.get_locus ())}),
locus (ident.get_locus ()),
@@ -1256,6 +1257,8 @@ public:
FieldAccess,
Closure,
Block,
+ ConstExpr,
+ ConstBlock,
Continue,
Break,
Range,
diff --git a/gcc/rust/ast/rust-collect-lang-items.cc b/gcc/rust/ast/rust-collect-lang-items.cc
index cd6be7f..306c6f7 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -109,5 +109,29 @@ CollectLangItems::visit (AST::EnumItem &item)
DefaultASTVisitor::visit (item);
}
+void
+CollectLangItems::visit (AST::EnumItemTuple &item)
+{
+ maybe_add_lang_item (item);
+
+ DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::EnumItemStruct &item)
+{
+ maybe_add_lang_item (item);
+
+ DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::EnumItemDiscriminant &item)
+{
+ maybe_add_lang_item (item);
+
+ DefaultASTVisitor::visit (item);
+}
+
} // namespace AST
} // namespace Rust
diff --git a/gcc/rust/ast/rust-collect-lang-items.h b/gcc/rust/ast/rust-collect-lang-items.h
index ddb34a9..ddc7b51 100644
--- a/gcc/rust/ast/rust-collect-lang-items.h
+++ b/gcc/rust/ast/rust-collect-lang-items.h
@@ -50,6 +50,9 @@ public:
void visit (AST::Function &item) override;
void visit (AST::StructStruct &item) override;
void visit (AST::EnumItem &item) override;
+ void visit (AST::EnumItemTuple &item) override;
+ void visit (AST::EnumItemStruct &item) override;
+ void visit (AST::EnumItemDiscriminant &item) override;
private:
template <typename T> void maybe_add_lang_item (const T &item);
diff --git a/gcc/rust/ast/rust-cond-compilation.h b/gcc/rust/ast/rust-cond-compilation.h
index 610b904..56a5646 100644
--- a/gcc/rust/ast/rust-cond-compilation.h
+++ b/gcc/rust/ast/rust-cond-compilation.h
@@ -42,8 +42,8 @@ public:
protected:
// Clone function impl to be overriden in base classes
- virtual ConfigurationPredicate *
- clone_configuration_predicate_impl () const = 0;
+ virtual ConfigurationPredicate *clone_configuration_predicate_impl () const
+ = 0;
};
// A configuration option - true if option is set, false if option is not set.
diff --git a/gcc/rust/ast/rust-desugar-apit.cc b/gcc/rust/ast/rust-desugar-apit.cc
new file mode 100644
index 0000000..bca14ee
--- /dev/null
+++ b/gcc/rust/ast/rust-desugar-apit.cc
@@ -0,0 +1,522 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-desugar-apit.h"
+#include "rust-ast.h"
+#include "rust-type.h"
+
+namespace Rust {
+namespace AST {
+
+class DesugarApitType : public DefaultASTVisitor
+{
+ using DefaultASTVisitor::visit;
+
+public:
+ static std::pair<AST::Type *, std::vector<std::unique_ptr<GenericParam>>>
+ Desugar (AST::Type &type)
+ {
+ DesugarApitType visitor (&type);
+ type.accept_vis (visitor);
+ rust_assert (visitor.translated != nullptr);
+ return std::make_pair (visitor.translated,
+ std::move (visitor.implicit_generic_params));
+ }
+
+ // Generate a unique impl trait parameter name
+ static Identifier get_impl_name ()
+ {
+ static size_t counter = 0;
+ return Identifier ("Impl_" + std::to_string (counter++));
+ }
+
+ // these can hold other types
+ void visit (AST::TupleType &tuple) override
+ {
+ for (auto &elem : tuple.get_elems ())
+ {
+ auto &type = *elem.get ();
+ auto desugar = Desugar (type);
+ auto tt = desugar.first;
+
+ auto &implicit_generics = desugar.second;
+ if (implicit_generics.empty ())
+ continue;
+
+ if (tt != elem.get ())
+ elem = std::unique_ptr<Type> (tt);
+
+ for (auto &implicit_generic : implicit_generics)
+ implicit_generic_params.push_back (std::move (implicit_generic));
+ }
+ }
+
+ void visit (AST::ArrayType &type) override
+ {
+ auto &element_type = type.get_element_type ();
+ auto desugar = Desugar (*element_type);
+ auto tt = desugar.first;
+
+ auto &implicit_generics = desugar.second;
+ if (implicit_generics.empty ())
+ return;
+
+ if (tt != element_type.get ())
+ element_type = std::unique_ptr<AST::Type> (tt);
+
+ for (auto &implicit_generic : implicit_generics)
+ implicit_generic_params.push_back (std::move (implicit_generic));
+ }
+
+ void visit (AST::ReferenceType &type) override
+ {
+ // Get a reference to the current type for in-place modification
+ auto &referenced_type = type.get_type_referenced ();
+ auto desugar = Desugar (referenced_type);
+ auto tt = desugar.first;
+
+ auto &implicit_generics = desugar.second;
+ if (implicit_generics.empty ())
+ return;
+
+ // Update the reference type's contents rather than creating a new one
+ if (&referenced_type != tt)
+ {
+ std::unique_ptr<AST::TypeNoBounds> new_type_no_bounds (
+ static_cast<AST::TypeNoBounds *> (tt));
+ type.get_type_ptr () = std::move (new_type_no_bounds);
+ }
+
+ // Collect all the implicit generic parameters we found
+ for (auto &implicit_generic : implicit_generics)
+ implicit_generic_params.push_back (std::move (implicit_generic));
+ }
+
+ void visit (AST::RawPointerType &type) override
+ {
+ auto &pointed_type = type.get_type_pointed_to ();
+ auto desugar = Desugar (pointed_type);
+ auto tt = desugar.first;
+
+ auto &implicit_generics = desugar.second;
+ if (implicit_generics.empty ())
+ return;
+
+ // Update the pointer's inner type directly using the new accessor
+ if (&pointed_type != tt)
+ {
+ std::unique_ptr<AST::TypeNoBounds> new_type_no_bounds (
+ static_cast<AST::TypeNoBounds *> (tt));
+ type.get_type_ptr () = std::move (new_type_no_bounds);
+ }
+
+ // Collect all the implicit generic parameters we found
+ for (auto &implicit_generic : implicit_generics)
+ implicit_generic_params.push_back (std::move (implicit_generic));
+ }
+
+ void visit (AST::SliceType &type) override
+ {
+ auto &element_type = type.get_elem_type ();
+ auto desugar = Desugar (element_type);
+ auto tt = desugar.first;
+
+ auto &implicit_generics = desugar.second;
+ if (implicit_generics.empty ())
+ return;
+
+ if (&element_type != tt)
+ {
+ std::unique_ptr<AST::Type> new_elem_type (tt);
+ type.get_elem_type_ptr () = std::move (new_elem_type);
+ }
+
+ // Collect all the implicit generic parameters we found
+ for (auto &implicit_generic : implicit_generics)
+ implicit_generic_params.push_back (std::move (implicit_generic));
+ }
+
+ void visit (AST::ParenthesisedType &type) override
+ {
+ auto &inner_type_ptr = type.get_type_in_parens ();
+ auto desugar = Desugar (*inner_type_ptr);
+ auto tt = desugar.first;
+
+ auto &implicit_generics = desugar.second;
+ if (implicit_generics.empty ())
+ return;
+
+ if (inner_type_ptr.get () != tt)
+ {
+ std::unique_ptr<AST::Type> new_inner_type (tt);
+ inner_type_ptr = std::move (new_inner_type);
+ }
+
+ // Collect all the implicit generic parameters we found
+ for (auto &implicit_generic : implicit_generics)
+ implicit_generic_params.push_back (std::move (implicit_generic));
+ }
+
+ // this is where the desugar happens
+ void visit (AST::ImplTraitType &type) override
+ {
+ // Generate a unique name using the static method
+ auto ident = get_impl_name ();
+
+ // Create a type path for the new generic parameter
+ // Create a SimplePathSegment with the identifier string
+ auto simple_seg = SimplePathSegment (ident.as_string (), type.get_locus ());
+ // Create a vector of SimplePathSegments for SimplePath constructor
+ std::vector<SimplePathSegment> simple_segs = {simple_seg};
+ // Create a SimplePath
+ auto simple_path = SimplePath (simple_segs, false, type.get_locus ());
+
+ // Convert to TypePath by creating path segments
+ std::vector<std::unique_ptr<TypePathSegment>> segments;
+ segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
+ PathIdentSegment (ident.as_string (), type.get_locus ()), false,
+ type.get_locus ())));
+
+ // Create TypePath from segments
+ auto type_path
+ = new TypePath (std::move (segments), type.get_locus (), false);
+
+ // Convert bounds from impl trait to generic parameter bounds
+ std::vector<std::unique_ptr<TypeParamBound>> bounds;
+ for (auto &bound : type.get_type_param_bounds ())
+ bounds.push_back (bound->clone_type_param_bound ());
+
+ // Create the new generic parameter
+ auto generic_param = std::unique_ptr<TypeParam> (
+ new TypeParam (ident, type.get_locus (), std::move (bounds), nullptr, {},
+ true /*from impl trait*/));
+
+ // Store the generic parameter to be added to the function signature
+ implicit_generic_params.push_back (std::move (generic_param));
+
+ // Replace impl trait with the new type parameter
+ translated = type_path;
+ }
+
+ void visit (AST::ImplTraitTypeOneBound &type) override
+ {
+ // Generate a unique name using the static method
+ auto ident = get_impl_name ();
+
+ // Create a type path for the new generic parameter
+ // Create a SimplePathSegment with the identifier string
+ auto simple_seg = SimplePathSegment (ident.as_string (), type.get_locus ());
+ // Create a vector of SimplePathSegments for SimplePath constructor
+ std::vector<SimplePathSegment> simple_segs = {simple_seg};
+ // Create a SimplePath
+ auto simple_path = SimplePath (simple_segs, false, type.get_locus ());
+
+ // Convert to TypePath by creating path segments
+ std::vector<std::unique_ptr<TypePathSegment>> segments;
+ segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
+ PathIdentSegment (ident.as_string (), type.get_locus ()), false,
+ type.get_locus ())));
+
+ // Create TypePath from segments
+ auto type_path
+ = new TypePath (std::move (segments), type.get_locus (), false);
+
+ // Convert the bound to a generic parameter bound
+ std::vector<std::unique_ptr<TypeParamBound>> bounds;
+ bounds.push_back (std::move (type.get_trait_bound ()));
+
+ // Create the new generic parameter
+ auto generic_param = std::unique_ptr<TypeParam> (
+ new TypeParam (ident, type.get_locus (), std::move (bounds), nullptr, {},
+ true /*from impl trait*/));
+
+ // Store the generic parameter to be added to the function signature
+ implicit_generic_params.push_back (std::move (generic_param));
+
+ // Replace impl trait with the new type parameter
+ translated = type_path;
+ }
+
+private:
+ DesugarApitType (AST::Type *base)
+ : translated (base), implicit_generic_params ()
+ {}
+
+ AST::Type *translated;
+ std::vector<std::unique_ptr<GenericParam>> implicit_generic_params;
+};
+
+// ---------
+
+class ApitBoundProcessor
+{
+public:
+ ApitBoundProcessor (
+ WhereClause &where_clause,
+ std::vector<std::unique_ptr<GenericParam>> &generic_params)
+ : where_clause (where_clause), generic_params (generic_params)
+ {}
+
+ void go (std::vector<std::unique_ptr<GenericParam>> &implicit_generics)
+ {
+ // some desugars are more complex so imagine this case
+ //
+ // pub fn foo(_value: impl Bar<Baz = impl Foo>) -> i32 {
+ // 15
+ // }
+ //
+ // this needs to become:
+ //
+ // pub fn foo<T, U>(_value: T) -> i32
+ // where
+ // T: Bar<Baz = U>,
+ // U: Foo,
+ // {
+ // 15
+ // }
+ //
+ // so we need to walk all the implicit generics and the trait bounds paths
+ // for more generics
+
+ for (auto &implicit_generic : implicit_generics)
+ {
+ switch (implicit_generic->get_kind ())
+ {
+ case GenericParam::Kind::Type:
+ {
+ TypeParam &p
+ = *static_cast<TypeParam *> (implicit_generic.get ());
+
+ process_type_param (p);
+ generic_params.push_back (std::move (implicit_generic));
+ for (auto &synth : synthetic_params)
+ generic_params.push_back (std::move (synth));
+ synthetic_params.clear ();
+ }
+ break;
+
+ default:
+ generic_params.push_back (std::move (implicit_generic));
+ break;
+ }
+ }
+ }
+
+private:
+ void process_type_param (TypeParam &p)
+ {
+ auto &bounds = p.get_type_param_bounds ();
+ std::vector<size_t> bounds_to_remove;
+ for (size_t i = 0; i < bounds.size (); i++)
+ {
+ auto &tb = bounds[i];
+ switch (tb->get_bound_type ())
+ {
+ case TypeParamBound::TypeParamBoundType::TRAIT:
+ {
+ TraitBound &ttb = *static_cast<TraitBound *> (tb.get ());
+ TypePath &path = ttb.get_type_path ();
+ bool deusgared = process_type_path (p, ttb, path);
+ if (deusgared)
+ bounds_to_remove.push_back (i);
+ }
+
+ default:
+ break;
+ }
+ }
+ for (auto it = bounds_to_remove.rbegin (); it != bounds_to_remove.rend ();
+ ++it)
+ bounds.erase (bounds.begin () + *it);
+ }
+
+ bool process_type_path (TypeParam &p, TraitBound &parent, TypePath &path)
+ {
+ bool desugared = false;
+ for (auto &segment : path.get_segments ())
+ {
+ switch (segment->get_type ())
+ {
+ case TypePathSegment::SegmentType::GENERIC:
+ {
+ TypePathSegmentGeneric &seg
+ = *static_cast<TypePathSegmentGeneric *> (segment.get ());
+ desugared |= process_generic_segment (p, parent, path, seg);
+ }
+
+ default:
+ break;
+ }
+ }
+ return desugared;
+ }
+
+ bool process_generic_segment (TypeParam &p, TraitBound &parent,
+ TypePath &path, TypePathSegmentGeneric &seg)
+ {
+ // we need to look for any impl types as default arguments in any generics
+ // and remove this index from the generic arguments by using a where
+ // constraint instead
+
+ std::vector<std::unique_ptr<WhereClauseItem>> new_clauses;
+ GenericArgs &generic_args = seg.get_generic_args ();
+ std::vector<std::reference_wrapper<const GenericArgsBinding>>
+ bindings_desugared;
+ std::vector<GenericArgsBinding> &bindings
+ = generic_args.get_binding_args ();
+
+ for (auto &generic : bindings)
+ {
+ auto &t = generic.get_type ();
+ auto translated = DesugarApitType::Desugar (t);
+ auto tt = translated.first;
+
+ auto &implicit_generics = translated.second;
+ if (implicit_generics.empty ())
+ continue;
+
+ if (tt != &t)
+ {
+ bindings_desugared.push_back (generic);
+ generic.get_type_ptr () = std::unique_ptr<Type> (tt);
+ }
+
+ for (auto &implicit_generic : implicit_generics)
+ {
+ switch (implicit_generic->get_kind ())
+ {
+ case GenericParam::Kind::Type:
+ {
+ TypeParam &tp
+ = *static_cast<TypeParam *> (implicit_generic.get ());
+
+ std::vector<std::unique_ptr<TypeParamBound>>
+ type_param_bounds;
+ for (auto &b : tp.get_type_param_bounds ())
+ type_param_bounds.push_back (std::move (b));
+ tp.get_type_param_bounds ().clear ();
+
+ // add synthetic parameter for this
+ synthetic_params.push_back (std::move (implicit_generic));
+
+ auto bound_type_path
+ = get_type_for_identifier (tp.get_type_representation ());
+
+ auto clause = new TypeBoundWhereClauseItem (
+ {}, std::move (bound_type_path),
+ std::move (type_param_bounds), tp.get_locus ());
+ std::unique_ptr<WhereClauseItem> clause_item
+ = std::unique_ptr<WhereClauseItem> (clause);
+ new_clauses.push_back (std::move (clause_item));
+ }
+ break;
+
+ default:
+ synthetic_params.push_back (std::move (implicit_generic));
+ break;
+ }
+ }
+ }
+
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
+ auto bound = std::unique_ptr<TypeParamBound> (new TraitBound (parent));
+ type_param_bounds.push_back (std::move (bound));
+ auto parent_type_path
+ = get_type_for_identifier (p.get_type_representation ());
+ auto clause
+ = new TypeBoundWhereClauseItem ({}, std::move (parent_type_path),
+ std::move (type_param_bounds),
+ parent.get_locus ());
+ std::unique_ptr<WhereClauseItem> clause_item
+ = std::unique_ptr<WhereClauseItem> (clause);
+ where_clause.get_items ().push_back (std::move (clause_item));
+
+ for (auto &where_item : new_clauses)
+ where_clause.get_items ().push_back (std::move (where_item));
+
+ return !bindings_desugared.empty ();
+ }
+
+ static std::unique_ptr<Type> get_type_for_identifier (const Identifier &ident)
+ {
+ auto simple_seg
+ = SimplePathSegment (ident.as_string (), ident.get_locus ());
+ std::vector<SimplePathSegment> simple_segs = {simple_seg};
+ auto simple_path = SimplePath (simple_segs, false, ident.get_locus ());
+ std::vector<std::unique_ptr<TypePathSegment>> segments;
+ segments.push_back (std::unique_ptr<TypePathSegment> (new TypePathSegment (
+ PathIdentSegment (ident.as_string (), ident.get_locus ()), false,
+ ident.get_locus ())));
+ auto type_path = new TypePath (std::move (segments), ident.get_locus ());
+ return std::unique_ptr<Type> (type_path);
+ }
+
+private:
+ WhereClause &where_clause;
+ std::vector<std::unique_ptr<GenericParam>> &generic_params;
+
+ // mutates
+ std::vector<std::unique_ptr<GenericParam>> synthetic_params;
+};
+
+// ---------
+
+DesugarApit::DesugarApit () {}
+
+void
+DesugarApit::go (AST::Crate &crate)
+{
+ DefaultASTVisitor::visit (crate);
+}
+
+void
+DesugarApit::visit (AST::Function &function)
+{
+ if (!function.has_function_params ())
+ return;
+
+ auto &fn_params = function.get_function_params ();
+ for (auto &param : fn_params)
+ {
+ if (param->is_variadic () || param->is_self ())
+ continue;
+
+ auto *p = param.get ();
+ auto &fp = *static_cast<AST::FunctionParam *> (p);
+ auto &type = fp.get_type ();
+
+ auto translated = DesugarApitType::Desugar (type);
+ auto tt = translated.first;
+
+ auto &implicit_generics = translated.second;
+ if (implicit_generics.empty ())
+ continue;
+
+ if (fp.get_type_ptr ().get () != tt)
+ {
+ fp.get_type_ptr () = std::unique_ptr<AST::Type> (tt);
+ }
+
+ ApitBoundProcessor processor (function.get_where_clause (),
+ function.get_generic_params ());
+ processor.go (implicit_generics);
+ }
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-macro.cc b/gcc/rust/ast/rust-desugar-apit.h
index 2703438..07c25e2 100644
--- a/gcc/rust/ast/rust-macro.cc
+++ b/gcc/rust/ast/rust-desugar-apit.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+// Copyright (C) 2025 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -16,10 +16,27 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include "rust-macro.h"
+#ifndef RUST_DESUGAR_APIT_H
+#define RUST_DESUGAR_APIT_H
+
+#include "rust-ast-visitor.h"
namespace Rust {
namespace AST {
+class DesugarApit : public DefaultASTVisitor
+{
+ using DefaultASTVisitor::visit;
+
+public:
+ DesugarApit ();
+ void go (AST::Crate &);
+
+private:
+ void visit (AST::Function &) override;
+};
+
} // namespace AST
} // namespace Rust
+
+#endif // ! RUST_DESUGAR_APIT_H
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index fdb6360..8f44d58 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -1214,6 +1214,8 @@ protected:
class ArrayElemsCopied : public ArrayElems
{
std::unique_ptr<Expr> elem_to_copy;
+
+ // TODO: This should be replaced by a ConstExpr
std::unique_ptr<Expr> num_copies;
location_t locus;
@@ -2504,6 +2506,8 @@ public:
bool get_has_move () const { return has_move; }
Expr::Kind get_expr_kind () const override { return Expr::Kind::Closure; }
+
+ virtual Expr &get_definition_expr () = 0;
};
// Represents a non-type-specified closure expression AST node
@@ -2563,7 +2567,7 @@ public:
return closure_inner == nullptr;
}
- Expr &get_definition_expr ()
+ Expr &get_definition_expr () override
{
rust_assert (closure_inner != nullptr);
return *closure_inner;
@@ -2744,6 +2748,124 @@ protected:
}
};
+class AnonConst : public ExprWithBlock
+{
+public:
+ AnonConst (std::unique_ptr<Expr> &&expr, location_t locus = UNKNOWN_LOCATION)
+ : ExprWithBlock (), locus (locus), expr (std::move (expr))
+ {
+ rust_assert (this->expr);
+ }
+
+ AnonConst (const AnonConst &other)
+ {
+ node_id = other.node_id;
+ locus = other.locus;
+ expr = other.expr->clone_expr ();
+ }
+
+ AnonConst operator= (const AnonConst &other)
+ {
+ node_id = other.node_id;
+ locus = other.locus;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+ }
+
+ std::string as_string () const override;
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::ConstExpr; }
+
+ location_t get_locus () const override { return locus; }
+ Expr &get_inner_expr () { return *expr; }
+ NodeId get_node_id () const override { return node_id; }
+
+ /* FIXME: AnonConst are always "internal" and should not have outer attributes
+ * - is that true? Or should we instead call
+ * expr->get_outer_attrs()/expr->set_outer_attrs() */
+
+ std::vector<Attribute> &get_outer_attrs () override
+ {
+ static auto attrs = std::vector<Attribute> ();
+ return attrs;
+ }
+
+ void set_outer_attrs (std::vector<Attribute>) override {}
+
+ /* FIXME: Likewise for mark_for_strip() ? */
+ void mark_for_strip () override {}
+ bool is_marked_for_strip () const override { return false; }
+
+ void accept_vis (ASTVisitor &vis) override;
+
+private:
+ location_t locus;
+ std::unique_ptr<Expr> expr;
+
+ AnonConst *clone_expr_with_block_impl () const override
+ {
+ return new AnonConst (*this);
+ }
+};
+
+class ConstBlock : public ExprWithBlock
+{
+public:
+ ConstBlock (AnonConst &&expr, location_t locus = UNKNOWN_LOCATION,
+ std::vector<Attribute> &&outer_attrs = {})
+ : ExprWithBlock (), expr (std::move (expr)),
+ outer_attrs (std::move (outer_attrs)), locus (locus)
+ {}
+
+ ConstBlock (const ConstBlock &other)
+ : ExprWithBlock (other), expr (other.expr), outer_attrs (other.outer_attrs),
+ locus (other.locus)
+ {}
+
+ ConstBlock operator= (const ConstBlock &other)
+ {
+ expr = other.expr;
+ node_id = other.node_id;
+ outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ return *this;
+ }
+
+ std::string as_string () const override;
+
+ Expr::Kind get_expr_kind () const override { return Expr::Kind::ConstBlock; }
+
+ AnonConst &get_const_expr () { return expr; }
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
+
+ void set_outer_attrs (std::vector<Attribute> new_attrs) override
+ {
+ outer_attrs = std::move (new_attrs);
+ }
+
+ location_t get_locus () const override { return locus; }
+
+ bool is_marked_for_strip () const override { return marked_for_strip; }
+ void mark_for_strip () override { marked_for_strip = true; }
+
+private:
+ AnonConst expr;
+
+ std::vector<Attribute> outer_attrs;
+ location_t locus;
+ bool marked_for_strip = false;
+
+ ConstBlock *clone_expr_with_block_impl () const override
+ {
+ return new ConstBlock (*this);
+ }
+};
+
// Represents a type-specified closure expression AST node
class ClosureExprInnerTyped : public ClosureExpr
{
@@ -2812,7 +2934,7 @@ public:
bool is_marked_for_strip () const override { return expr == nullptr; }
// TODO: is this better? Or is a "vis_block" better?
- BlockExpr &get_definition_block ()
+ BlockExpr &get_definition_expr () override
{
rust_assert (expr != nullptr);
return *expr;
@@ -4836,29 +4958,6 @@ enum class InlineAsmOption
MAY_UNWIND = 1 << 8,
};
-struct AnonConst
-{
- NodeId id;
- std::unique_ptr<Expr> expr;
- AnonConst (NodeId id, std::unique_ptr<Expr> expr)
- : id (id), expr (std::move (expr))
- {
- rust_assert (this->expr != nullptr);
- }
- AnonConst (const AnonConst &other)
- {
- id = other.id;
- expr = other.expr->clone_expr ();
- }
-
- AnonConst operator= (const AnonConst &other)
- {
- id = other.id;
- expr = other.expr->clone_expr ();
- return *this;
- }
-};
-
struct InlineAsmRegOrRegClass
{
enum Type
@@ -5288,6 +5387,20 @@ struct TupleTemplateStr
// Inline Assembly Node
class InlineAsm : public ExprWithoutBlock
{
+public:
+ enum class Option
+ {
+ PURE = 1 << 0,
+ NOMEM = 1 << 1,
+ READONLY = 1 << 2,
+ PRESERVES_FLAGS = 1 << 3,
+ NORETURN = 1 << 4,
+ NOSTACK = 1 << 5,
+ ATT_SYNTAX = 1 << 6,
+ RAW = 1 << 7,
+ MAY_UNWIND = 1 << 8,
+ };
+
private:
location_t locus;
// TODO: Not sure how outer_attrs plays with InlineAsm, I put it here in order
@@ -5311,7 +5424,7 @@ public:
std::map<std::string, int> named_args;
std::set<int> reg_args;
std::vector<TupleClobber> clobber_abi;
- std::set<InlineAsmOption> options;
+ std::set<InlineAsm::Option> options;
std::vector<location_t> line_spans;
@@ -5342,7 +5455,7 @@ public:
std::vector<TupleClobber> get_clobber_abi () { return clobber_abi; }
- std::set<InlineAsmOption> get_options () { return options; }
+ std::set<InlineAsm::Option> get_options () { return options; }
InlineAsm *clone_expr_without_block_impl () const override
{
@@ -5350,6 +5463,33 @@ public:
}
Expr::Kind get_expr_kind () const override { return Expr::Kind::InlineAsm; }
+
+ static std::string option_to_string (Option option)
+ {
+ switch (option)
+ {
+ case Option::PURE:
+ return "pure";
+ case Option::NOMEM:
+ return "nomem";
+ case Option::READONLY:
+ return "readonly";
+ case Option::PRESERVES_FLAGS:
+ return "preserves_flags";
+ case Option::NORETURN:
+ return "noreturn";
+ case Option::NOSTACK:
+ return "nostack";
+ case Option::ATT_SYNTAX:
+ return "att_syntax";
+ case Option::RAW:
+ return "raw";
+ case Option::MAY_UNWIND:
+ return "may_unwind";
+ default:
+ rust_unreachable ();
+ }
+ }
};
class LlvmInlineAsm : public ExprWithoutBlock
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index a54faec..3722db2 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -266,11 +266,10 @@ enum ParseMode
extern "C" {
-FormatArgsHandle
-collect_pieces (const char *input, bool append_newline, ParseMode parse_mode);
+FormatArgsHandle collect_pieces (const char *input, bool append_newline,
+ ParseMode parse_mode);
-FormatArgsHandle
-clone_pieces (const FormatArgsHandle &);
+FormatArgsHandle clone_pieces (const FormatArgsHandle &);
void destroy_pieces (FormatArgsHandle);
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 062f85d..d11eed7 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -51,21 +51,12 @@ class TypePath;
// A type generic parameter (as opposed to a lifetime generic parameter)
class TypeParam : public GenericParam
{
- // bool has_outer_attribute;
- // std::unique_ptr<Attribute> outer_attr;
AST::AttrVec outer_attrs;
-
Identifier type_representation;
-
- // bool has_type_param_bounds;
- // TypeParamBounds type_param_bounds;
- std::vector<std::unique_ptr<TypeParamBound>>
- type_param_bounds; // inlined form
-
- // bool has_type;
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
std::unique_ptr<Type> type;
-
location_t locus;
+ bool was_impl_trait;
public:
Identifier get_type_representation () const { return type_representation; }
@@ -85,18 +76,19 @@ public:
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds
= std::vector<std::unique_ptr<TypeParamBound>> (),
std::unique_ptr<Type> type = nullptr,
- AST::AttrVec outer_attrs = {})
+ AST::AttrVec outer_attrs = {}, bool was_impl_trait = false)
: GenericParam (Analysis::Mappings::get ().get_next_node_id ()),
outer_attrs (std::move (outer_attrs)),
type_representation (std::move (type_representation)),
type_param_bounds (std::move (type_param_bounds)),
- type (std::move (type)), locus (locus)
+ type (std::move (type)), locus (locus), was_impl_trait (was_impl_trait)
{}
// Copy constructor uses clone
TypeParam (TypeParam const &other)
: GenericParam (other.node_id), outer_attrs (other.outer_attrs),
- type_representation (other.type_representation), locus (other.locus)
+ type_representation (other.type_representation), locus (other.locus),
+ was_impl_trait (other.was_impl_trait)
{
// guard to prevent null pointer dereference
if (other.type != nullptr)
@@ -114,6 +106,7 @@ public:
outer_attrs = other.outer_attrs;
locus = other.locus;
node_id = other.node_id;
+ was_impl_trait = other.was_impl_trait;
// guard to prevent null pointer dereference
if (other.type != nullptr)
@@ -153,17 +146,19 @@ public:
return type;
}
- // TODO: mutable getter seems kinda dodgy
std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
{
return type_param_bounds;
}
+
const std::vector<std::unique_ptr<TypeParamBound>> &
get_type_param_bounds () const
{
return type_param_bounds;
}
+ bool from_impl_trait () const { return was_impl_trait; }
+
protected:
// Clone function implementation as virtual method
TypeParam *clone_generic_param_impl () const override
@@ -2455,7 +2450,7 @@ class ConstantItem : public VisItem, public AssociatedItem
// either has an identifier or "_" - maybe handle in identifier?
// bool identifier_is_underscore;
// if no identifier declared, identifier will be "_"
- std::string identifier;
+ Identifier identifier;
std::unique_ptr<Type> type;
std::unique_ptr<Expr> const_expr;
@@ -2465,7 +2460,7 @@ class ConstantItem : public VisItem, public AssociatedItem
public:
std::string as_string () const override;
- ConstantItem (std::string ident, Visibility vis, std::unique_ptr<Type> type,
+ ConstantItem (Identifier ident, Visibility vis, std::unique_ptr<Type> type,
std::unique_ptr<Expr> const_expr,
std::vector<Attribute> outer_attrs, location_t locus)
: VisItem (std::move (vis), std::move (outer_attrs)),
@@ -2473,7 +2468,7 @@ public:
const_expr (std::move (const_expr)), locus (locus)
{}
- ConstantItem (std::string ident, Visibility vis, std::unique_ptr<Type> type,
+ ConstantItem (Identifier ident, Visibility vis, std::unique_ptr<Type> type,
std::vector<Attribute> outer_attrs, location_t locus)
: VisItem (std::move (vis), std::move (outer_attrs)),
identifier (std::move (ident)), type (std::move (type)),
@@ -2516,7 +2511,7 @@ public:
/* Returns whether constant item is an "unnamed" (wildcard underscore used
* as identifier) constant. */
- bool is_unnamed () const { return identifier == "_"; }
+ bool is_unnamed () const { return identifier.as_string () == "_"; }
location_t get_locus () const override final { return locus; }
@@ -2561,7 +2556,7 @@ public:
return type;
}
- std::string get_identifier () const { return identifier; }
+ const Identifier &get_identifier () const { return identifier; }
Item::Kind get_item_kind () const override
{
diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index 8e43ddf..793423a 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -266,6 +266,27 @@ TypePath::as_simple_path () const
locus);
}
+std::string
+TypePath::make_debug_string () const
+{
+ rust_assert (!segments.empty ());
+
+ std::string output;
+
+ for (const auto &segment : segments)
+ {
+ if (segment != nullptr && !segment->is_lang_item ()
+ && !segment->is_error ())
+ {
+ if (!output.empty () || has_opening_scope_resolution_op ())
+ output.append ("::");
+ output.append (segment->get_ident_segment ().as_string ());
+ }
+ }
+
+ return output;
+}
+
// hopefully definition here will prevent circular dependency issue
TraitBound *
TypePath::to_trait_bound (bool in_parens) const
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index a4ba93b..11f7248 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -968,11 +968,7 @@ public:
void accept_vis (ASTVisitor &vis) override;
// TODO: is this better? Or is a "vis_pattern" better?
- GenericArgs &get_generic_args ()
- {
- rust_assert (has_generic_args ());
- return generic_args;
- }
+ GenericArgs &get_generic_args () { return generic_args; }
// Use covariance to override base class method
TypePathSegmentGeneric *clone_type_path_segment_impl () const override
@@ -1215,6 +1211,8 @@ public:
std::string as_string () const override;
+ std::string make_debug_string () const;
+
/* Converts TypePath to SimplePath if possible (i.e. no generic or function
* arguments). Otherwise returns an empty SimplePath. */
SimplePath as_simple_path () const;
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index fc7b610..62bf6f2 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -65,8 +65,8 @@ IdentifierPattern::as_string () const
str += variable_ident.as_string ();
- if (has_pattern_to_bind ())
- str += " @ " + to_bind->as_string ();
+ if (has_subpattern ())
+ str += " @ " + subpattern->as_string ();
return str;
}
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 69dbd98..195a08f 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -74,7 +74,7 @@ class IdentifierPattern : public Pattern
bool is_mut;
// bool has_pattern;
- std::unique_ptr<Pattern> to_bind;
+ std::unique_ptr<Pattern> subpattern;
location_t locus;
NodeId node_id;
@@ -82,22 +82,22 @@ public:
std::string as_string () const override;
// Returns whether the IdentifierPattern has a pattern to bind.
- bool has_pattern_to_bind () const { return to_bind != nullptr; }
+ bool has_subpattern () const { return subpattern != nullptr; }
// Constructor
IdentifierPattern (Identifier ident, location_t locus, bool is_ref = false,
bool is_mut = false,
- std::unique_ptr<Pattern> to_bind = nullptr)
+ std::unique_ptr<Pattern> subpattern = nullptr)
: Pattern (), variable_ident (std::move (ident)), is_ref (is_ref),
- is_mut (is_mut), to_bind (std::move (to_bind)), locus (locus),
+ is_mut (is_mut), subpattern (std::move (subpattern)), locus (locus),
node_id (Analysis::Mappings::get ().get_next_node_id ())
{}
IdentifierPattern (NodeId node_id, Identifier ident, location_t locus,
bool is_ref = false, bool is_mut = false,
- std::unique_ptr<Pattern> to_bind = nullptr)
+ std::unique_ptr<Pattern> subpattern = nullptr)
: Pattern (), variable_ident (std::move (ident)), is_ref (is_ref),
- is_mut (is_mut), to_bind (std::move (to_bind)), locus (locus),
+ is_mut (is_mut), subpattern (std::move (subpattern)), locus (locus),
node_id (node_id)
{}
@@ -107,8 +107,8 @@ public:
is_mut (other.is_mut), locus (other.locus), node_id (other.node_id)
{
// fix to get prevent null pointer dereference
- if (other.to_bind != nullptr)
- to_bind = other.to_bind->clone_pattern ();
+ if (other.subpattern != nullptr)
+ subpattern = other.subpattern->clone_pattern ();
}
// Overload assignment operator to use clone
@@ -121,10 +121,10 @@ public:
node_id = other.node_id;
// fix to prevent null pointer dereference
- if (other.to_bind != nullptr)
- to_bind = other.to_bind->clone_pattern ();
+ if (other.subpattern != nullptr)
+ subpattern = other.subpattern->clone_pattern ();
else
- to_bind = nullptr;
+ subpattern = nullptr;
return *this;
}
@@ -140,8 +140,8 @@ public:
// TODO: is this better? Or is a "vis_pattern" better?
Pattern &get_pattern_to_bind ()
{
- rust_assert (has_pattern_to_bind ());
- return *to_bind;
+ rust_assert (has_subpattern ());
+ return *subpattern;
}
Identifier get_ident () const { return variable_ident; }
@@ -375,8 +375,7 @@ enum class RangeKind
EXCLUDED,
};
-RangeKind
-tokenid_to_rangekind (TokenId id);
+RangeKind tokenid_to_rangekind (TokenId id);
// AST node for matching within a certain range (range pattern)
class RangePattern : public Pattern
{
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 1bb521d..6c0652a 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -73,6 +73,13 @@ public:
type_path (std::move (type_path)), locus (locus)
{}
+ TraitBound (TraitBound const &other)
+ : TypeParamBound (other.get_node_id ()), in_parens (other.in_parens),
+ opening_question_mark (other.opening_question_mark),
+ for_lifetimes (other.for_lifetimes), type_path (other.type_path),
+ locus (other.locus)
+ {}
+
std::string as_string () const override;
location_t get_locus () const override final { return locus; }
@@ -305,33 +312,31 @@ public:
// Impl trait with a single bound? Poor reference material here.
class ImplTraitTypeOneBound : public TypeNoBounds
{
- TraitBound trait_bound;
+ std::unique_ptr<TypeParamBound> trait_bound;
location_t locus;
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- ImplTraitTypeOneBound *clone_type_no_bounds_impl () const override
- {
- return new ImplTraitTypeOneBound (*this);
- }
-
public:
- ImplTraitTypeOneBound (TraitBound trait_bound, location_t locus)
+ ImplTraitTypeOneBound (std::unique_ptr<TypeParamBound> trait_bound,
+ location_t locus)
: trait_bound (std::move (trait_bound)), locus (locus)
{}
+ ImplTraitTypeOneBound (ImplTraitTypeOneBound const &other)
+ : trait_bound (other.trait_bound->clone_type_param_bound ()),
+ locus (other.locus)
+ {}
+
std::string as_string () const override;
location_t get_locus () const override final { return locus; }
void accept_vis (ASTVisitor &vis) override;
- // TODO: would a "vis_type" be better?
- TraitBound &get_trait_bound ()
+ std::unique_ptr<TypeParamBound> &get_trait_bound () { return trait_bound; }
+
+ TypeNoBounds *clone_type_no_bounds_impl () const override
{
- // TODO: check to ensure invariants are met?
- return trait_bound;
+ return new ImplTraitTypeOneBound (*this);
}
};
@@ -529,6 +534,9 @@ public:
return *type;
}
+ // Getter for direct access to the type unique_ptr
+ std::unique_ptr<TypeNoBounds> &get_type_ptr () { return type; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -604,6 +612,9 @@ public:
TypeNoBounds &get_base_type () { return *type; }
+ // Getter for direct access to the type unique_ptr
+ std::unique_ptr<TypeNoBounds> &get_type_ptr () { return type; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -666,6 +677,11 @@ public:
return *size;
}
+ std::unique_ptr<Type> &get_element_type () { return elem_type; }
+
+ // Additional getter for direct access to the size expr unique_ptr
+ std::unique_ptr<Expr> &get_size_ptr () { return size; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -719,6 +735,9 @@ public:
return *elem_type;
}
+ // Getter for direct access to the elem_type unique_ptr
+ std::unique_ptr<Type> &get_elem_type_ptr () { return elem_type; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 12b9561..84c4bcd 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -687,11 +687,6 @@ HIRCompileBase::compile_function (
}
std::string asm_name = fn_name;
- auto &mappings = Analysis::Mappings::get ();
-
- if (flag_name_resolution_2_0)
- ir_symbol_name = mappings.get_current_crate_name () + "::" + ir_symbol_name;
-
unsigned int flags = 0;
tree fndecl = Backend::function (compiled_fn_type, ir_symbol_name,
"" /* asm_name */, flags, locus);
diff --git a/gcc/rust/backend/rust-compile-block.cc b/gcc/rust/backend/rust-compile-block.cc
index f844a27..03c36d2 100644
--- a/gcc/rust/backend/rust-compile-block.cc
+++ b/gcc/rust/backend/rust-compile-block.cc
@@ -19,6 +19,7 @@
#include "rust-compile-block.h"
#include "rust-compile-stmt.h"
#include "rust-compile-expr.h"
+#include "rust-hir-expr.h"
namespace Rust {
namespace Compile {
diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h
index 3f38d08..90515f6 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -83,6 +83,8 @@ public:
void visit (HIR::MethodCallExpr &) override {}
void visit (HIR::FieldAccessExpr &) override {}
void visit (HIR::BlockExpr &) override {}
+ void visit (HIR::AnonConst &) override {}
+ void visit (HIR::ConstBlock &) override {}
void visit (HIR::ContinueExpr &) override {}
void visit (HIR::BreakExpr &) override {}
void visit (HIR::RangeFromToExpr &) override {}
@@ -138,6 +140,12 @@ public:
translated = CompileBlock::compile (expr, ctx, result);
}
+ void visit (HIR::ConstBlock &expr) override
+ {
+ rust_unreachable ();
+ // translated = CompileExpr::compile (expr, ctx, result);
+ }
+
// Empty visit for unused Expression HIR nodes.
void visit (HIR::PathInExpression &) override {}
void visit (HIR::QualifiedPathInExpression &) override {}
@@ -184,6 +192,7 @@ public:
void visit (HIR::AsyncBlockExpr &) override {}
void visit (HIR::InlineAsm &) override {}
void visit (HIR::LlvmInlineAsm &) override {}
+ void visit (HIR::AnonConst &) override {}
private:
CompileExprWithBlock (Context *ctx, Bvariable *result)
diff --git a/gcc/rust/backend/rust-compile-context.cc b/gcc/rust/backend/rust-compile-context.cc
index 86f0894..284a5aa 100644
--- a/gcc/rust/backend/rust-compile-context.cc
+++ b/gcc/rust/backend/rust-compile-context.cc
@@ -70,7 +70,8 @@ Context::type_hasher (tree type)
hstate.add_object (TYPE_HASH (TYPE_OFFSET_BASETYPE (type)));
break;
- case ARRAY_TYPE: {
+ case ARRAY_TYPE:
+ {
if (TYPE_DOMAIN (type))
hstate.add_object (TYPE_HASH (TYPE_DOMAIN (type)));
if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
@@ -81,7 +82,8 @@ Context::type_hasher (tree type)
}
break;
- case INTEGER_TYPE: {
+ case INTEGER_TYPE:
+ {
tree t = TYPE_MAX_VALUE (type);
if (!t)
t = TYPE_MIN_VALUE (type);
@@ -91,7 +93,8 @@ Context::type_hasher (tree type)
}
case REAL_TYPE:
- case FIXED_POINT_TYPE: {
+ case FIXED_POINT_TYPE:
+ {
unsigned prec = TYPE_PRECISION (type);
hstate.add_object (prec);
break;
@@ -103,7 +106,8 @@ Context::type_hasher (tree type)
case RECORD_TYPE:
case UNION_TYPE:
- case QUAL_UNION_TYPE: {
+ case QUAL_UNION_TYPE:
+ {
for (tree t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
{
hashval_t name_hash = IDENTIFIER_HASH_VALUE (DECL_NAME (t));
@@ -118,7 +122,8 @@ Context::type_hasher (tree type)
break;
case REFERENCE_TYPE:
- case POINTER_TYPE: {
+ case POINTER_TYPE:
+ {
hashval_t type_hash = type_hasher (TREE_TYPE (type));
hstate.add_object (type_hash);
}
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index dd3420f..d8ddab5 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -30,6 +30,7 @@
#include "realmpfr.h"
#include "convert.h"
#include "print-tree.h"
+#include "rust-hir-expr.h"
#include "rust-system.h"
#include "rust-tyty.h"
@@ -441,6 +442,18 @@ CompileExpr::visit (HIR::BlockExpr &expr)
}
void
+CompileExpr::visit (HIR::AnonConst &expr)
+{
+ expr.get_inner_expr ().accept_vis (*this);
+}
+
+void
+CompileExpr::visit (HIR::ConstBlock &expr)
+{
+ expr.get_const_expr ().accept_vis (*this);
+}
+
+void
CompileExpr::visit (HIR::UnsafeBlockExpr &expr)
{
expr.get_block_expr ().accept_vis (*this);
@@ -1883,7 +1896,8 @@ CompileExpr::visit (HIR::ArrayExpr &expr)
HIR::ArrayElems &elements = expr.get_internal_elements ();
switch (elements.get_array_expr_type ())
{
- case HIR::ArrayElems::ArrayExprType::VALUES: {
+ case HIR::ArrayElems::ArrayExprType::VALUES:
+ {
HIR::ArrayElemsValues &elems
= static_cast<HIR::ArrayElemsValues &> (elements);
translated
@@ -2032,7 +2046,8 @@ HIRCompileBase::resolve_adjustements (
return error_mark_node;
case Resolver::Adjustment::AdjustmentType::IMM_REF:
- case Resolver::Adjustment::AdjustmentType::MUT_REF: {
+ case Resolver::Adjustment::AdjustmentType::MUT_REF:
+ {
if (!RS_DST_FLAG (TREE_TYPE (e)))
{
e = address_expression (e, locus);
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 65ed4b3..bc347bf 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -48,6 +48,8 @@ public:
void visit (HIR::IfExpr &expr) override;
void visit (HIR::IfExprConseqElse &expr) override;
void visit (HIR::BlockExpr &expr) override;
+ void visit (HIR::AnonConst &expr) override;
+ void visit (HIR::ConstBlock &expr) override;
void visit (HIR::UnsafeBlockExpr &expr) override;
void visit (HIR::StructExprStruct &struct_expr) override;
void visit (HIR::StructExprStructFields &struct_expr) override;
diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc
index 1230c85..f9172c5 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -33,8 +33,8 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- canonical_path = nr_ctx.values.to_canonical_path (
- constant.get_mappings ().get_nodeid ());
+ canonical_path
+ = nr_ctx.to_canonical_path (constant.get_mappings ().get_nodeid ());
}
else
{
@@ -103,7 +103,7 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func)
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
- = nr_ctx.values.to_canonical_path (func.get_mappings ().get_nodeid ());
+ = nr_ctx.to_canonical_path (func.get_mappings ().get_nodeid ());
}
else
{
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 4888e23..7627620 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -32,8 +32,7 @@
// declaration taken from "stringpool.h"
// the get_identifier macro causes compilation issues
-extern tree
-get_identifier (const char *);
+extern tree get_identifier (const char *);
namespace Rust {
namespace Compile {
@@ -70,28 +69,19 @@ check_for_basic_integer_type (const std::string &intrinsic_str,
return is_basic_integer;
}
-static tree
-offset_handler (Context *ctx, TyTy::FnType *fntype);
-static tree
-sizeof_handler (Context *ctx, TyTy::FnType *fntype);
-static tree
-transmute_handler (Context *ctx, TyTy::FnType *fntype);
-static tree
-rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
-static tree
-wrapping_op_handler_inner (Context *ctx, TyTy::FnType *fntype, tree_code op);
-static tree
-op_with_overflow_inner (Context *ctx, TyTy::FnType *fntype, tree_code op);
-static tree
-uninit_handler (Context *ctx, TyTy::FnType *fntype);
-static tree
-move_val_init_handler (Context *ctx, TyTy::FnType *fntype);
-static tree
-assume_handler (Context *ctx, TyTy::FnType *fntype);
-static tree
-discriminant_value_handler (Context *ctx, TyTy::FnType *fntype);
-static tree
-variant_count_handler (Context *ctx, TyTy::FnType *fntype);
+static tree offset_handler (Context *ctx, TyTy::FnType *fntype);
+static tree sizeof_handler (Context *ctx, TyTy::FnType *fntype);
+static tree transmute_handler (Context *ctx, TyTy::FnType *fntype);
+static tree rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
+static tree wrapping_op_handler_inner (Context *ctx, TyTy::FnType *fntype,
+ tree_code op);
+static tree op_with_overflow_inner (Context *ctx, TyTy::FnType *fntype,
+ tree_code op);
+static tree uninit_handler (Context *ctx, TyTy::FnType *fntype);
+static tree move_val_init_handler (Context *ctx, TyTy::FnType *fntype);
+static tree assume_handler (Context *ctx, TyTy::FnType *fntype);
+static tree discriminant_value_handler (Context *ctx, TyTy::FnType *fntype);
+static tree variant_count_handler (Context *ctx, TyTy::FnType *fntype);
enum class Prefetch
{
@@ -99,8 +89,8 @@ enum class Prefetch
Write
};
-static tree
-prefetch_data_handler (Context *ctx, TyTy::FnType *fntype, Prefetch kind);
+static tree prefetch_data_handler (Context *ctx, TyTy::FnType *fntype,
+ Prefetch kind);
static inline tree
rotate_left_handler (Context *ctx, TyTy::FnType *fntype)
@@ -140,10 +130,10 @@ prefetch_write_data (Context *ctx, TyTy::FnType *fntype)
return prefetch_data_handler (ctx, fntype, Prefetch::Write);
}
-static tree
-atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering);
-static tree
-atomic_load_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering);
+static tree atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype,
+ int ordering);
+static tree atomic_load_handler_inner (Context *ctx, TyTy::FnType *fntype,
+ int ordering);
static inline std::function<tree (Context *, TyTy::FnType *)>
atomic_store_handler (int ordering)
@@ -161,8 +151,8 @@ atomic_load_handler (int ordering)
};
}
-static inline tree
-unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op);
+static inline tree unchecked_op_inner (Context *ctx, TyTy::FnType *fntype,
+ tree_code op);
const static std::function<tree (Context *, TyTy::FnType *)>
unchecked_op_handler (tree_code op)
@@ -172,8 +162,8 @@ unchecked_op_handler (tree_code op)
};
}
-static inline tree
-copy_handler_inner (Context *ctx, TyTy::FnType *fntype, bool overlaps);
+static inline tree copy_handler_inner (Context *ctx, TyTy::FnType *fntype,
+ bool overlaps);
const static std::function<tree (Context *, TyTy::FnType *)>
copy_handler (bool overlaps)
@@ -183,8 +173,8 @@ copy_handler (bool overlaps)
};
}
-static inline tree
-expect_handler_inner (Context *ctx, TyTy::FnType *fntype, bool likely);
+static inline tree expect_handler_inner (Context *ctx, TyTy::FnType *fntype,
+ bool likely);
const static std::function<tree (Context *, TyTy::FnType *)>
expect_handler (bool likely)
@@ -194,8 +184,8 @@ expect_handler (bool likely)
};
}
-static tree
-try_handler_inner (Context *ctx, TyTy::FnType *fntype, bool is_new_api);
+static tree try_handler_inner (Context *ctx, TyTy::FnType *fntype,
+ bool is_new_api);
const static std::function<tree (Context *, TyTy::FnType *)>
try_handler (bool is_new_api)
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 9666990..3e7ea9a 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -58,7 +58,7 @@ CompileItem::visit (HIR::StaticItem &var)
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
- = nr_ctx.values.to_canonical_path (var.get_mappings ().get_nodeid ());
+ = nr_ctx.to_canonical_path (var.get_mappings ().get_nodeid ());
}
else
{
@@ -124,8 +124,7 @@ CompileItem::visit (HIR::ConstantItem &constant)
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- canonical_path
- = nr_ctx.values.to_canonical_path (mappings.get_nodeid ()).value ();
+ canonical_path = nr_ctx.to_canonical_path (mappings.get_nodeid ());
}
else
{
@@ -218,10 +217,8 @@ CompileItem::visit (HIR::Function &function)
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto path = nr_ctx.values.to_canonical_path (
- function.get_mappings ().get_nodeid ());
-
- canonical_path = path.value ();
+ canonical_path
+ = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
}
else
{
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index e83717b..e19aa67 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -22,6 +22,11 @@
#include "rust-constexpr.h"
#include "rust-compile-type.h"
#include "print-tree.h"
+#include "rust-diagnostics.h"
+#include "rust-hir-pattern-abstract.h"
+#include "rust-hir-pattern.h"
+#include "rust-system.h"
+#include "rust-tyty.h"
namespace Rust {
namespace Compile {
@@ -107,7 +112,8 @@ compile_range_pattern_bound (HIR::RangePatternBound &bound,
tree result = NULL_TREE;
switch (bound.get_bound_type ())
{
- case HIR::RangePatternBound::RangePatternBoundType::LITERAL: {
+ case HIR::RangePatternBound::RangePatternBoundType::LITERAL:
+ {
auto &ref = static_cast<HIR::RangePatternBoundLiteral &> (bound);
HIR::LiteralExpr litexpr (mappings, ref.get_literal (), locus,
@@ -117,7 +123,8 @@ compile_range_pattern_bound (HIR::RangePatternBound &bound,
}
break;
- case HIR::RangePatternBound::RangePatternBoundType::PATH: {
+ case HIR::RangePatternBound::RangePatternBoundType::PATH:
+ {
auto &ref = static_cast<HIR::RangePatternBoundPath &> (bound);
result = ResolvePathRef::Compile (ref.get_path (), ctx);
@@ -127,7 +134,8 @@ compile_range_pattern_bound (HIR::RangePatternBound &bound,
}
break;
- case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: {
+ case HIR::RangePatternBound::RangePatternBoundType::QUALPATH:
+ {
auto &ref = static_cast<HIR::RangePatternBoundQualPath &> (bound);
result = ResolvePathRef::Compile (ref.get_qualified_path (), ctx);
@@ -204,6 +212,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
rust_assert (adt->number_of_variants () > 0);
TyTy::VariantDef *variant = nullptr;
+ tree variant_accesser_expr = nullptr;
if (adt->is_enum ())
{
// lookup the variant
@@ -218,9 +227,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
// find expected discriminant
// // need to access qualifier the field, if we use QUAL_UNION_TYPE this
- // // would be DECL_QUALIFIER i think. For now this will just access the
- // // first record field and its respective qualifier because it will
- // // always be set because this is all a big special union
+ // // would be DECL_QUALIFIER i think.
HIR::Expr &discrim_expr = variant->get_discriminant ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
@@ -229,6 +236,14 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
= Backend::struct_field_expression (match_scrutinee_expr, 0,
pattern.get_path ().get_locus ());
+ // access variant data
+ tree scrutinee_union_expr
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern.get_path ().get_locus ());
+ variant_accesser_expr
+ = Backend::struct_field_expression (scrutinee_union_expr, variant_index,
+ pattern.get_path ().get_locus ());
+
check_expr
= Backend::comparison_expression (ComparisonOperator::EQUAL,
scrutinee_expr_qualifier_expr,
@@ -240,6 +255,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
else
{
variant = adt->get_variants ().at (0);
+ variant_accesser_expr = match_scrutinee_expr;
check_expr = boolean_true_node;
}
@@ -248,13 +264,15 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
{
switch (field->get_item_type ())
{
- case HIR::StructPatternField::ItemType::TUPLE_PAT: {
+ case HIR::StructPatternField::ItemType::TUPLE_PAT:
+ {
// TODO
rust_unreachable ();
}
break;
- case HIR::StructPatternField::ItemType::IDENT_PAT: {
+ case HIR::StructPatternField::ItemType::IDENT_PAT:
+ {
HIR::StructPatternFieldIdentPat &ident
= static_cast<HIR::StructPatternFieldIdentPat &> (*field.get ());
@@ -263,11 +281,8 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
nullptr, &offs);
rust_assert (ok);
- // we may be offsetting by + 1 here since the first field in the
- // record is always the discriminator
- offs += adt->is_enum ();
tree field_expr
- = Backend::struct_field_expression (match_scrutinee_expr, offs,
+ = Backend::struct_field_expression (variant_accesser_expr, offs,
ident.get_locus ());
tree check_expr_sub
@@ -279,7 +294,8 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
}
break;
- case HIR::StructPatternField::ItemType::IDENT: {
+ case HIR::StructPatternField::ItemType::IDENT:
+ {
// ident pattern always matches - do nothing
}
break;
@@ -338,13 +354,15 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
HIR::TupleStructItems &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case HIR::TupleStructItems::RANGED: {
+ case HIR::TupleStructItems::RANGED:
+ {
// TODO
rust_unreachable ();
}
break;
- case HIR::TupleStructItems::MULTIPLE: {
+ case HIR::TupleStructItems::MULTIPLE:
+ {
HIR::TupleStructItemsNoRange &items_no_range
= static_cast<HIR::TupleStructItemsNoRange &> (items);
@@ -386,13 +404,15 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::RANGED: {
+ case HIR::TuplePatternItems::RANGED:
+ {
// TODO
gcc_unreachable ();
}
break;
- case HIR::TuplePatternItems::MULTIPLE: {
+ case HIR::TuplePatternItems::MULTIPLE:
+ {
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
pattern.get_items ());
size_t tuple_field_index = 0;
@@ -414,6 +434,20 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
}
}
+void
+CompilePatternCheckExpr::visit (HIR::IdentifierPattern &pattern)
+{
+ if (pattern.has_subpattern ())
+ {
+ check_expr = CompilePatternCheckExpr::Compile (pattern.get_subpattern (),
+ match_scrutinee_expr, ctx);
+ }
+ else
+ {
+ check_expr = boolean_true_node;
+ }
+}
+
// setup the bindings
void
@@ -449,13 +483,15 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
HIR::TupleStructItems &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case HIR::TupleStructItems::RANGED: {
+ case HIR::TupleStructItems::RANGED:
+ {
// TODO
rust_unreachable ();
}
break;
- case HIR::TupleStructItems::MULTIPLE: {
+ case HIR::TupleStructItems::MULTIPLE:
+ {
HIR::TupleStructItemsNoRange &items_no_range
= static_cast<HIR::TupleStructItemsNoRange &> (items);
@@ -504,6 +540,71 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
}
}
+tree
+CompilePatternBindings::make_struct_access (TyTy::ADTType *adt,
+ TyTy::VariantDef *variant,
+ const Identifier &ident,
+ int variant_index)
+{
+ size_t offs = 0;
+ auto ok = variant->lookup_field (ident.as_string (), nullptr, &offs);
+ rust_assert (ok);
+
+ if (adt->is_enum ())
+ {
+ tree payload_accessor_union
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ ident.get_locus ());
+
+ tree variant_accessor
+ = Backend::struct_field_expression (payload_accessor_union,
+ variant_index, ident.get_locus ());
+
+ return Backend::struct_field_expression (variant_accessor, offs,
+ ident.get_locus ());
+ }
+ else
+ {
+ tree variant_accessor = match_scrutinee_expr;
+
+ return Backend::struct_field_expression (variant_accessor, offs,
+ ident.get_locus ());
+ }
+}
+
+void
+CompilePatternBindings::handle_struct_pattern_ident (
+ HIR::StructPatternField &pat, TyTy::ADTType *adt, TyTy::VariantDef *variant,
+ int variant_index)
+{
+ HIR::StructPatternFieldIdent &ident
+ = static_cast<HIR::StructPatternFieldIdent &> (pat);
+
+ auto identifier = ident.get_identifier ();
+ tree binding = make_struct_access (adt, variant, identifier, variant_index);
+
+ ctx->insert_pattern_binding (ident.get_mappings ().get_hirid (), binding);
+}
+
+void
+CompilePatternBindings::handle_struct_pattern_ident_pat (
+ HIR::StructPatternField &pat, TyTy::ADTType *adt, TyTy::VariantDef *variant,
+ int variant_index)
+{
+ auto &pattern = static_cast<HIR::StructPatternFieldIdentPat &> (pat);
+
+ tree binding = make_struct_access (adt, variant, pattern.get_identifier (),
+ variant_index);
+ CompilePatternBindings::Compile (pattern.get_pattern (), binding, ctx);
+}
+
+void
+CompilePatternBindings::handle_struct_pattern_tuple_pat (
+ HIR::StructPatternField &pat)
+{
+ rust_unreachable ();
+}
+
void
CompilePatternBindings::visit (HIR::StructPattern &pattern)
{
@@ -539,54 +640,14 @@ CompilePatternBindings::visit (HIR::StructPattern &pattern)
{
switch (field->get_item_type ())
{
- case HIR::StructPatternField::ItemType::TUPLE_PAT: {
- // TODO
- rust_unreachable ();
- }
+ case HIR::StructPatternField::ItemType::TUPLE_PAT:
+ handle_struct_pattern_tuple_pat (*field);
break;
-
- case HIR::StructPatternField::ItemType::IDENT_PAT: {
- // TODO
- rust_unreachable ();
- }
+ case HIR::StructPatternField::ItemType::IDENT_PAT:
+ handle_struct_pattern_ident_pat (*field, adt, variant, variant_index);
break;
-
- case HIR::StructPatternField::ItemType::IDENT: {
- HIR::StructPatternFieldIdent &ident
- = static_cast<HIR::StructPatternFieldIdent &> (*field.get ());
-
- size_t offs = 0;
- ok = variant->lookup_field (ident.get_identifier ().as_string (),
- nullptr, &offs);
- rust_assert (ok);
-
- tree binding = error_mark_node;
- if (adt->is_enum ())
- {
- tree payload_accessor_union
- = Backend::struct_field_expression (match_scrutinee_expr, 1,
- ident.get_locus ());
-
- tree variant_accessor
- = Backend::struct_field_expression (payload_accessor_union,
- variant_index,
- ident.get_locus ());
-
- binding
- = Backend::struct_field_expression (variant_accessor, offs,
- ident.get_locus ());
- }
- else
- {
- tree variant_accessor = match_scrutinee_expr;
- binding
- = Backend::struct_field_expression (variant_accessor, offs,
- ident.get_locus ());
- }
-
- ctx->insert_pattern_binding (ident.get_mappings ().get_hirid (),
- binding);
- }
+ case HIR::StructPatternField::ItemType::IDENT:
+ handle_struct_pattern_ident (*field, adt, variant, variant_index);
break;
}
}
@@ -631,7 +692,8 @@ CompilePatternBindings::visit (HIR::TuplePattern &pattern)
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::ItemType::RANGED: {
+ case HIR::TuplePatternItems::ItemType::RANGED:
+ {
size_t tuple_idx = 0;
auto &items
= static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
@@ -674,7 +736,8 @@ CompilePatternBindings::visit (HIR::TuplePattern &pattern)
return;
}
- case HIR::TuplePatternItems::ItemType::MULTIPLE: {
+ case HIR::TuplePatternItems::ItemType::MULTIPLE:
+ {
size_t tuple_idx = 0;
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
pattern.get_items ());
@@ -695,7 +758,8 @@ CompilePatternBindings::visit (HIR::TuplePattern &pattern)
return;
}
- default: {
+ default:
+ {
rust_unreachable ();
}
}
@@ -755,7 +819,8 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::ItemType::RANGED: {
+ case HIR::TuplePatternItems::ItemType::RANGED:
+ {
size_t tuple_idx = 0;
auto &items
= static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
@@ -799,7 +864,8 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
return;
}
- case HIR::TuplePatternItems::ItemType::MULTIPLE: {
+ case HIR::TuplePatternItems::ItemType::MULTIPLE:
+ {
size_t tuple_idx = 0;
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
pattern.get_items ());
@@ -821,7 +887,8 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
return;
}
- default: {
+ default:
+ {
rust_unreachable ();
}
}
diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h
index c7a62fc..4dd7d55 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -17,7 +17,9 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile-base.h"
+#include "rust-hir-pattern.h"
#include "rust-hir-visitor.h"
+#include "rust-tyty.h"
namespace Rust {
namespace Compile {
@@ -43,12 +45,9 @@ public:
void visit (HIR::StructPattern &) override;
void visit (HIR::TupleStructPattern &) override;
void visit (HIR::TuplePattern &) override;
+ void visit (HIR::IdentifierPattern &) override;
// Always succeeds
- void visit (HIR::IdentifierPattern &) override
- {
- check_expr = boolean_true_node;
- }
void visit (HIR::WildcardPattern &) override
{
check_expr = boolean_true_node;
@@ -78,6 +77,19 @@ public:
pattern.accept_vis (compiler);
}
+ tree make_struct_access (TyTy::ADTType *adt, TyTy::VariantDef *variant,
+ const Identifier &ident, int variant_index);
+
+ void handle_struct_pattern_ident (HIR::StructPatternField &pat,
+ TyTy::ADTType *adt,
+ TyTy::VariantDef *variant,
+ int variant_index);
+ void handle_struct_pattern_ident_pat (HIR::StructPatternField &pat,
+ TyTy::ADTType *adt,
+ TyTy::VariantDef *variant,
+ int variant_index);
+ void handle_struct_pattern_tuple_pat (HIR::StructPatternField &pat);
+
void visit (HIR::StructPattern &pattern) override;
void visit (HIR::TupleStructPattern &pattern) override;
void visit (HIR::ReferencePattern &pattern) override;
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index 83e5756..7e56a0f 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -17,11 +17,11 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile-type.h"
-#include "rust-compile-expr.h"
#include "rust-constexpr.h"
-#include "rust-gcc.h"
+#include "rust-compile-base.h"
#include "tree.h"
+#include "fold-const.h"
#include "stor-layout.h"
namespace Rust {
@@ -454,7 +454,7 @@ TyTyResolveCompile::visit (const TyTy::TupleType &type)
}
tree struct_type_record = Backend::struct_type (fields);
- translated = Backend::named_type (type.as_string (), struct_type_record,
+ translated = Backend::named_type (type.get_name (), struct_type_record,
type.get_ident ().locus);
}
@@ -480,9 +480,12 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type)
tree folded_capacity_expr = fold_expr (capacity_expr);
- translated = Backend::array_type (element_type, folded_capacity_expr);
- if (translated != error_mark_node)
- translated = ctx->insert_compiled_type (translated);
+ // build_index_type takes the maximum index, which is one less than
+ // the length.
+ tree index_type_tree = build_index_type (
+ fold_build2 (MINUS_EXPR, sizetype, folded_capacity_expr, size_one_node));
+
+ translated = build_array_type (element_type, index_type_tree, false);
}
void
@@ -755,7 +758,9 @@ TyTyResolveCompile::visit (const TyTy::DynamicObjectType &type)
void
TyTyResolveCompile::visit (const TyTy::OpaqueType &type)
{
- translated = error_mark_node;
+ rust_assert (type.can_resolve ());
+ auto underlying = type.resolve ();
+ translated = TyTyResolveCompile::compile (ctx, underlying, trait_object_mode);
}
tree
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 4c46a7b..5c6d145 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -70,7 +70,8 @@ public:
{
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::ItemType::MULTIPLE: {
+ case HIR::TuplePatternItems::ItemType::MULTIPLE:
+ {
rust_assert (TREE_CODE (translated_type) == RECORD_TYPE);
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
pattern.get_items ());
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index dc2d6b1..d524d09 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -68,32 +68,24 @@ literal_type_p (tree t)
return false;
}
-static bool
-verify_constant (tree, bool, bool *, bool *);
-
-static HOST_WIDE_INT
-find_array_ctor_elt (tree ary, tree dindex, bool insert = false);
-static int
-array_index_cmp (tree key, tree index);
-static bool
-potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
- tsubst_flags_t flags, tree *jump_target);
-bool
-potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
- tsubst_flags_t flags);
-tree
-unshare_constructor (tree t MEM_STAT_DECL);
-void
-maybe_save_constexpr_fundef (tree fun);
-
-static bool
-returns (tree *jump_target);
-static bool
-breaks (tree *jump_target);
-static bool
-continues (tree *jump_target);
-static bool
-switches (tree *jump_target);
+static bool verify_constant (tree, bool, bool *, bool *);
+
+static HOST_WIDE_INT find_array_ctor_elt (tree ary, tree dindex,
+ bool insert = false);
+static int array_index_cmp (tree key, tree index);
+static bool potential_constant_expression_1 (tree t, bool want_rval,
+ bool strict, bool now,
+ tsubst_flags_t flags,
+ tree *jump_target);
+bool potential_constant_expression_1 (tree t, bool want_rval, bool strict,
+ bool now, tsubst_flags_t flags);
+tree unshare_constructor (tree t MEM_STAT_DECL);
+void maybe_save_constexpr_fundef (tree fun);
+
+static bool returns (tree *jump_target);
+static bool breaks (tree *jump_target);
+static bool continues (tree *jump_target);
+static bool switches (tree *jump_target);
struct constexpr_global_ctx
{
@@ -463,60 +455,52 @@ save_fundef_copy (tree fun, tree copy)
*slot = copy;
}
-static tree
-constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p,
- bool unshare_p);
-tree
-decl_constant_value (tree decl, bool unshare_p);
+static tree constant_value_1 (tree decl, bool strict_p,
+ bool return_aggregate_cst_ok_p, bool unshare_p);
+tree decl_constant_value (tree decl, bool unshare_p);
-static void
-non_const_var_error (location_t loc, tree r);
+static void non_const_var_error (location_t loc, tree r);
-static tree
-eval_constant_expression (const constexpr_ctx *ctx, tree, bool, bool *, bool *,
- tree * = NULL);
+static tree eval_constant_expression (const constexpr_ctx *ctx, tree, bool,
+ bool *, bool *, tree * = NULL);
-static tree
-constexpr_fn_retval (const constexpr_ctx *ctx, tree r);
+static tree constexpr_fn_retval (const constexpr_ctx *ctx, tree r);
-static tree
-eval_store_expression (const constexpr_ctx *ctx, tree r, bool, bool *, bool *);
+static tree eval_store_expression (const constexpr_ctx *ctx, tree r, bool,
+ bool *, bool *);
-static tree
-eval_call_expression (const constexpr_ctx *ctx, tree r, bool, bool *, bool *);
+static tree eval_call_expression (const constexpr_ctx *ctx, tree r, bool,
+ bool *, bool *);
-static tree
-eval_binary_expression (const constexpr_ctx *ctx, tree r, bool, bool *, bool *);
+static tree eval_binary_expression (const constexpr_ctx *ctx, tree r, bool,
+ bool *, bool *);
-static tree
-get_function_named_in_call (tree t);
+static tree get_function_named_in_call (tree t);
-static tree
-eval_statement_list (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
- bool *overflow_p, tree *jump_target);
-static tree
-extract_string_elt (tree string, unsigned chars_per_elt, unsigned index);
+static tree eval_statement_list (const constexpr_ctx *ctx, tree t,
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target);
+static tree extract_string_elt (tree string, unsigned chars_per_elt,
+ unsigned index);
-static tree
-eval_conditional_expression (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p,
- tree *jump_target);
+static tree eval_conditional_expression (const constexpr_ctx *ctx, tree t,
+ bool lval, bool *non_constant_p,
+ bool *overflow_p, tree *jump_target);
-static tree
-eval_bit_field_ref (const constexpr_ctx *ctx, tree t, bool lval,
- bool *non_constant_p, bool *overflow_p);
+static tree eval_bit_field_ref (const constexpr_ctx *ctx, tree t, bool lval,
+ bool *non_constant_p, bool *overflow_p);
-static tree
-eval_loop_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
- bool *overflow_p, tree *jump_target);
+static tree eval_loop_expr (const constexpr_ctx *ctx, tree t,
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target);
-static tree
-eval_switch_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
- bool *overflow_p, tree *jump_target);
+static tree eval_switch_expr (const constexpr_ctx *ctx, tree t,
+ bool *non_constant_p, bool *overflow_p,
+ tree *jump_target);
-static tree
-eval_unary_expression (const constexpr_ctx *ctx, tree t, bool /*lval*/,
- bool *non_constant_p, bool *overflow_p);
+static tree eval_unary_expression (const constexpr_ctx *ctx, tree t,
+ bool /*lval*/, bool *non_constant_p,
+ bool *overflow_p);
/* Variables and functions to manage constexpr call expansion context.
These do not need to be marked for PCH or GC. */
@@ -1235,7 +1219,8 @@ get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1)
/* We fell off the end of the CONSTRUCTOR, so insert a new
entry at the end. */
- insert : {
+ insert:
+ {
constructor_elt ce = {index, NULL_TREE};
vec_safe_insert (CONSTRUCTOR_ELTS (ctor), idx, ce);
@@ -1568,10 +1553,9 @@ free_constructor (tree t)
}
}
-static tree
-eval_and_check_array_index (const constexpr_ctx *ctx, tree t,
- bool allow_one_past, bool *non_constant_p,
- bool *overflow_p);
+static tree eval_and_check_array_index (const constexpr_ctx *ctx, tree t,
+ bool allow_one_past,
+ bool *non_constant_p, bool *overflow_p);
// forked from gcc/cp/constexpr.cc cxx_eval_array_reference
@@ -1901,6 +1885,9 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
location_t loc = EXPR_LOCATION (t);
+ if (t == NULL_TREE)
+ return NULL_TREE;
+
if (CONSTANT_CLASS_P (t))
{
if (TREE_OVERFLOW (t))
@@ -1936,8 +1923,9 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
return eval_constant_expression (ctx, r, lval, non_constant_p,
overflow_p);
}
- /* fall through */
- case CONST_DECL: {
+ /* fall through */
+ case CONST_DECL:
+ {
/* We used to not check lval for CONST_DECL, but darwin.cc uses
CONST_DECL for aggregate constants. */
if (lval)
@@ -2045,7 +2033,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
overflow_p);
break;
- case TARGET_EXPR: {
+ case TARGET_EXPR:
+ {
tree type = TREE_TYPE (t);
if (!literal_type_p (type))
@@ -2129,7 +2118,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
}
break;
- case DECL_EXPR: {
+ case DECL_EXPR:
+ {
r = DECL_EXPR_DECL (t);
if (AGGREGATE_TYPE_P (TREE_TYPE (r)) || VECTOR_TYPE_P (TREE_TYPE (r)))
@@ -2201,7 +2191,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
return eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t), lval,
non_constant_p, overflow_p);
- case EXIT_EXPR: {
+ case EXIT_EXPR:
+ {
tree cond = TREE_OPERAND (t, 0);
cond = eval_constant_expression (ctx, cond, /*lval*/ false,
non_constant_p, overflow_p);
@@ -2243,7 +2234,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
}
break;
- case ADDR_EXPR: {
+ case ADDR_EXPR:
+ {
tree oldop = TREE_OPERAND (t, 0);
tree op = eval_constant_expression (ctx, oldop,
/*lval*/ true, non_constant_p,
@@ -2261,7 +2253,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
break;
}
- case COMPOUND_EXPR: {
+ case COMPOUND_EXPR:
+ {
/* check_return_expr sometimes wraps a TARGET_EXPR in a
COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
introduced by build_call_a. */
@@ -2401,7 +2394,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
non_constant_p, overflow_p, jump_target);
break;
- case CLEANUP_POINT_EXPR: {
+ case CLEANUP_POINT_EXPR:
+ {
auto_vec<tree, 2> cleanups;
vec<tree> *prev_cleanups = ctx->global->cleanups;
ctx->global->cleanups = &cleanups;
@@ -2441,7 +2435,8 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
/* FALLTHROUGH. */
case NOP_EXPR:
case CONVERT_EXPR:
- case VIEW_CONVERT_EXPR: {
+ case VIEW_CONVERT_EXPR:
+ {
tree oldop = TREE_OPERAND (t, 0);
tree op = eval_constant_expression (ctx, oldop, lval, non_constant_p,
@@ -2688,7 +2683,8 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
{
case BIT_FIELD_REF:
case COMPONENT_REF:
- case ARRAY_REF: {
+ case ARRAY_REF:
+ {
tree ob = TREE_OPERAND (probe, 0);
tree elt = TREE_OPERAND (probe, 1);
if (TREE_CODE (elt) == FIELD_DECL /*&& DECL_MUTABLE_P (elt)*/)
@@ -3940,7 +3936,8 @@ constexpr_fn_retval (const constexpr_ctx *ctx, tree body)
{
switch (TREE_CODE (body))
{
- case STATEMENT_LIST: {
+ case STATEMENT_LIST:
+ {
tree expr = NULL_TREE;
for (tree stmt : tsi_range (body))
{
@@ -3958,13 +3955,15 @@ constexpr_fn_retval (const constexpr_ctx *ctx, tree body)
return expr;
}
- case RETURN_EXPR: {
+ case RETURN_EXPR:
+ {
bool non_constant_p = false;
bool overflow_p = false;
return eval_constant_expression (ctx, body, false, &non_constant_p,
&overflow_p);
}
- case DECL_EXPR: {
+ case DECL_EXPR:
+ {
tree decl = DECL_EXPR_DECL (body);
if (TREE_CODE (decl) == USING_DECL
/* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. */
@@ -3976,7 +3975,8 @@ constexpr_fn_retval (const constexpr_ctx *ctx, tree body)
case CLEANUP_POINT_EXPR:
return constexpr_fn_retval (ctx, TREE_OPERAND (body, 0));
- case BIND_EXPR: {
+ case BIND_EXPR:
+ {
tree b = BIND_EXPR_BODY (body);
return constexpr_fn_retval (ctx, b);
}
@@ -4136,7 +4136,8 @@ array_index_cmp (tree key, tree index)
{
case INTEGER_CST:
return tree_int_cst_compare (key, index);
- case RANGE_EXPR: {
+ case RANGE_EXPR:
+ {
tree lo = TREE_OPERAND (index, 0);
tree hi = TREE_OPERAND (index, 1);
if (tree_int_cst_lt (key, lo))
@@ -5943,7 +5944,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case BIT_FIELD_REF:
return RECUR (TREE_OPERAND (t, 0), want_rval);
- case INDIRECT_REF: {
+ case INDIRECT_REF:
+ {
tree x = TREE_OPERAND (t, 0);
STRIP_NOPS (x);
return RECUR (x, rval);
@@ -6214,7 +6216,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case INIT_EXPR:
return RECUR (TREE_OPERAND (t, 1), rval);
- case CONSTRUCTOR: {
+ case CONSTRUCTOR:
+ {
vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
constructor_elt *ce;
for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
@@ -6223,7 +6226,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
return true;
}
- case TREE_LIST: {
+ case TREE_LIST:
+ {
gcc_assert (TREE_PURPOSE (t) == NULL_TREE || DECL_P (TREE_PURPOSE (t)));
if (!RECUR (TREE_VALUE (t), want_rval))
return false;
@@ -6238,7 +6242,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case ROUND_DIV_EXPR:
case TRUNC_MOD_EXPR:
case CEIL_MOD_EXPR:
- case ROUND_MOD_EXPR: {
+ case ROUND_MOD_EXPR:
+ {
tree denom = TREE_OPERAND (t, 1);
if (!RECUR (denom, rval))
return false;
@@ -6258,7 +6263,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
}
}
- case COMPOUND_EXPR: {
+ case COMPOUND_EXPR:
+ {
/* check_return_expr sometimes wraps a TARGET_EXPR in a
COMPOUND_EXPR; don't get confused. */
tree op0 = TREE_OPERAND (t, 0);
@@ -6280,7 +6286,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case TRUTH_OR_EXPR:
case TRUTH_ORIF_EXPR:
tmp = boolean_false_node;
- truth : {
+ truth:
+ {
tree op0 = TREE_OPERAND (t, 0);
tree op1 = TREE_OPERAND (t, 1);
if (!RECUR (op0, rval))
diff --git a/gcc/rust/backend/rust-constexpr.h b/gcc/rust/backend/rust-constexpr.h
index 77a0797..27f0a2e 100644
--- a/gcc/rust/backend/rust-constexpr.h
+++ b/gcc/rust/backend/rust-constexpr.h
@@ -24,8 +24,7 @@ namespace Rust {
namespace Compile {
extern tree fold_expr (tree);
-extern void
-maybe_save_constexpr_fundef (tree fun);
+extern void maybe_save_constexpr_fundef (tree fun);
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-mangle-v0.cc b/gcc/rust/backend/rust-mangle-v0.cc
index d0df4ab..f6b1a4c 100644
--- a/gcc/rust/backend/rust-mangle-v0.cc
+++ b/gcc/rust/backend/rust-mangle-v0.cc
@@ -62,9 +62,9 @@ struct V0Path
}
};
-static std::string
-v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
- const Resolver::CanonicalPath &path);
+static std::string v0_path (Rust::Compile::Context *ctx,
+ const TyTy::BaseType *ty,
+ const Resolver::CanonicalPath &path);
static std::string
v0_tuple_prefix (const TyTy::BaseType *ty)
@@ -148,7 +148,8 @@ v0_complex_type_prefix (Context *ctx, const TyTy::BaseType *ty)
// TODO: generics
switch (ty->get_kind ())
{
- case TyTy::TypeKind::ADT: {
+ case TyTy::TypeKind::ADT:
+ {
const TyTy::ADTType *adt = static_cast<const TyTy::ADTType *> (ty);
return v0_path (ctx, ty, adt->get_ident ().path);
}
@@ -387,7 +388,8 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
{
switch (impl_item->first->get_impl_item_type ())
{
- case HIR::ImplItem::FUNCTION: {
+ case HIR::ImplItem::FUNCTION:
+ {
HIR::Function *fn
= static_cast<HIR::Function *> (impl_item->first);
v0path
@@ -408,7 +410,8 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
{
switch (trait_item.value ()->get_item_kind ())
{
- case HIR::TraitItem::FUNC: {
+ case HIR::TraitItem::FUNC:
+ {
auto fn = static_cast<HIR::TraitItemFunc *> (*trait_item);
rust_unreachable ();
v0path = v0_function_path (v0path, ctx, ty,
@@ -428,7 +431,8 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
else if (auto item = mappings.lookup_hir_item (hir_id))
switch (item.value ()->get_item_kind ())
{
- case HIR::Item::ItemKind::Function: {
+ case HIR::Item::ItemKind::Function:
+ {
HIR::Function *fn = static_cast<HIR::Function *> (*item);
v0path
= v0_function_path (v0path, ctx, ty, fn->get_generic_params (),
diff --git a/gcc/rust/backend/rust-mangle.h b/gcc/rust/backend/rust-mangle.h
index 2a84b6b..418f2bd 100644
--- a/gcc/rust/backend/rust-mangle.h
+++ b/gcc/rust/backend/rust-mangle.h
@@ -49,13 +49,12 @@ private:
static enum MangleVersion version;
};
-std::string
-legacy_mangle_item (const TyTy::BaseType *ty,
- const Resolver::CanonicalPath &path);
+std::string legacy_mangle_item (const TyTy::BaseType *ty,
+ const Resolver::CanonicalPath &path);
-std::string
-v0_mangle_item (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
- const Resolver::CanonicalPath &path);
+std::string v0_mangle_item (Rust::Compile::Context *ctx,
+ const TyTy::BaseType *ty,
+ const Resolver::CanonicalPath &path);
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 2302ffb..b86c3c8 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -268,7 +268,8 @@ convert_to_void (tree expr, impl_conv_void implicit)
return expr;
switch (TREE_CODE (expr))
{
- case COND_EXPR: {
+ case COND_EXPR:
+ {
/* The two parts of a cond expr might be separate lvalues. */
tree op1 = TREE_OPERAND (expr, 1);
tree op2 = TREE_OPERAND (expr, 2);
@@ -294,7 +295,8 @@ convert_to_void (tree expr, impl_conv_void implicit)
break;
}
- case COMPOUND_EXPR: {
+ case COMPOUND_EXPR:
+ {
/* The second part of a compound expr contains the value. */
tree op1 = TREE_OPERAND (expr, 1);
tree new_op1;
@@ -323,7 +325,8 @@ convert_to_void (tree expr, impl_conv_void implicit)
maybe_warn_nodiscard (expr, implicit);
break;
- case INDIRECT_REF: {
+ case INDIRECT_REF:
+ {
tree type = TREE_TYPE (expr);
int is_reference = TYPE_REF_P (TREE_TYPE (TREE_OPERAND (expr, 0)));
int is_volatile = TYPE_VOLATILE (type);
@@ -518,7 +521,8 @@ convert_to_void (tree expr, impl_conv_void implicit)
break;
}
- case VAR_DECL: {
+ case VAR_DECL:
+ {
/* External variables might be incomplete. */
tree type = TREE_TYPE (expr);
int is_complete = COMPLETE_TYPE_P (type);
@@ -1485,7 +1489,8 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void *data)
parameter pack. ??? Should some of these be in cp_walk_subtrees? */
switch (TREE_CODE (t))
{
- case DECL_EXPR: {
+ case DECL_EXPR:
+ {
tree decl = DECL_EXPR_DECL (t);
if (is_typedef_decl (decl))
/* Since we stop at typedefs above, we need to look through them at
@@ -1506,7 +1511,8 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void *data)
*walk_subtrees = 0;
return NULL_TREE;
- case DECLTYPE_TYPE: {
+ case DECLTYPE_TYPE:
+ {
/* When traversing a DECLTYPE_TYPE_EXPR, we need to set
type_pack_expansion_p to false so that any placeholders
within the expression don't get marked as parameter packs. */
@@ -1970,7 +1976,8 @@ rs_tree_equal (tree t1, tree t2)
case SAVE_EXPR:
return rs_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- case CALL_EXPR: {
+ case CALL_EXPR:
+ {
if (KOENIG_LOOKUP_P (t1) != KOENIG_LOOKUP_P (t2))
return false;
@@ -1996,7 +2003,8 @@ rs_tree_equal (tree t1, tree t2)
return true;
}
- case TARGET_EXPR: {
+ case TARGET_EXPR:
+ {
tree o1 = TREE_OPERAND (t1, 0);
tree o2 = TREE_OPERAND (t2, 0);
@@ -2067,7 +2075,8 @@ rs_tree_equal (tree t1, tree t2)
case tcc_expression:
case tcc_vl_exp:
case tcc_reference:
- case tcc_statement: {
+ case tcc_statement:
+ {
int n = rs_tree_operand_length (t1);
if (TREE_CODE_CLASS (code1) == tcc_vl_exp
&& n != TREE_OPERAND_LENGTH (t2))
@@ -2095,7 +2104,11 @@ rs_tree_equal (tree t1, tree t2)
/* TRUE iff TYPE is publicly & uniquely derived from PARENT. */
-bool publicly_uniquely_derived_p (tree, tree) { return false; }
+bool
+publicly_uniquely_derived_p (tree, tree)
+{
+ return false;
+}
// forked from gcc/cp/typeck.cc comp_except_types
@@ -3375,7 +3388,11 @@ release_tree_vector (vec<tree, va_gc> *vec)
/* As above, but also check value-dependence of the expression as a whole. */
-bool instantiation_dependent_expression_p (tree) { return false; }
+bool
+instantiation_dependent_expression_p (tree)
+{
+ return false;
+}
// forked from gcc/cp/cvt.cc cp_get_callee
@@ -3425,7 +3442,11 @@ scalarish_type_p (const_tree t)
constructors are deleted. This function implements the ABI notion of
non-trivial copy, which has diverged from the one in the standard. */
-bool type_has_nontrivial_copy_init (const_tree) { return false; }
+bool
+type_has_nontrivial_copy_init (const_tree)
+{
+ return false;
+}
// forked from gcc/cp/tree.cc build_local_temp
@@ -3448,7 +3469,11 @@ build_local_temp (tree type)
/* Returns true iff DECL is a capture proxy for a normal capture
(i.e. without explicit initializer). */
-bool is_normal_capture_proxy (tree) { return false; }
+bool
+is_normal_capture_proxy (tree)
+{
+ return false;
+}
// forked from gcc/cp/c-common.cc reject_gcc_builtin
@@ -3522,7 +3547,8 @@ is_bitfield_expr_with_lowered_type (const_tree exp)
case BIT_NOT_EXPR:
return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
- case COMPONENT_REF: {
+ case COMPONENT_REF:
+ {
tree field;
field = TREE_OPERAND (exp, 1);
@@ -3909,7 +3935,8 @@ retry:
break;
case OFFSET_TYPE:
- bad_member : {
+ bad_member:
+ {
tree member = TREE_OPERAND (value, 1);
if (is_overloaded_fn (member))
member = get_first_fn (member);
@@ -3994,13 +4021,21 @@ decl_constant_var_p (tree decl)
/* Returns true iff DECL is a variable or function declared with an auto type
that has not yet been deduced to a real type. */
-bool undeduced_auto_decl (tree) { return false; }
+bool
+undeduced_auto_decl (tree)
+{
+ return false;
+}
// forked from gcc/cp/decl.cc require_deduced_type
/* Complain if DECL has an undeduced return type. */
-bool require_deduced_type (tree, tsubst_flags_t) { return true; }
+bool
+require_deduced_type (tree, tsubst_flags_t)
+{
+ return true;
+}
/* Return the location of a tree passed to %+ formats. */
@@ -4290,10 +4325,9 @@ struct GTY ((for_user)) source_location_table_entry
} // namespace Rust
-extern void
-gt_pch_nx (Rust::source_location_table_entry &);
-extern void
-gt_pch_nx (Rust::source_location_table_entry *, gt_pointer_operator, void *);
+extern void gt_pch_nx (Rust::source_location_table_entry &);
+extern void gt_pch_nx (Rust::source_location_table_entry *, gt_pointer_operator,
+ void *);
namespace Rust {
@@ -4421,7 +4455,8 @@ lvalue_kind (const_tree ref)
case VIEW_CONVERT_EXPR:
return lvalue_kind (TREE_OPERAND (ref, 0));
- case ARRAY_REF: {
+ case ARRAY_REF:
+ {
tree op1 = TREE_OPERAND (ref, 0);
if (TREE_CODE (TREE_TYPE (op1)) == ARRAY_TYPE)
{
@@ -4518,7 +4553,8 @@ lvalue_kind (const_tree ref)
op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1));
break;
- case COND_EXPR: {
+ case COND_EXPR:
+ {
tree op1 = TREE_OPERAND (ref, 1);
if (!op1)
op1 = TREE_OPERAND (ref, 0);
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 3630b0e..9e859d4 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -1543,7 +1543,7 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
#if defined ENABLE_TREE_CHECKING
#define LANG_DECL_MIN_CHECK(NODE) \
- __extension__({ \
+ __extension__ ({ \
struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (!LANG_DECL_HAS_MIN (NODE)) \
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
@@ -1554,7 +1554,7 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
template, not just on a FUNCTION_DECL. So when looking for things in
lang_decl_fn, look down through a TEMPLATE_DECL into its result. */
#define LANG_DECL_FN_CHECK(NODE) \
- __extension__({ \
+ __extension__ ({ \
struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (!DECL_DECLARES_FUNCTION_P (NODE) || lt->u.base.selector != lds_fn) \
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
@@ -1562,7 +1562,7 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
})
#define LANG_DECL_NS_CHECK(NODE) \
- __extension__({ \
+ __extension__ ({ \
struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (TREE_CODE (NODE) != NAMESPACE_DECL || lt->u.base.selector != lds_ns) \
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
@@ -1570,7 +1570,7 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
})
#define LANG_DECL_PARM_CHECK(NODE) \
- __extension__({ \
+ __extension__ ({ \
struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (TREE_CODE (NODE) != PARM_DECL || lt->u.base.selector != lds_parm) \
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
@@ -1578,7 +1578,7 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
})
#define LANG_DECL_DECOMP_CHECK(NODE) \
- __extension__({ \
+ __extension__ ({ \
struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (!VAR_P (NODE) || lt->u.base.selector != lds_decomp) \
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
@@ -2060,8 +2060,8 @@ struct GTY (()) rust_cxx_saved_binding
// forked from gcc/cp/name-lookup.h resort_type_member_vec
/* needed for GTY annotation */
-extern void
-resort_type_member_vec (void *, void *, gt_pointer_operator, void *);
+extern void resort_type_member_vec (void *, void *, gt_pointer_operator,
+ void *);
// forked from gcc/cp/cp-tree.h saved_scope
@@ -2895,8 +2895,7 @@ enum compare_bounds_t
bounds_first
};
-extern tree
-convert_to_void (tree expr, impl_conv_void implicit);
+extern tree convert_to_void (tree expr, impl_conv_void implicit);
// The lvalue-to-rvalue conversion (7.1) is applied if and only if the
// expression is a glvalue of volatile-qualified type and it is one of the
@@ -2911,63 +2910,52 @@ convert_to_void (tree expr, impl_conv_void implicit);
// operands are one of these expressions, or
// * comma expression (8.19) where the right operand is one of these
// expressions.
-extern tree
-mark_discarded_use (tree expr);
+extern tree mark_discarded_use (tree expr);
// Mark EXP as read, not just set, for set but not used -Wunused warning
// purposes.
-extern void
-mark_exp_read (tree exp);
+extern void mark_exp_read (tree exp);
// We've seen an actual use of EXPR. Possibly replace an outer variable
// reference inside with its constant value or a lambda capture.
-extern tree
-mark_use (tree expr, bool rvalue_p, bool read_p, location_t loc,
- bool reject_builtin);
+extern tree mark_use (tree expr, bool rvalue_p, bool read_p, location_t loc,
+ bool reject_builtin);
// Called whenever the expression EXPR is used in an rvalue context.
// When REJECT_BUILTIN is true the expression is checked to make sure
// it doesn't make it possible to obtain the address of a GCC built-in
// function with no library fallback (or any of its bits, such as in
// a conversion to bool).
-extern tree
-mark_rvalue_use (tree, location_t = UNKNOWN_LOCATION,
- bool reject_builtin = true);
+extern tree mark_rvalue_use (tree, location_t = UNKNOWN_LOCATION,
+ bool reject_builtin = true);
// Called whenever an expression is used in an lvalue context.
-extern tree
-mark_lvalue_use (tree expr);
+extern tree mark_lvalue_use (tree expr);
// As above, but don't consider this use a read.
-extern tree
-mark_lvalue_use_nonread (tree expr);
+extern tree mark_lvalue_use_nonread (tree expr);
// We are using a reference VAL for its value. Bash that reference all the way
// down to its lowest form.
-extern tree
-convert_from_reference (tree val);
+extern tree convert_from_reference (tree val);
// Subroutine of convert_to_void. Warn if we're discarding something with
// attribute [[nodiscard]].
-extern void
-maybe_warn_nodiscard (tree expr, impl_conv_void implicit);
+extern void maybe_warn_nodiscard (tree expr, impl_conv_void implicit);
-extern location_t
-expr_loc_or_loc (const_tree t, location_t or_loc);
+extern location_t expr_loc_or_loc (const_tree t, location_t or_loc);
-extern location_t
-expr_loc_or_input_loc (const_tree t);
+extern location_t expr_loc_or_input_loc (const_tree t);
// FN is the callee of a CALL_EXPR or AGGR_INIT_EXPR; return the FUNCTION_DECL
// if we can.
-extern tree
-get_fndecl_from_callee (tree fn);
+extern tree get_fndecl_from_callee (tree fn);
// FIXME some helpers from HIRCompileBase could probably be moved here over time
// Return an expression for the address of BASE[INDEX], used in offset intrinsic
-extern tree
-pointer_offset_expression (tree base_tree, tree index_tree, location_t locus);
+extern tree pointer_offset_expression (tree base_tree, tree index_tree,
+ location_t locus);
/* A tree node, together with a location, so that we can track locations
(and ranges) during parsing.
@@ -2978,11 +2966,9 @@ pointer_offset_expression (tree base_tree, tree index_tree, location_t locus);
extern location_t rs_expr_location (const_tree);
-extern int
-is_empty_class (tree type);
+extern int is_empty_class (tree type);
-extern bool
-is_really_empty_class (tree, bool);
+extern bool is_really_empty_class (tree, bool);
extern bool builtin_valid_in_constant_expr_p (const_tree);
@@ -2990,15 +2976,13 @@ extern bool maybe_constexpr_fn (tree);
extern bool var_in_maybe_constexpr_fn (tree);
-extern int
-rs_type_quals (const_tree type);
+extern int rs_type_quals (const_tree type);
inline bool type_unknown_p (const_tree);
extern bool decl_maybe_constant_var_p (tree);
-extern void
-init_modules ();
+extern void init_modules ();
extern bool var_in_constexpr_fn (tree);
@@ -3006,11 +2990,9 @@ inline tree ovl_first (tree) ATTRIBUTE_PURE;
inline bool type_unknown_p (const_tree);
-extern tree
-lookup_add (tree fns, tree lookup);
+extern tree lookup_add (tree fns, tree lookup);
-extern tree
-ovl_make (tree fn, tree next = NULL_TREE);
+extern tree ovl_make (tree fn, tree next = NULL_TREE);
extern int is_overloaded_fn (tree) ATTRIBUTE_PURE;
@@ -3024,19 +3006,15 @@ extern tree make_conv_op_name (tree);
extern int type_memfn_quals (const_tree);
-struct c_fileinfo *
-get_fileinfo (const char *);
+struct c_fileinfo *get_fileinfo (const char *);
-extern tree
-cxx_make_type (enum tree_code CXX_MEM_STAT_INFO);
+extern tree cxx_make_type (enum tree_code CXX_MEM_STAT_INFO);
-extern tree
-build_cplus_array_type (tree, tree, int is_dep = -1);
+extern tree build_cplus_array_type (tree, tree, int is_dep = -1);
extern bool is_byte_access_type (tree);
-extern bool
-comptypes (tree, tree, int);
+extern bool comptypes (tree, tree, int);
extern tree canonical_eh_spec (tree);
@@ -3046,8 +3024,7 @@ extern bool rs_tree_equal (tree, tree);
extern bool compparms (const_tree, const_tree);
-extern tree
-rs_build_qualified_type_real (tree, int, tsubst_flags_t);
+extern tree rs_build_qualified_type_real (tree, int, tsubst_flags_t);
#define rs_build_qualified_type(TYPE, QUALS) \
rs_build_qualified_type_real ((TYPE), (QUALS), tf_warning_or_error)
extern bool cv_qualified_p (const_tree);
@@ -3056,21 +3033,18 @@ extern bool similar_type_p (tree, tree);
extern bool rs_tree_equal (tree, tree);
-extern bool
-vector_targets_convertible_p (const_tree t1, const_tree t2);
+extern bool vector_targets_convertible_p (const_tree t1, const_tree t2);
extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree);
extern bool comp_ptr_ttypes_const (tree, tree, compare_bounds_t);
-extern tree
-get_class_binding_direct (tree, tree, bool want_type = false);
+extern tree get_class_binding_direct (tree, tree, bool want_type = false);
extern tree skip_artificial_parms_for (const_tree, tree);
-extern void
-lang_check_failed (const char *, int,
- const char *) ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
+extern void lang_check_failed (const char *, int,
+ const char *) ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern tree default_init_uninitialized_part (tree);
@@ -3088,8 +3062,7 @@ extern tree in_class_defaulted_default_constructor (tree);
extern bool is_instantiation_of_constexpr (tree);
-extern bool
-check_for_uninitialized_const_var (tree, bool, tsubst_flags_t);
+extern bool check_for_uninitialized_const_var (tree, bool, tsubst_flags_t);
extern bool reduced_constant_expression_p (tree);
@@ -3108,19 +3081,17 @@ extern tree is_bitfield_expr_with_lowered_type (const_tree);
extern tree convert_bitfield_to_declared_type (tree);
-extern tree
-cp_fold_maybe_rvalue (tree, bool);
+extern tree cp_fold_maybe_rvalue (tree, bool);
extern tree maybe_undo_parenthesized_ref (tree);
-extern tree
-fold_offsetof (tree, tree = size_type_node, tree_code ctx = ERROR_MARK);
+extern tree fold_offsetof (tree, tree = size_type_node,
+ tree_code ctx = ERROR_MARK);
extern tree cp_truthvalue_conversion (tree, tsubst_flags_t);
-extern tree
-fold_non_dependent_expr (tree, tsubst_flags_t = tf_warning_or_error,
- bool = false, tree = NULL_TREE);
+extern tree fold_non_dependent_expr (tree, tsubst_flags_t = tf_warning_or_error,
+ bool = false, tree = NULL_TREE);
extern int char_type_p (tree);
@@ -3163,13 +3134,11 @@ extern tree build_new_constexpr_heap_type (tree, tree, tree);
extern bool is_empty_field (tree);
-extern bool
-in_immediate_context ();
+extern bool in_immediate_context ();
extern tree cp_get_callee_fndecl_nofold (tree);
-extern bool
-cxx_mark_addressable (tree, bool = false);
+extern bool cxx_mark_addressable (tree, bool = false);
extern tree fold_builtin_source_location (location_t);
@@ -3183,25 +3152,22 @@ extern bool glvalue_p (const_tree);
extern cp_lvalue_kind lvalue_kind (const_tree);
-extern tree
-decl_constant_value (tree, bool);
+extern tree decl_constant_value (tree, bool);
extern tree lookup_enumerator (tree, tree);
-extern int
-is_class_type (tree, int);
+extern int is_class_type (tree, int);
extern tree braced_lists_to_strings (tree, tree);
-extern tree
-fold_builtin_is_pointer_inverconvertible_with_class (location_t, int, tree *);
+extern tree fold_builtin_is_pointer_inverconvertible_with_class (location_t,
+ int, tree *);
extern bool layout_compatible_type_p (tree, tree);
extern tree finish_underlying_type (tree);
-extern tree
-c_common_type_for_mode (machine_mode, int);
+extern tree c_common_type_for_mode (machine_mode, int);
extern bool std_layout_type_p (const_tree);
@@ -3213,25 +3179,21 @@ extern void note_failed_type_completion_for_satisfaction (tree);
extern tree complete_type_or_maybe_complain (tree, tree, tsubst_flags_t);
-extern bool
-next_common_initial_seqence (tree &, tree &);
+extern bool next_common_initial_seqence (tree &, tree &);
extern bool null_member_pointer_value_p (tree);
-extern tree
-fold_builtin_is_corresponding_member (location_t, int, tree *);
+extern tree fold_builtin_is_corresponding_member (location_t, int, tree *);
extern tree cp_fold_rvalue (tree);
-extern tree
-maybe_constant_value (tree, tree = NULL_TREE, bool = false);
+extern tree maybe_constant_value (tree, tree = NULL_TREE, bool = false);
extern tree lvalue_type (tree);
extern void lvalue_error (location_t, enum lvalue_use);
-extern tree
-cp_fold_maybe_rvalue (tree, bool);
+extern tree cp_fold_maybe_rvalue (tree, bool);
extern tree get_first_fn (tree) ATTRIBUTE_PURE;
@@ -3253,13 +3215,12 @@ enum
ce_exact
};
-extern tree
-rs_build_qualified_type_real (tree, int, tsubst_flags_t);
+extern tree rs_build_qualified_type_real (tree, int, tsubst_flags_t);
#define rs_build_qualified_type(TYPE, QUALS) \
rs_build_qualified_type_real ((TYPE), (QUALS), tf_warning_or_error)
-extern tree
-rs_walk_subtrees (tree *, int *, walk_tree_fn, void *, hash_set<tree> *);
+extern tree rs_walk_subtrees (tree *, int *, walk_tree_fn, void *,
+ hash_set<tree> *);
#define rs_walk_tree(tp, func, data, pset) \
walk_tree_1 (tp, func, data, pset, rs_walk_subtrees)
#define rs_walk_tree_without_duplicates(tp, func, data) \
@@ -3351,11 +3312,9 @@ gnu_vector_type_p (const_tree type)
return TREE_CODE (type) == VECTOR_TYPE && !TYPE_INDIVISIBLE_P (type);
}
-extern vec<tree, va_gc> *
-make_tree_vector (void);
+extern vec<tree, va_gc> *make_tree_vector (void);
-extern void
-release_tree_vector (vec<tree, va_gc> *);
+extern void release_tree_vector (vec<tree, va_gc> *);
/* Simplified unique_ptr clone to release a tree vec on exit. */
@@ -3373,7 +3332,7 @@ public:
releasing_vec &operator= (const releasing_vec &);
vec_t &operator* () const { return *v; }
- vec_t *operator-> () const { return v; }
+ vec_t *operator->() const { return v; }
vec_t *get () const { return v; }
operator vec_t * () const { return v; }
vec_t **operator& () { return &v; }
@@ -3442,8 +3401,7 @@ cxx_incomplete_type_error (const_tree value, const_tree type)
cxx_incomplete_type_diagnostic (value, type, diagnostics::kind::error);
}
-extern location_t
-location_of (tree t);
+extern location_t location_of (tree t);
/* Helpers for IMPLICIT_RVALUE_P to look through automatic dereference. */
@@ -3465,23 +3423,18 @@ set_implicit_rvalue_p (tree ot)
}
namespace Compile {
-extern tree
-maybe_constant_init (tree, tree = NULL_TREE, bool = false);
+extern tree maybe_constant_init (tree, tree = NULL_TREE, bool = false);
-extern void
-explain_invalid_constexpr_fn (tree fun);
+extern void explain_invalid_constexpr_fn (tree fun);
extern bool potential_constant_expression (tree);
-extern bool
-literal_type_p (tree t);
+extern bool literal_type_p (tree t);
-extern bool
-maybe_constexpr_fn (tree t);
+extern bool maybe_constexpr_fn (tree t);
-extern tree
-fold_non_dependent_init (tree, tsubst_flags_t = tf_warning_or_error,
- bool = false, tree = NULL_TREE);
+extern tree fold_non_dependent_init (tree, tsubst_flags_t = tf_warning_or_error,
+ bool = false, tree = NULL_TREE);
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h
index 0ce2142..0434bcf 100644
--- a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h
+++ b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h
@@ -239,31 +239,25 @@ struct Facts
*
* Output is not yet implemented and is only dumped to stdout.
*/
-extern "C" FFI::Output
-polonius_run (FFI::FactsView input, bool dump_enabled);
+extern "C" FFI::Output polonius_run (FFI::FactsView input, bool dump_enabled);
// Helper functions for FFIVector to be used on Rust side
extern "C" {
-FFI::FFIVector<size_t> *
-FFIVector__new ();
+FFI::FFIVector<size_t> *FFIVector__new ();
-FFI::FFIVectorPair *
-FFIVector__new_vec_pair ();
+FFI::FFIVectorPair *FFIVector__new_vec_pair ();
-FFI::FFIVectorTriple *
-FFIVector__new_vec_triple ();
+FFI::FFIVectorTriple *FFIVector__new_vec_triple ();
-void
-FFIVector__push (FFI::FFIVector<size_t> *vector, size_t element);
+void FFIVector__push (FFI::FFIVector<size_t> *vector, size_t element);
void
FFIVector__push_vec_pair (FFI::FFIVectorPair *vector,
FFI::Pair<size_t, FFI::FFIVector<size_t> *> element);
-void
-FFIVector__push_vec_triple (FFI::FFIVectorTriple *vector,
- FFI::Triple<size_t, size_t, size_t> element);
+void FFIVector__push_vec_triple (FFI::FFIVectorTriple *vector,
+ FFI::Triple<size_t, size_t, size_t> element);
}
} // namespace Polonius
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 6b8b2e9..0799a4e 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -240,7 +240,8 @@ ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
auto &elems = expr.get_internal_elements ();
switch (elems.get_array_expr_type ())
{
- case HIR::ArrayElems::VALUES: {
+ case HIR::ArrayElems::VALUES:
+ {
auto &elem_vals = (static_cast<HIR::ArrayElemsValues &> (elems));
auto init_values = visit_list (elem_vals.get_values ());
// collect locations
@@ -254,7 +255,8 @@ ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
lookup_type (expr), expr.get_locus ());
break;
}
- case HIR::ArrayElems::COPIED: {
+ case HIR::ArrayElems::COPIED:
+ {
auto &elem_copied = (static_cast<HIR::ArrayElemsCopied &> (elems));
auto init = visit_expr (elem_copied.get_elem_to_copy ());
return_expr (new InitializerExpr ({init}), lookup_type (expr),
@@ -415,6 +417,18 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
}
void
+ExprStmtBuilder::visit (HIR::AnonConst &block)
+{
+ rust_unreachable ();
+}
+
+void
+ExprStmtBuilder::visit (HIR::ConstBlock &block)
+{
+ rust_unreachable ();
+}
+
+void
ExprStmtBuilder::visit (HIR::ContinueExpr &cont)
{
LoopAndLabelCtx info = cont.has_label () ? get_label_ctx (cont.get_label ())
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
index 5cab3c4..45d3d58 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
@@ -84,6 +84,8 @@ protected: // Expr
void visit (HIR::MethodCallExpr &expr) override;
void visit (HIR::FieldAccessExpr &expr) override;
void visit (HIR::BlockExpr &block) override;
+ void visit (HIR::AnonConst &block) override;
+ void visit (HIR::ConstBlock &block) override;
void visit (HIR::ContinueExpr &cont) override;
void visit (HIR::BreakExpr &brk) override;
void visit (HIR::RangeFromToExpr &range) override;
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
index 4df0e14..e2cc2dd 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -27,6 +27,8 @@
#include "rust-name-resolver.h"
#include "rust-bir.h"
#include "rust-bir-free-region.h"
+#include "rust-immutable-name-resolution-context.h"
+#include "options.h"
namespace Rust {
@@ -402,19 +404,40 @@ protected: // HIR resolution helpers
template <typename T> NodeId resolve_label (T &expr)
{
NodeId resolved_label;
- bool ok
- = ctx.resolver.lookup_resolved_label (expr.get_mappings ().get_nodeid (),
- &resolved_label);
- rust_assert (ok);
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+ auto res = nr_ctx.lookup (expr.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ resolved_label = res.value ();
+ }
+ else
+ {
+ bool ok = ctx.resolver.lookup_resolved_label (
+ expr.get_mappings ().get_nodeid (), &resolved_label);
+ rust_assert (ok);
+ }
return resolved_label;
}
template <typename T> PlaceId resolve_variable (T &variable)
{
NodeId variable_id;
- bool ok = ctx.resolver.lookup_resolved_name (
- variable.get_mappings ().get_nodeid (), &variable_id);
- rust_assert (ok);
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+ auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ variable_id = res.value ();
+ }
+ else
+ {
+ bool ok = ctx.resolver.lookup_resolved_name (
+ variable.get_mappings ().get_nodeid (), &variable_id);
+ rust_assert (ok);
+ }
return ctx.place_db.lookup_variable (variable_id);
}
@@ -425,9 +448,20 @@ protected: // HIR resolution helpers
// Unlike variables,
// functions do not have to be declared in PlaceDB before use.
NodeId variable_id;
- bool ok = ctx.resolver.lookup_resolved_name (
- variable.get_mappings ().get_nodeid (), &variable_id);
- rust_assert (ok);
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx
+ = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+ auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ());
+ rust_assert (res.has_value ());
+ variable_id = res.value ();
+ }
+ else
+ {
+ bool ok = ctx.resolver.lookup_resolved_name (
+ variable.get_mappings ().get_nodeid (), &variable_id);
+ rust_assert (ok);
+ }
if (ty->is<TyTy::FnType> ())
return ctx.place_db.get_constant (ty);
else
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
index b7a1555..a5ec569 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
@@ -169,6 +169,14 @@ public:
{
return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
}
+ void visit (HIR::AnonConst &expr) override
+ {
+ return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
+ }
+ void visit (HIR::ConstBlock &expr) override
+ {
+ return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
+ }
void visit (HIR::UnsafeBlockExpr &expr) override
{
return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
index ee37bb0..2d655f9 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
@@ -101,7 +101,8 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
{
switch (field->get_item_type ())
{
- case HIR::StructPatternField::TUPLE_PAT: {
+ case HIR::StructPatternField::TUPLE_PAT:
+ {
auto tuple
= static_cast<HIR::StructPatternFieldTuplePat *> (field.get ());
@@ -123,7 +124,8 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
tuple->get_tuple_pattern ().accept_vis (*this);
break;
}
- case HIR::StructPatternField::IDENT_PAT: {
+ case HIR::StructPatternField::IDENT_PAT:
+ {
auto ident_field
= static_cast<HIR::StructPatternFieldIdentPat *> (field.get ());
TyTy::StructFieldType *field_ty = nullptr;
@@ -139,7 +141,8 @@ PatternBindingBuilder::visit (HIR::StructPattern &pattern)
ident_field->get_pattern ().accept_vis (*this);
break;
}
- case HIR::StructPatternField::IDENT: {
+ case HIR::StructPatternField::IDENT:
+ {
auto ident_field
= static_cast<HIR::StructPatternFieldIdent *> (field.get ());
TyTy::StructFieldType *field_ty = nullptr;
@@ -199,13 +202,15 @@ PatternBindingBuilder::visit (HIR::TuplePattern &pattern)
size_t index = 0;
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::MULTIPLE: {
+ case HIR::TuplePatternItems::MULTIPLE:
+ {
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
- case HIR::TuplePatternItems::RANGED: {
+ case HIR::TuplePatternItems::RANGED:
+ {
auto &items
= static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
@@ -244,7 +249,8 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
size_t index = 0;
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TupleStructItems::RANGED: {
+ case HIR::TupleStructItems::RANGED:
+ {
auto &items
= static_cast<HIR::TupleStructItemsRange &> (pattern.get_items ());
@@ -261,7 +267,8 @@ PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
visit_tuple_fields (items.get_upper_patterns (), saved, index);
break;
}
- case HIR::TupleStructItems::MULTIPLE: {
+ case HIR::TupleStructItems::MULTIPLE:
+ {
auto &items
= static_cast<HIR::TupleStructItemsNoRange &> (pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index 84311cc..2e11f63 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -133,6 +133,8 @@ protected:
void visit (HIR::MethodCallExpr &expr) override { rust_unreachable (); }
void visit (HIR::FieldAccessExpr &expr) override { rust_unreachable (); }
void visit (HIR::BlockExpr &expr) override { rust_unreachable (); }
+ void visit (HIR::AnonConst &expr) override { rust_unreachable (); }
+ void visit (HIR::ConstBlock &expr) override { rust_unreachable (); }
void visit (HIR::ClosureExpr &expr) override { rust_unreachable (); }
void visit (HIR::ContinueExpr &expr) override { rust_unreachable (); }
void visit (HIR::BreakExpr &expr) override { rust_unreachable (); }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index 3864b81..9a7bb20 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -182,7 +182,8 @@ Dump::visit (const Statement &stmt)
statement_place = stmt.get_place ();
switch (stmt.get_kind ())
{
- case Statement::Kind::ASSIGNMENT: {
+ case Statement::Kind::ASSIGNMENT:
+ {
visit_place (stmt.get_place ());
stream << " = ";
stmt.get_expr ().accept_vis (*this);
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
index 32a4cd7..e3a1247 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
@@ -232,42 +232,50 @@ protected: // Main collection entry points (for different categories).
{
switch (stmt.get_kind ())
{
- case Statement::Kind::ASSIGNMENT: {
+ case Statement::Kind::ASSIGNMENT:
+ {
// TODO: for unwind, must had hadning for non-panic-only assignements
issue_write_deep (stmt.get_place ());
visit_assignment_expr (stmt.get_place (), stmt.get_expr ());
break;
}
- case Statement::Kind::SWITCH: {
+ case Statement::Kind::SWITCH:
+ {
issue_read_move (stmt.get_place ());
issue_jumps ();
}
break;
- case Statement::Kind::GOTO: {
+ case Statement::Kind::GOTO:
+ {
issue_jumps ();
}
break;
- case Statement::Kind::RETURN: {
+ case Statement::Kind::RETURN:
+ {
issue_place_access (RETURN_VALUE_PLACE);
issue_locals_dealloc ();
break;
}
- case Statement::Kind::STORAGE_DEAD: {
+ case Statement::Kind::STORAGE_DEAD:
+ {
facts.path_moved_at_base.emplace_back (stmt.get_place ().value,
get_current_point_mid ());
facts.var_defined_at.emplace_back (stmt.get_place ().value,
get_current_point_mid ());
break;
}
- case Statement::Kind::STORAGE_LIVE: {
+ case Statement::Kind::STORAGE_LIVE:
+ {
issue_write_deep (stmt.get_place (), true);
break;
}
- case Statement::Kind::USER_TYPE_ASCRIPTION: {
+ case Statement::Kind::USER_TYPE_ASCRIPTION:
+ {
issue_user_type_constraints (stmt.get_place (), stmt.get_type ());
break;
}
- case Statement::Kind::FAKE_READ: {
+ case Statement::Kind::FAKE_READ:
+ {
issue_place_access (stmt.get_place ());
break;
}
@@ -791,7 +799,8 @@ protected: // Subset helpers.
type->as<const TyTy::SliceType> ()->get_element_type (), region_start,
regions);
case TyTy::FNDEF:
- case TyTy::TUPLE: {
+ case TyTy::TUPLE:
+ {
for (auto &field : type->as<const TyTy::TupleType> ()->get_fields ())
sanitize_constraints (field.get_tyty (), region_start, regions);
}
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-place.h b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
index dd9e672..14f1dd6 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-place.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
@@ -217,7 +217,7 @@ public:
const T &operator[] (I pid) const { return internal_vector[pid.value]; }
void push_back (T &&param) { internal_vector.push_back (std::move (param)); }
- template <typename... Args> void emplace_back (Args &&... args)
+ template <typename... Args> void emplace_back (Args &&...args)
{
internal_vector.emplace_back (std::forward<Args> (args)...);
}
@@ -471,14 +471,16 @@ private:
case TyTy::FNDEF:
case TyTy::NEVER:
return true;
- case TyTy::TUPLE: {
+ case TyTy::TUPLE:
+ {
auto &fields = ty->as<TyTy::TupleType> ()->get_fields ();
return std::all_of (fields.begin (), fields.end (),
[] (const TyTy::TyVar &field) {
return is_type_copy (field.get_tyty ());
});
}
- case TyTy::ARRAY: {
+ case TyTy::ARRAY:
+ {
return is_type_copy (ty->as<TyTy::ArrayType> ()->get_element_type ());
}
case TyTy::INFER:
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-visitor.h b/gcc/rust/checks/errors/borrowck/rust-bir-visitor.h
index 5dac89e..d405569 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-visitor.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-visitor.h
@@ -51,7 +51,7 @@ template <typename BASE, typename T> class VisitableImpl : public BASE
{
public:
template <typename... Args>
- explicit VisitableImpl (Args &&... args) : BASE (std::forward<Args> (args)...)
+ explicit VisitableImpl (Args &&...args) : BASE (std::forward<Args> (args)...)
{}
void accept_vis (Visitor &visitor) override
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index 7cf0952..860915e 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -104,6 +104,8 @@ public:
void visit (HIR::MethodCallExpr &expr) override {}
void visit (HIR::FieldAccessExpr &expr) override {}
void visit (HIR::BlockExpr &expr) override {}
+ void visit (HIR::AnonConst &expr) override {}
+ void visit (HIR::ConstBlock &expr) override {}
void visit (HIR::ContinueExpr &expr) override {}
void visit (HIR::BreakExpr &expr) override {}
void visit (HIR::RangeFromToExpr &expr) override {}
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
index 3d25459..5291276 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
@@ -25,8 +25,7 @@
#include "rust-pub-restricted-visitor.h"
#include "rust-privacy-reporter.h"
-extern bool
-saw_errors (void);
+extern bool saw_errors (void);
namespace Rust {
namespace Privacy {
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-ctx.h b/gcc/rust/checks/errors/privacy/rust-privacy-ctx.h
index a506613f..9699ac4 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-ctx.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-ctx.h
@@ -71,8 +71,7 @@ private:
#if CHECKING_P
namespace selftest {
-void
-rust_privacy_ctx_test (void);
+void rust_privacy_ctx_test (void);
}
#endif // !CHECKING_P
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 2a10053..e8a6792 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -157,7 +157,8 @@ PrivacyReporter::check_for_privacy_violation (const NodeId &use_id,
{
case ModuleVisibility::Public:
break;
- case ModuleVisibility::Restricted: {
+ case ModuleVisibility::Restricted:
+ {
// If we are in the crate, everything is restricted correctly, but we
// can't get a module for it
if (!current_module.has_value ())
@@ -215,12 +216,14 @@ PrivacyReporter::check_base_type_privacy (Analysis::NodeMapping &node_mappings,
case TyTy::USIZE:
case TyTy::ISIZE:
case TyTy::ADT:
- case TyTy::STR: {
+ case TyTy::STR:
+ {
auto ref_id = ty->get_ref ();
if (auto lookup_id = mappings.lookup_hir_to_node (ref_id))
return check_for_privacy_violation (*lookup_id, locus);
- rust_unreachable ();
}
+ break;
+
case TyTy::REF:
return recursive_check (
static_cast<const TyTy::ReferenceType *> (ty)->get_base ());
@@ -243,7 +246,8 @@ PrivacyReporter::check_base_type_privacy (Analysis::NodeMapping &node_mappings,
static_cast<const TyTy::TupleType *> (ty)->get_fields ())
recursive_check (param.get_tyty ());
return;
- case TyTy::PLACEHOLDER: {
+ case TyTy::PLACEHOLDER:
+ {
const auto p = static_cast<const TyTy::PlaceholderType *> (ty);
if (!p->can_resolve ())
return;
@@ -413,7 +417,8 @@ PrivacyReporter::visit (HIR::ArrayExpr &expr)
HIR::ArrayElems &elements = expr.get_internal_elements ();
switch (elements.get_array_expr_type ())
{
- case HIR::ArrayElems::ArrayExprType::VALUES: {
+ case HIR::ArrayElems::ArrayExprType::VALUES:
+ {
auto &elems = static_cast<HIR::ArrayElemsValues &> (elements);
for (auto &value : elems.get_values ())
value->accept_vis (*this);
@@ -518,6 +523,18 @@ PrivacyReporter::visit (HIR::BlockExpr &expr)
}
void
+PrivacyReporter::visit (HIR::AnonConst &expr)
+{
+ expr.get_inner_expr ().accept_vis (*this);
+}
+
+void
+PrivacyReporter::visit (HIR::ConstBlock &expr)
+{
+ expr.get_const_expr ().accept_vis (*this);
+}
+
+void
PrivacyReporter::visit (HIR::ContinueExpr &)
{}
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
index 7df2cf4..07eebf6 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
@@ -106,6 +106,8 @@ types
virtual void visit (HIR::MethodCallExpr &expr);
virtual void visit (HIR::FieldAccessExpr &expr);
virtual void visit (HIR::BlockExpr &expr);
+ virtual void visit (HIR::AnonConst &expr);
+ virtual void visit (HIR::ConstBlock &expr);
virtual void visit (HIR::ContinueExpr &expr);
virtual void visit (HIR::BreakExpr &expr);
virtual void visit (HIR::RangeFromToExpr &expr);
diff --git a/gcc/rust/checks/errors/privacy/rust-reachability.cc b/gcc/rust/checks/errors/privacy/rust-reachability.cc
index 1e57674..223c77b 100644
--- a/gcc/rust/checks/errors/privacy/rust-reachability.cc
+++ b/gcc/rust/checks/errors/privacy/rust-reachability.cc
@@ -158,7 +158,8 @@ ReachabilityVisitor::visit (HIR::Enum &enum_item)
switch (variant->get_enum_item_kind ())
{
- case HIR::EnumItem::Tuple: {
+ case HIR::EnumItem::Tuple:
+ {
// Should we update the fields only if they are public? Similarly to
// what we do in the ReachabilityVisitor for HIR::TupleStruct?
auto tuple_variant
@@ -167,7 +168,8 @@ ReachabilityVisitor::visit (HIR::Enum &enum_item)
ctx.update_reachability (field.get_mappings (), variant_reach);
break;
}
- case HIR::EnumItem::Struct: {
+ case HIR::EnumItem::Struct:
+ {
// Should we update the fields only if they are public? Similarly to
// what we do in the ReachabilityVisitor for HIR::StructStruct?
auto struct_variant
diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
index f0da745..c59763d 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
@@ -127,7 +127,8 @@ VisibilityResolver::resolve_visibility (const HIR::Visibility &visibility,
case HIR::Visibility::PUBLIC:
to_resolve = ModuleVisibility::create_public ();
return true;
- case HIR::Visibility::RESTRICTED: {
+ case HIR::Visibility::RESTRICTED:
+ {
// FIXME: We also need to handle 2015 vs 2018 edition conflicts
auto id = UNKNOWN_DEFID;
auto result = resolve_module_path (visibility.get_path (), id);
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index 3716ea5..5cbab3d 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -417,6 +417,26 @@ ConstChecker::visit (BlockExpr &expr)
}
void
+ConstChecker::visit (AnonConst &expr)
+{
+ const_context.enter (expr.get_mappings ().get_hirid ());
+
+ expr.get_inner_expr ().accept_vis (*this);
+
+ const_context.exit ();
+}
+
+void
+ConstChecker::visit (ConstBlock &expr)
+{
+ const_context.enter (expr.get_mappings ().get_hirid ());
+
+ expr.get_const_expr ().accept_vis (*this);
+
+ const_context.exit ();
+}
+
+void
ConstChecker::visit (ContinueExpr &)
{}
diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h
index b954330..2239874 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -113,6 +113,8 @@ private:
virtual void visit (FieldAccessExpr &expr) override;
virtual void visit (ClosureExpr &expr) override;
virtual void visit (BlockExpr &expr) override;
+ virtual void visit (AnonConst &expr) override;
+ virtual void visit (ConstBlock &expr) override;
virtual void visit (ContinueExpr &expr) override;
virtual void visit (BreakExpr &expr) override;
virtual void visit (RangeFromToExpr &expr) override;
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index 648bc07..ec22a0e 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -295,6 +295,18 @@ PatternChecker::visit (BlockExpr &expr)
}
void
+PatternChecker::visit (AnonConst &expr)
+{
+ expr.get_inner_expr ().accept_vis (*this);
+}
+
+void
+PatternChecker::visit (ConstBlock &expr)
+{
+ expr.get_const_expr ().accept_vis (*this);
+}
+
+void
PatternChecker::visit (ContinueExpr &)
{}
@@ -728,23 +740,27 @@ Constructor::is_covered_by (const Constructor &o) const
switch (kind)
{
- case ConstructorKind::VARIANT: {
+ case ConstructorKind::VARIANT:
+ {
rust_assert (kind == ConstructorKind::VARIANT);
return variant_idx == o.variant_idx;
}
break;
- case ConstructorKind::INT_RANGE: {
+ case ConstructorKind::INT_RANGE:
+ {
rust_assert (kind == ConstructorKind::INT_RANGE);
return int_range.lo >= o.int_range.lo && int_range.hi <= o.int_range.hi;
}
break;
- case ConstructorKind::WILDCARD: {
+ case ConstructorKind::WILDCARD:
+ {
// TODO: wildcard is covered by a variant of enum with a single
// variant
return false;
}
break;
- case ConstructorKind::STRUCT: {
+ case ConstructorKind::STRUCT:
+ {
// Struct pattern is always covered by a other struct constructor.
return true;
}
@@ -900,19 +916,22 @@ PlaceInfo::specialize (const Constructor &c) const
switch (c.get_kind ())
{
case Constructor::ConstructorKind::WILDCARD:
- case Constructor::ConstructorKind::INT_RANGE: {
+ case Constructor::ConstructorKind::INT_RANGE:
+ {
return {};
}
break;
case Constructor::ConstructorKind::STRUCT:
- case Constructor::ConstructorKind::VARIANT: {
+ case Constructor::ConstructorKind::VARIANT:
+ {
rust_assert (ty->get_kind () == TyTy::TypeKind::ADT);
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (ty);
switch (adt->get_adt_kind ())
{
case TyTy::ADTType::ADTKind::ENUM:
case TyTy::ADTType::ADTKind::STRUCT_STRUCT:
- case TyTy::ADTType::ADTKind::TUPLE_STRUCT: {
+ case TyTy::ADTType::ADTKind::TUPLE_STRUCT:
+ {
TyTy::VariantDef *variant
= adt->get_variants ().at (c.get_variant_index ());
if (variant->get_variant_type ()
@@ -926,14 +945,16 @@ PlaceInfo::specialize (const Constructor &c) const
return new_place_infos;
}
break;
- case TyTy::ADTType::ADTKind::UNION: {
+ case TyTy::ADTType::ADTKind::UNION:
+ {
// TODO: support unions
rust_unreachable ();
}
}
}
break;
- default: {
+ default:
+ {
rust_unreachable ();
}
break;
@@ -991,7 +1012,8 @@ WitnessPat::to_string () const
{
switch (ctor.get_kind ())
{
- case Constructor::ConstructorKind::STRUCT: {
+ case Constructor::ConstructorKind::STRUCT:
+ {
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (ty);
TyTy::VariantDef *variant
= adt->get_variants ().at (ctor.get_variant_index ());
@@ -1016,7 +1038,8 @@ WitnessPat::to_string () const
return buf;
}
break;
- case Constructor::ConstructorKind::VARIANT: {
+ case Constructor::ConstructorKind::VARIANT:
+ {
std::string buf;
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (ty);
buf += adt->get_identifier ();
@@ -1026,11 +1049,13 @@ WitnessPat::to_string () const
switch (variant->get_variant_type ())
{
- case TyTy::VariantDef::VariantType::NUM: {
+ case TyTy::VariantDef::VariantType::NUM:
+ {
return buf;
}
break;
- case TyTy::VariantDef::VariantType::TUPLE: {
+ case TyTy::VariantDef::VariantType::TUPLE:
+ {
buf += "(";
for (size_t i = 0; i < fields.size (); i++)
{
@@ -1042,7 +1067,8 @@ WitnessPat::to_string () const
return buf;
}
break;
- case TyTy::VariantDef::VariantType::STRUCT: {
+ case TyTy::VariantDef::VariantType::STRUCT:
+ {
buf += " {";
if (!fields.empty ())
buf += " ";
@@ -1061,7 +1087,8 @@ WitnessPat::to_string () const
buf += "}";
}
break;
- default: {
+ default:
+ {
rust_unreachable ();
}
break;
@@ -1069,21 +1096,25 @@ WitnessPat::to_string () const
return buf;
}
break;
- case Constructor::ConstructorKind::INT_RANGE: {
+ case Constructor::ConstructorKind::INT_RANGE:
+ {
// TODO: implement
rust_unreachable ();
}
break;
- case Constructor::ConstructorKind::WILDCARD: {
+ case Constructor::ConstructorKind::WILDCARD:
+ {
return "_";
}
break;
- case Constructor::ConstructorKind::REFERENCE: {
+ case Constructor::ConstructorKind::REFERENCE:
+ {
// TODO: implement
rust_unreachable ();
}
break;
- default: {
+ default:
+ {
rust_unreachable ();
}
break;
@@ -1100,12 +1131,14 @@ WitnessMatrix::apply_constructor (const Constructor &ctor,
// TODO: only support struct and variant ctor for now.
switch (ctor.get_kind ())
{
- case Constructor::ConstructorKind::WILDCARD: {
+ case Constructor::ConstructorKind::WILDCARD:
+ {
arity = 0;
}
break;
case Constructor::ConstructorKind::STRUCT:
- case Constructor::ConstructorKind::VARIANT: {
+ case Constructor::ConstructorKind::VARIANT:
+ {
if (ty->get_kind () == TyTy::TypeKind::ADT)
{
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (ty);
@@ -1118,7 +1151,8 @@ WitnessMatrix::apply_constructor (const Constructor &ctor,
}
}
break;
- default: {
+ default:
+ {
rust_unreachable ();
}
}
@@ -1160,9 +1194,9 @@ WitnessMatrix::extend (const WitnessMatrix &other)
}
// forward declarations
-static DeconstructedPat
-lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern &pattern,
- TyTy::BaseType *scrutinee_ty);
+static DeconstructedPat lower_pattern (Resolver::TypeCheckContext *ctx,
+ HIR::Pattern &pattern,
+ TyTy::BaseType *scrutinee_ty);
static DeconstructedPat
lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
@@ -1175,7 +1209,8 @@ lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
std::vector<DeconstructedPat> fields;
switch (elems.get_item_type ())
{
- case HIR::TupleStructItems::ItemType::MULTIPLE: {
+ case HIR::TupleStructItems::ItemType::MULTIPLE:
+ {
HIR::TupleStructItemsNoRange &multiple
= static_cast<HIR::TupleStructItemsNoRange &> (elems);
@@ -1191,12 +1226,14 @@ lower_tuple_pattern (Resolver::TypeCheckContext *ctx,
return DeconstructedPat (ctor, arity, fields, pattern.get_locus ());
}
break;
- case HIR::TupleStructItems::ItemType::RANGED: {
+ case HIR::TupleStructItems::ItemType::RANGED:
+ {
// TODO: ranged tuple struct items
rust_unreachable ();
}
break;
- default: {
+ default:
+ {
rust_unreachable ();
}
}
@@ -1227,7 +1264,8 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
{
switch (elem->get_item_type ())
{
- case HIR::StructPatternField::ItemType::IDENT: {
+ case HIR::StructPatternField::ItemType::IDENT:
+ {
HIR::StructPatternFieldIdent *ident
= static_cast<HIR::StructPatternFieldIdent *> (elem.get ());
int field_idx
@@ -1236,7 +1274,8 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
= DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- case HIR::StructPatternField::ItemType::IDENT_PAT: {
+ case HIR::StructPatternField::ItemType::IDENT_PAT:
+ {
HIR::StructPatternFieldIdentPat *ident_pat
= static_cast<HIR::StructPatternFieldIdentPat *> (elem.get ());
int field_idx
@@ -1246,12 +1285,14 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
variant->get_fields ().at (field_idx)->get_field_type ());
}
break;
- case HIR::StructPatternField::ItemType::TUPLE_PAT: {
+ case HIR::StructPatternField::ItemType::TUPLE_PAT:
+ {
// TODO: tuple: pat
rust_unreachable ();
}
break;
- default: {
+ default:
+ {
rust_unreachable ();
}
}
@@ -1268,11 +1309,13 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern &pattern,
switch (pat_type)
{
case HIR::Pattern::PatternType::WILDCARD:
- case HIR::Pattern::PatternType::IDENTIFIER: {
+ case HIR::Pattern::PatternType::IDENTIFIER:
+ {
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- case HIR::Pattern::PatternType::PATH: {
+ case HIR::Pattern::PatternType::PATH:
+ {
// TODO: support constants, associated constants, enum variants and
// structs
// https://doc.rust-lang.org/reference/patterns.html#path-patterns
@@ -1280,13 +1323,15 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern &pattern,
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- case HIR::Pattern::PatternType::REFERENCE: {
+ case HIR::Pattern::PatternType::REFERENCE:
+ {
// TODO: unimplemented. Treat this pattern as wildcard for now.
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
case HIR::Pattern::PatternType::STRUCT:
- case HIR::Pattern::PatternType::TUPLE_STRUCT: {
+ case HIR::Pattern::PatternType::TUPLE_STRUCT:
+ {
HirId path_id = UNKNOWN_HIRID;
if (pat_type == HIR::Pattern::PatternType::STRUCT)
{
@@ -1343,37 +1388,44 @@ lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern &pattern,
}
}
break;
- case HIR::Pattern::PatternType::TUPLE: {
+ case HIR::Pattern::PatternType::TUPLE:
+ {
// TODO: unimplemented. Treat this pattern as wildcard for now.
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- case HIR::Pattern::PatternType::SLICE: {
+ case HIR::Pattern::PatternType::SLICE:
+ {
// TODO: unimplemented. Treat this pattern as wildcard for now.
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- case HIR::Pattern::PatternType::ALT: {
+ case HIR::Pattern::PatternType::ALT:
+ {
// TODO: unimplemented. Treat this pattern as wildcard for now.
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- case HIR::Pattern::PatternType::LITERAL: {
+ case HIR::Pattern::PatternType::LITERAL:
+ {
// TODO: unimplemented. Treat this pattern as wildcard for now.
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- case HIR::Pattern::PatternType::RANGE: {
+ case HIR::Pattern::PatternType::RANGE:
+ {
// TODO: unimplemented. Treat this pattern as wildcard for now.
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- case HIR::Pattern::PatternType::GROUPED: {
+ case HIR::Pattern::PatternType::GROUPED:
+ {
// TODO: unimplemented. Treat this pattern as wildcard for now.
return DeconstructedPat::make_wildcard (pattern.get_locus ());
}
break;
- default: {
+ default:
+ {
rust_unreachable ();
}
}
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
index 6d60ced..5766180 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
@@ -33,9 +33,9 @@ namespace Analysis {
using namespace HIR;
-void
-check_match_usefulness (Resolver::TypeCheckContext *ctx,
- TyTy::BaseType *scrutinee_ty, HIR::MatchExpr &expr);
+void check_match_usefulness (Resolver::TypeCheckContext *ctx,
+ TyTy::BaseType *scrutinee_ty,
+ HIR::MatchExpr &expr);
class PatternChecker : public HIR::HIRFullVisitor
{
@@ -86,6 +86,8 @@ private:
virtual void visit (MethodCallExpr &expr) override;
virtual void visit (FieldAccessExpr &expr) override;
virtual void visit (BlockExpr &expr) override;
+ virtual void visit (AnonConst &expr) override;
+ virtual void visit (ConstBlock &expr) override;
virtual void visit (ClosureExpr &expr) override;
virtual void visit (ContinueExpr &expr) override;
virtual void visit (BreakExpr &expr) override;
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 46eef11..d90088f 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -540,6 +540,18 @@ UnsafeChecker::visit (BlockExpr &expr)
}
void
+UnsafeChecker::visit (AnonConst &expr)
+{
+ expr.get_inner_expr ().accept_vis (*this);
+}
+
+void
+UnsafeChecker::visit (ConstBlock &expr)
+{
+ expr.get_const_expr ().accept_vis (*this);
+}
+
+void
UnsafeChecker::visit (ContinueExpr &)
{}
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h
index 9a8fb7c..8a9830f 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -95,6 +95,8 @@ private:
virtual void visit (FieldAccessExpr &expr) override;
virtual void visit (ClosureExpr &expr) override;
virtual void visit (BlockExpr &expr) override;
+ virtual void visit (AnonConst &expr) override;
+ virtual void visit (ConstBlock &expr) override;
virtual void visit (ContinueExpr &expr) override;
virtual void visit (BreakExpr &expr) override;
virtual void visit (RangeFromToExpr &expr) override;
diff --git a/gcc/rust/expand/rust-cfg-strip.cc b/gcc/rust/expand/rust-cfg-strip.cc
index a8c3ca5..0db6122 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -289,7 +289,8 @@ CfgStrip::maybe_strip_generic_args (AST::GenericArgs &args)
{
switch (arg.get_kind ())
{
- case AST::GenericArg::Kind::Type: {
+ case AST::GenericArg::Kind::Type:
+ {
auto &type = arg.get_type ();
type.accept_vis (*this);
@@ -298,7 +299,8 @@ CfgStrip::maybe_strip_generic_args (AST::GenericArgs &args)
"cannot strip type in this position");
break;
}
- case AST::GenericArg::Kind::Const: {
+ case AST::GenericArg::Kind::Const:
+ {
auto &expr = arg.get_expression ();
expr.accept_vis (*this);
@@ -1190,7 +1192,7 @@ CfgStrip::visit (AST::ClosureExprInnerTyped &expr)
rust_error_at (type.get_locus (), "cannot strip type in this position");
// can't strip expression itself, but can strip sub-expressions
- auto &definition_block = expr.get_definition_block ();
+ auto &definition_block = expr.get_definition_expr ();
definition_block.accept_vis (*this);
if (definition_block.is_marked_for_strip ())
rust_error_at (definition_block.get_locus (),
@@ -2260,7 +2262,7 @@ void
CfgStrip::visit (AST::IdentifierPattern &pattern)
{
// can only strip sub-patterns of the inner pattern to bind
- if (!pattern.has_pattern_to_bind ())
+ if (!pattern.has_subpattern ())
return;
AST::DefaultASTVisitor::visit (pattern);
diff --git a/gcc/rust/expand/rust-derive-clone.h b/gcc/rust/expand/rust-derive-clone.h
index 61224ba..a3320c7 100644
--- a/gcc/rust/expand/rust-derive-clone.h
+++ b/gcc/rust/expand/rust-derive-clone.h
@@ -29,7 +29,7 @@ class DeriveClone : DeriveVisitor
public:
DeriveClone (location_t loc);
- std::unique_ptr<AST::Item> go (Item &item);
+ std::unique_ptr<Item> go (Item &item);
private:
std::unique_ptr<Item> expanded;
@@ -80,10 +80,10 @@ private:
MatchCase clone_enum_struct (PathInExpression variant_path,
const EnumItemStruct &variant);
- virtual void visit_struct (StructStruct &item);
- virtual void visit_tuple (TupleStruct &item);
- virtual void visit_enum (Enum &item);
- virtual void visit_union (Union &item);
+ virtual void visit_struct (StructStruct &item) override;
+ virtual void visit_tuple (TupleStruct &item) override;
+ virtual void visit_enum (Enum &item) override;
+ virtual void visit_union (Union &item) override;
};
} // namespace AST
diff --git a/gcc/rust/expand/rust-derive-copy.h b/gcc/rust/expand/rust-derive-copy.h
index 71972eb..664a8e0 100644
--- a/gcc/rust/expand/rust-derive-copy.h
+++ b/gcc/rust/expand/rust-derive-copy.h
@@ -44,10 +44,10 @@ private:
copy_impl (std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics);
- virtual void visit_struct (StructStruct &item);
- virtual void visit_tuple (TupleStruct &item);
- virtual void visit_enum (Enum &item);
- virtual void visit_union (Union &item);
+ virtual void visit_struct (StructStruct &item) override;
+ virtual void visit_tuple (TupleStruct &item) override;
+ virtual void visit_enum (Enum &item) override;
+ virtual void visit_union (Union &item) override;
};
} // namespace AST
diff --git a/gcc/rust/expand/rust-derive-default.cc b/gcc/rust/expand/rust-derive-default.cc
index 2e8b456..1b497b5 100644
--- a/gcc/rust/expand/rust-derive-default.cc
+++ b/gcc/rust/expand/rust-derive-default.cc
@@ -98,7 +98,8 @@ DeriveDefault::visit_struct (StructStruct &item)
for (auto &field : item.get_fields ())
{
auto name = field.get_field_name ().as_string ();
- auto expr = default_call (field.get_field_type ().clone_type ());
+ auto type = Builder::new_type (field.get_field_type ());
+ auto expr = default_call (std::move (type));
cloned_fields.emplace_back (
builder.struct_expr_field (std::move (name), std::move (expr)));
@@ -119,7 +120,7 @@ DeriveDefault::visit_tuple (TupleStruct &tuple_item)
for (auto &field : tuple_item.get_fields ())
{
- auto type = field.get_field_type ().clone_type ();
+ auto type = Builder::new_type (field.get_field_type ());
defaulted_fields.emplace_back (default_call (std::move (type)));
}
diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc
index 5e7a894..9765127 100644
--- a/gcc/rust/expand/rust-derive-eq.cc
+++ b/gcc/rust/expand/rust-derive-eq.cc
@@ -142,7 +142,10 @@ DeriveEq::visit_tuple (TupleStruct &item)
auto types = std::vector<std::unique_ptr<Type>> ();
for (auto &field : item.get_fields ())
- types.emplace_back (field.get_field_type ().clone_type ());
+ {
+ auto type = Builder::new_type (field.get_field_type ());
+ types.emplace_back (std::move (type));
+ }
expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
item.get_identifier ().as_string (),
@@ -155,7 +158,10 @@ DeriveEq::visit_struct (StructStruct &item)
auto types = std::vector<std::unique_ptr<Type>> ();
for (auto &field : item.get_fields ())
- types.emplace_back (field.get_field_type ().clone_type ());
+ {
+ auto type = Builder::new_type (field.get_field_type ());
+ types.emplace_back (std::move (type));
+ }
expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
item.get_identifier ().as_string (),
@@ -175,19 +181,26 @@ DeriveEq::visit_enum (Enum &item)
case EnumItem::Kind::Discriminant:
// nothing to do as they contain no inner types
continue;
- case EnumItem::Kind::Tuple: {
+ case EnumItem::Kind::Tuple:
+ {
auto &tuple = static_cast<EnumItemTuple &> (*variant);
for (auto &field : tuple.get_tuple_fields ())
- types.emplace_back (field.get_field_type ().clone_type ());
-
+ {
+ auto type = Builder::new_type (field.get_field_type ());
+ types.emplace_back (std::move (type));
+ }
break;
}
- case EnumItem::Kind::Struct: {
+ case EnumItem::Kind::Struct:
+ {
auto &tuple = static_cast<EnumItemStruct &> (*variant);
for (auto &field : tuple.get_struct_fields ())
- types.emplace_back (field.get_field_type ().clone_type ());
+ {
+ auto type = Builder::new_type (field.get_field_type ());
+ types.emplace_back (std::move (type));
+ }
break;
}
@@ -205,7 +218,10 @@ DeriveEq::visit_union (Union &item)
auto types = std::vector<std::unique_ptr<Type>> ();
for (auto &field : item.get_variants ())
- types.emplace_back (field.get_field_type ().clone_type ());
+ {
+ auto type = Builder::new_type (field.get_field_type ());
+ types.emplace_back (std::move (type));
+ }
expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)),
item.get_identifier ().as_string (),
diff --git a/gcc/rust/expand/rust-derive-eq.h b/gcc/rust/expand/rust-derive-eq.h
index 17af526..fb187cc 100644
--- a/gcc/rust/expand/rust-derive-eq.h
+++ b/gcc/rust/expand/rust-derive-eq.h
@@ -31,7 +31,7 @@ class DeriveEq : DeriveVisitor
public:
DeriveEq (location_t loc);
- std::vector<std::unique_ptr<AST::Item>> go (Item &item);
+ std::vector<std::unique_ptr<Item>> go (Item &item);
private:
std::vector<std::unique_ptr<Item>> expanded;
@@ -70,10 +70,10 @@ private:
*/
std::unique_ptr<Stmt> assert_type_is_eq (std::unique_ptr<Type> &&type);
- virtual void visit_struct (StructStruct &item);
- virtual void visit_tuple (TupleStruct &item);
- virtual void visit_enum (Enum &item);
- virtual void visit_union (Union &item);
+ virtual void visit_struct (StructStruct &item) override;
+ virtual void visit_tuple (TupleStruct &item) override;
+ virtual void visit_enum (Enum &item) override;
+ virtual void visit_union (Union &item) override;
};
} // namespace AST
diff --git a/gcc/rust/expand/rust-derive-hash.h b/gcc/rust/expand/rust-derive-hash.h
index 02b0bee..67170d0 100644
--- a/gcc/rust/expand/rust-derive-hash.h
+++ b/gcc/rust/expand/rust-derive-hash.h
@@ -29,7 +29,7 @@ class DeriveHash : DeriveVisitor
public:
DeriveHash (location_t loc);
- std::unique_ptr<AST::Item> go (Item &item);
+ std::unique_ptr<Item> go (Item &item);
private:
std::unique_ptr<Item> expanded;
@@ -49,10 +49,10 @@ private:
MatchCase match_enum_struct (PathInExpression variant_path,
const EnumItemStruct &variant);
- virtual void visit_struct (StructStruct &item);
- virtual void visit_tuple (TupleStruct &item);
- virtual void visit_enum (Enum &item);
- virtual void visit_union (Union &item);
+ virtual void visit_struct (StructStruct &item) override;
+ virtual void visit_tuple (TupleStruct &item) override;
+ virtual void visit_enum (Enum &item) override;
+ virtual void visit_union (Union &item) override;
};
} // namespace AST
diff --git a/gcc/rust/expand/rust-derive-ord.cc b/gcc/rust/expand/rust-derive-ord.cc
new file mode 100644
index 0000000..7eaaa47
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-ord.cc
@@ -0,0 +1,172 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-derive-ord.h"
+#include "rust-ast-dump.h"
+#include "rust-ast.h"
+#include "rust-derive.h"
+#include "rust-item.h"
+
+namespace Rust {
+namespace AST {
+
+DeriveOrd::DeriveOrd (Ordering ordering, location_t loc)
+ : DeriveVisitor (loc), ordering (ordering)
+{}
+
+std::unique_ptr<Item>
+DeriveOrd::go (Item &item)
+{
+ item.accept_vis (*this);
+
+ AST::Dump::debug (*expanded);
+
+ return std::move (expanded);
+}
+
+std::unique_ptr<Item>
+DeriveOrd::cmp_impl (
+ std::unique_ptr<BlockExpr> &&fn_block, Identifier type_name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics)
+{
+ auto fn = cmp_fn (std::move (fn_block), type_name);
+
+ auto trait = ordering == Ordering::Partial ? "PartialOrd" : "Ord";
+ auto trait_path = builder.type_path ({"core", "cmp", trait}, true);
+
+ auto trait_bound
+ = builder.trait_bound (builder.type_path ({"core", "cmp", trait}, true));
+
+ auto trait_items = vec (std::move (fn));
+
+ auto cmp_generics
+ = setup_impl_generics (type_name.as_string (), type_generics,
+ std::move (trait_bound));
+
+ return builder.trait_impl (trait_path, std::move (cmp_generics.self_type),
+ std::move (trait_items),
+ std::move (cmp_generics.impl));
+}
+
+std::unique_ptr<AssociatedItem>
+DeriveOrd::cmp_fn (std::unique_ptr<BlockExpr> &&block, Identifier type_name)
+{
+ // Ordering
+ auto return_type = builder.type_path ({"core", "cmp", "Ordering"}, true);
+
+ // In the case of PartialOrd, we return an Option<Ordering>
+ if (ordering == Ordering::Partial)
+ {
+ auto generic = GenericArg::create_type (ptrify (return_type));
+
+ auto generic_seg = builder.type_path_segment_generic (
+ "Option", GenericArgs ({}, {generic}, {}, loc));
+ auto core = builder.type_path_segment ("core");
+ auto option = builder.type_path_segment ("option");
+
+ return_type
+ = builder.type_path (vec (std::move (core), std::move (option),
+ std::move (generic_seg)),
+ true);
+ }
+
+ // &self, other: &Self
+ auto params = vec (
+ builder.self_ref_param (),
+ builder.function_param (builder.identifier_pattern ("other"),
+ builder.reference_type (ptrify (
+ builder.type_path (type_name.as_string ())))));
+
+ auto function_name = ordering == Ordering::Partial ? "partial_cmp" : "cmp";
+
+ return builder.function (function_name, std::move (params),
+ ptrify (return_type), std::move (block));
+}
+std::unique_ptr<Expr>
+recursive_match ()
+{
+ return nullptr;
+}
+
+// we need to do a recursive match expression for all of the fields used in a
+// struct so for something like struct Foo { a: i32, b: i32, c: i32 } we must
+// first compare each `a` field, then `b`, then `c`, like this:
+//
+// match cmp_fn(self.<field>, other.<field>) {
+// Ordering::Equal => <recurse>,
+// cmp => cmp,
+// }
+//
+// and the recurse will be the exact same expression, on the next field. so that
+// our result looks like this:
+//
+// match cmp_fn(self.a, other.a) {
+// Ordering::Equal => match cmp_fn(self.b, other.b) {
+// Ordering::Equal =>cmp_fn(self.c, other.c),
+// cmp => cmp,
+// }
+// cmp => cmp,
+// }
+//
+// the last field comparison needs not to be a match but just the function call.
+// this is going to be annoying lol
+void
+DeriveOrd::visit_struct (StructStruct &item)
+{
+ // FIXME: Put cmp_fn call inside cmp_impl, pass a block to cmp_impl instead -
+ // this avoids repeating the same parameter twice (the type name)
+ expanded = cmp_impl (builder.block (), item.get_identifier (),
+ item.get_generic_params ());
+}
+
+// same as structs, but for each field index instead of each field name -
+// straightforward once we have `visit_struct` working
+void
+DeriveOrd::visit_tuple (TupleStruct &item)
+{}
+
+// for enums, we need to generate a match for each of the enum's variant that
+// contains data and then do the same thing as visit_struct or visit_enum. if
+// the two aren't the same variant, then compare the two discriminant values for
+// all the dataless enum variants and in the general case.
+//
+// so for enum Foo { A(i32, i32), B, C } we need to do the following
+//
+// match (self, other) {
+// (A(self_0, self_1), A(other_0, other_1)) => {
+// match cmp_fn(self_0, other_0) {
+// Ordering::Equal => cmp_fn(self_1, other_1),
+// cmp => cmp,
+// },
+// _ => cmp_fn(discr_value(self), discr_value(other))
+// }
+void
+DeriveOrd::visit_enum (Enum &item)
+{}
+
+void
+DeriveOrd::visit_union (Union &item)
+{
+ auto trait_name = ordering == Ordering::Total ? "Ord" : "PartialOrd";
+
+ rust_error_at (item.get_locus (), "derive(%s) cannot be used on unions",
+ trait_name);
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-ord.h b/gcc/rust/expand/rust-derive-ord.h
new file mode 100644
index 0000000..fae1326
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-ord.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_DERIVE_ORD_H
+#define RUST_DERIVE_ORD_H
+
+#include "rust-ast.h"
+#include "rust-derive.h"
+
+namespace Rust {
+namespace AST {
+
+/**
+ * DeriveOrd is a bit special as the expansion of both `PartialOrd` and `Ord`
+ * is extremely similar. The only difference is that `PartialOrd` concerns
+ * partial-ordering, and thus its main method returns an `Option<Ordering>`,
+ * while `Ord` concerns total-ordering, and its main method returns an
+ * `Ordering`. Otherwise, the expansion logic is the same, so we factor both
+ * derives into one.
+ */
+class DeriveOrd : public DeriveVisitor
+{
+public:
+ enum class Ordering
+ {
+ Total,
+ Partial
+ };
+
+ DeriveOrd (Ordering ordering, location_t loc);
+
+ std::unique_ptr<Item> go (Item &item);
+
+private:
+ std::unique_ptr<Item> expanded;
+
+ Ordering ordering;
+
+ /**
+ * Create the recursive matching structure used when implementing the
+ * comparison function on multiple sub items (fields, tuple indexes...) */
+ std::unique_ptr<Expr> recursive_match ();
+
+ std::unique_ptr<Item>
+ cmp_impl (std::unique_ptr<BlockExpr> &&fn_block, Identifier type_name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics);
+ std::unique_ptr<AssociatedItem> cmp_fn (std::unique_ptr<BlockExpr> &&block,
+ Identifier type_name);
+
+ virtual void visit_struct (StructStruct &item) override;
+ virtual void visit_tuple (TupleStruct &item) override;
+ virtual void visit_enum (Enum &item) override;
+ virtual void visit_union (Union &item) override;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_DERIVE_ORD_H
diff --git a/gcc/rust/expand/rust-derive-partial-eq.cc b/gcc/rust/expand/rust-derive-partial-eq.cc
index ff66faa..22368bc 100644
--- a/gcc/rust/expand/rust-derive-partial-eq.cc
+++ b/gcc/rust/expand/rust-derive-partial-eq.cc
@@ -199,8 +199,6 @@ DerivePartialEq::match_enum_tuple (PathInExpression variant_path,
auto self_pattern_str = "__self_" + std::to_string (i);
auto other_pattern_str = "__other_" + std::to_string (i);
- rust_debug ("]ARTHUR[ %s", self_pattern_str.c_str ());
-
self_patterns.emplace_back (
builder.identifier_pattern (self_pattern_str));
other_patterns.emplace_back (
@@ -240,15 +238,55 @@ MatchCase
DerivePartialEq::match_enum_struct (PathInExpression variant_path,
const EnumItemStruct &variant)
{
- // NOTE: We currently do not support compiling struct patterns where an
- // identifier is assigned a new pattern, e.g. Bloop { f0: x }
- // This is what we should be using to compile PartialEq for enum struct
- // variants, as we need to be comparing the field of each instance meaning we
- // need to give two different names to two different instances of the same
- // field. We cannot just use the field's name like we do when deriving
- // `Clone`.
-
- rust_unreachable ();
+ auto self_fields = std::vector<std::unique_ptr<StructPatternField>> ();
+ auto other_fields = std::vector<std::unique_ptr<StructPatternField>> ();
+
+ auto self_other_exprs = std::vector<SelfOther> ();
+
+ for (auto &field : variant.get_struct_fields ())
+ {
+ // The patterns we're creating for each field are `self_<field>` and
+ // `other_<field>` where `field` is the name of the field. It doesn't
+ // actually matter what we use, as long as it's ordered, unique, and that
+ // we can reuse it in the match case's return expression to check that
+ // they are equal.
+
+ auto field_name = field.get_field_name ().as_string ();
+
+ auto self_pattern_str = "__self_" + field_name;
+ auto other_pattern_str = "__other_" + field_name;
+
+ self_fields.emplace_back (builder.struct_pattern_ident_pattern (
+ field_name, builder.identifier_pattern (self_pattern_str)));
+ other_fields.emplace_back (builder.struct_pattern_ident_pattern (
+ field_name, builder.identifier_pattern (other_pattern_str)));
+
+ self_other_exprs.emplace_back (SelfOther{
+ builder.identifier (self_pattern_str),
+ builder.identifier (other_pattern_str),
+ });
+ }
+
+ auto self_elts = StructPatternElements (std::move (self_fields));
+ auto other_elts = StructPatternElements (std::move (other_fields));
+
+ auto self_pattern = std::unique_ptr<Pattern> (
+ new ReferencePattern (std::unique_ptr<Pattern> (new StructPattern (
+ variant_path, loc, std::move (self_elts))),
+ false, false, loc));
+ auto other_pattern = std::unique_ptr<Pattern> (
+ new ReferencePattern (std::unique_ptr<Pattern> (new StructPattern (
+ variant_path, loc, std::move (other_elts))),
+ false, false, loc));
+
+ auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
+ vec (std::move (self_pattern), std::move (other_pattern)));
+
+ auto pattern = std::make_unique<TuplePattern> (std::move (tuple_items), loc);
+
+ auto expr = build_eq_expression (std::move (self_other_exprs));
+
+ return builder.match_case (std::move (pattern), std::move (expr));
}
void
@@ -275,9 +313,9 @@ DerivePartialEq::visit_enum (Enum &item)
static_cast<EnumItemTuple &> (*variant)));
break;
case EnumItem::Kind::Struct:
- rust_sorry_at (
- item.get_locus (),
- "cannot derive(PartialEq) for enum struct variants yet");
+ cases.emplace_back (
+ match_enum_struct (variant_path,
+ static_cast<EnumItemStruct &> (*variant)));
break;
}
}
diff --git a/gcc/rust/expand/rust-derive-partial-eq.h b/gcc/rust/expand/rust-derive-partial-eq.h
index ac963a6..12d793d 100644
--- a/gcc/rust/expand/rust-derive-partial-eq.h
+++ b/gcc/rust/expand/rust-derive-partial-eq.h
@@ -30,7 +30,7 @@ class DerivePartialEq : DeriveVisitor
public:
DerivePartialEq (location_t loc);
- std::vector<std::unique_ptr<AST::Item>> go (Item &item);
+ std::vector<std::unique_ptr<Item>> go (Item &item);
private:
std::vector<std::unique_ptr<Item>> expanded;
@@ -73,10 +73,10 @@ private:
MatchCase match_enum_struct (PathInExpression variant_path,
const EnumItemStruct &variant);
- virtual void visit_struct (StructStruct &item);
- virtual void visit_tuple (TupleStruct &item);
- virtual void visit_enum (Enum &item);
- virtual void visit_union (Union &item);
+ virtual void visit_struct (StructStruct &item) override;
+ virtual void visit_tuple (TupleStruct &item) override;
+ virtual void visit_enum (Enum &item) override;
+ virtual void visit_union (Union &item) override;
};
} // namespace AST
diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index 015b81e..69081db 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -22,6 +22,7 @@
#include "rust-derive-debug.h"
#include "rust-derive-default.h"
#include "rust-derive-eq.h"
+#include "rust-derive-ord.h"
#include "rust-derive-partial-eq.h"
#include "rust-derive-hash.h"
@@ -59,10 +60,11 @@ DeriveVisitor::derive (Item &item, const Attribute &attr,
case BuiltinMacro::Hash:
return vec (DeriveHash (loc).go (item));
case BuiltinMacro::Ord:
+ return vec (DeriveOrd (DeriveOrd::Ordering::Total, loc).go (item));
case BuiltinMacro::PartialOrd:
+ return vec (DeriveOrd (DeriveOrd::Ordering::Partial, loc).go (item));
default:
- rust_sorry_at (loc, "unimplemented builtin derive macro");
- return {};
+ rust_unreachable ();
};
}
@@ -79,7 +81,8 @@ DeriveVisitor::setup_impl_generics (
{
switch (generic->get_kind ())
{
- case GenericParam::Kind::Lifetime: {
+ case GenericParam::Kind::Lifetime:
+ {
LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get ();
Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ());
@@ -91,7 +94,8 @@ DeriveVisitor::setup_impl_generics (
}
break;
- case GenericParam::Kind::Type: {
+ case GenericParam::Kind::Type:
+ {
TypeParam &type_param = (TypeParam &) *generic.get ();
std::unique_ptr<Type> associated_type = builder.single_type_path (
@@ -113,7 +117,8 @@ DeriveVisitor::setup_impl_generics (
}
break;
- case GenericParam::Kind::Const: {
+ case GenericParam::Kind::Const:
+ {
rust_unreachable ();
// TODO
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index 5fca49c..ff4f427 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -147,6 +147,8 @@ private:
virtual void visit (FieldAccessExpr &expr) override final{};
virtual void visit (ClosureExprInner &expr) override final{};
virtual void visit (BlockExpr &expr) override final{};
+ virtual void visit (AnonConst &expr) override final{};
+ virtual void visit (ConstBlock &expr) override final{};
virtual void visit (ClosureExprInnerTyped &expr) override final{};
virtual void visit (ContinueExpr &expr) override final{};
virtual void visit (BreakExpr &expr) override final{};
diff --git a/gcc/rust/expand/rust-expand-format-args.cc b/gcc/rust/expand/rust-expand-format-args.cc
index af6182f..bda28dd 100644
--- a/gcc/rust/expand/rust-expand-format-args.cc
+++ b/gcc/rust/expand/rust-expand-format-args.cc
@@ -85,11 +85,13 @@ expand_format_args (AST::FormatArgs &fmt,
static_pieces.emplace_back (
builder.literal_string (node.string._0.to_string ()));
break;
- case ffi::Piece::Tag::NextArgument: {
+ case ffi::Piece::Tag::NextArgument:
+ {
auto next_argument = node.next_argument._0;
switch (node.next_argument._0.position.tag)
{
- case ffi::Position::Tag::ArgumentImplicitlyIs: {
+ case ffi::Position::Tag::ArgumentImplicitlyIs:
+ {
auto idx = next_argument.position.argument_implicitly_is._0;
auto trait = next_argument.format;
auto arg = arguments.at (idx);
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index 42df5e1..ba7bac1 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -641,7 +641,7 @@ ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
maybe_expand_type (expr.get_return_type_ptr ());
- visit (expr.get_definition_block ());
+ visit (expr.get_definition_expr ());
}
void
diff --git a/gcc/rust/expand/rust-expand-visitor.h b/gcc/rust/expand/rust-expand-visitor.h
index ad237c0..b82040c 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -28,14 +28,12 @@ namespace Rust {
/**
* Whether or not an attribute is a derive attribute
*/
-bool
-is_derive (AST::Attribute &attr);
+bool is_derive (AST::Attribute &attr);
/**
* Whether or not an attribute is builtin
*/
-bool
-is_builtin (AST::Attribute &attr);
+bool is_builtin (AST::Attribute &attr);
class ExpandVisitor : public AST::DefaultASTVisitor
{
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc
index e255729..850c8dd 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -25,18 +25,6 @@
#include "rust-parse.h"
namespace Rust {
-std::map<AST::InlineAsmOption, std::string> InlineAsmOptionMap{
- {AST::InlineAsmOption::PURE, "pure"},
- {AST::InlineAsmOption::NOMEM, "nomem"},
- {AST::InlineAsmOption::READONLY, "readonly"},
- {AST::InlineAsmOption::PRESERVES_FLAGS, "preserves_flags"},
- {AST::InlineAsmOption::NORETURN, "noreturn"},
- {AST::InlineAsmOption::NOSTACK, "nostack"},
- {AST::InlineAsmOption::MAY_UNWIND, "may_unwind"},
- {AST::InlineAsmOption::ATT_SYNTAX, "att_syntax"},
- {AST::InlineAsmOption::RAW, "raw"},
-};
-
std::set<std::string> potentially_nonpromoted_keywords
= {"in", "out", "lateout", "inout", "inlateout", "const", "sym", "label"};
@@ -500,7 +488,7 @@ parse_reg_operand_unexpected (InlineAsmContext inline_asm_ctx)
}
void
-check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsmOption option)
+check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsm::Option option)
{
auto &parser = inline_asm_ctx.parser;
auto &inline_asm = inline_asm_ctx.inline_asm;
@@ -509,7 +497,7 @@ check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsmOption option)
// TODO: report an error of duplication
rust_error_at (parser.peek_current_token ()->get_locus (),
"the %qs option was already provided",
- InlineAsmOptionMap[option].c_str ());
+ AST::InlineAsm::option_to_string (option).c_str ());
return;
}
else
@@ -536,39 +524,40 @@ parse_options (InlineAsmContext &inline_asm_ctx)
{
if (!is_global_asm && check_identifier (parser, "pure"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::PURE);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::PURE);
}
else if (!is_global_asm && check_identifier (parser, "nomem"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::NOMEM);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::NOMEM);
}
else if (!is_global_asm && check_identifier (parser, "readonly"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::READONLY);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::READONLY);
}
else if (!is_global_asm && check_identifier (parser, "preserves_flags"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::PRESERVES_FLAGS);
+ check_and_set (inline_asm_ctx,
+ AST::InlineAsm::Option::PRESERVES_FLAGS);
}
else if (!is_global_asm && check_identifier (parser, "noreturn"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::NORETURN);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::NORETURN);
}
else if (!is_global_asm && check_identifier (parser, "nostack"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::NOSTACK);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::NOSTACK);
}
else if (!is_global_asm && check_identifier (parser, "may_unwind"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::MAY_UNWIND);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::MAY_UNWIND);
}
else if (check_identifier (parser, "att_syntax"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::ATT_SYNTAX);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::ATT_SYNTAX);
}
else if (check_identifier (parser, "raw"))
{
- check_and_set (inline_asm_ctx, AST::InlineAsmOption::RAW);
+ check_and_set (inline_asm_ctx, AST::InlineAsm::Option::RAW);
}
else
{
@@ -807,7 +796,8 @@ expand_inline_asm_strings (InlineAsmContext inline_asm_ctx)
auto next_argument = piece.next_argument._0;
switch (piece.next_argument._0.position.tag)
{
- case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs: {
+ case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs:
+ {
auto idx = next_argument.position.argument_implicitly_is._0;
/*auto trait = next_argument.format;*/
/*auto arg = arguments.at (idx);*/
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h b/gcc/rust/expand/rust-macro-builtins-asm.h
index bd64a7f..3196a5a 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -142,16 +142,16 @@ tl::expected<InlineAsmContext, InlineAsmParseError>
parse_reg_operand_unexpected (InlineAsmContext inline_asm_ctx);
WARN_UNUSED_RESULT
-tl::optional<AST::Fragment>
-parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
- AST::InvocKind semicolon, AST::AsmKind is_global_asm);
+tl::optional<AST::Fragment> parse_asm (location_t invoc_locus,
+ AST::MacroInvocData &invoc,
+ AST::InvocKind semicolon,
+ AST::AsmKind is_global_asm);
WARN_UNUSED_RESULT
-bool
-check_identifier (Parser<MacroInvocLexer> &parser, std::string ident);
+bool check_identifier (Parser<MacroInvocLexer> &parser, std::string ident);
-void
-check_and_set (InlineAsmContext &inline_asm_ctx, AST::InlineAsmOption option);
+void check_and_set (InlineAsmContext &inline_asm_ctx,
+ AST::InlineAsm::Option option);
// From rustc
WARN_UNUSED_RESULT
@@ -168,9 +168,9 @@ tl::optional<std::string>
parse_format_string (InlineAsmContext &inline_asm_ctx);
WARN_UNUSED_RESULT
-tl::optional<std::string>
-parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
- InlineAsmContext &inline_asm_ctx);
+tl::optional<std::string> parse_label (Parser<MacroInvocLexer> &parser,
+ TokenId last_token_id,
+ InlineAsmContext &inline_asm_ctx);
// LLVM ASM bits
@@ -188,17 +188,13 @@ public:
{}
};
-void
-parse_llvm_outputs (LlvmAsmContext &ctx);
+void parse_llvm_outputs (LlvmAsmContext &ctx);
-void
-parse_llvm_inputs (LlvmAsmContext &ctx);
+void parse_llvm_inputs (LlvmAsmContext &ctx);
-void
-parse_llvm_clobbers (LlvmAsmContext &ctx);
+void parse_llvm_clobbers (LlvmAsmContext &ctx);
-void
-parse_llvm_options (LlvmAsmContext &ctx);
+void parse_llvm_options (LlvmAsmContext &ctx);
WARN_UNUSED_RESULT tl::optional<AST::Fragment>
parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.h b/gcc/rust/expand/rust-macro-builtins-helpers.h
index 429537e..32cf58f 100644
--- a/gcc/rust/expand/rust-macro-builtins-helpers.h
+++ b/gcc/rust/expand/rust-macro-builtins-helpers.h
@@ -33,29 +33,23 @@
#include "rust-token.h"
namespace Rust {
-std::string
-make_macro_path_str (BuiltinMacro kind);
+std::string make_macro_path_str (BuiltinMacro kind);
-std::vector<std::unique_ptr<AST::MacroInvocation>>
-check_for_eager_invocations (
+std::vector<std::unique_ptr<AST::MacroInvocation>> check_for_eager_invocations (
std::vector<std::unique_ptr<AST::Expr>> &expressions);
// Shorthand function for creating unique_ptr tokens
-std::unique_ptr<AST::Token>
-make_token (const TokenPtr tok);
+std::unique_ptr<AST::Token> make_token (const TokenPtr tok);
-std::unique_ptr<AST::Expr>
-make_string (location_t locus, std::string value);
+std::unique_ptr<AST::Expr> make_string (location_t locus, std::string value);
// TODO: Is this correct?
-AST::Fragment
-make_eager_builtin_invocation (
+AST::Fragment make_eager_builtin_invocation (
BuiltinMacro kind, location_t locus, AST::DelimTokenTree arguments,
std::vector<std::unique_ptr<AST::MacroInvocation>> &&pending_invocations);
// Match the end token of a macro given the start delimiter of the macro
-TokenId
-macro_end_token (AST::DelimTokenTree &invoc_token_tree,
- Parser<MacroInvocLexer> &parser);
+TokenId macro_end_token (AST::DelimTokenTree &invoc_token_tree,
+ Parser<MacroInvocLexer> &parser);
// Expand and then extract a string literal from the macro
std::unique_ptr<AST::LiteralExpr>
try_extract_string_literal_from_fragment (const location_t &parent_locus,
@@ -70,21 +64,18 @@ try_expand_many_expr (Parser<MacroInvocLexer> &parser,
// and return the LiteralExpr for it. Allow for an optional trailing comma,
// but otherwise enforce that these are the only tokens.
-std::unique_ptr<AST::Expr>
-parse_single_string_literal (BuiltinMacro kind,
- AST::DelimTokenTree &invoc_token_tree,
- location_t invoc_locus, MacroExpander *expander,
- bool is_semicoloned = false);
+std::unique_ptr<AST::Expr> parse_single_string_literal (
+ BuiltinMacro kind, AST::DelimTokenTree &invoc_token_tree,
+ location_t invoc_locus, MacroExpander *expander, bool is_semicoloned = false);
// Treat PATH as a path relative to the source file currently being
// compiled, and return the absolute path for it.
-std::string
-source_relative_path (std::string path, location_t locus);
+std::string source_relative_path (std::string path, location_t locus);
// Read the full contents of the file FILENAME and return them in a vector.
// FIXME: platform specific.
-tl::optional<std::vector<uint8_t>>
-load_file_bytes (location_t invoc_locus, const char *filename);
+tl::optional<std::vector<uint8_t>> load_file_bytes (location_t invoc_locus,
+ const char *filename);
} // namespace Rust
#endif // GCCRS_RUST_MACRO_BUILTINS_HELPERS_H
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 673b8fb..475ad56 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -430,7 +430,8 @@ MacroExpander::match_fragment (Parser<MacroInvocLexer> &parser,
parser.parse_visibility ();
break;
- case AST::MacroFragSpec::STMT: {
+ case AST::MacroFragSpec::STMT:
+ {
auto restrictions = ParseRestrictions ();
restrictions.consume_semi = false;
parser.parse_stmt (restrictions);
@@ -480,19 +481,22 @@ MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
// this is used so we can check that we delimit the stream correctly.
switch (delimiter->get_id ())
{
- case LEFT_PAREN: {
+ case LEFT_PAREN:
+ {
if (!check_delim (AST::DelimType::PARENS))
return false;
}
break;
- case LEFT_SQUARE: {
+ case LEFT_SQUARE:
+ {
if (!check_delim (AST::DelimType::SQUARE))
return false;
}
break;
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
if (!check_delim (AST::DelimType::CURLY))
return false;
}
@@ -510,7 +514,8 @@ MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
switch (match->get_macro_match_type ())
{
- case AST::MacroMatch::MacroMatchType::Fragment: {
+ case AST::MacroMatch::MacroMatchType::Fragment:
+ {
AST::MacroMatchFragment *fragment
= static_cast<AST::MacroMatchFragment *> (match.get ());
if (!match_fragment (parser, *fragment))
@@ -524,14 +529,16 @@ MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
}
break;
- case AST::MacroMatch::MacroMatchType::Tok: {
+ case AST::MacroMatch::MacroMatchType::Tok:
+ {
AST::Token *tok = static_cast<AST::Token *> (match.get ());
if (!match_token (parser, *tok))
return false;
}
break;
- case AST::MacroMatch::MacroMatchType::Repetition: {
+ case AST::MacroMatch::MacroMatchType::Repetition:
+ {
AST::MacroMatchRepetition *rep
= static_cast<AST::MacroMatchRepetition *> (match.get ());
if (!match_repetition (parser, *rep))
@@ -539,7 +546,8 @@ MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
}
break;
- case AST::MacroMatch::MacroMatchType::Matcher: {
+ case AST::MacroMatch::MacroMatchType::Matcher:
+ {
AST::MacroMatcher *m
= static_cast<AST::MacroMatcher *> (match.get ());
expansion_depth++;
@@ -556,19 +564,22 @@ MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
switch (delimiter->get_id ())
{
- case LEFT_PAREN: {
+ case LEFT_PAREN:
+ {
if (!parser.skip_token (RIGHT_PAREN))
return false;
}
break;
- case LEFT_SQUARE: {
+ case LEFT_SQUARE:
+ {
if (!parser.skip_token (RIGHT_SQUARE))
return false;
}
break;
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
if (!parser.skip_token (RIGHT_CURLY))
return false;
}
@@ -617,7 +628,8 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
size_t offs_begin = source.get_offs ();
switch (match->get_macro_match_type ())
{
- case AST::MacroMatch::MacroMatchType::Fragment: {
+ case AST::MacroMatch::MacroMatchType::Fragment:
+ {
AST::MacroMatchFragment *fragment
= static_cast<AST::MacroMatchFragment *> (match.get ());
valid_current_match = match_fragment (parser, *fragment);
@@ -632,20 +644,23 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
}
break;
- case AST::MacroMatch::MacroMatchType::Tok: {
+ case AST::MacroMatch::MacroMatchType::Tok:
+ {
AST::Token *tok = static_cast<AST::Token *> (match.get ());
valid_current_match = match_token (parser, *tok);
}
break;
- case AST::MacroMatch::MacroMatchType::Repetition: {
+ case AST::MacroMatch::MacroMatchType::Repetition:
+ {
AST::MacroMatchRepetition *rep
= static_cast<AST::MacroMatchRepetition *> (match.get ());
valid_current_match = match_repetition (parser, *rep);
}
break;
- case AST::MacroMatch::MacroMatchType::Matcher: {
+ case AST::MacroMatch::MacroMatchType::Matcher:
+ {
AST::MacroMatcher *m
= static_cast<AST::MacroMatcher *> (match.get ());
valid_current_match = match_matcher (parser, *m, true);
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc
index 02e4e3b..ac36ed8 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.cc
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc
@@ -273,7 +273,8 @@ SubstituteCtx::substitute_token (size_t token_idx)
// don't substitute, dollar sign is alone/metavar is unknown
return {std::vector<std::unique_ptr<AST::Token>> (), 0};
- case LEFT_PAREN: {
+ case LEFT_PAREN:
+ {
// We need to parse up until the closing delimiter and expand this
// fragment->n times.
rust_debug ("expanding repetition");
diff --git a/gcc/rust/expand/rust-proc-macro.h b/gcc/rust/expand/rust-proc-macro.h
index 6ffaaf6..058c93a 100644
--- a/gcc/rust/expand/rust-proc-macro.h
+++ b/gcc/rust/expand/rust-proc-macro.h
@@ -82,11 +82,9 @@ public:
*
* @param The path to the shared object file to load.
*/
-const std::vector<ProcMacro::Procmacro>
-load_macros (std::string path);
+const std::vector<ProcMacro::Procmacro> load_macros (std::string path);
-std::string
-generate_proc_macro_decls_symbol (std::uint32_t stable_crate_id);
+std::string generate_proc_macro_decls_symbol (std::uint32_t stable_crate_id);
} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index 2d9a445..5b35052 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -201,6 +201,12 @@ void
ASTLoweringBase::visit (AST::BlockExpr &)
{}
void
+ASTLoweringBase::visit (AST::AnonConst &)
+{}
+void
+ASTLoweringBase::visit (AST::ConstBlock &)
+{}
+void
ASTLoweringBase::visit (AST::ClosureExprInnerTyped &)
{}
void
@@ -648,12 +654,14 @@ ASTLoweringBase::lower_generic_args (AST::GenericArgs &args)
{
switch (arg.get_kind ())
{
- case AST::GenericArg::Kind::Type: {
+ case AST::GenericArg::Kind::Type:
+ {
auto type = ASTLoweringType::translate (arg.get_type ());
type_args.emplace_back (std::unique_ptr<HIR::Type> (type));
break;
}
- case AST::GenericArg::Kind::Const: {
+ case AST::GenericArg::Kind::Const:
+ {
auto expr = ASTLoweringExpr::translate (arg.get_expression ());
const_args.emplace_back (
HIR::ConstGenericArg (std::unique_ptr<HIR::Expr> (expr),
@@ -887,7 +895,8 @@ ASTLoweringBase::lower_range_pattern_bound (AST::RangePatternBound &bound)
std::unique_ptr<HIR::RangePatternBound> hir_bound = nullptr;
switch (bound.get_bound_type ())
{
- case AST::RangePatternBound::RangePatternBoundType::LITERAL: {
+ case AST::RangePatternBound::RangePatternBoundType::LITERAL:
+ {
AST::RangePatternBoundLiteral &ref
= static_cast<AST::RangePatternBoundLiteral &> (bound);
@@ -898,7 +907,8 @@ ASTLoweringBase::lower_range_pattern_bound (AST::RangePatternBound &bound)
ref.get_has_minus ()));
}
break;
- case AST::RangePatternBound::RangePatternBoundType::PATH: {
+ case AST::RangePatternBound::RangePatternBoundType::PATH:
+ {
auto &ref = static_cast<AST::RangePatternBoundPath &> (bound);
HIR::PathInExpression *path
@@ -908,7 +918,8 @@ ASTLoweringBase::lower_range_pattern_bound (AST::RangePatternBound &bound)
new HIR::RangePatternBoundPath (*path));
}
break;
- case AST::RangePatternBound::RangePatternBoundType::QUALPATH: {
+ case AST::RangePatternBound::RangePatternBoundType::QUALPATH:
+ {
auto &ref = static_cast<AST::RangePatternBoundQualPath &> (bound);
HIR::QualifiedPathInExpression *qualpath
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index 3116181..51912be 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -131,6 +131,8 @@ public:
virtual void visit (AST::FieldAccessExpr &expr) override;
virtual void visit (AST::ClosureExprInner &expr) override;
virtual void visit (AST::BlockExpr &expr) override;
+ virtual void visit (AST::AnonConst &expr) override;
+ virtual void visit (AST::ConstBlock &expr) override;
virtual void visit (AST::ClosureExprInnerTyped &expr) override;
virtual void visit (AST::ContinueExpr &expr) override;
virtual void visit (AST::BreakExpr &expr) override;
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc
index 07d0c835..3f3d600 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -25,6 +25,7 @@
#include "rust-ast-lower-type.h"
#include "rust-ast.h"
#include "rust-diagnostics.h"
+#include "rust-hir-map.h"
#include "rust-system.h"
#include "tree/rust-hir-expr.h"
@@ -127,6 +128,43 @@ ASTLoweringExpr::visit (AST::BlockExpr &expr)
}
void
+ASTLoweringExpr::visit (AST::AnonConst &expr)
+{
+ auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ());
+
+ auto &mappings = Analysis::Mappings::get ();
+ auto crate_num = mappings.get_current_crate ();
+ auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ translated = new HIR::AnonConst (std::move (mapping),
+ std::unique_ptr<Expr> (inner_expr),
+ expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ConstBlock &expr)
+{
+ auto inner_expr = ASTLoweringExpr::translate (expr.get_const_expr ());
+
+ // we know this will always be an `AnonConst`, or we have an issue. Let's
+ // assert just to be sure.
+ rust_assert (inner_expr->get_expression_type () == Expr::ExprType::AnonConst);
+ auto anon_const = static_cast<AnonConst *> (inner_expr);
+
+ auto &mappings = Analysis::Mappings::get ();
+ auto crate_num = mappings.get_current_crate ();
+ auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ translated
+ = new HIR::ConstBlock (std::move (mapping), std::move (*anon_const),
+ expr.get_locus (), expr.get_outer_attrs ());
+}
+
+void
ASTLoweringExpr::visit (AST::UnsafeBlockExpr &expr)
{
translated = ASTLoweringBlock::translate (expr, &terminated);
@@ -798,7 +836,7 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
{
HIR::Type *closure_return_type = nullptr;
HIR::Expr *closure_expr
- = ASTLoweringExpr::translate (expr.get_definition_block ());
+ = ASTLoweringExpr::translate (expr.get_definition_expr ());
std::vector<HIR::ClosureParam> closure_params;
for (auto &param : expr.get_params ())
@@ -841,6 +879,7 @@ translate_operand_out (const AST::InlineAsmOperand &operand)
*out_value.expr.get ())));
return out;
}
+
HIR::InlineAsmOperand
translate_operand_inout (const AST::InlineAsmOperand &operand)
{
@@ -851,6 +890,7 @@ translate_operand_inout (const AST::InlineAsmOperand &operand)
*inout_value.expr.get ())));
return inout;
}
+
HIR::InlineAsmOperand
translate_operand_split_in_out (const AST::InlineAsmOperand &operand)
{
@@ -863,19 +903,21 @@ translate_operand_split_in_out (const AST::InlineAsmOperand &operand)
ASTLoweringExpr::translate (*split_in_out_value.out_expr.get ())));
return split_in_out;
}
+
HIR::InlineAsmOperand
translate_operand_const (const AST::InlineAsmOperand &operand)
{
auto const_value = operand.get_const ();
- struct HIR::AnonConst anon_const (const_value.anon_const.id,
- std::unique_ptr<Expr> (
- ASTLoweringExpr::translate (
- *const_value.anon_const.expr.get ())));
- struct HIR::InlineAsmOperand::Const cnst
- {
- anon_const
- };
- return cnst;
+
+ auto inner_expr = ASTLoweringExpr::translate (const_value.anon_const);
+
+ // Like `ConstBlock`, we know this should only be an `AnonConst` - let's
+ // assert to make sure and static cast
+ rust_assert (inner_expr->get_expression_type () == Expr::ExprType::AnonConst);
+
+ auto anon_const = static_cast<AnonConst *> (inner_expr);
+
+ return HIR::InlineAsmOperand::Const{*anon_const};
}
HIR::InlineAsmOperand
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index adedeb3..9d1bf68 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -82,6 +82,8 @@ public:
void visit (AST::IfLetExpr &expr) override;
void visit (AST::IfLetExprConseqElse &expr) override;
void visit (AST::BlockExpr &expr) override;
+ void visit (AST::AnonConst &expr) override;
+ void visit (AST::ConstBlock &expr) override;
void visit (AST::UnsafeBlockExpr &expr) override;
void visit (AST::PathInExpression &expr) override;
void visit (AST::QualifiedPathInExpression &expr) override;
diff --git a/gcc/rust/hir/rust-ast-lower-extern.h b/gcc/rust/hir/rust-ast-lower-extern.h
index 0105e38..3dca1b6 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -99,7 +99,7 @@ public:
= static_cast<AST::IdentifierPattern &> (param.get_pattern ());
Identifier param_name = param_kind == AST::Pattern::Kind::Identifier
? param_ident.get_ident ()
- : std::string ("_");
+ : Identifier ("_", param.get_locus ());
HIR::Type *param_type = ASTLoweringType::translate (param.get_type ());
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc
index d815a71..fc9fe1a 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.cc
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -138,7 +138,8 @@ ASTLowerImplItem::visit (AST::Function &function)
std::unique_ptr<HIR::Type> return_type
= function.has_return_type () ? std::unique_ptr<HIR::Type> (
- ASTLoweringType::translate (function.get_return_type ()))
+ ASTLoweringType::translate (function.get_return_type (), false,
+ true /* impl trait is allowed here*/))
: nullptr;
Defaultness defaultness
diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc
index f4396b5..acec008 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -217,7 +217,7 @@ ASTLoweringItem::visit (AST::StructStruct &struct_decl)
field.get_outer_attrs ());
if (struct_field_name_exists (fields, translated_field))
- break;
+ continue;
fields.push_back (std::move (translated_field));
}
@@ -411,7 +411,8 @@ ASTLoweringItem::visit (AST::Function &function)
std::unique_ptr<HIR::Type> return_type
= function.has_return_type () ? std::unique_ptr<HIR::Type> (
- ASTLoweringType::translate (function.get_return_type ()))
+ ASTLoweringType::translate (function.get_return_type (), false,
+ true /* impl trait is allowed here*/))
: nullptr;
std::vector<HIR::FunctionParam> function_params;
@@ -494,7 +495,8 @@ ASTLoweringItem::visit (AST::InherentImpl &impl_block)
{
switch (generic_param->get_kind ())
{
- case HIR::GenericParam::GenericKind::TYPE: {
+ case HIR::GenericParam::GenericKind::TYPE:
+ {
const HIR::TypeParam &t
= static_cast<const HIR::TypeParam &> (*generic_param);
@@ -651,7 +653,8 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block)
{
switch (generic_param->get_kind ())
{
- case HIR::GenericParam::GenericKind::TYPE: {
+ case HIR::GenericParam::GenericKind::TYPE:
+ {
const HIR::TypeParam &t
= static_cast<const HIR::TypeParam &> (*generic_param);
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index b7a4c56..9baf81d 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -49,13 +49,18 @@ ASTLoweringPattern::visit (AST::IdentifierPattern &pattern)
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- std::unique_ptr<Pattern> to_bind;
+ std::unique_ptr<Pattern> subpattern;
+ if (pattern.has_subpattern ())
+ {
+ subpattern = std::unique_ptr<Pattern> (
+ ASTLoweringPattern::translate (pattern.get_pattern_to_bind ()));
+ }
translated
= new HIR::IdentifierPattern (mapping, pattern.get_ident (),
pattern.get_locus (), pattern.get_is_ref (),
pattern.get_is_mut () ? Mutability::Mut
: Mutability::Imm,
- std::move (to_bind));
+ std::move (subpattern));
}
void
@@ -74,13 +79,15 @@ ASTLoweringPattern::visit (AST::TupleStructPattern &pattern)
auto &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case AST::TupleStructItems::RANGE: {
+ case AST::TupleStructItems::RANGE:
+ {
// TODO
rust_unreachable ();
}
break;
- case AST::TupleStructItems::NO_RANGE: {
+ case AST::TupleStructItems::NO_RANGE:
+ {
AST::TupleStructItemsNoRange &items_no_range
= static_cast<AST::TupleStructItemsNoRange &> (items);
@@ -120,7 +127,8 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern)
HIR::StructPatternField *f = nullptr;
switch (field->get_item_type ())
{
- case AST::StructPatternField::ItemType::TUPLE_PAT: {
+ case AST::StructPatternField::ItemType::TUPLE_PAT:
+ {
auto &tuple
= static_cast<AST::StructPatternFieldTuplePat &> (*field);
@@ -140,7 +148,8 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern)
}
break;
- case AST::StructPatternField::ItemType::IDENT_PAT: {
+ case AST::StructPatternField::ItemType::IDENT_PAT:
+ {
AST::StructPatternFieldIdentPat &ident
= static_cast<AST::StructPatternFieldIdentPat &> (*field);
@@ -160,7 +169,8 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern)
}
break;
- case AST::StructPatternField::ItemType::IDENT: {
+ case AST::StructPatternField::ItemType::IDENT:
+ {
AST::StructPatternFieldIdent &ident
= static_cast<AST::StructPatternFieldIdent &> (*field.get ());
@@ -213,7 +223,8 @@ ASTLoweringPattern::visit (AST::TuplePattern &pattern)
std::unique_ptr<HIR::TuplePatternItems> items;
switch (pattern.get_items ().get_pattern_type ())
{
- case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
+ case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE:
+ {
AST::TuplePatternItemsMultiple &ref
= static_cast<AST::TuplePatternItemsMultiple &> (
pattern.get_items ());
@@ -221,7 +232,8 @@ ASTLoweringPattern::visit (AST::TuplePattern &pattern)
}
break;
- case AST::TuplePatternItems::TuplePatternItemType::RANGED: {
+ case AST::TuplePatternItems::TuplePatternItemType::RANGED:
+ {
AST::TuplePatternItemsRanged &ref
= static_cast<AST::TuplePatternItemsRanged &> (pattern.get_items ());
items = lower_tuple_pattern_ranged (ref);
diff --git a/gcc/rust/hir/rust-ast-lower-type.cc b/gcc/rust/hir/rust-ast-lower-type.cc
index a678f18..1841576 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -209,10 +209,17 @@ ASTLowerQualifiedPathInType::visit (AST::QualifiedPathInType &path)
path.get_locus ());
}
+ASTLoweringType::ASTLoweringType (bool default_to_static_lifetime,
+ bool impl_trait_allowed)
+ : ASTLoweringBase (), default_to_static_lifetime (default_to_static_lifetime),
+ impl_trait_allowed (impl_trait_allowed), translated (nullptr)
+{}
+
HIR::Type *
-ASTLoweringType::translate (AST::Type &type, bool default_to_static_lifetime)
+ASTLoweringType::translate (AST::Type &type, bool default_to_static_lifetime,
+ bool impl_trait_allowed)
{
- ASTLoweringType resolver (default_to_static_lifetime);
+ ASTLoweringType resolver (default_to_static_lifetime, impl_trait_allowed);
type.accept_vis (resolver);
rust_assert (resolver.translated != nullptr);
@@ -260,7 +267,8 @@ ASTLoweringType::visit (AST::BareFunctionType &fntype)
HIR::Type *param_type
= ASTLoweringType::translate (param.get_type (),
- default_to_static_lifetime);
+ default_to_static_lifetime,
+ impl_trait_allowed);
HIR::MaybeNamedParam p (param.get_name (), kind,
std::unique_ptr<HIR::Type> (param_type),
@@ -272,7 +280,8 @@ ASTLoweringType::visit (AST::BareFunctionType &fntype)
if (fntype.has_return_type ())
{
return_type = ASTLoweringType::translate (fntype.get_return_type (),
- default_to_static_lifetime);
+ default_to_static_lifetime,
+ impl_trait_allowed);
}
auto crate_num = mappings.get_current_crate ();
@@ -292,8 +301,8 @@ ASTLoweringType::visit (AST::TupleType &tuple)
std::vector<std::unique_ptr<HIR::Type>> elems;
for (auto &e : tuple.get_elems ())
{
- HIR::Type *t
- = ASTLoweringType::translate (*e, default_to_static_lifetime);
+ HIR::Type *t = ASTLoweringType::translate (*e, default_to_static_lifetime,
+ impl_trait_allowed);
elems.push_back (std::unique_ptr<HIR::Type> (t));
}
@@ -323,7 +332,8 @@ ASTLoweringType::visit (AST::ArrayType &type)
{
HIR::Type *translated_type
= ASTLoweringType::translate (type.get_elem_type (),
- default_to_static_lifetime);
+ default_to_static_lifetime,
+ impl_trait_allowed);
HIR::Expr *array_size = ASTLoweringExpr::translate (type.get_size_expr ());
auto crate_num = mappings.get_current_crate ();
@@ -343,9 +353,9 @@ ASTLoweringType::visit (AST::ReferenceType &type)
HIR::Lifetime lifetime
= lower_lifetime (type.get_lifetime (), default_to_static_lifetime);
- HIR::Type *base_type
- = ASTLoweringType::translate (type.get_base_type (),
- default_to_static_lifetime);
+ HIR::Type *base_type = ASTLoweringType::translate (type.get_base_type (),
+ default_to_static_lifetime,
+ impl_trait_allowed);
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
@@ -364,7 +374,8 @@ ASTLoweringType::visit (AST::RawPointerType &type)
{
HIR::Type *base_type
= ASTLoweringType::translate (type.get_type_pointed_to (),
- default_to_static_lifetime);
+ default_to_static_lifetime,
+ impl_trait_allowed);
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
@@ -384,9 +395,9 @@ ASTLoweringType::visit (AST::RawPointerType &type)
void
ASTLoweringType::visit (AST::SliceType &type)
{
- HIR::Type *base_type
- = ASTLoweringType::translate (type.get_elem_type (),
- default_to_static_lifetime);
+ HIR::Type *base_type = ASTLoweringType::translate (type.get_elem_type (),
+ default_to_static_lifetime,
+ impl_trait_allowed);
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
@@ -463,7 +474,8 @@ void
ASTLoweringType::visit (AST::ParenthesisedType &type)
{
auto *inner = ASTLoweringType::translate (*type.get_type_in_parens (),
- default_to_static_lifetime);
+ default_to_static_lifetime,
+ impl_trait_allowed);
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
@@ -480,6 +492,9 @@ ASTLoweringType::visit (AST::ParenthesisedType &type)
void
ASTLoweringType::visit (AST::ImplTraitType &type)
{
+ if (!impl_trait_allowed)
+ emit_impl_trait_error (type.get_locus ());
+
std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds;
for (auto &bound : type.get_type_param_bounds ())
{
@@ -499,9 +514,12 @@ ASTLoweringType::visit (AST::ImplTraitType &type)
void
ASTLoweringType::visit (AST::ImplTraitTypeOneBound &type)
{
+ if (!impl_trait_allowed)
+ emit_impl_trait_error (type.get_locus ());
+
std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds;
- auto b = ASTLoweringTypeBounds::translate (type.get_trait_bound ());
+ auto b = ASTLoweringTypeBounds::translate (*type.get_trait_bound ().get ());
bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (b));
auto crate_num = mappings.get_current_crate ();
@@ -513,6 +531,15 @@ ASTLoweringType::visit (AST::ImplTraitTypeOneBound &type)
= new HIR::ImplTraitType (mapping, std::move (bounds), type.get_locus ());
}
+void
+ASTLoweringType::emit_impl_trait_error (location_t locus)
+{
+ rich_location r (line_table, locus);
+ rust_error_at (r, ErrorCode::E0562,
+ "%<impl Trait%> not allowed outside of function and inherent "
+ "method return types");
+}
+
HIR::GenericParam *
ASTLowerGenericParam::translate (AST::GenericParam &param)
{
@@ -593,7 +620,8 @@ ASTLowerGenericParam::visit (AST::TypeParam &param)
translated
= new HIR::TypeParam (mapping, param.get_type_representation (),
param.get_locus (), std::move (type_param_bounds),
- std::move (type), param.get_outer_attrs ());
+ std::move (type), param.get_outer_attrs (),
+ param.from_impl_trait ());
}
HIR::TypeParamBound *
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index 4efaeee..50f543a 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -66,7 +66,8 @@ class ASTLoweringType : public ASTLoweringBase
public:
static HIR::Type *translate (AST::Type &type,
- bool default_to_static_lifetime = false);
+ bool default_to_static_lifetime = false,
+ bool impl_trait_allowed = false);
void visit (AST::BareFunctionType &fntype) override;
void visit (AST::TupleType &tuple) override;
@@ -81,19 +82,17 @@ public:
void visit (AST::TraitObjectTypeOneBound &type) override;
void visit (AST::TraitObjectType &type) override;
void visit (AST::ParenthesisedType &type) override;
-
void visit (AST::ImplTraitType &type) override;
void visit (AST::ImplTraitTypeOneBound &type) override;
+ void emit_impl_trait_error (location_t locus);
+
private:
- ASTLoweringType (bool default_to_static_lifetime)
- : ASTLoweringBase (),
- default_to_static_lifetime (default_to_static_lifetime),
- translated (nullptr)
- {}
+ ASTLoweringType (bool default_to_static_lifetime, bool impl_trait_allowed);
/** Used when compiling const and static items. */
bool default_to_static_lifetime;
+ bool impl_trait_allowed;
HIR::Type *translated;
};
diff --git a/gcc/rust/hir/rust-ast-lower.h b/gcc/rust/hir/rust-ast-lower.h
index cc74082..0787ddf 100644
--- a/gcc/rust/hir/rust-ast-lower.h
+++ b/gcc/rust/hir/rust-ast-lower.h
@@ -28,16 +28,14 @@ namespace HIR {
/* Checks whether the name of a field already exists. Returns true
and produces an error if so. */
-bool
-struct_field_name_exists (std::vector<HIR::StructField> &fields,
- HIR::StructField &new_field);
+bool struct_field_name_exists (std::vector<HIR::StructField> &fields,
+ HIR::StructField &new_field);
/**
* Lowers a Visibility from the AST into an HIR Visibility, desugaring it in
* the process
*/
-Visibility
-translate_visibility (const AST::Visibility &vis);
+Visibility translate_visibility (const AST::Visibility &vis);
/**
* Main base class used for lowering AST to HIR.
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index cb32f68..38079c7 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1297,6 +1297,28 @@ Dump::visit (BlockExpr &e)
}
void
+Dump::visit (AnonConst &e)
+{
+ begin ("AnonConst");
+ do_expr (e);
+
+ visit_field ("inner", e.get_inner_expr ());
+
+ end ("AnonConst");
+}
+
+void
+Dump::visit (ConstBlock &e)
+{
+ begin ("ConstBlock");
+ do_expr (e);
+
+ visit_field ("inner", e.get_const_expr ());
+
+ end ("ConstBlock");
+}
+
+void
Dump::visit (ContinueExpr &e)
{
begin ("ContinueExpr");
@@ -1602,7 +1624,8 @@ Dump::visit (UseTreeGlob &e)
case UseTreeGlob::PathType::GLOBAL:
glob = "::*";
break;
- case UseTreeGlob::PathType::PATH_PREFIXED: {
+ case UseTreeGlob::PathType::PATH_PREFIXED:
+ {
path = e.get_path ().as_string ();
glob = "::*";
break;
@@ -1630,7 +1653,8 @@ Dump::visit (UseTreeList &e)
case UseTreeList::PathType::GLOBAL:
path_type = "::*";
break;
- case UseTreeList::PathType::PATH_PREFIXED: {
+ case UseTreeList::PathType::PATH_PREFIXED:
+ {
path = e.get_path ().as_string ();
path_type = "::*";
break;
@@ -2091,10 +2115,10 @@ Dump::visit (IdentifierPattern &e)
put_field ("is_ref", std::to_string (e.get_is_ref ()));
put_field ("mut", std::to_string (e.is_mut ()));
- if (e.has_pattern_to_bind ())
- put_field ("to_bind", e.get_to_bind ().as_string ());
+ if (e.has_subpattern ())
+ visit_field ("subpattern", e.get_subpattern ());
else
- put_field ("to_bind", "none");
+ put_field ("subpattern", "none");
end ("IdentifierPattern");
}
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index 45b1708..8c39f48 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -146,6 +146,8 @@ private:
virtual void visit (FieldAccessExpr &) override;
virtual void visit (ClosureExpr &) override;
virtual void visit (BlockExpr &) override;
+ virtual void visit (AnonConst &) override;
+ virtual void visit (ConstBlock &) override;
virtual void visit (ContinueExpr &) override;
virtual void visit (BreakExpr &) override;
virtual void visit (RangeFromToExpr &) override;
@@ -252,7 +254,6 @@ private:
} // namespace Rust
// In the global namespace to make it easier to call from debugger
-void
-debug (Rust::HIR::FullVisitable &v);
+void debug (Rust::HIR::FullVisitable &v);
#endif // !RUST_HIR_DUMP_H
diff --git a/gcc/rust/hir/tree/rust-hir-expr-abstract.h b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
index 5bc5d89..8272a828 100644
--- a/gcc/rust/hir/tree/rust-hir-expr-abstract.h
+++ b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
@@ -43,7 +43,7 @@ public:
WITHOUT_BLOCK,
};
- enum ExprType
+ enum class ExprType
{
Lit,
Operator,
@@ -58,6 +58,8 @@ public:
FieldAccess,
Closure,
Block,
+ AnonConst,
+ ConstBlock,
Continue,
Break,
Range,
diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc
index 266c79c..93dcec2 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.cc
+++ b/gcc/rust/hir/tree/rust-hir-expr.cc
@@ -790,6 +790,50 @@ BlockExpr::operator= (BlockExpr const &other)
return *this;
}
+AnonConst::AnonConst (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> &&expr, location_t locus)
+ : ExprWithBlock (std::move (mappings), {}), locus (locus),
+ expr (std::move (expr))
+{
+ rust_assert (this->expr);
+}
+
+AnonConst::AnonConst (const AnonConst &other)
+ : ExprWithBlock (other), locus (other.locus), expr (other.expr->clone_expr ())
+{}
+
+AnonConst
+AnonConst::operator= (const AnonConst &other)
+{
+ ExprWithBlock::operator= (other);
+
+ locus = other.locus;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+}
+
+ConstBlock::ConstBlock (Analysis::NodeMapping mappings, AnonConst &&expr,
+ location_t locus, AST::AttrVec outer_attrs)
+ : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
+ expr (std::move (expr)), locus (locus)
+{}
+
+ConstBlock::ConstBlock (const ConstBlock &other)
+ : ExprWithBlock (other), expr (other.expr), locus (other.locus)
+{}
+
+ConstBlock
+ConstBlock::operator= (const ConstBlock &other)
+{
+ ExprWithBlock::operator= (other);
+
+ expr = other.expr;
+ locus = other.locus;
+
+ return *this;
+}
+
ContinueExpr::ContinueExpr (Analysis::NodeMapping mappings, location_t locus,
tl::optional<Lifetime> label,
AST::AttrVec outer_attribs)
@@ -1310,26 +1354,6 @@ OperatorExprMeta::OperatorExprMeta (HIR::ComparisonExpr &expr)
locus (expr.get_locus ())
{}
-AnonConst::AnonConst (NodeId id, std::unique_ptr<Expr> expr)
- : id (id), expr (std::move (expr))
-{
- rust_assert (this->expr != nullptr);
-}
-
-AnonConst::AnonConst (const AnonConst &other)
-{
- id = other.id;
- expr = other.expr->clone_expr ();
-}
-
-AnonConst
-AnonConst::operator= (const AnonConst &other)
-{
- id = other.id;
- expr = other.expr->clone_expr ();
- return *this;
-}
-
InlineAsmOperand::In::In (
const tl::optional<struct AST::InlineAsmRegOrRegClass> &reg,
std::unique_ptr<Expr> expr)
@@ -1476,7 +1500,7 @@ InlineAsm::InlineAsm (location_t locus, bool is_global_asm,
std::vector<AST::TupleTemplateStr> template_strs,
std::vector<HIR::InlineAsmOperand> operands,
std::vector<AST::TupleClobber> clobber_abi,
- std::set<AST::InlineAsmOption> options,
+ std::set<AST::InlineAsm::Option> options,
Analysis::NodeMapping mappings,
AST::AttrVec outer_attribs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 375f474..bf278d6 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -19,12 +19,14 @@
#ifndef RUST_HIR_EXPR_H
#define RUST_HIR_EXPR_H
+#include "rust-ast.h"
#include "rust-hir-expr-abstract.h"
#include "rust-hir-literal.h"
#include "rust-common.h"
#include "rust-hir-bound.h"
#include "rust-hir-attrs.h"
#include "rust-expr.h"
+#include "rust-hir-map.h"
namespace Rust {
namespace HIR {
@@ -1800,6 +1802,71 @@ protected:
}
};
+class AnonConst : public ExprWithBlock
+{
+public:
+ AnonConst (Analysis::NodeMapping mappings, std::unique_ptr<Expr> &&expr,
+ location_t locus = UNKNOWN_LOCATION);
+ AnonConst (const AnonConst &other);
+ AnonConst operator= (const AnonConst &other);
+
+ std::string as_string () const override;
+
+ void accept_vis (HIRFullVisitor &vis) override;
+ void accept_vis (HIRExpressionVisitor &vis) override;
+
+ ExprType get_expression_type () const final override
+ {
+ return ExprType::AnonConst;
+ }
+
+ location_t get_locus () const override { return locus; }
+ Expr &get_inner_expr () { return *expr; }
+ const Expr &get_inner_expr () const { return *expr; }
+
+private:
+ location_t locus;
+ std::unique_ptr<Expr> expr;
+
+ AnonConst *clone_expr_with_block_impl () const override
+ {
+ return new AnonConst (*this);
+ }
+};
+
+class ConstBlock : public ExprWithBlock
+{
+public:
+ ConstBlock (Analysis::NodeMapping mappings, AnonConst &&expr,
+ location_t locus = UNKNOWN_LOCATION,
+ AST::AttrVec outer_attrs = {});
+ ConstBlock (const ConstBlock &other);
+ ConstBlock operator= (const ConstBlock &other);
+
+ void accept_vis (HIRFullVisitor &vis) override;
+ void accept_vis (HIRExpressionVisitor &vis) override;
+
+ std::string as_string () const override;
+
+ ExprType get_expression_type () const final override
+ {
+ return ExprType::ConstBlock;
+ }
+
+ location_t get_locus () const override { return locus; }
+ AnonConst &get_const_expr () { return expr; }
+ const AnonConst &get_const_expr () const { return expr; }
+
+private:
+ AnonConst expr;
+ location_t locus;
+
+ ConstBlock *clone_expr_with_block_impl () const override
+ {
+ return new ConstBlock (*this);
+ }
+};
+
// HIR node representing continue expression within loops
class ContinueExpr : public ExprWithoutBlock
{
@@ -2892,18 +2959,6 @@ class InlineAsmRegClass
std::string placeholder;
};
-struct AnonConst
-{
- NodeId id;
- std::unique_ptr<Expr> expr;
-
- AnonConst (NodeId id, std::unique_ptr<Expr> expr);
-
- AnonConst (const AnonConst &other);
-
- AnonConst operator= (const AnonConst &other);
-};
-
class InlineAsmOperand
{
public:
@@ -3059,7 +3114,7 @@ public:
std::vector<AST::TupleTemplateStr> template_strs;
std::vector<HIR::InlineAsmOperand> operands;
std::vector<AST::TupleClobber> clobber_abi;
- std::set<AST::InlineAsmOption> options;
+ std::set<AST::InlineAsm::Option> options;
std::vector<location_t> line_spans;
@@ -3094,7 +3149,7 @@ public:
std::vector<AST::TupleClobber> get_clobber_abi () { return clobber_abi; }
- std::set<AST::InlineAsmOption> get_options () { return options; }
+ std::set<AST::InlineAsm::Option> get_options () { return options; }
bool is_simple_asm ()
{
@@ -3113,7 +3168,7 @@ public:
std::vector<AST::TupleTemplateStr> template_strs,
std::vector<HIR::InlineAsmOperand> operands,
std::vector<AST::TupleClobber> clobber_abi,
- std::set<AST::InlineAsmOption> options,
+ std::set<AST::InlineAsm::Option> options,
Analysis::NodeMapping mappings,
AST::AttrVec outer_attribs = AST::AttrVec ());
};
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 1e313ec..2905117 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -95,6 +95,8 @@ class FieldAccessExpr;
struct ClosureParam;
class ClosureExpr;
class BlockExpr;
+class AnonConst;
+class ConstBlock;
class ContinueExpr;
class BreakExpr;
class RangeExpr;
@@ -123,7 +125,6 @@ class AwaitExpr;
class AsyncBlockExpr;
class InlineAsmReg;
class InlineAsmRegClass;
-struct AnonConst;
class InlineAsmOperand;
class InlineAsm;
class LlvmInlineAsm;
diff --git a/gcc/rust/hir/tree/rust-hir-item.cc b/gcc/rust/hir/tree/rust-hir-item.cc
index 160f710..1406e7a 100644
--- a/gcc/rust/hir/tree/rust-hir-item.cc
+++ b/gcc/rust/hir/tree/rust-hir-item.cc
@@ -26,16 +26,18 @@ TypeParam::TypeParam (
Analysis::NodeMapping mappings, Identifier type_representation,
location_t locus,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
- tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs)
+ tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs,
+ bool was_impl_trait)
: GenericParam (mappings), outer_attrs (std::move (outer_attrs)),
type_representation (std::move (type_representation)),
type_param_bounds (std::move (type_param_bounds)), type (std::move (type)),
- locus (locus)
+ locus (locus), was_impl_trait (was_impl_trait)
{}
TypeParam::TypeParam (TypeParam const &other)
: GenericParam (other.mappings), outer_attrs (other.outer_attrs),
- type_representation (other.type_representation), locus (other.locus)
+ type_representation (other.type_representation), locus (other.locus),
+ was_impl_trait (other.was_impl_trait)
{
// guard to prevent null pointer dereference
if (other.has_type ())
@@ -55,6 +57,7 @@ TypeParam::operator= (TypeParam const &other)
outer_attrs = other.outer_attrs;
locus = other.locus;
mappings = other.mappings;
+ was_impl_trait = other.was_impl_trait;
// guard to prevent null pointer dereference
if (other.has_type ())
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 37f599c..d610277 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -95,17 +95,11 @@ protected:
class TypeParam : public GenericParam
{
AST::AttrVec outer_attrs;
-
Identifier type_representation;
-
- // bool has_type_param_bounds;
- // TypeParamBounds type_param_bounds;
- std::vector<std::unique_ptr<TypeParamBound>>
- type_param_bounds; // inlined form
-
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
tl::optional<std::unique_ptr<Type>> type;
-
location_t locus;
+ bool was_impl_trait;
public:
// Returns whether the type of the type param has been specified.
@@ -121,9 +115,9 @@ public:
TypeParam (Analysis::NodeMapping mappings, Identifier type_representation,
location_t locus = UNDEF_LOCATION,
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds
- = std::vector<std::unique_ptr<TypeParamBound>> (),
+ = {},
tl::optional<std::unique_ptr<Type>> type = tl::nullopt,
- AST::AttrVec outer_attrs = std::vector<AST::Attribute> ());
+ AST::AttrVec outer_attrs = {}, bool was_impl_trait = false);
// Copy constructor uses clone
TypeParam (TypeParam const &other);
@@ -154,6 +148,8 @@ public:
std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ();
+ bool from_impl_trait () const { return was_impl_trait; }
+
protected:
// Clone function implementation as (not pure) virtual method
TypeParam *clone_generic_param_impl () const override
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index 5cc5c95..9c636ca 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -80,7 +80,7 @@ class IdentifierPattern : public Pattern
Identifier variable_ident;
bool is_ref;
Mutability mut;
- std::unique_ptr<Pattern> to_bind;
+ std::unique_ptr<Pattern> subpattern;
location_t locus;
Analysis::NodeMapping mappings;
@@ -88,15 +88,15 @@ public:
std::string as_string () const override;
// Returns whether the IdentifierPattern has a pattern to bind.
- bool has_pattern_to_bind () const { return to_bind != nullptr; }
+ bool has_subpattern () const { return subpattern != nullptr; }
// Constructor
IdentifierPattern (Analysis::NodeMapping mappings, Identifier ident,
location_t locus, bool is_ref = false,
Mutability mut = Mutability::Imm,
- std::unique_ptr<Pattern> to_bind = nullptr)
+ std::unique_ptr<Pattern> subpattern = nullptr)
: variable_ident (std::move (ident)), is_ref (is_ref), mut (mut),
- to_bind (std::move (to_bind)), locus (locus), mappings (mappings)
+ subpattern (std::move (subpattern)), locus (locus), mappings (mappings)
{}
// Copy constructor with clone
@@ -105,8 +105,8 @@ public:
mut (other.mut), locus (other.locus), mappings (other.mappings)
{
// fix to get prevent null pointer dereference
- if (other.to_bind != nullptr)
- to_bind = other.to_bind->clone_pattern ();
+ if (other.subpattern != nullptr)
+ subpattern = other.subpattern->clone_pattern ();
}
// Overload assignment operator to use clone
@@ -119,8 +119,8 @@ public:
mappings = other.mappings;
// fix to get prevent null pointer dereference
- if (other.to_bind != nullptr)
- to_bind = other.to_bind->clone_pattern ();
+ if (other.subpattern != nullptr)
+ subpattern = other.subpattern->clone_pattern ();
return *this;
}
@@ -133,7 +133,7 @@ public:
bool is_mut () const { return mut == Mutability::Mut; }
bool get_is_ref () const { return is_ref; }
- Pattern &get_to_bind () { return *to_bind; }
+ Pattern &get_subpattern () { return *subpattern; }
void accept_vis (HIRFullVisitor &vis) override;
void accept_vis (HIRPatternVisitor &vis) override;
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 283cc34..43f00dd 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -64,6 +64,8 @@ public:
virtual void visit (MethodCallExpr &expr) = 0;
virtual void visit (FieldAccessExpr &expr) = 0;
virtual void visit (BlockExpr &expr) = 0;
+ virtual void visit (AnonConst &expr) = 0;
+ virtual void visit (ConstBlock &expr) = 0;
virtual void visit (ClosureExpr &expr) = 0;
virtual void visit (ContinueExpr &expr) = 0;
virtual void visit (BreakExpr &expr) = 0;
@@ -201,6 +203,8 @@ public:
virtual void visit (FieldAccessExpr &) override {}
virtual void visit (ClosureExpr &) override {}
virtual void visit (BlockExpr &) override {}
+ virtual void visit (AnonConst &) override {}
+ virtual void visit (ConstBlock &) override {}
virtual void visit (ContinueExpr &) override {}
virtual void visit (BreakExpr &) override {}
virtual void visit (RangeFromToExpr &) override {}
@@ -427,6 +431,8 @@ public:
virtual void visit (MethodCallExpr &expr) = 0;
virtual void visit (FieldAccessExpr &expr) = 0;
virtual void visit (BlockExpr &expr) = 0;
+ virtual void visit (AnonConst &expr) = 0;
+ virtual void visit (ConstBlock &expr) = 0;
virtual void visit (ContinueExpr &expr) = 0;
virtual void visit (BreakExpr &expr) = 0;
virtual void visit (RangeFromToExpr &expr) = 0;
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index 093d8d5..dc94fb5 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -577,7 +577,8 @@ UseTreeGlob::as_string () const
return "*";
case GLOBAL:
return "::*";
- case PATH_PREFIXED: {
+ case PATH_PREFIXED:
+ {
std::string path_str = path.as_string ();
return path_str + "::*";
}
@@ -600,7 +601,8 @@ UseTreeList::as_string () const
case GLOBAL:
path_str = "::{";
break;
- case PATH_PREFIXED: {
+ case PATH_PREFIXED:
+ {
path_str = path.as_string () + "::{";
break;
}
@@ -1048,6 +1050,33 @@ BlockExpr::as_string () const
}
std::string
+AnonConst::as_string () const
+{
+ std::string istr = indent_spaces (enter);
+ std::string str = istr + "AnonConst:\n" + istr;
+
+ str += get_inner_expr ().as_string ();
+
+ str += "\n" + indent_spaces (out);
+
+ return str;
+}
+
+std::string
+ConstBlock::as_string () const
+{
+ std::string istr = indent_spaces (enter);
+
+ std::string str = istr + "ConstBlock:\n" + istr;
+
+ str += get_const_expr ().as_string ();
+
+ str += "\n" + indent_spaces (out);
+
+ return str;
+}
+
+std::string
TypeAlias::as_string () const
{
std::string str = VisItem::as_string ();
@@ -2579,9 +2608,9 @@ IdentifierPattern::as_string () const
str += variable_ident.as_string ();
- if (has_pattern_to_bind ())
+ if (has_subpattern ())
{
- str += " @ " + to_bind->as_string ();
+ str += " @ " + subpattern->as_string ();
}
return str;
@@ -4055,6 +4084,18 @@ BlockExpr::accept_vis (HIRFullVisitor &vis)
}
void
+AnonConst::accept_vis (HIRFullVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+ConstBlock::accept_vis (HIRFullVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
ContinueExpr::accept_vis (HIRFullVisitor &vis)
{
vis.visit (*this);
@@ -5027,6 +5068,18 @@ BlockExpr::accept_vis (HIRExpressionVisitor &vis)
}
void
+AnonConst::accept_vis (HIRExpressionVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+ConstBlock::accept_vis (HIRExpressionVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
Function::accept_vis (HIRStmtVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index b143e70..76ff15c 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -1317,7 +1317,8 @@ Lexer::parse_escape (char opening_char)
switch (current_char.value)
{
- case 'x': {
+ case 'x':
+ {
auto hex_escape_pair = parse_partial_hex_escape ();
long hexLong = hex_escape_pair.first;
additional_length_offset += hex_escape_pair.second;
@@ -1400,7 +1401,8 @@ Lexer::parse_utf8_escape ()
switch (current_char.value)
{
- case 'x': {
+ case 'x':
+ {
auto hex_escape_pair = parse_partial_hex_escape ();
long hexLong = hex_escape_pair.first;
additional_length_offset += hex_escape_pair.second;
@@ -1438,7 +1440,8 @@ Lexer::parse_utf8_escape ()
case '"':
output_char = '"';
break;
- case 'u': {
+ case 'u':
+ {
auto unicode_escape_pair = parse_partial_unicode_escape ();
output_char = unicode_escape_pair.first;
additional_length_offset += unicode_escape_pair.second;
@@ -1894,6 +1897,11 @@ Lexer::parse_raw_byte_string (location_t loc)
break;
}
}
+ else if (current_char.is_eof ())
+ {
+ rust_error_at (string_begin_locus, "unended raw byte string literal");
+ return Token::make (END_OF_FILE, get_current_location ());
+ }
else if (current_char.value > 127)
{
rust_error_at (get_current_location (),
@@ -1901,11 +1909,6 @@ Lexer::parse_raw_byte_string (location_t loc)
current_char.as_string ().c_str ());
current_char = 0;
}
- else if (current_char.is_eof ())
- {
- rust_error_at (string_begin_locus, "unended raw byte string literal");
- return Token::make (END_OF_FILE, get_current_location ());
- }
length++;
current_column++;
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index 10293e0..383ffac 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -263,8 +263,7 @@ private:
#if CHECKING_P
namespace selftest {
-void
-rust_input_source_test ();
+void rust_input_source_test ();
} // namespace selftest
diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc
index 8493889..c396e10 100644
--- a/gcc/rust/lex/rust-token.cc
+++ b/gcc/rust/lex/rust-token.cc
@@ -20,6 +20,7 @@
#include "rust-token.h"
#include "rust-diagnostics.h"
#include "rust-unicode.h"
+#include "rust-ast.h"
namespace Rust {
// Hackily defined way to get token description for enum value using x-macros
@@ -88,7 +89,8 @@ token_id_keyword_string (TokenId id)
switch (id)
{
#define RS_TOKEN_KEYWORD_2015(id, str_ptr) \
- case id: { \
+ case id: \
+ { \
static const std::string str (str_ptr); \
return str; \
} \
@@ -234,6 +236,13 @@ escape_special_chars (const std::string &source, Context ctx)
} // namespace
+TokenPtr
+Token::make_identifier (const Identifier &ident)
+{
+ std::string str = ident;
+ return make_identifier (ident.get_locus (), std::move (str));
+}
+
std::string
Token::as_string () const
{
diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h
index c683ecd..2021aec 100644
--- a/gcc/rust/lex/rust-token.h
+++ b/gcc/rust/lex/rust-token.h
@@ -24,6 +24,10 @@
#include "rust-unicode.h"
namespace Rust {
+
+// used by Rust::Token::make_identifier
+class Identifier;
+
// "Primitive core types" in Rust - the different int and float types, as well
// as some others
enum PrimitiveCoreType
@@ -221,25 +225,20 @@ typedef std::shared_ptr<Token> TokenPtr;
typedef std::shared_ptr<const Token> const_TokenPtr;
// Hackily defined way to get token description for enum value using x-macros
-const char *
-get_token_description (TokenId id);
+const char *get_token_description (TokenId id);
/* Hackily defined way to get token description as a string for enum value using
* x-macros */
-const char *
-token_id_to_str (TokenId id);
+const char *token_id_to_str (TokenId id);
/* checks if a token is a keyword */
-bool
-token_id_is_keyword (TokenId id);
+bool token_id_is_keyword (TokenId id);
/* gets the string associated with a keyword */
-const std::string &
-token_id_keyword_string (TokenId id);
+const std::string &token_id_keyword_string (TokenId id);
// Get type hint description as a string.
-const char *
-get_type_hint_string (PrimitiveCoreType type);
+const char *get_type_hint_string (PrimitiveCoreType type);
/* Normalize string if a token is a identifier */
-std::string
-nfc_normalize_token_string (location_t loc, TokenId id, const std::string &str);
+std::string nfc_normalize_token_string (location_t loc, TokenId id,
+ const std::string &str);
// Represents a single token. Create using factory static methods.
class Token
@@ -329,6 +328,8 @@ public:
return TokenPtr (new Token (IDENTIFIER, locus, std::move (str)));
}
+ static TokenPtr make_identifier (const Identifier &ident);
+
// Makes and returns a new TokenPtr of type INT_LITERAL.
static TokenPtr make_int (location_t locus, std::string &&str,
PrimitiveCoreType type_hint = CORETYPE_UNKNOWN)
diff --git a/gcc/rust/metadata/rust-export-metadata.cc b/gcc/rust/metadata/rust-export-metadata.cc
index 771bec6..1829a85 100644
--- a/gcc/rust/metadata/rust-export-metadata.cc
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -263,8 +263,7 @@ PublicInterface::write_to_path (const std::string &path) const
FILE *nfd = fopen (path.c_str (), "wb");
if (nfd == NULL)
{
- rust_error_at (UNDEF_LOCATION,
- "failed to open file %qs for writing: %s",
+ rust_error_at (UNDEF_LOCATION, "failed to open file %qs for writing: %s",
path.c_str (), xstrerror (errno));
return;
}
diff --git a/gcc/rust/metadata/rust-import-archive.cc b/gcc/rust/metadata/rust-import-archive.cc
index cf24607..f64de4e 100644
--- a/gcc/rust/metadata/rust-import-archive.cc
+++ b/gcc/rust/metadata/rust-import-archive.cc
@@ -683,7 +683,7 @@ public:
const Header &operator* () const { return this->header_; }
- const Header *operator-> () const { return &this->header_; }
+ const Header *operator->() const { return &this->header_; }
Archive_iterator &operator++ ()
{
diff --git a/gcc/rust/metadata/rust-imports.h b/gcc/rust/metadata/rust-imports.h
index a497c67..65a2af1 100644
--- a/gcc/rust/metadata/rust-imports.h
+++ b/gcc/rust/metadata/rust-imports.h
@@ -11,8 +11,7 @@
namespace Rust {
-extern void
-add_search_path (const std::string &path);
+extern void add_search_path (const std::string &path);
class Import
{
diff --git a/gcc/rust/parse/rust-cfg-parser.h b/gcc/rust/parse/rust-cfg-parser.h
index 0d64016..61db240 100644
--- a/gcc/rust/parse/rust-cfg-parser.h
+++ b/gcc/rust/parse/rust-cfg-parser.h
@@ -36,15 +36,14 @@ namespace Rust {
*
* @return false if the given input was invalid, true otherwise
*/
-bool
-parse_cfg_option (std::string &input, std::string &key, std::string &value);
+bool parse_cfg_option (std::string &input, std::string &key,
+ std::string &value);
} // namespace Rust
#if CHECKING_P
namespace selftest {
-extern void
-rust_cfg_parser_test (void);
+extern void rust_cfg_parser_test (void);
} // namespace selftest
#endif // CHECKING_P
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 9dda231..9c9208f 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -227,19 +227,22 @@ Parser<ManagedTokenSource>::skip_generics_right_angle ()
// this is good - skip token
lexer.skip_token ();
return true;
- case RIGHT_SHIFT: {
+ case RIGHT_SHIFT:
+ {
// new implementation that should be better
lexer.split_current_token (RIGHT_ANGLE, RIGHT_ANGLE);
lexer.skip_token ();
return true;
}
- case GREATER_OR_EQUAL: {
+ case GREATER_OR_EQUAL:
+ {
// new implementation that should be better
lexer.split_current_token (RIGHT_ANGLE, EQUAL);
lexer.skip_token ();
return true;
}
- case RIGHT_SHIFT_EQ: {
+ case RIGHT_SHIFT_EQ:
+ {
// new implementation that should be better
lexer.split_current_token (RIGHT_ANGLE, GREATER_OR_EQUAL);
lexer.skip_token ();
@@ -790,7 +793,8 @@ Parser<ManagedTokenSource>::parse_attr_input ()
{
case LEFT_PAREN:
case LEFT_SQUARE:
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// must be a delimited token tree, so parse that
std::unique_ptr<AST::AttrInput> input_tree (
new AST::DelimTokenTree (parse_delim_token_tree ()));
@@ -799,7 +803,8 @@ Parser<ManagedTokenSource>::parse_attr_input ()
return input_tree;
}
- case EQUAL: {
+ case EQUAL:
+ {
// = LiteralExpr
lexer.skip_token ();
@@ -877,7 +882,10 @@ Parser<ManagedTokenSource>::parse_attr_input ()
return attr_input_lit;
}
break;
+ case RIGHT_PAREN:
case RIGHT_SQUARE:
+ case RIGHT_CURLY:
+ case END_OF_FILE:
// means AttrInput is missing, which is allowed
return nullptr;
default:
@@ -2117,7 +2125,8 @@ Parser<ManagedTokenSource>::parse_macro_match ()
{
case LEFT_PAREN:
case LEFT_SQUARE:
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// must be macro matcher as delimited
AST::MacroMatcher matcher = parse_macro_matcher ();
if (matcher.is_error ())
@@ -2131,7 +2140,8 @@ Parser<ManagedTokenSource>::parse_macro_match ()
return std::unique_ptr<AST::MacroMatcher> (
new AST::MacroMatcher (std::move (matcher)));
}
- case DOLLAR_SIGN: {
+ case DOLLAR_SIGN:
+ {
// have to do more lookahead to determine if fragment or repetition
const_TokenPtr t2 = lexer.peek_token (1);
switch (t2->get_id ())
@@ -2402,7 +2412,8 @@ Parser<ManagedTokenSource>::parse_visibility ()
skip_token (RIGHT_PAREN);
return AST::Visibility::create_super (path_loc, vis_loc);
- case IN: {
+ case IN:
+ {
lexer.skip_token ();
// parse the "in" path as well
@@ -2466,7 +2477,8 @@ Parser<ManagedTokenSource>::parse_module (AST::Visibility vis,
new AST::Module (std::move (name), std::move (vis),
std::move (outer_attrs), locus, safety,
lexer.get_filename (), inline_module_stack));
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
lexer.skip_token ();
// parse inner attributes
@@ -2730,7 +2742,8 @@ Parser<ManagedTokenSource>::parse_use_tree ()
return std::unique_ptr<AST::UseTreeGlob> (
new AST::UseTreeGlob (AST::UseTreeGlob::NO_PATH,
AST::SimplePath::create_empty (), locus));
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// nested tree UseTree type
lexer.skip_token ();
@@ -2808,7 +2821,8 @@ Parser<ManagedTokenSource>::parse_use_tree ()
return std::unique_ptr<AST::UseTreeGlob> (
new AST::UseTreeGlob (AST::UseTreeGlob::PATH_PREFIXED,
std::move (path), locus));
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// nested tree UseTree type
lexer.skip_token ();
@@ -2845,7 +2859,8 @@ Parser<ManagedTokenSource>::parse_use_tree ()
std::move (path), std::move (use_trees),
locus));
}
- case AS: {
+ case AS:
+ {
// rebind UseTree type
lexer.skip_token ();
@@ -3100,7 +3115,8 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
switch (token->get_id ())
{
- case LIFETIME: {
+ case LIFETIME:
+ {
auto lifetime = parse_lifetime (false);
if (!lifetime)
{
@@ -3126,7 +3142,8 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
std::move (outer_attrs), token->get_locus ()));
break;
}
- case IDENTIFIER: {
+ case IDENTIFIER:
+ {
auto type_ident = token->get_str ();
lexer.skip_token ();
@@ -3161,7 +3178,8 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token)
std::move (outer_attrs)));
break;
}
- case CONST: {
+ case CONST:
+ {
lexer.skip_token ();
auto name_token = expect_token (IDENTIFIER);
@@ -4356,7 +4374,8 @@ Parser<ManagedTokenSource>::parse_struct (AST::Visibility vis,
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// struct with body
// skip curly bracket
@@ -4759,7 +4778,8 @@ Parser<ManagedTokenSource>::parse_enum_item ()
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_PAREN: {
+ case LEFT_PAREN:
+ {
// tuple enum item
lexer.skip_token ();
@@ -4780,7 +4800,8 @@ Parser<ManagedTokenSource>::parse_enum_item ()
std::move (item_name), std::move (vis), std::move (tuple_fields),
std::move (outer_attrs), item_name_tok->get_locus ()));
}
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// struct enum item
lexer.skip_token ();
@@ -4797,7 +4818,8 @@ Parser<ManagedTokenSource>::parse_enum_item ()
std::move (item_name), std::move (vis), std::move (struct_fields),
std::move (outer_attrs), item_name_tok->get_locus ()));
}
- case EQUAL: {
+ case EQUAL:
+ {
// discriminant enum item
lexer.skip_token ();
@@ -5450,7 +5472,8 @@ Parser<ManagedTokenSource>::parse_inherent_impl_item ()
case SUPER:
case SELF:
case CRATE:
- case PUB: {
+ case PUB:
+ {
// visibility, so not a macro invocation semi - must be constant,
// function, or method
AST::Visibility vis = parse_visibility ();
@@ -5964,7 +5987,8 @@ Parser<ManagedTokenSource>::parse_external_item ()
{
case IDENTIFIER:
return parse_macro_invocation_semi (outer_attrs);
- case STATIC_KW: {
+ case STATIC_KW:
+ {
// parse extern static item
lexer.skip_token ();
@@ -6261,7 +6285,8 @@ Parser<ManagedTokenSource>::parse_generic_arg ()
switch (tok->get_id ())
{
- case IDENTIFIER: {
+ case IDENTIFIER:
+ {
// This is a bit of a weird situation: With an identifier token, we
// could either have a valid type or a macro (FIXME: anything else?). So
// we need one bit of lookahead to differentiate if this is really
@@ -6309,9 +6334,10 @@ Parser<ManagedTokenSource>::parse_generic_arg ()
case FALSE_LITERAL:
expr = parse_literal_expr ();
break;
- // FIXME: Because of this, error reporting is garbage for const generic
- // parameter's default values
- default: {
+ // FIXME: Because of this, error reporting is garbage for const generic
+ // parameter's default values
+ default:
+ {
auto type = parse_type ();
// FIXME: Find a better way to do this?
if (type)
@@ -6510,7 +6536,8 @@ Parser<ManagedTokenSource>::parse_type_path_segment ()
switch (t->get_id ())
{
case LEFT_SHIFT:
- case LEFT_ANGLE: {
+ case LEFT_ANGLE:
+ {
// parse generic args
AST::GenericArgs generic_args = parse_path_generic_args ();
@@ -6519,7 +6546,8 @@ Parser<ManagedTokenSource>::parse_type_path_segment ()
has_separating_scope_resolution,
std::move (generic_args), locus));
}
- case LEFT_PAREN: {
+ case LEFT_PAREN:
+ {
// parse type path function
AST::TypePathFunction type_path_function
= parse_type_path_function (locus);
@@ -7068,16 +7096,14 @@ Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs,
case SELF:
case SELF_ALIAS:
case DOLLAR_SIGN:
- case SCOPE_RESOLUTION: {
+ case SCOPE_RESOLUTION:
+ {
AST::PathInExpression path = parse_path_in_expression ();
std::unique_ptr<AST::Expr> null_denotation;
if (lexer.peek_token ()->get_id () == EXCLAM)
{
- // Bind a reference to avoid -Wredundant-move on post-P1825R0
- // compilers. Change to non-reference type and remove the moves
- // below once C++20 is required to build gcc.
- std::unique_ptr<AST::MacroInvocation> &&invoc
+ std::unique_ptr<AST::MacroInvocation> invoc
= parse_macro_invocation_partial (std::move (path),
std::move (outer_attrs));
@@ -7085,7 +7111,7 @@ Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs,
{
invoc->add_semicolon ();
// Macro invocation with semicolon.
- return std::move (invoc);
+ return invoc;
}
TokenId after_macro = lexer.peek_token ()->get_id ();
@@ -7093,14 +7119,14 @@ Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs,
if (restrictions.allow_close_after_expr_stmt
&& (after_macro == RIGHT_PAREN || after_macro == RIGHT_CURLY
|| after_macro == RIGHT_SQUARE))
- return std::move (invoc);
+ return invoc;
if (invoc->get_invoc_data ().get_delim_tok_tree ().get_delim_type ()
== AST::CURLY
&& after_macro != DOT && after_macro != QUESTION_MARK)
{
rust_debug ("braced macro statement");
- return std::move (invoc);
+ return invoc;
}
null_denotation = std::move (invoc);
@@ -7238,6 +7264,30 @@ Parser<ManagedTokenSource>::parse_block_expr (
std::move (label), locus, end_locus));
}
+/* Parse a "const block", a block preceded by the `const` keyword whose
+ * statements can be const evaluated and used in constant contexts */
+template <typename ManagedTokenSource>
+std::unique_ptr<AST::ConstBlock>
+Parser<ManagedTokenSource>::parse_const_block_expr (AST::AttrVec outer_attrs,
+ location_t locus)
+{
+ auto block = parse_block_expr ();
+
+ if (!block)
+ {
+ add_error (Error (locus, "failed to parse inner block in const block"));
+ skip_after_end_block ();
+
+ return nullptr;
+ }
+
+ auto block_locus = block->get_locus ();
+
+ return std::make_unique<AST::ConstBlock> (AST::AnonConst (std::move (block),
+ block_locus),
+ locus, std::move (outer_attrs));
+}
+
/* Parses a "grouped" expression (expression in parentheses), used to control
* precedence. */
template <typename ManagedTokenSource>
@@ -7675,7 +7725,8 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec outer_attrs,
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// double selection - else
// parse else block expr (required)
std::unique_ptr<AST::BlockExpr> else_body = parse_block_expr ();
@@ -7696,7 +7747,8 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec outer_attrs,
std::move (else_body),
std::move (outer_attrs), locus));
}
- case IF: {
+ case IF:
+ {
// multiple selection - else if or else if let
// branch on whether next token is 'let' or not
if (lexer.peek_token (1)->get_id () == LET)
@@ -7857,7 +7909,8 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec outer_attrs,
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// double selection - else
// parse else block expr (required)
std::unique_ptr<AST::BlockExpr> else_body = parse_block_expr ();
@@ -7879,7 +7932,8 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec outer_attrs,
std::move (else_body),
std::move (outer_attrs), locus));
}
- case IF: {
+ case IF:
+ {
// multiple selection - else if or else if let
// branch on whether next token is 'let' or not
if (lexer.peek_token (1)->get_id () == LET)
@@ -8931,7 +8985,8 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
// slice type or array type - requires further disambiguation
return parse_slice_or_array_type ();
case LEFT_SHIFT:
- case LEFT_ANGLE: {
+ case LEFT_ANGLE:
+ {
// qualified path in type
AST::QualifiedPathInType path = parse_qualified_path_in_type ();
if (path.is_error ())
@@ -8960,7 +9015,8 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
case LOGICAL_AND:
// reference type
return parse_reference_type ();
- case LIFETIME: {
+ case LIFETIME:
+ {
/* probably a lifetime bound, so probably type param bounds in
* TraitObjectType */
std::vector<std::unique_ptr<AST::TypeParamBound>> bounds
@@ -8976,7 +9032,8 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
case SELF_ALIAS:
case CRATE:
case DOLLAR_SIGN:
- case SCOPE_RESOLUTION: {
+ case SCOPE_RESOLUTION:
+ {
// macro invocation or type path - requires further disambiguation.
/* for parsing path component of each rule, perhaps parse it as a
* typepath and attempt conversion to simplepath if a trailing '!' is
@@ -9006,7 +9063,8 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
t = lexer.peek_token ();
switch (t->get_id ())
{
- case EXCLAM: {
+ case EXCLAM:
+ {
// macro invocation
// convert to simple path
AST::SimplePath macro_path = path.as_simple_path ();
@@ -9032,7 +9090,8 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
std::move (tok_tree)),
{}, locus);
}
- case PLUS: {
+ case PLUS:
+ {
// type param bounds
std::vector<std::unique_ptr<AST::TypeParamBound>> bounds;
@@ -9117,14 +9176,8 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
t = lexer.peek_token ();
if (t->get_id () != PLUS)
{
- // convert trait bound to value object
- AST::TraitBound value_bound (*initial_bound);
-
- // DEBUG: removed as unique ptr, so should auto-delete
- // delete initial_bound;
-
return std::unique_ptr<AST::ImplTraitTypeOneBound> (
- new AST::ImplTraitTypeOneBound (std::move (value_bound),
+ new AST::ImplTraitTypeOneBound (std::move (initial_bound),
locus));
}
@@ -9152,7 +9205,8 @@ Parser<ManagedTokenSource>::parse_type (bool save_errors)
new AST::ImplTraitType (std::move (bounds), locus));
}
case DYN:
- case QUESTION_MARK: {
+ case QUESTION_MARK:
+ {
// either TraitObjectType or TraitObjectTypeOneBound
bool has_dyn = false;
if (t->get_id () == DYN)
@@ -9405,7 +9459,8 @@ Parser<ManagedTokenSource>::parse_for_prefixed_type ()
case SELF:
case SELF_ALIAS:
case CRATE:
- case DOLLAR_SIGN: {
+ case DOLLAR_SIGN:
+ {
// path, so trait type
// parse type path to finish parsing trait bound
@@ -9751,7 +9806,8 @@ Parser<ManagedTokenSource>::parse_slice_or_array_type ()
return std::unique_ptr<AST::SliceType> (
new AST::SliceType (std::move (inner_type), locus));
- case SEMICOLON: {
+ case SEMICOLON:
+ {
// array type
lexer.skip_token ();
@@ -9802,7 +9858,8 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
// slice type or array type - requires further disambiguation
return parse_slice_or_array_type ();
case LEFT_SHIFT:
- case LEFT_ANGLE: {
+ case LEFT_ANGLE:
+ {
// qualified path in type
AST::QualifiedPathInType path = parse_qualified_path_in_type ();
if (path.is_error ())
@@ -9843,7 +9900,8 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
case SELF_ALIAS:
case CRATE:
case DOLLAR_SIGN:
- case SCOPE_RESOLUTION: {
+ case SCOPE_RESOLUTION:
+ {
// macro invocation or type path - requires further disambiguation.
/* for parsing path component of each rule, perhaps parse it as a
* typepath and attempt conversion to simplepath if a trailing '!' is
@@ -9871,7 +9929,8 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
t = lexer.peek_token ();
switch (t->get_id ())
{
- case EXCLAM: {
+ case EXCLAM:
+ {
// macro invocation
// convert to simple path
AST::SimplePath macro_path = path.as_simple_path ();
@@ -9955,14 +10014,12 @@ Parser<ManagedTokenSource>::parse_type_no_bounds ()
return nullptr;
}
- // convert trait bound to value object
- AST::TraitBound value_bound (*initial_bound);
-
return std::unique_ptr<AST::ImplTraitTypeOneBound> (
- new AST::ImplTraitTypeOneBound (std::move (value_bound), locus));
+ new AST::ImplTraitTypeOneBound (std::move (initial_bound), locus));
}
case DYN:
- case QUESTION_MARK: {
+ case QUESTION_MARK:
+ {
// either TraitObjectTypeOneBound
bool has_dyn = false;
if (t->get_id () == DYN)
@@ -10303,7 +10360,8 @@ Parser<ManagedTokenSource>::parse_range_pattern_bound ()
case SELF_ALIAS:
case CRATE:
case SCOPE_RESOLUTION:
- case DOLLAR_SIGN: {
+ case DOLLAR_SIGN:
+ {
// path in expression
AST::PathInExpression path = parse_path_in_expression ();
if (path.is_error ())
@@ -10319,7 +10377,8 @@ Parser<ManagedTokenSource>::parse_range_pattern_bound ()
new AST::RangePatternBoundPath (std::move (path)));
}
case LEFT_SHIFT:
- case LEFT_ANGLE: {
+ case LEFT_ANGLE:
+ {
// qualified path in expression
AST::QualifiedPathInExpression path
= parse_qualified_path_in_expression ();
@@ -10464,7 +10523,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
// slice pattern
return parse_slice_pattern ();
case LEFT_SHIFT:
- case LEFT_ANGLE: {
+ case LEFT_ANGLE:
+ {
// qualified path in expression or qualified range pattern bound
AST::QualifiedPathInExpression path
= parse_qualified_path_in_expression ();
@@ -10500,7 +10560,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
case SELF_ALIAS:
case CRATE:
case SCOPE_RESOLUTION:
- case DOLLAR_SIGN: {
+ case DOLLAR_SIGN:
+ {
// path in expression or range pattern bound
AST::PathInExpression path = parse_path_in_expression ();
@@ -10509,7 +10570,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
{
case DOT_DOT_EQ:
case DOT_DOT:
- case ELLIPSIS: {
+ case ELLIPSIS:
+ {
// qualified range pattern bound, so parse rest of range pattern
AST::RangeKind kind = AST::tokenid_to_rangekind (next->get_id ());
lexer.skip_token ();
@@ -10527,7 +10589,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
case EXCLAM:
return parse_macro_invocation_partial (std::move (path),
AST::AttrVec ());
- case LEFT_PAREN: {
+ case LEFT_PAREN:
+ {
// tuple struct
lexer.skip_token ();
@@ -10552,7 +10615,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
new AST::TupleStructPattern (std::move (path),
std::move (items)));
}
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// struct
lexer.skip_token ();
@@ -10722,7 +10786,8 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern ()
return std::unique_ptr<AST::GroupedPattern> (
new AST::GroupedPattern (std::move (initial_pattern), paren_locus));
- case COMMA: {
+ case COMMA:
+ {
// tuple pattern
lexer.skip_token ();
@@ -10979,7 +11044,8 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern ()
{
case EXCLAM:
return parse_macro_invocation_partial (std::move (path), AST::AttrVec ());
- case LEFT_PAREN: {
+ case LEFT_PAREN:
+ {
// tuple struct
lexer.skip_token ();
@@ -11012,7 +11078,8 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern ()
return std::unique_ptr<AST::TupleStructPattern> (
new AST::TupleStructPattern (std::move (path), std::move (items)));
}
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// struct
lexer.skip_token ();
@@ -11033,7 +11100,8 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern ()
}
case DOT_DOT_EQ:
case DOT_DOT:
- case ELLIPSIS: {
+ case ELLIPSIS:
+ {
// range
AST::RangeKind kind
= AST::tokenid_to_rangekind (lexer.peek_token ()->get_id ());
@@ -11050,7 +11118,8 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern ()
std::move (upper_bound), kind,
t->get_locus ()));
}
- case PATTERN_BIND: {
+ case PATTERN_BIND:
+ {
// only allow on single-segment paths
if (path.is_single_segment ())
{
@@ -11188,7 +11257,8 @@ Parser<ManagedTokenSource>::parse_tuple_struct_items ()
case RIGHT_PAREN:
return std::unique_ptr<AST::TupleStructItemsNoRange> (
new AST::TupleStructItemsNoRange (std::move (lower_patterns)));
- case DOT_DOT: {
+ case DOT_DOT:
+ {
// has an upper range that must be parsed separately
lexer.skip_token ();
@@ -11308,7 +11378,8 @@ Parser<ManagedTokenSource>::parse_struct_pattern_field_partial (
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case INT_LITERAL: {
+ case INT_LITERAL:
+ {
// tuple index
std::string index_str = t->get_str ();
int index = atoi (index_str.c_str ());
@@ -11342,7 +11413,8 @@ Parser<ManagedTokenSource>::parse_struct_pattern_field_partial (
// branch on next token
switch (lexer.peek_token (1)->get_id ())
{
- case COLON: {
+ case COLON:
+ {
// identifier-pattern
Identifier ident{t};
lexer.skip_token ();
@@ -11367,7 +11439,8 @@ Parser<ManagedTokenSource>::parse_struct_pattern_field_partial (
t->get_locus ()));
}
case COMMA:
- case RIGHT_CURLY: {
+ case RIGHT_CURLY:
+ {
// identifier only
Identifier ident = {t};
lexer.skip_token ();
@@ -11386,7 +11459,8 @@ Parser<ManagedTokenSource>::parse_struct_pattern_field_partial (
return nullptr;
}
case REF:
- case MUT: {
+ case MUT:
+ {
// only identifier
bool has_ref = false;
if (t->get_id () == REF)
@@ -11458,7 +11532,8 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr ()
t = lexer.peek_token ();
switch (t->get_id ())
{
- case LET: {
+ case LET:
+ {
// let statement
std::unique_ptr<AST::LetStmt> stmt (
parse_let_stmt (std::move (outer_attrs)));
@@ -11476,42 +11551,48 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr ()
case STATIC_KW:
case AUTO:
case TRAIT:
- case IMPL: {
+ case IMPL:
+ {
std::unique_ptr<AST::VisItem> item (
parse_vis_item (std::move (outer_attrs)));
return ExprOrStmt (std::move (item));
}
- /* TODO: implement union keyword but not really because of
- * context-dependence crappy hack way to parse a union written below to
- * separate it from the good code. */
- // case UNION:
- case UNSAFE: { // maybe - unsafe traits are a thing
+ /* TODO: implement union keyword but not really because of
+ * context-dependence crappy hack way to parse a union written below to
+ * separate it from the good code. */
+ // case UNION:
+ case UNSAFE:
+ { // maybe - unsafe traits are a thing
/* if any of these (should be all possible VisItem prefixes), parse a
* VisItem - can't parse item because would require reparsing outer
* attributes */
const_TokenPtr t2 = lexer.peek_token (1);
switch (t2->get_id ())
{
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
// unsafe block: parse as expression
expr = parse_expr (std::move (outer_attrs), restrictions);
break;
}
case AUTO:
- case TRAIT: {
+ case TRAIT:
+ {
// unsafe trait
std::unique_ptr<AST::VisItem> item (
parse_vis_item (std::move (outer_attrs)));
return ExprOrStmt (std::move (item));
}
case EXTERN_KW:
- case FN_KW: {
+ case FN_KW:
+ {
// unsafe function
std::unique_ptr<AST::VisItem> item (
parse_vis_item (std::move (outer_attrs)));
return ExprOrStmt (std::move (item));
}
- case IMPL: {
+ case IMPL:
+ {
// unsafe trait impl
std::unique_ptr<AST::VisItem> item (
parse_vis_item (std::move (outer_attrs)));
@@ -11556,7 +11637,8 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr ()
case SELF_ALIAS:
case CRATE:
case SCOPE_RESOLUTION:
- case DOLLAR_SIGN: {
+ case DOLLAR_SIGN:
+ {
AST::PathInExpression path = parse_path_in_expression ();
std::unique_ptr<AST::Expr> null_denotation;
@@ -11680,7 +11762,8 @@ Parser<ManagedTokenSource>::parse_struct_expr_field ()
std::move (outer_attrs),
t->get_locus ()));
}
- case INT_LITERAL: {
+ case INT_LITERAL:
+ {
// parse tuple index field
int index = atoi (t->get_str ().c_str ());
lexer.skip_token ();
@@ -11920,7 +12003,7 @@ Parser<ManagedTokenSource>::skip_after_end_attribute ()
{
const_TokenPtr t = lexer.peek_token ();
- while (t->get_id () != RIGHT_SQUARE)
+ while (t->get_id () != RIGHT_SQUARE && t->get_id () != END_OF_FILE)
{
lexer.skip_token ();
t = lexer.peek_token ();
@@ -12050,7 +12133,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
case SELF_ALIAS:
case DOLLAR_SIGN:
case CRATE:
- case SUPER: {
+ case SUPER:
+ {
// DEBUG
rust_debug ("beginning null denotation identifier handling");
@@ -12061,7 +12145,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
return null_denotation_path (std::move (path), std::move (outer_attrs),
restrictions);
}
- case SCOPE_RESOLUTION: {
+ case SCOPE_RESOLUTION:
+ {
// TODO: fix: this is for global paths, i.e. std::string::whatever
Error error (tok->get_locus (),
"found null denotation scope resolution operator, and "
@@ -12103,7 +12188,8 @@ Parser<ManagedTokenSource>::null_denotation_path (
// macro
return parse_macro_invocation_partial (std::move (path),
std::move (outer_attrs));
- case LEFT_CURLY: {
+ case LEFT_CURLY:
+ {
bool not_a_block = lexer.peek_token (1)->get_id () == IDENTIFIER
&& (lexer.peek_token (2)->get_id () == COMMA
|| (lexer.peek_token (2)->get_id () == COLON
@@ -12179,7 +12265,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
{
// FIXME: Handle in null_denotation_path?
case LEFT_SHIFT:
- case LEFT_ANGLE: {
+ case LEFT_ANGLE:
+ {
// qualified path
// HACK: add outer attrs to path
AST::QualifiedPathInExpression path
@@ -12237,23 +12324,24 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
return parse_grouped_or_tuple_expr (std::move (outer_attrs),
tok->get_locus ());
- /*case PLUS: { // unary plus operator
- // invoke parse_expr recursively with appropriate priority, etc. for
- below AST::Expr* expr = parse_expr(LBP_UNARY_PLUS);
+ /*case PLUS: { // unary plus operator
+ // invoke parse_expr recursively with appropriate priority, etc. for
+ below AST::Expr* expr = parse_expr(LBP_UNARY_PLUS);
- if (expr == nullptr)
- return nullptr;
- // can only apply to integer and float expressions
- if (expr->get_type() != integer_type_node || expr->get_type() !=
- float_type_node) { rust_error_at(tok->get_locus(), "operand of unary
- plus must be int or float but it is %s", print_type(expr->get_type()));
- return nullptr;
- }
+ if (expr == nullptr)
+ return nullptr;
+ // can only apply to integer and float expressions
+ if (expr->get_type() != integer_type_node || expr->get_type() !=
+ float_type_node) { rust_error_at(tok->get_locus(), "operand of unary
+ plus must be int or float but it is %s", print_type(expr->get_type()));
+ return nullptr;
+ }
- return Tree(expr, tok->get_locus());
- }*/
- // Rust has no unary plus operator
- case MINUS: { // unary minus
+ return Tree(expr, tok->get_locus());
+ }*/
+ // Rust has no unary plus operator
+ case MINUS:
+ { // unary minus
ParseRestrictions entered_from_unary;
entered_from_unary.entered_from_unary = true;
if (!restrictions.can_be_struct_expr)
@@ -12280,7 +12368,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
new AST::NegationExpr (std::move (expr), NegationOperator::NEGATE,
std::move (outer_attrs), tok->get_locus ()));
}
- case EXCLAM: { // logical or bitwise not
+ case EXCLAM:
+ { // logical or bitwise not
ParseRestrictions entered_from_unary;
entered_from_unary.entered_from_unary = true;
if (!restrictions.can_be_struct_expr)
@@ -12305,7 +12394,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
new AST::NegationExpr (std::move (expr), NegationOperator::NOT,
std::move (outer_attrs), tok->get_locus ()));
}
- case ASTERISK: {
+ case ASTERISK:
+ {
/* pointer dereference only - HACK: as struct expressions should
* always be value expressions, cannot be dereferenced */
ParseRestrictions entered_from_unary;
@@ -12318,7 +12408,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
new AST::DereferenceExpr (std::move (expr), std::move (outer_attrs),
tok->get_locus ()));
}
- case AMP: {
+ case AMP:
+ {
// (single) "borrow" expression - shared (mutable) or immutable
std::unique_ptr<AST::Expr> expr = nullptr;
Mutability mutability = Mutability::Imm;
@@ -12375,7 +12466,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
new AST::BorrowExpr (std::move (expr), mutability, raw_borrow, false,
std::move (outer_attrs), tok->get_locus ()));
}
- case LOGICAL_AND: {
+ case LOGICAL_AND:
+ {
// (double) "borrow" expression - shared (mutable) or immutable
std::unique_ptr<AST::Expr> expr = nullptr;
Mutability mutability = Mutability::Imm;
@@ -12469,6 +12561,9 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
"use of %qs is not allowed on the right-side of an assignment",
tok->get_token_description ()));
return nullptr;
+ case CONST:
+ return parse_const_block_expr (std::move (outer_attrs),
+ tok->get_locus ());
default:
if (!restrictions.expr_can_be_null)
add_error (Error (tok->get_locus (),
@@ -12491,8 +12586,9 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
// Token passed in has already been skipped, so peek gives "next" token
switch (tok->get_id ())
{
- // FIXME: allow for outer attributes to be applied
- case QUESTION_MARK: {
+ // FIXME: allow for outer attributes to be applied
+ case QUESTION_MARK:
+ {
location_t left_locus = left->get_locus ();
// error propagation expression - unary postfix
return std::unique_ptr<AST::ErrorPropagationExpr> (
@@ -12746,7 +12842,8 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
"function - this should probably be handled elsewhere"));
return nullptr;
- case DOT: {
+ case DOT:
+ {
/* field expression or method call - relies on parentheses after next
* identifier or await if token after is "await" (unary postfix) or
* tuple index if token after is a decimal int literal */
@@ -14062,7 +14159,8 @@ Parser<ManagedTokenSource>::parse_struct_expr_struct_partial (
* algorithm should work too. As such, AST type not happening. */
case IDENTIFIER:
case HASH:
- case INT_LITERAL: {
+ case INT_LITERAL:
+ {
// struct with struct expr fields
// parse struct expr fields
@@ -14359,7 +14457,8 @@ Parser<ManagedTokenSource>::parse_closure_expr_pratt (const_TokenPtr tok,
case OR:
// no parameters, don't skip token
break;
- case PIPE: {
+ case PIPE:
+ {
// actually may have parameters
// don't skip token
const_TokenPtr t = lexer.peek_token ();
diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc
index 43d15aa..860fd11 100644
--- a/gcc/rust/parse/rust-parse.cc
+++ b/gcc/rust/parse/rust-parse.cc
@@ -42,8 +42,7 @@ extract_module_path (const AST::AttrVec &inner_attrs,
{
rust_error_at (
path_attr.get_locus (),
- // Split the format string so that -Wformat-diag does not complain...
- "path attributes must contain a filename: '%s'", "#![path = \"file\"]");
+ "path attributes must contain a filename: %<#[path = \"file\"]%>");
return name;
}
@@ -67,8 +66,7 @@ extract_module_path (const AST::AttrVec &inner_attrs,
{
rust_error_at (
path_attr.get_locus (),
- // Split the format string so that -Wformat-diag does not complain...
- "path attributes must contain a filename: '%s'", "#[path = \"file\"]");
+ "path attributes must contain a filename: %<#[path = \"file\"]%>");
return name;
}
@@ -80,6 +78,15 @@ extract_module_path (const AST::AttrVec &inner_attrs,
// a character that is not an equal sign or whitespace
auto filename_begin = path_value.find_first_not_of ("=\t ");
+ // If the path consists of only whitespace, then we have an error
+ if (filename_begin == std::string::npos)
+ {
+ rust_error_at (
+ path_attr.get_locus (),
+ "path attributes must contain a filename: %<#[path = \"file\"]%>");
+ return name;
+ }
+
auto path = path_value.substr (filename_begin);
// On windows, the path might mix '/' and '\' separators. Replace the
@@ -144,10 +151,9 @@ peculiar_fragment_match_compatible_fragment (
= contains (fragment_follow_set[last_spec.get_kind ()], spec.get_kind ());
if (!is_valid)
- rust_error_at (
- match_locus,
- "fragment specifier %qs is not allowed after %qs fragments",
- spec.as_string ().c_str (), last_spec.as_string ().c_str ());
+ rust_error_at (match_locus,
+ "fragment specifier %qs is not allowed after %qs fragments",
+ spec.as_string ().c_str (), last_spec.as_string ().c_str ());
return is_valid;
}
@@ -244,7 +250,8 @@ peculiar_fragment_match_compatible (const AST::MacroMatchFragment &last_match,
// the error.
switch (match.get_macro_match_type ())
{
- case AST::MacroMatch::Tok: {
+ case AST::MacroMatch::Tok:
+ {
auto tok = static_cast<const AST::Token *> (&match);
if (contains (allowed_toks, tok->get_id ()))
return true;
@@ -254,7 +261,8 @@ peculiar_fragment_match_compatible (const AST::MacroMatchFragment &last_match,
break;
}
break;
- case AST::MacroMatch::Repetition: {
+ case AST::MacroMatch::Repetition:
+ {
auto repetition
= static_cast<const AST::MacroMatchRepetition *> (&match);
auto &matches = repetition->get_matches ();
@@ -263,7 +271,8 @@ peculiar_fragment_match_compatible (const AST::MacroMatchFragment &last_match,
return peculiar_fragment_match_compatible (last_match, *first_frag);
break;
}
- case AST::MacroMatch::Matcher: {
+ case AST::MacroMatch::Matcher:
+ {
auto matcher = static_cast<const AST::MacroMatcher *> (&match);
auto first_token = matcher->get_delim_type ();
TokenId delim_id;
@@ -289,7 +298,8 @@ peculiar_fragment_match_compatible (const AST::MacroMatchFragment &last_match,
error_locus = matcher->get_match_locus ();
break;
}
- case AST::MacroMatch::Fragment: {
+ case AST::MacroMatch::Fragment:
+ {
auto last_spec = last_match.get_frag_spec ();
auto fragment = static_cast<const AST::MacroMatchFragment *> (&match);
if (last_spec.has_follow_set_fragment_restrictions ())
@@ -328,10 +338,11 @@ is_match_compatible (const AST::MacroMatch &last_match,
switch (last_match.get_macro_match_type ())
{
- // This is our main stop condition: When we are finally looking at the
- // last match (or its actual last component), and it is a fragment, it
- // may contain some follow up restrictions.
- case AST::MacroMatch::Fragment: {
+ // This is our main stop condition: When we are finally looking at the
+ // last match (or its actual last component), and it is a fragment, it
+ // may contain some follow up restrictions.
+ case AST::MacroMatch::Fragment:
+ {
auto fragment
= static_cast<const AST::MacroMatchFragment *> (&last_match);
if (fragment->get_frag_spec ().has_follow_set_restrictions ())
@@ -339,7 +350,8 @@ is_match_compatible (const AST::MacroMatch &last_match,
else
return true;
}
- case AST::MacroMatch::Repetition: {
+ case AST::MacroMatch::Repetition:
+ {
// A repetition on the left hand side means we want to make sure the
// last match of the repetition is compatible with the new match
auto repetition
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 827d91d..4fab60f 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef RUST_PARSE_H
#define RUST_PARSE_H
+#include "rust-ast.h"
#include "rust-item.h"
#include "rust-lex.h"
#include "rust-ast-full.h"
@@ -165,6 +166,10 @@ public:
tl::optional<AST::LoopLabel> = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
+ std::unique_ptr<AST::ConstBlock>
+ parse_const_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
+ location_t loc = UNKNOWN_LOCATION);
+
bool is_macro_rules_def (const_TokenPtr t);
std::unique_ptr<AST::Item> parse_item (bool called_from_statement);
std::unique_ptr<AST::Pattern> parse_pattern ();
@@ -764,9 +769,9 @@ private:
};
};
-std::string
-extract_module_path (const AST::AttrVec &inner_attrs,
- const AST::AttrVec &outer_attrs, const std::string &name);
+std::string extract_module_path (const AST::AttrVec &inner_attrs,
+ const AST::AttrVec &outer_attrs,
+ const std::string &name);
/**
* Check if a MacroMatch is allowed to follow the last parsed MacroMatch.
@@ -776,9 +781,8 @@ extract_module_path (const AST::AttrVec &inner_attrs,
*
* @return true if the follow-up is valid, false otherwise
*/
-bool
-is_match_compatible (const AST::MacroMatch &last_match,
- const AST::MacroMatch &current_match);
+bool is_match_compatible (const AST::MacroMatch &last_match,
+ const AST::MacroMatch &current_match);
} // namespace Rust
// as now template, include implementations of all methods
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc
index b781ce33..71c4c48 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -232,6 +232,14 @@ ResolverBase::visit (AST::BlockExpr &)
{}
void
+ResolverBase::visit (AST::AnonConst &)
+{}
+
+void
+ResolverBase::visit (AST::ConstBlock &)
+{}
+
+void
ResolverBase::visit (AST::ClosureExprInnerTyped &)
{}
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
index 5bb9e4f..e17bdcb 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -21,6 +21,7 @@
#include "rust-ast-visitor.h"
#include "rust-ast.h"
+#include "rust-expr.h"
#include "rust-name-resolver.h"
#include "rust-diagnostics.h"
#include "rust-location.h"
@@ -85,6 +86,8 @@ public:
void visit (AST::FieldAccessExpr &);
void visit (AST::ClosureExprInner &);
void visit (AST::BlockExpr &);
+ void visit (AST::AnonConst &);
+ void visit (AST::ConstBlock &);
void visit (AST::ClosureExprInnerTyped &);
void visit (AST::ContinueExpr &);
void visit (AST::BreakExpr &);
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 5524e18..a410193 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -315,6 +315,18 @@ ResolveExpr::visit (AST::BlockExpr &expr)
}
void
+ResolveExpr::visit (AST::AnonConst &expr)
+{
+ ResolveExpr::go (expr.get_inner_expr (), prefix, canonical_prefix);
+}
+
+void
+ResolveExpr::visit (AST::ConstBlock &expr)
+{
+ ResolveExpr::go (expr.get_const_expr (), prefix, canonical_prefix);
+}
+
+void
translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix,
const CanonicalPath &canonical_prefix)
{
@@ -324,38 +336,46 @@ translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix,
{
switch (operand.get_register_type ())
{
- case RegisterType::In: {
+ case RegisterType::In:
+ {
auto in = operand.get_in ();
ResolveExpr::go (*in.expr, prefix, canonical_prefix);
break;
}
- case RegisterType::Out: {
+ case RegisterType::Out:
+ {
auto out = operand.get_out ();
ResolveExpr::go (*out.expr, prefix, canonical_prefix);
break;
}
- case RegisterType::InOut: {
+ case RegisterType::InOut:
+ {
auto in_out = operand.get_in_out ();
ResolveExpr::go (*in_out.expr, prefix, canonical_prefix);
break;
}
- case RegisterType::SplitInOut: {
+ case RegisterType::SplitInOut:
+ {
auto split_in_out = operand.get_split_in_out ();
ResolveExpr::go (*split_in_out.in_expr, prefix, canonical_prefix);
ResolveExpr::go (*split_in_out.out_expr, prefix, canonical_prefix);
break;
}
- case RegisterType::Const: {
+ case RegisterType::Const:
+ {
auto anon_const = operand.get_const ().anon_const;
- ResolveExpr::go (*anon_const.expr, prefix, canonical_prefix);
+ ResolveExpr::go (anon_const.get_inner_expr (), prefix,
+ canonical_prefix);
break;
}
- case RegisterType::Sym: {
+ case RegisterType::Sym:
+ {
auto sym = operand.get_sym ();
ResolveExpr::go (*sym.expr, prefix, canonical_prefix);
break;
}
- case RegisterType::Label: {
+ case RegisterType::Label:
+ {
auto label = operand.get_label ();
ResolveExpr::go (*label.expr, prefix, canonical_prefix);
break;
@@ -766,7 +786,7 @@ ResolveExpr::visit (AST::ClosureExprInnerTyped &expr)
resolver->push_closure_context (expr.get_node_id ());
- ResolveExpr::go (expr.get_definition_block (), prefix, canonical_prefix);
+ ResolveExpr::go (expr.get_definition_expr (), prefix, canonical_prefix);
resolver->pop_closure_context ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index b296d66..aad1605 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -56,6 +56,8 @@ public:
void visit (AST::IfLetExpr &expr) override;
void visit (AST::IfLetExprConseqElse &expr) override;
void visit (AST::BlockExpr &expr) override;
+ void visit (AST::AnonConst &expr) override;
+ void visit (AST::ConstBlock &expr) override;
void visit (AST::InlineAsm &expr) override;
void visit (AST::LlvmInlineAsm &expr) override;
void visit (AST::UnsafeBlockExpr &expr) override;
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 30f6d43..0937d65 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -608,10 +608,7 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
}
else
{
- std::string seg_buf = "<impl " + self_cpath.get () + ">";
- CanonicalPath seg
- = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
- cpath = canonical_prefix.append (seg);
+ cpath = canonical_prefix.append (impl_type_seg);
}
// done setup paths
@@ -732,13 +729,7 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
}
else
{
- std::string projection_str = canonical_projection.get ();
- std::string seg_buf
- = "<impl " + projection_str.substr (1, projection_str.size () - 2)
- + ">";
- CanonicalPath seg
- = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
- cpath = canonical_prefix.append (seg);
+ cpath = canonical_prefix.append (canonical_projection);
}
// DONE setup canonical-path
@@ -838,29 +829,32 @@ ResolveItem::resolve_extern_item (AST::ExternalItem &item)
ResolveExternItem::go (item, prefix, canonical_prefix);
}
-static void
-flatten_glob (const AST::UseTreeGlob &glob, std::vector<Import> &imports);
-static void
-flatten_rebind (const AST::UseTreeRebind &glob, std::vector<Import> &imports);
-static void
-flatten_list (const AST::UseTreeList &glob, std::vector<Import> &imports);
+static void flatten_glob (const AST::UseTreeGlob &glob,
+ std::vector<Import> &imports);
+static void flatten_rebind (const AST::UseTreeRebind &glob,
+ std::vector<Import> &imports);
+static void flatten_list (const AST::UseTreeList &glob,
+ std::vector<Import> &imports);
static void
flatten (const AST::UseTree *tree, std::vector<Import> &imports)
{
switch (tree->get_kind ())
{
- case AST::UseTree::Glob: {
+ case AST::UseTree::Glob:
+ {
auto glob = static_cast<const AST::UseTreeGlob *> (tree);
flatten_glob (*glob, imports);
break;
}
- case AST::UseTree::Rebind: {
+ case AST::UseTree::Rebind:
+ {
auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
flatten_rebind (*rebind, imports);
break;
}
- case AST::UseTree::List: {
+ case AST::UseTree::List:
+ {
auto list = static_cast<const AST::UseTreeList *> (tree);
flatten_list (*list, imports);
break;
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 776dd53..d31f910 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -153,8 +153,7 @@ private:
#if CHECKING_P
namespace selftest {
-extern void
-rust_simple_path_resolve_test (void);
+extern void rust_simple_path_resolve_test (void);
} // namespace selftest
#endif // CHECKING_P
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index ee84be8..2b5e2bf 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -94,13 +94,15 @@ PatternDeclaration::visit (AST::TupleStructPattern &pattern)
AST::TupleStructItems &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case AST::TupleStructItems::RANGE: {
+ case AST::TupleStructItems::RANGE:
+ {
// TODO
rust_unreachable ();
}
break;
- case AST::TupleStructItems::NO_RANGE: {
+ case AST::TupleStructItems::NO_RANGE:
+ {
auto &items_no_range
= static_cast<AST::TupleStructItemsNoRange &> (items);
@@ -123,7 +125,8 @@ PatternDeclaration::visit (AST::StructPattern &pattern)
{
switch (field->get_item_type ())
{
- case AST::StructPatternField::ItemType::TUPLE_PAT: {
+ case AST::StructPatternField::ItemType::TUPLE_PAT:
+ {
AST::StructPatternFieldTuplePat &tuple
= static_cast<AST::StructPatternFieldTuplePat &> (*field);
@@ -131,7 +134,8 @@ PatternDeclaration::visit (AST::StructPattern &pattern)
}
break;
- case AST::StructPatternField::ItemType::IDENT_PAT: {
+ case AST::StructPatternField::ItemType::IDENT_PAT:
+ {
AST::StructPatternFieldIdentPat &ident
= static_cast<AST::StructPatternFieldIdentPat &> (*field);
@@ -139,7 +143,8 @@ PatternDeclaration::visit (AST::StructPattern &pattern)
}
break;
- case AST::StructPatternField::ItemType::IDENT: {
+ case AST::StructPatternField::ItemType::IDENT:
+ {
auto &ident = static_cast<AST::StructPatternFieldIdent &> (*field);
Mutability mut
@@ -160,7 +165,8 @@ PatternDeclaration::visit (AST::TuplePattern &pattern)
auto &items = pattern.get_items ();
switch (items.get_pattern_type ())
{
- case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
+ case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE:
+ {
auto &ref = static_cast<AST::TuplePatternItemsMultiple &> (
pattern.get_items ());
@@ -169,7 +175,8 @@ PatternDeclaration::visit (AST::TuplePattern &pattern)
}
break;
- case AST::TuplePatternItems::TuplePatternItemType::RANGED: {
+ case AST::TuplePatternItems::TuplePatternItemType::RANGED:
+ {
auto &ref
= static_cast<AST::TuplePatternItemsRanged &> (pattern.get_items ());
@@ -348,14 +355,16 @@ resolve_range_pattern_bound (AST::RangePatternBound &bound)
// Nothing to resolve for a literal.
break;
- case AST::RangePatternBound::RangePatternBoundType::PATH: {
+ case AST::RangePatternBound::RangePatternBoundType::PATH:
+ {
auto &ref = static_cast<AST::RangePatternBoundPath &> (bound);
ResolvePath::go (ref.get_path ());
}
break;
- case AST::RangePatternBound::RangePatternBoundType::QUALPATH: {
+ case AST::RangePatternBound::RangePatternBoundType::QUALPATH:
+ {
auto &ref = static_cast<AST::RangePatternBoundQualPath &> (bound);
ResolvePath::go (ref.get_qualified_path ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index 8fd69c3..a040228 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -140,7 +140,7 @@ ResolveType::visit (AST::ImplTraitType &type)
void
ResolveType::visit (AST::ImplTraitTypeOneBound &type)
{
- ResolveTypeBound::go (type.get_trait_bound ());
+ ResolveTypeBound::go (*type.get_trait_bound ().get ());
}
// resolve relative type-paths
@@ -210,7 +210,8 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
switch (segment->get_type ())
{
- case AST::TypePathSegment::SegmentType::GENERIC: {
+ case AST::TypePathSegment::SegmentType::GENERIC:
+ {
AST::TypePathSegmentGeneric *s
= static_cast<AST::TypePathSegmentGeneric *> (segment.get ());
if (s->has_generic_args ())
@@ -509,7 +510,8 @@ ResolveTypeToCanonicalPath::visit (AST::TypePath &path)
auto &final_seg = path.get_segments ().back ();
switch (final_seg->get_type ())
{
- case AST::TypePathSegment::SegmentType::GENERIC: {
+ case AST::TypePathSegment::SegmentType::GENERIC:
+ {
AST::TypePathSegmentGeneric *s
= static_cast<AST::TypePathSegmentGeneric *> (final_seg.get ());
@@ -651,7 +653,8 @@ ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
switch (additional_bound->get_bound_type ())
{
- case AST::TypeParamBound::TRAIT: {
+ case AST::TypeParamBound::TRAIT:
+ {
auto bound_path = CanonicalPath::create_empty ();
auto &bound_type_path
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 3e3c992..2208f70 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -24,8 +24,7 @@
#include "rust-ast-resolve-expr.h"
#include "rust-ast-resolve-struct-expr-field.h"
-extern bool
-saw_errors (void);
+extern bool saw_errors (void);
namespace Rust {
namespace Resolver {
diff --git a/gcc/rust/resolve/rust-default-resolver.cc b/gcc/rust/resolve/rust-default-resolver.cc
index 480034c..01906cf 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -25,6 +25,21 @@ namespace Rust {
namespace Resolver2_0 {
void
+DefaultResolver::visit (AST::Crate &crate)
+{
+ auto inner_fn = [this, &crate] () { AST::DefaultASTVisitor::visit (crate); };
+
+ auto &mappings = Analysis::Mappings::get ();
+
+ auto crate_num = mappings.lookup_crate_num (crate.get_node_id ());
+ rust_assert (crate_num.has_value ());
+ auto crate_name = mappings.get_crate_name (*crate_num);
+ rust_assert (crate_name.has_value ());
+
+ ctx.canonical_ctx.scope_crate (crate.get_node_id (), *crate_name, inner_fn);
+}
+
+void
DefaultResolver::visit (AST::BlockExpr &expr)
{
// extracting the lambda from the `scoped` call otherwise the code looks like
@@ -38,19 +53,32 @@ DefaultResolver::visit (AST::BlockExpr &expr)
void
DefaultResolver::visit (AST::Module &module)
{
- auto item_fn = [this, &module] () { AST::DefaultASTVisitor::visit (module); };
+ auto item_fn_1
+ = [this, &module] () { AST::DefaultASTVisitor::visit (module); };
+
+ auto item_fn_2 = [this, &module, &item_fn_1] () {
+ ctx.canonical_ctx.scope (module.get_node_id (), module.get_name (),
+ std::move (item_fn_1));
+ };
- ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn,
+ ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn_2,
module.get_name ());
}
void
DefaultResolver::visit (AST::Function &function)
{
- auto def_fn
+ auto def_fn_1
= [this, &function] () { AST::DefaultASTVisitor::visit (function); };
- ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn);
+ auto def_fn_2 = [this, &function, &def_fn_1] () {
+ ctx.canonical_ctx.scope (function.get_node_id (),
+ function.get_function_name (),
+ std::move (def_fn_1));
+ };
+
+ ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn_2,
+ function.get_function_name ());
}
void
@@ -61,73 +89,227 @@ DefaultResolver::visit (AST::ForLoopExpr &expr)
}
void
+DefaultResolver::visit_if_let_patterns (AST::IfLetExpr &expr)
+{
+ for (auto &pattern : expr.get_patterns ())
+ visit (pattern);
+}
+
+void
+DefaultResolver::visit (AST::IfLetExpr &expr)
+{
+ auto inner_vis = [this, &expr] () {
+ visit_if_let_patterns (expr);
+ visit (expr.get_if_block ());
+ };
+
+ visit_outer_attrs (expr);
+
+ visit (expr.get_value_expr ());
+
+ ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_vis);
+}
+
+void
DefaultResolver::visit (AST::Trait &trait)
{
- auto inner_fn = [this, &trait] () { AST::DefaultASTVisitor::visit (trait); };
+ auto inner_fn_1
+ = [this, &trait] () { AST::DefaultASTVisitor::visit (trait); };
- ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn,
+ auto inner_fn_2 = [this, &trait, &inner_fn_1] () {
+ ctx.canonical_ctx.scope (trait.get_node_id (), trait.get_identifier (),
+ std::move (inner_fn_1));
+ };
+
+ ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn_2,
trait.get_identifier () /* FIXME: Is that valid?*/);
}
void
DefaultResolver::visit (AST::InherentImpl &impl)
{
- auto inner_fn = [this, &impl] () { AST::DefaultASTVisitor::visit (impl); };
-
- ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
+ visit_outer_attrs (impl);
+ visit (impl.get_visibility ());
+ visit_inner_attrs (impl);
+
+ auto inner_fn_1 = [this, &impl] () {
+ for (auto &item : impl.get_impl_items ())
+ visit (item);
+ };
+
+ auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
+ maybe_insert_big_self (impl);
+ for (auto &generic : impl.get_generic_params ())
+ visit (generic);
+ if (impl.has_where_clause ())
+ visit (impl.get_where_clause ());
+ visit_impl_type (impl.get_type ());
+
+ ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
+ };
+
+ auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
+ ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
+ };
+
+ ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
}
void
DefaultResolver::visit (AST::TraitImpl &impl)
{
- auto inner_fn = [this, &impl] () { AST::DefaultASTVisitor::visit (impl); };
-
- ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
+ visit_outer_attrs (impl);
+ visit (impl.get_visibility ());
+ visit_inner_attrs (impl);
+
+ auto inner_fn_1 = [this, &impl] () {
+ for (auto &item : impl.get_impl_items ())
+ visit (item);
+ };
+
+ auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
+ maybe_insert_big_self (impl);
+ for (auto &generic : impl.get_generic_params ())
+ visit (generic);
+ if (impl.has_where_clause ())
+ visit (impl.get_where_clause ());
+ visit_impl_type (impl.get_type ());
+ visit (impl.get_trait_path ());
+
+ ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
+ };
+
+ auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
+ ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
+ };
+
+ ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
}
void
DefaultResolver::visit (AST::StructStruct &type)
{
- auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+ auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+ auto inner_fn_2 = [this, &type, &inner_fn_1] () {
+ ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
+ std::move (inner_fn_1));
+ };
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
- inner_fn, type.get_struct_name ());
+ inner_fn_2, type.get_struct_name ());
}
void
DefaultResolver::visit (AST::TupleStruct &type)
{
- auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+ auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+ auto inner_fn_2 = [this, &type, &inner_fn_1] () {
+ ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
+ std::move (inner_fn_1));
+ };
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
- inner_fn, type.get_struct_name ());
+ inner_fn_2, type.get_struct_name ());
+}
+
+void
+DefaultResolver::visit (AST::EnumItem &item)
+{
+ auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
+
+ ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
+ inner_fn);
+}
+
+void
+DefaultResolver::visit (AST::EnumItemTuple &item)
+{
+ auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
+
+ ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
+ inner_fn);
+}
+
+void
+DefaultResolver::visit (AST::EnumItemStruct &item)
+{
+ auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
+
+ ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
+ inner_fn);
+}
+
+void
+DefaultResolver::visit (AST::EnumItemDiscriminant &item)
+{
+ auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
+
+ ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
+ inner_fn);
}
void
DefaultResolver::visit (AST::Enum &type)
{
- auto variant_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+ auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+ auto inner_fn_2 = [this, &type, &inner_fn_1] () {
+ ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
+ std::move (inner_fn_1));
+ };
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
- variant_fn, type.get_identifier ());
+ inner_fn_2, type.get_identifier ());
}
void
DefaultResolver::visit (AST::Union &type)
{
- auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+ auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+ auto inner_fn_2 = [this, &type, &inner_fn_1] () {
+ ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
+ std::move (inner_fn_1));
+ };
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
- inner_fn, type.get_identifier ());
+ inner_fn_2, type.get_identifier ());
}
void
DefaultResolver::visit (AST::TypeAlias &type)
{
- auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+ auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+ auto inner_fn_2 = [this, &type, &inner_fn_1] () {
+ ctx.canonical_ctx.scope (type.get_node_id (), type.get_new_type_name (),
+ std::move (inner_fn_1));
+ };
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
- inner_fn, type.get_new_type_name ());
+ inner_fn_2, type.get_new_type_name ());
+}
+
+void
+DefaultResolver::visit_closure_params (AST::ClosureExpr &expr)
+{
+ for (auto &param : expr.get_params ())
+ visit (param);
+}
+
+void
+DefaultResolver::visit (AST::ClosureExpr &expr)
+{
+ auto expr_fn = [this, &expr] () {
+ visit_closure_params (expr);
+ visit (expr.get_definition_expr ());
+ };
+
+ visit_outer_attrs (expr);
+
+ ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), expr_fn);
}
void
@@ -136,7 +318,7 @@ DefaultResolver::visit (AST::ClosureExprInner &expr)
if (expr.is_marked_for_strip ())
return;
- AST::DefaultASTVisitor::visit (expr);
+ visit (static_cast<AST::ClosureExpr &> (expr));
}
void
@@ -145,7 +327,8 @@ DefaultResolver::visit (AST::ClosureExprInnerTyped &expr)
if (expr.is_marked_for_strip ())
return;
- AST::DefaultASTVisitor::visit (expr);
+ visit (static_cast<AST::ClosureExpr &> (expr));
+ visit (expr.get_return_type ());
}
void
@@ -162,21 +345,31 @@ DefaultResolver::visit (AST::ConstantItem &item)
{
if (item.has_expr ())
{
- auto expr_vis
+ auto expr_vis_1
= [this, &item] () { AST::DefaultASTVisitor::visit (item); };
+ auto expr_vis_2 = [this, &item, &expr_vis_1] () {
+ ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
+ std::move (expr_vis_1));
+ };
+
// FIXME: Why do we need a Rib here?
- ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis);
+ ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
}
}
void
DefaultResolver::visit (AST::StaticItem &item)
{
- auto expr_vis = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
+ auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
+
+ auto expr_vis_2 = [this, &item, &expr_vis_1] () {
+ ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
+ std::move (expr_vis_1));
+ };
// FIXME: Why do we need a Rib here?
- ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis);
+ ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
}
void
diff --git a/gcc/rust/resolve/rust-default-resolver.h b/gcc/rust/resolve/rust-default-resolver.h
index 2a987ef..99fd8e7 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -39,6 +39,7 @@ public:
virtual ~DefaultResolver () {}
+ void visit (AST::Crate &) override;
// First, our lexical scope expressions - these visit their sub nodes, always
// these nodes create new scopes and ribs - they are often used to declare new
// variables, such as a for loop's iterator, or a function's arguments
@@ -46,7 +47,12 @@ public:
void visit (AST::Module &) override;
void visit (AST::Function &) override;
void visit (AST::ForLoopExpr &expr) override;
+ virtual void visit_if_let_patterns (AST::IfLetExpr &expr);
+ void visit (AST::IfLetExpr &expr) override;
void visit (AST::Trait &) override;
+ // used to handle Self insertion in TopLevel
+ virtual void maybe_insert_big_self (AST::Impl &) {}
+ virtual void visit_impl_type (AST::Type &type) { visit (type); }
void visit (AST::InherentImpl &) override;
void visit (AST::TraitImpl &) override;
@@ -55,11 +61,17 @@ public:
// type dec nodes, which visit their fields or variants by default
void visit (AST::StructStruct &) override;
void visit (AST::TupleStruct &) override;
+ void visit (AST::EnumItem &) override;
+ void visit (AST::EnumItemTuple &) override;
+ void visit (AST::EnumItemStruct &) override;
+ void visit (AST::EnumItemDiscriminant &) override;
void visit (AST::Enum &) override;
void visit (AST::Union &) override;
void visit (AST::TypeAlias &) override;
// Visitors that visit their expression node(s)
+ virtual void visit_closure_params (AST::ClosureExpr &);
+ virtual void visit (AST::ClosureExpr &);
void visit (AST::ClosureExprInner &) override;
void visit (AST::ClosureExprInnerTyped &) override;
void visit (AST::MatchExpr &) override;
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 3390f09..c10379a 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -62,8 +62,9 @@ Early::go (AST::Crate &crate)
// We now proceed with resolving macros, which can be nested in almost any
// items
textual_scope.push ();
- for (auto &item : crate.items)
- item->accept_vis (*this);
+
+ visit (crate);
+
textual_scope.pop ();
}
@@ -249,7 +250,7 @@ Early::visit (AST::Module &module)
void
Early::visit (AST::MacroInvocation &invoc)
{
- auto path = invoc.get_invoc_data ().get_path ();
+ auto &path = invoc.get_invoc_data ().get_path ();
if (invoc.get_kind () == AST::MacroInvocation::InvocKind::Builtin)
for (auto &pending_invoc : invoc.get_pending_eager_invocations ())
@@ -272,7 +273,7 @@ Early::visit (AST::MacroInvocation &invoc)
// we won't have changed `definition` from `nullopt` if there are more
// than one segments in our path
if (!definition.has_value ())
- definition = ctx.resolve_path (path.get_segments (), Namespace::Macros);
+ definition = ctx.resolve_path (path, Namespace::Macros);
// if the definition still does not have a value, then it's an error
if (!definition.has_value ())
@@ -314,8 +315,8 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
auto traits = attr.get_traits_to_derive ();
for (auto &trait : traits)
{
- auto definition = ctx.resolve_path (trait.get ().get_segments (),
- Namespace::Macros);
+ auto definition
+ = ctx.resolve_path (trait.get (), Namespace::Macros);
if (!definition.has_value ())
{
// FIXME: Change to proper error message
@@ -337,8 +338,8 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
->lookup_builtin (name)
.is_error ()) // Do not resolve builtins
{
- auto definition = ctx.resolve_path (attr.get_path ().get_segments (),
- Namespace::Macros);
+ auto definition
+ = ctx.resolve_path (attr.get_path (), Namespace::Macros);
if (!definition.has_value ())
{
// FIXME: Change to proper error message
@@ -350,7 +351,8 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
auto pm_def = mappings.lookup_attribute_proc_macro_def (
definition->get_node_id ());
- rust_assert (pm_def.has_value ());
+ if (!pm_def.has_value ())
+ return;
mappings.insert_attribute_proc_macro_invocation (attr.get_path (),
pm_def.value ());
@@ -419,7 +421,8 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
declared_name = rebind.get_identifier ().as_string ();
locus = rebind.get_identifier ().get_locus ();
break;
- case AST::UseTreeRebind::NewBindType::NONE: {
+ case AST::UseTreeRebind::NewBindType::NONE:
+ {
const auto &segments = path.get_segments ();
// We don't want to insert `self` with `use module::self`
if (path.get_final_segment ().is_lower_self_seg ())
diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h
index 81468e5..75dd873 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -543,6 +543,13 @@ private:
Node root;
};
+enum class ResolutionMode
+{
+ Normal,
+ FromRoot,
+ FromExtern, // extern prelude
+};
+
template <Namespace N> class ForeverStack
{
public:
@@ -672,14 +679,11 @@ public:
*/
template <typename S>
tl::optional<Rib::Definition> resolve_path (
- const std::vector<S> &segments, bool has_opening_scope_resolution,
+ const std::vector<S> &segments, ResolutionMode mode,
std::function<void (const S &, NodeId)> insert_segment_resolution,
std::vector<Error> &collect_errors);
// FIXME: Documentation
- tl::optional<Resolver::CanonicalPath> to_canonical_path (NodeId id) const;
-
- // FIXME: Documentation
tl::optional<Rib &> to_rib (NodeId rib_id);
tl::optional<const Rib &> to_rib (NodeId rib_id) const;
@@ -739,6 +743,9 @@ private:
tl::optional<Node &> parent; // `None` only if the node is a root
};
+ // private overload which allows specifying a starting point
+ tl::optional<Rib::Definition> get (Node &start, const Identifier &name);
+
/* Should we keep going upon seeing a Rib? */
enum class KeepGoing
{
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index 069111ee..8721386 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -291,12 +291,12 @@ ForeverStack<N>::update_cursor (Node &new_cursor)
template <Namespace N>
tl::optional<Rib::Definition>
-ForeverStack<N>::get (const Identifier &name)
+ForeverStack<N>::get (Node &start, const Identifier &name)
{
tl::optional<Rib::Definition> resolved_definition = tl::nullopt;
// TODO: Can we improve the API? have `reverse_iter` return an optional?
- reverse_iter ([&resolved_definition, &name] (Node &current) {
+ reverse_iter (start, [&resolved_definition, &name] (Node &current) {
auto candidate = current.rib.get (name.as_string ());
return candidate.map_or (
@@ -320,6 +320,13 @@ ForeverStack<N>::get (const Identifier &name)
template <Namespace N>
tl::optional<Rib::Definition>
+ForeverStack<N>::get (const Identifier &name)
+{
+ return get (cursor (), name);
+}
+
+template <Namespace N>
+tl::optional<Rib::Definition>
ForeverStack<N>::get_lang_prelude (const Identifier &name)
{
return lang_prelude.rib.get (name.as_string ());
@@ -625,88 +632,118 @@ template <Namespace N>
template <typename S>
tl::optional<Rib::Definition>
ForeverStack<N>::resolve_path (
- const std::vector<S> &segments, bool has_opening_scope_resolution,
+ const std::vector<S> &segments, ResolutionMode mode,
std::function<void (const S &, NodeId)> insert_segment_resolution,
std::vector<Error> &collect_errors)
{
- // TODO: What to do if segments.empty() ?
+ rust_assert (!segments.empty ());
- // handle paths with opening scopes
- std::function<void (void)> cleanup_current = [] () {};
- if (has_opening_scope_resolution)
+ std::reference_wrapper<Node> starting_point = cursor ();
+ switch (mode)
{
- Node *last_current = &cursor_reference.get ();
- if (get_rust_edition () == Edition::E2015)
- cursor_reference = root;
- else
- cursor_reference = extern_prelude;
- cleanup_current
- = [this, last_current] () { cursor_reference = *last_current; };
+ case ResolutionMode::Normal:
+ break; // default
+ case ResolutionMode::FromRoot:
+ starting_point = root;
+ break;
+ case ResolutionMode::FromExtern:
+ starting_point = extern_prelude;
+ break;
+ default:
+ rust_unreachable ();
}
// if there's only one segment, we just use `get`
if (segments.size () == 1)
{
- auto &seg = segments.front ();
- if (auto lang_item = unwrap_segment_get_lang_item (seg))
+ auto &outer_seg = segments.front ();
+ if (auto lang_item = unwrap_segment_get_lang_item (outer_seg))
{
NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node (
lang_item.value ());
- insert_segment_resolution (seg, seg_id);
- cleanup_current ();
+ insert_segment_resolution (outer_seg, seg_id);
// TODO: does NonShadowable matter?
return Rib::Definition::NonShadowable (seg_id);
}
+ auto &seg = unwrap_type_segment (outer_seg);
+
tl::optional<Rib::Definition> res
- = get (unwrap_type_segment (segments.back ()).as_string ());
+ = get (starting_point.get (), seg.as_string ());
if (!res)
- res = get_lang_prelude (
- unwrap_type_segment (segments.back ()).as_string ());
+ res = get_lang_prelude (seg.as_string ());
+
+ if (!res && N == Namespace::Types)
+ {
+ if (seg.is_crate_path_seg ())
+ {
+ insert_segment_resolution (outer_seg, root.id);
+ // TODO: does NonShadowable matter?
+ return Rib::Definition::NonShadowable (root.id);
+ }
+ else if (seg.is_lower_self_seg ())
+ {
+ NodeId id = find_closest_module (starting_point.get ()).id;
+ insert_segment_resolution (outer_seg, id);
+ // TODO: does NonShadowable matter?
+ return Rib::Definition::NonShadowable (id);
+ }
+ else if (seg.is_super_path_seg ())
+ {
+ Node &closest_module
+ = find_closest_module (starting_point.get ());
+ if (closest_module.is_root ())
+ {
+ rust_error_at (seg.get_locus (), ErrorCode::E0433,
+ "too many leading %<super%> keywords");
+ return tl::nullopt;
+ }
+
+ NodeId id
+ = find_closest_module (closest_module.parent.value ()).id;
+ insert_segment_resolution (outer_seg, id);
+ // TODO: does NonShadowable matter?
+ return Rib::Definition::NonShadowable (id);
+ }
+ }
if (res && !res->is_ambiguous ())
- insert_segment_resolution (segments.back (), res->get_node_id ());
- cleanup_current ();
+ insert_segment_resolution (outer_seg, res->get_node_id ());
return res;
}
- std::reference_wrapper<Node> starting_point = cursor ();
+ return find_starting_point (segments, starting_point,
+ insert_segment_resolution, collect_errors)
+ .and_then (
+ [this, &segments, &starting_point, &insert_segment_resolution,
+ &collect_errors] (typename std::vector<S>::const_iterator iterator) {
+ return resolve_segments (starting_point.get (), segments, iterator,
+ insert_segment_resolution, collect_errors);
+ })
+ .and_then ([this, &segments, &insert_segment_resolution] (
+ Node &final_node) -> tl::optional<Rib::Definition> {
+ // leave resolution within impl blocks to type checker
+ if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
+ return tl::nullopt;
- auto res
- = find_starting_point (segments, starting_point, insert_segment_resolution,
- collect_errors)
- .and_then (
- [this, &segments, &starting_point, &insert_segment_resolution,
- &collect_errors] (typename std::vector<S>::const_iterator iterator) {
- return resolve_segments (starting_point.get (), segments, iterator,
- insert_segment_resolution, collect_errors);
- })
- .and_then ([this, &segments, &insert_segment_resolution] (
- Node &final_node) -> tl::optional<Rib::Definition> {
- // leave resolution within impl blocks to type checker
- if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
- return tl::nullopt;
-
- auto &seg = unwrap_type_segment (segments.back ());
- std::string seg_name = seg.as_string ();
-
- // assuming this can't be a lang item segment
- tl::optional<Rib::Definition> res
- = resolve_final_segment (final_node, seg_name,
- seg.is_lower_self_seg ());
- // Ok we didn't find it in the rib, Lets try the prelude...
- if (!res)
- res = get_lang_prelude (seg_name);
-
- if (res && !res->is_ambiguous ())
- insert_segment_resolution (segments.back (), res->get_node_id ());
-
- return res;
- });
- cleanup_current ();
- return res;
+ auto &seg = unwrap_type_segment (segments.back ());
+ std::string seg_name = seg.as_string ();
+
+ // assuming this can't be a lang item segment
+ tl::optional<Rib::Definition> res
+ = resolve_final_segment (final_node, seg_name,
+ seg.is_lower_self_seg ());
+ // Ok we didn't find it in the rib, Lets try the prelude...
+ if (!res)
+ res = get_lang_prelude (seg_name);
+
+ if (res && !res->is_ambiguous ())
+ insert_segment_resolution (segments.back (), res->get_node_id ());
+
+ return res;
+ });
}
template <Namespace N>
@@ -771,67 +808,6 @@ ForeverStack<N>::dfs (const ForeverStack<N>::Node &starting_point,
}
template <Namespace N>
-tl::optional<Resolver::CanonicalPath>
-ForeverStack<N>::to_canonical_path (NodeId id) const
-{
- // find the id in the current forever stack, starting from the root,
- // performing either a BFS or DFS once the Node containing the ID is found, go
- // back up to the root (parent().parent().parent()...) accumulate link
- // segments reverse them that's your canonical path
-
- return dfs (root, id).map ([this, id] (ConstDfsResult tuple) {
- auto containing_node = tuple.first;
- auto name = tuple.second;
-
- auto segments = std::vector<Resolver::CanonicalPath> ();
-
- reverse_iter (containing_node, [&segments] (const Node &current) {
- if (current.is_root ())
- return KeepGoing::No;
-
- auto children = current.parent.value ().children;
- const Link *outer_link = nullptr;
-
- for (auto &kv : children)
- {
- auto &link = kv.first;
- auto &child = kv.second;
-
- if (current.id == child.id)
- {
- outer_link = &link;
- break;
- }
- }
-
- rust_assert (outer_link);
-
- outer_link->path.map ([&segments, outer_link] (Identifier path) {
- segments.emplace (segments.begin (),
- Resolver::CanonicalPath::new_seg (outer_link->id,
- path.as_string ()));
- });
-
- return KeepGoing::Yes;
- });
-
- auto &mappings = Analysis::Mappings::get ();
- CrateNum crate_num = mappings.lookup_crate_num (root.id).value ();
- auto path = Resolver::CanonicalPath::new_seg (
- root.id, mappings.get_crate_name (crate_num).value ());
- path.set_crate_num (crate_num);
-
- for (const auto &segment : segments)
- path = path.append (segment);
-
- // Finally, append the name
- path = path.append (Resolver::CanonicalPath::new_seg (id, name));
-
- return path;
- });
-}
-
-template <Namespace N>
tl::optional<Rib &>
ForeverStack<N>::dfs_rib (ForeverStack<N>::Node &starting_point, NodeId to_find)
{
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index a15e17f..62829e0 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -33,7 +33,9 @@
namespace Rust {
namespace Resolver2_0 {
-Late::Late (NameResolutionContext &ctx) : DefaultResolver (ctx) {}
+Late::Late (NameResolutionContext &ctx)
+ : DefaultResolver (ctx), funny_error (false), block_big_self (false)
+{}
static NodeId
next_node_id ()
@@ -114,8 +116,7 @@ Late::go (AST::Crate &crate)
{
setup_builtin_types ();
- for (auto &item : crate.items)
- item->accept_vis (*this);
+ visit (crate);
}
void
@@ -145,19 +146,13 @@ Late::visit (AST::ForLoopExpr &expr)
}
void
-Late::visit (AST::IfLetExpr &expr)
+Late::visit_if_let_patterns (AST::IfLetExpr &expr)
{
- visit_outer_attrs (expr);
+ ctx.bindings.enter (BindingSource::IfLet);
- ctx.bindings.enter (BindingSource::Let);
-
- for (auto &pattern : expr.get_patterns ())
- visit (pattern);
+ DefaultResolver::visit_if_let_patterns (expr);
ctx.bindings.exit ();
-
- visit (expr.get_value_expr ());
- visit (expr.get_if_block ());
}
void
@@ -213,46 +208,55 @@ Late::visit (AST::LetStmt &let)
// let.get_node_id (), [] () {});
}
-void
-Late::visit (AST::IdentifierPattern &identifier)
+static void
+visit_identifier_as_pattern (NameResolutionContext &ctx,
+ const Identifier &ident, location_t locus,
+ NodeId node_id)
{
// do we insert in labels or in values
// but values does not allow shadowing... since functions cannot shadow
// do we insert functions in labels as well?
- if (ctx.bindings.peek ().is_and_bound (identifier.get_ident ()))
+ if (ctx.bindings.peek ().is_and_bound (ident))
{
if (ctx.bindings.peek ().get_source () == BindingSource::Param)
rust_error_at (
- identifier.get_locus (), ErrorCode::E0415,
+ locus, ErrorCode::E0415,
"identifier %qs is bound more than once in the same parameter list",
- identifier.as_string ().c_str ());
+ ident.as_string ().c_str ());
else
rust_error_at (
- identifier.get_locus (), ErrorCode::E0416,
+ locus, ErrorCode::E0416,
"identifier %qs is bound more than once in the same pattern",
- identifier.as_string ().c_str ());
+ ident.as_string ().c_str ());
return;
}
- ctx.bindings.peek ().insert_ident (identifier.get_ident ());
+ ctx.bindings.peek ().insert_ident (ident);
- if (ctx.bindings.peek ().is_or_bound (identifier.get_ident ()))
+ if (ctx.bindings.peek ().is_or_bound (ident))
{
- // FIXME: map usage instead
- std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
- identifier.get_node_id ());
+ auto res = ctx.values.get (ident);
+ rust_assert (res.has_value () && !res->is_ambiguous ());
+ ctx.map_usage (Usage (node_id), Definition (res->get_node_id ()));
}
else
{
// We do want to ignore duplicated data because some situations rely on
// it.
- std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
- identifier.get_node_id ());
+ std::ignore = ctx.values.insert_shadowable (ident, node_id);
}
}
void
+Late::visit (AST::IdentifierPattern &identifier)
+{
+ visit_identifier_as_pattern (ctx, identifier.get_ident (),
+ identifier.get_locus (),
+ identifier.get_node_id ());
+}
+
+void
Late::visit (AST::AltPattern &pattern)
{
ctx.bindings.peek ().push (Binding::Kind::Or);
@@ -279,9 +283,8 @@ Late::visit_function_params (AST::Function &function)
void
Late::visit (AST::StructPatternFieldIdent &field)
{
- // We do want to ignore duplicated data because some situations rely on it.
- std::ignore = ctx.values.insert_shadowable (field.get_identifier (),
- field.get_node_id ());
+ visit_identifier_as_pattern (ctx, field.get_identifier (), field.get_locus (),
+ field.get_node_id ());
}
void
@@ -375,7 +378,8 @@ Late::visit (AST::IdentifierExpr &expr)
}
else if (funny_error)
{
- diagnostics::text_finalizer (global_dc) = Resolver::funny_ice_text_finalizer;
+ diagnostics::text_finalizer (global_dc)
+ = Resolver::funny_ice_text_finalizer;
emit_diagnostic (diagnostics::kind::ice_nobt, expr.get_locus (), -1,
"are you trying to break %s? how dare you?",
expr.as_string ().c_str ());
@@ -477,6 +481,16 @@ Late::visit (AST::PathInExpression &expr)
}
void
+Late::visit_impl_type (AST::Type &type)
+{
+ // TODO: does this have to handle reentrancy?
+ rust_assert (!block_big_self);
+ block_big_self = true;
+ visit (type);
+ block_big_self = false;
+}
+
+void
Late::visit (AST::TypePath &type)
{
// should we add type path resolution in `ForeverStack` directly? Since it's
@@ -486,6 +500,16 @@ Late::visit (AST::TypePath &type)
DefaultResolver::visit (type);
+ // prevent "impl Self {}" and similar
+ if (type.get_segments ().size () == 1
+ && !type.get_segments ().front ()->is_lang_item ()
+ && type.get_segments ().front ()->is_big_self_seg () && block_big_self)
+ {
+ rust_error_at (type.get_locus (),
+ "%<Self%> is not valid in the self type of an impl block");
+ return;
+ }
+
// this *should* mostly work
// TODO: make sure typepath-like path resolution (?) is working
auto resolved = ctx.resolve_path (type, Namespace::Types);
@@ -493,15 +517,16 @@ Late::visit (AST::TypePath &type)
if (!resolved.has_value ())
{
if (!ctx.lookup (type.get_segments ().front ()->get_node_id ()))
- rust_error_at (type.get_locus (), "could not resolve type path %qs",
- type.as_string ().c_str ());
+ rust_error_at (type.get_locus (), ErrorCode::E0412,
+ "could not resolve type path %qs",
+ type.make_debug_string ().c_str ());
return;
}
if (resolved->is_ambiguous ())
{
rust_error_at (type.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
- type.as_string ().c_str ());
+ type.make_debug_string ().c_str ());
return;
}
@@ -518,6 +543,62 @@ Late::visit (AST::TypePath &type)
}
void
+Late::visit (AST::Visibility &vis)
+{
+ if (!vis.has_path ())
+ return;
+
+ AST::SimplePath &path = vis.get_path ();
+
+ rust_assert (path.get_segments ().size ());
+ auto &first_seg = path.get_segments ()[0];
+
+ auto mode = ResolutionMode::Normal;
+
+ if (path.has_opening_scope_resolution ())
+ {
+ if (get_rust_edition () == Edition::E2015)
+ mode = ResolutionMode::FromRoot;
+ else
+ mode = ResolutionMode::FromExtern;
+ }
+ else if (!first_seg.is_crate_path_seg () && !first_seg.is_super_path_seg ()
+ && !first_seg.is_lower_self_seg ())
+ {
+ if (get_rust_edition () == Edition::E2015)
+ {
+ mode = ResolutionMode::FromRoot;
+ }
+ else
+ {
+ rust_error_at (path.get_locus (),
+ "relative paths are not supported in visibilities in "
+ "2018 edition or later");
+ return;
+ }
+ }
+
+ auto res = ctx.resolve_path (path.get_segments (), mode, Namespace::Types);
+
+ if (!res.has_value ())
+ {
+ rust_error_at (path.get_locus (), ErrorCode::E0433,
+ "could not resolve path %qs", path.as_string ().c_str ());
+ return;
+ }
+
+ // TODO: is this possible?
+ if (res->is_ambiguous ())
+ {
+ rust_error_at (path.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
+ path.as_string ().c_str ());
+ return;
+ }
+
+ ctx.map_usage (Usage (path.get_node_id ()), Definition (res->get_node_id ()));
+}
+
+void
Late::visit (AST::Trait &trait)
{
// kind of weird how this is done
@@ -613,51 +694,27 @@ Late::visit (AST::GenericArg &arg)
DefaultResolver::visit (arg);
}
-template <class Closure>
-static void
-add_captures (Closure &closure, NameResolutionContext &ctx)
-{
- auto vals = ctx.values.peek ().get_values ();
- for (auto &val : vals)
- {
- ctx.mappings.add_capture (closure.get_node_id (),
- val.second.get_node_id ());
- }
-}
-
void
-Late::visit (AST::ClosureExprInner &closure)
+Late::visit_closure_params (AST::ClosureExpr &closure)
{
- add_captures (closure, ctx);
-
- visit_outer_attrs (closure);
-
ctx.bindings.enter (BindingSource::Param);
- for (auto &param : closure.get_params ())
- visit (param);
+ DefaultResolver::visit_closure_params (closure);
ctx.bindings.exit ();
-
- visit (closure.get_definition_expr ());
}
void
-Late::visit (AST::ClosureExprInnerTyped &closure)
+Late::visit (AST::ClosureExpr &expr)
{
- add_captures (closure, ctx);
-
- visit_outer_attrs (closure);
-
- ctx.bindings.enter (BindingSource::Param);
-
- for (auto &param : closure.get_params ())
- visit (param);
-
- ctx.bindings.exit ();
+ // add captures
+ auto vals = ctx.values.peek ().get_values ();
+ for (auto &val : vals)
+ {
+ ctx.mappings.add_capture (expr.get_node_id (), val.second.get_node_id ());
+ }
- visit (closure.get_return_type ());
- visit (closure.get_definition_block ());
+ DefaultResolver::visit (expr);
}
} // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 171d9bf..f2907c9 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -50,7 +50,7 @@ public:
void visit (AST::SelfParam &) override;
void visit (AST::MatchArm &) override;
void visit (AST::ForLoopExpr &) override;
- void visit (AST::IfLetExpr &) override;
+ void visit_if_let_patterns (AST::IfLetExpr &) override;
// resolutions
void visit (AST::IdentifierExpr &) override;
@@ -59,7 +59,9 @@ public:
void visit (AST::ContinueExpr &) override;
void visit (AST::LoopLabel &) override;
void visit (AST::PathInExpression &) override;
+ void visit_impl_type (AST::Type &) override;
void visit (AST::TypePath &) override;
+ void visit (AST::Visibility &) override;
void visit (AST::Trait &) override;
void visit (AST::StructExprStruct &) override;
void visit (AST::StructExprStructBase &) override;
@@ -67,8 +69,8 @@ public:
void visit (AST::StructStruct &) override;
void visit (AST::GenericArgs &) override;
void visit (AST::GenericArg &);
- void visit (AST::ClosureExprInner &) override;
- void visit (AST::ClosureExprInnerTyped &) override;
+ void visit_closure_params (AST::ClosureExpr &) override;
+ void visit (AST::ClosureExpr &) override;
private:
void resolve_label (AST::Lifetime &lifetime);
@@ -77,6 +79,9 @@ private:
void setup_builtin_types ();
bool funny_error;
+
+ /* used to prevent "impl Self {}", "impl (Self, i32) {}", etc */
+ bool block_big_self;
};
// TODO: Add missing mappings and data structures
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc b/gcc/rust/resolve/rust-name-resolution-context.cc
index f098e48..34615ed 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -82,8 +82,63 @@ BindingLayer::get_source () const
return source;
}
+Resolver::CanonicalPath
+CanonicalPathRecordCrateRoot::as_path (const NameResolutionContext &)
+{
+ auto ret = Resolver::CanonicalPath::new_seg (node_id, seg);
+ ret.set_crate_num (crate_num);
+ return ret;
+}
+
+Resolver::CanonicalPath
+CanonicalPathRecordNormal::as_path (const NameResolutionContext &ctx)
+{
+ auto parent_path = get_parent ().as_path (ctx);
+ return parent_path.append (Resolver::CanonicalPath::new_seg (node_id, seg));
+}
+
+Resolver::CanonicalPath
+CanonicalPathRecordLookup::as_path (const NameResolutionContext &ctx)
+{
+ if (!cache)
+ {
+ auto res = ctx.lookup (lookup_id).and_then (
+ [&ctx] (NodeId id) { return ctx.canonical_ctx.get_record_opt (id); });
+
+ if (!res)
+ {
+ // HACK: use a dummy value
+ // this should bring us roughly to parity with nr1.0
+ // since nr1.0 doesn't seem to handle canonical paths for generics
+ // quite right anyways
+ return Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "XXX");
+ }
+
+ cache = res.value ();
+ }
+ return cache->as_path (ctx);
+}
+
+Resolver::CanonicalPath
+CanonicalPathRecordImpl::as_path (const NameResolutionContext &ctx)
+{
+ auto parent_path = get_parent ().as_path (ctx);
+ return parent_path.append (
+ Resolver::CanonicalPath::inherent_impl_seg (impl_id,
+ type_record.as_path (ctx)));
+}
+
+Resolver::CanonicalPath
+CanonicalPathRecordTraitImpl::as_path (const NameResolutionContext &ctx)
+{
+ auto parent_path = get_parent ().as_path (ctx);
+ return parent_path.append (
+ Resolver::CanonicalPath::trait_impl_projection_seg (
+ impl_id, trait_path_record.as_path (ctx), type_record.as_path (ctx)));
+}
+
NameResolutionContext::NameResolutionContext ()
- : mappings (Analysis::Mappings::get ())
+ : mappings (Analysis::Mappings::get ()), canonical_ctx (*this)
{}
tl::expected<NodeId, DuplicateNameError>
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index 19ba750..bb8519a 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -24,6 +24,7 @@
#include "rust-hir-map.h"
#include "rust-rib.h"
#include "rust-stacked-contexts.h"
+#include "rust-item.h"
namespace Rust {
namespace Resolver2_0 {
@@ -177,6 +178,7 @@ enum class BindingSource
{
Match,
Let,
+ IfLet,
For,
/* Closure param or function param */
Param
@@ -213,6 +215,248 @@ public:
BindingSource get_source () const;
};
+class NameResolutionContext;
+/*
+ * Used to handle canonical paths
+ * Similar to ForeverStack, but namespace independent and more specialized
+ */
+class CanonicalPathRecord
+{
+public:
+ virtual Resolver::CanonicalPath as_path (const NameResolutionContext &) = 0;
+
+ virtual bool is_root () const = 0;
+
+ virtual ~CanonicalPathRecord () = default;
+};
+
+class CanonicalPathRecordWithParent : public CanonicalPathRecord
+{
+public:
+ CanonicalPathRecordWithParent (CanonicalPathRecord &parent) : parent (&parent)
+ {}
+
+ CanonicalPathRecord &get_parent () { return *parent; }
+
+ bool is_root () const override final { return false; }
+
+private:
+ CanonicalPathRecord *parent;
+};
+
+class CanonicalPathRecordCrateRoot : public CanonicalPathRecord
+{
+public:
+ CanonicalPathRecordCrateRoot (NodeId node_id, std::string seg)
+ : node_id (node_id), seg (std::move (seg))
+ {
+ rust_assert (Analysis::Mappings::get ().node_is_crate (node_id));
+ crate_num = Analysis::Mappings::get ().lookup_crate_num (node_id).value ();
+ }
+
+ Resolver::CanonicalPath as_path (const NameResolutionContext &) override;
+
+ bool is_root () const override final { return true; }
+
+private:
+ NodeId node_id;
+ CrateNum crate_num;
+ std::string seg;
+};
+
+class CanonicalPathRecordNormal : public CanonicalPathRecordWithParent
+{
+public:
+ CanonicalPathRecordNormal (CanonicalPathRecord &parent, NodeId node_id,
+ std::string seg)
+ : CanonicalPathRecordWithParent (parent), node_id (node_id),
+ seg (std::move (seg))
+ {
+ rust_assert (!Analysis::Mappings::get ().node_is_crate (node_id));
+ }
+
+ Resolver::CanonicalPath as_path (const NameResolutionContext &) override;
+
+private:
+ NodeId node_id;
+ std::string seg;
+};
+
+class CanonicalPathRecordLookup : public CanonicalPathRecord
+{
+public:
+ CanonicalPathRecordLookup (NodeId lookup_id)
+ : lookup_id (lookup_id), cache (nullptr)
+ {}
+
+ Resolver::CanonicalPath as_path (const NameResolutionContext &) override;
+
+ bool is_root () const override final { return true; }
+
+private:
+ NodeId lookup_id;
+ CanonicalPathRecord *cache;
+};
+
+class CanonicalPathRecordImpl : public CanonicalPathRecordWithParent
+{
+public:
+ CanonicalPathRecordImpl (CanonicalPathRecord &parent, NodeId impl_id,
+ NodeId type_id)
+ : CanonicalPathRecordWithParent (parent), impl_id (impl_id),
+ type_record (type_id)
+ {}
+
+ Resolver::CanonicalPath as_path (const NameResolutionContext &) override;
+
+private:
+ NodeId impl_id;
+ CanonicalPathRecordLookup type_record;
+};
+
+class CanonicalPathRecordTraitImpl : public CanonicalPathRecordWithParent
+{
+public:
+ CanonicalPathRecordTraitImpl (CanonicalPathRecord &parent, NodeId impl_id,
+ NodeId type_id, NodeId trait_path_id)
+ : CanonicalPathRecordWithParent (parent), impl_id (impl_id),
+ type_record (type_id), trait_path_record (trait_path_id)
+ {}
+
+ Resolver::CanonicalPath as_path (const NameResolutionContext &) override;
+
+private:
+ NodeId impl_id;
+ CanonicalPathRecordLookup type_record;
+ CanonicalPathRecordLookup trait_path_record;
+};
+
+class CanonicalPathCtx
+{
+public:
+ CanonicalPathCtx (const NameResolutionContext &ctx)
+ : current_record (nullptr), nr_ctx (&ctx)
+ {}
+
+ Resolver::CanonicalPath get_path (NodeId id) const
+ {
+ return get_record (id).as_path (*nr_ctx);
+ }
+
+ CanonicalPathRecord &get_record (NodeId id) const
+ {
+ auto it = records.find (id);
+ rust_assert (it != records.end ());
+ return *it->second;
+ }
+
+ tl::optional<CanonicalPathRecord *> get_record_opt (NodeId id) const
+ {
+ auto it = records.find (id);
+ if (it == records.end ())
+ return tl::nullopt;
+ else
+ return it->second.get ();
+ }
+
+ void insert_record (NodeId id, const Identifier &ident)
+ {
+ insert_record (id, ident.as_string ());
+ }
+
+ void insert_record (NodeId id, std::string seg)
+ {
+ rust_assert (current_record != nullptr);
+
+ auto it = records.find (id);
+ if (it == records.end ())
+ {
+ auto record = new CanonicalPathRecordNormal (*current_record, id,
+ std::move (seg));
+ bool ok
+ = records.emplace (id, std::unique_ptr<CanonicalPathRecord> (record))
+ .second;
+ rust_assert (ok);
+ }
+ }
+
+ template <typename F> void scope (NodeId id, const Identifier &ident, F &&f)
+ {
+ scope (id, ident.as_string (), std::forward<F> (f));
+ }
+
+ template <typename F> void scope (NodeId id, std::string seg, F &&f)
+ {
+ rust_assert (current_record != nullptr);
+
+ scope_inner (id, std::forward<F> (f), [this, id, &seg] () {
+ return new CanonicalPathRecordNormal (*current_record, id,
+ std::move (seg));
+ });
+ }
+
+ template <typename F> void scope_impl (AST::InherentImpl &impl, F &&f)
+ {
+ rust_assert (current_record != nullptr);
+
+ NodeId id = impl.get_node_id ();
+ scope_inner (id, std::forward<F> (f), [this, id, &impl] () {
+ return new CanonicalPathRecordImpl (*current_record, id,
+ impl.get_type ().get_node_id ());
+ });
+ }
+
+ template <typename F> void scope_impl (AST::TraitImpl &impl, F &&f)
+ {
+ rust_assert (current_record != nullptr);
+
+ NodeId id = impl.get_node_id ();
+ scope_inner (id, std::forward<F> (f), [this, id, &impl] () {
+ return new CanonicalPathRecordTraitImpl (
+ *current_record, id, impl.get_type ().get_node_id (),
+ impl.get_trait_path ().get_node_id ());
+ });
+ }
+
+ template <typename F>
+ void scope_crate (NodeId node_id, std::string crate_name, F &&f)
+ {
+ scope_inner (node_id, std::forward<F> (f), [node_id, &crate_name] () {
+ return new CanonicalPathRecordCrateRoot (node_id, std::move (crate_name));
+ });
+ }
+
+private:
+ template <typename FCreate, typename FCallback>
+ void scope_inner (NodeId id, FCallback &&f_callback, FCreate &&f_create)
+ {
+ auto it = records.find (id);
+ if (it == records.end ())
+ {
+ CanonicalPathRecord *record = std::forward<FCreate> (f_create) ();
+ it = records.emplace (id, std::unique_ptr<CanonicalPathRecord> (record))
+ .first;
+ }
+
+ rust_assert (it->second->is_root ()
+ || &static_cast<CanonicalPathRecordWithParent &> (*it->second)
+ .get_parent ()
+ == current_record);
+
+ CanonicalPathRecord *stash = it->second.get ();
+ std::swap (stash, current_record);
+
+ std::forward<FCallback> (f_callback) ();
+
+ std::swap (stash, current_record);
+ }
+
+ std::unordered_map<NodeId, std::unique_ptr<CanonicalPathRecord>> records;
+ CanonicalPathRecord *current_record;
+
+ const NameResolutionContext *nr_ctx;
+};
+
// Now our resolver, which keeps track of all the `ForeverStack`s we could want
class NameResolutionContext
{
@@ -271,16 +515,22 @@ public:
Analysis::Mappings &mappings;
StackedContexts<BindingLayer> bindings;
+ CanonicalPathCtx canonical_ctx;
+
// TODO: Rename
// TODO: Use newtype pattern for Usage and Definition
void map_usage (Usage usage, Definition definition);
tl::optional<NodeId> lookup (NodeId usage) const;
+ Resolver::CanonicalPath to_canonical_path (NodeId id) const
+ {
+ return canonical_ctx.get_path (id);
+ }
+
template <typename S>
tl::optional<Rib::Definition>
- resolve_path (const std::vector<S> &segments,
- bool has_opening_scope_resolution,
+ resolve_path (const std::vector<S> &segments, ResolutionMode mode,
std::vector<Error> &collect_errors, Namespace ns)
{
std::function<void (const S &, NodeId)> insert_segment_resolution
@@ -292,17 +542,17 @@ public:
switch (ns)
{
case Namespace::Values:
- return values.resolve_path (segments, has_opening_scope_resolution,
- insert_segment_resolution, collect_errors);
+ return values.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
case Namespace::Types:
- return types.resolve_path (segments, has_opening_scope_resolution,
- insert_segment_resolution, collect_errors);
+ return types.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
case Namespace::Macros:
- return macros.resolve_path (segments, has_opening_scope_resolution,
- insert_segment_resolution, collect_errors);
+ return macros.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
case Namespace::Labels:
- return labels.resolve_path (segments, has_opening_scope_resolution,
- insert_segment_resolution, collect_errors);
+ return labels.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
default:
rust_unreachable ();
}
@@ -310,8 +560,7 @@ public:
template <typename S, typename... Args>
tl::optional<Rib::Definition>
- resolve_path (const std::vector<S> &segments,
- bool has_opening_scope_resolution,
+ resolve_path (const std::vector<S> &segments, ResolutionMode mode,
tl::optional<std::vector<Error> &> collect_errors,
Namespace ns_first, Args... ns_args)
{
@@ -320,8 +569,7 @@ public:
for (auto ns : namespaces)
{
std::vector<Error> collect_errors_inner;
- if (auto ret = resolve_path (segments, has_opening_scope_resolution,
- collect_errors_inner, ns))
+ if (auto ret = resolve_path (segments, mode, collect_errors_inner, ns))
return ret;
if (!collect_errors_inner.empty ())
{
@@ -343,52 +591,68 @@ public:
return tl::nullopt;
}
- template <typename... Args>
+ template <typename S, typename... Args>
tl::optional<Rib::Definition>
- resolve_path (const AST::SimplePath &path,
+ resolve_path (const std::vector<S> &path_segments,
+ bool has_opening_scope_resolution,
tl::optional<std::vector<Error> &> collect_errors,
Namespace ns_first, Args... ns_args)
{
- return resolve_path (path.get_segments (),
- path.has_opening_scope_resolution (), collect_errors,
- ns_first, ns_args...);
+ auto mode = ResolutionMode::Normal;
+ if (has_opening_scope_resolution)
+ {
+ if (get_rust_edition () == Edition::E2015)
+ mode = ResolutionMode::FromRoot;
+ else
+ mode = ResolutionMode::FromExtern;
+ }
+ return resolve_path (path_segments, mode, collect_errors, ns_first,
+ ns_args...);
}
- template <typename... Args>
+ template <typename S, typename... Args>
tl::optional<Rib::Definition>
- resolve_path (const AST::PathInExpression &path,
- tl::optional<std::vector<Error> &> collect_errors,
- Namespace ns_first, Args... ns_args)
+ resolve_path (const std::vector<S> &path_segments,
+ bool has_opening_scope_resolution, Namespace ns_first,
+ Args... ns_args)
{
- return resolve_path (path.get_segments (), path.opening_scope_resolution (),
- collect_errors, ns_first, ns_args...);
+ return resolve_path (path_segments, has_opening_scope_resolution,
+ tl::nullopt, ns_first, ns_args...);
}
- template <typename... Args>
+ template <typename S, typename... Args>
tl::optional<Rib::Definition>
- resolve_path (const AST::TypePath &path,
- tl::optional<std::vector<Error> &> collect_errors,
+ resolve_path (const std::vector<S> &path_segments, ResolutionMode mode,
Namespace ns_first, Args... ns_args)
{
+ return resolve_path (path_segments, mode, tl::nullopt, ns_first,
+ ns_args...);
+ }
+
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::SimplePath &path,
+ Args &&...args)
+ {
return resolve_path (path.get_segments (),
- path.has_opening_scope_resolution_op (),
- collect_errors, ns_first, ns_args...);
+ path.has_opening_scope_resolution (),
+ std::forward<Args> (args)...);
}
- template <typename P, typename... Args>
- tl::optional<Rib::Definition> resolve_path (const P &path, Namespace ns_first,
- Args... ns_args)
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::PathInExpression &path,
+ Args &&...args)
{
- return resolve_path (path, tl::nullopt, ns_first, ns_args...);
+ return resolve_path (path.get_segments (), path.opening_scope_resolution (),
+ std::forward<Args> (args)...);
}
- template <typename P, typename... Args>
- tl::optional<Rib::Definition>
- resolve_path (const P &path_segments, bool has_opening_scope_resolution,
- Namespace ns_first, Args... ns_args)
+ template <typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const AST::TypePath &path,
+ Args &&...args)
{
- return resolve_path (path_segments, has_opening_scope_resolution,
- tl::nullopt, ns_first, ns_args...);
+ return resolve_path (path.get_segments (),
+ path.has_opening_scope_resolution_op (),
+ std::forward<Args> (args)...);
}
private:
diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h
index c498328..140c991 100644
--- a/gcc/rust/resolve/rust-rib.h
+++ b/gcc/rust/resolve/rust-rib.h
@@ -188,6 +188,8 @@ public:
* restriction that you cannot `use` items from the Prelude
*/
Prelude,
+ /* Generic rib, used to store generics */
+ Generics,
} kind;
static std::string kind_to_string (Rib::Kind kind)
@@ -214,9 +216,13 @@ public:
return "Forward type param ban";
case Rib::Kind::ConstParamType:
return "Const Param Type";
- default:
- rust_unreachable ();
+ case Kind::Prelude:
+ return "Prelude";
+ case Kind::Generics:
+ return "Generics";
}
+
+ rust_unreachable ();
}
Rib (Kind kind);
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 2f036fe..3e5ed53 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -95,8 +95,7 @@ TopLevel::go (AST::Crate &crate)
// times in a row in a fixed-point fashion, so it would make the code
// responsible for this ugly and perfom a lot of error checking.
- for (auto &item : crate.items)
- item->accept_vis (*this);
+ visit (crate);
}
void
@@ -141,33 +140,10 @@ TopLevel::visit (AST::Trait &trait)
}
void
-TopLevel::visit (AST::InherentImpl &impl)
+TopLevel::maybe_insert_big_self (AST::Impl &impl)
{
- auto inner_fn = [this, &impl] () {
- insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
- impl.get_type (), Namespace::Types);
-
- // We do want to visit with the default visitor instead of default resolver
- // because we don't want to insert the scope twice.
- AST::DefaultASTVisitor::visit (impl);
- };
-
- ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
-}
-
-void
-TopLevel::visit (AST::TraitImpl &impl)
-{
- auto inner_fn = [this, &impl] () {
- insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
- impl.get_type (), Namespace::Types);
-
- // We do want to visit using the default visitor instead of default resolver
- // because we don't want to insert the scope twice.
- AST::DefaultASTVisitor::visit (impl);
- };
-
- ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
+ insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
+ impl.get_type (), Namespace::Types);
}
void
@@ -217,7 +193,7 @@ TopLevel::visit (AST::ExternCrate &crate)
auto derive_macros = mappings.lookup_derive_proc_macros (num);
- auto sub_visitor = [&] () {
+ auto sub_visitor_1 = [&] () {
// TODO: Find a way to keep this part clean without the double dispatch.
if (derive_macros.has_value ())
{
@@ -239,11 +215,17 @@ TopLevel::visit (AST::ExternCrate &crate)
}
};
+ auto sub_visitor_2 = [&] () {
+ ctx.canonical_ctx.scope_crate (crate.get_node_id (),
+ crate.get_referenced_crate (),
+ std::move (sub_visitor_1));
+ };
+
if (crate.has_as_clause ())
- ctx.scoped (Rib::Kind::Module, crate.get_node_id (), sub_visitor,
+ ctx.scoped (Rib::Kind::Module, crate.get_node_id (), sub_visitor_2,
crate.get_as_clause ());
else
- ctx.scoped (Rib::Kind::Module, crate.get_node_id (), sub_visitor,
+ ctx.scoped (Rib::Kind::Module, crate.get_node_id (), sub_visitor_2,
crate.get_referenced_crate ());
}
@@ -321,14 +303,7 @@ TopLevel::visit (AST::ExternalStaticItem &static_item)
void
TopLevel::visit (AST::StructStruct &struct_item)
{
- auto generic_vis = [this, &struct_item] () {
- for (auto &g : struct_item.get_generic_params ())
- {
- g->accept_vis (*this);
- }
- };
-
- ctx.scoped (Rib::Kind::Item, struct_item.get_node_id (), generic_vis);
+ DefaultResolver::visit (struct_item);
insert_or_error_out (struct_item.get_struct_name (), struct_item,
Namespace::Types);
@@ -374,24 +349,32 @@ void
TopLevel::visit (AST::EnumItem &variant)
{
insert_enum_variant_or_error_out (variant.get_identifier (), variant);
+
+ DefaultResolver::visit (variant);
}
void
TopLevel::visit (AST::EnumItemTuple &variant)
{
insert_enum_variant_or_error_out (variant.get_identifier (), variant);
+
+ DefaultResolver::visit (variant);
}
void
TopLevel::visit (AST::EnumItemStruct &variant)
{
insert_enum_variant_or_error_out (variant.get_identifier (), variant);
+
+ DefaultResolver::visit (variant);
}
void
TopLevel::visit (AST::EnumItemDiscriminant &variant)
{
insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+
+ DefaultResolver::visit (variant);
}
void
@@ -430,21 +413,18 @@ TopLevel::visit (AST::TypeAlias &type_item)
DefaultResolver::visit (type_item);
}
-static void
-flatten_rebind (
+static void flatten_rebind (
const AST::UseTreeRebind &glob,
std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths);
-static void
-flatten_list (
+static void flatten_list (
const AST::UseTreeList &glob, std::vector<AST::SimplePath> &paths,
std::vector<AST::SimplePath> &glob_paths,
std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
NameResolutionContext &ctx);
-static void
-flatten_glob (const AST::UseTreeGlob &glob,
- std::vector<AST::SimplePath> &glob_paths,
- NameResolutionContext &ctx);
+static void flatten_glob (const AST::UseTreeGlob &glob,
+ std::vector<AST::SimplePath> &glob_paths,
+ NameResolutionContext &ctx);
static void
flatten (
@@ -455,17 +435,20 @@ flatten (
{
switch (tree->get_kind ())
{
- case AST::UseTree::Rebind: {
+ case AST::UseTree::Rebind:
+ {
auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
flatten_rebind (*rebind, rebind_paths);
break;
}
- case AST::UseTree::List: {
+ case AST::UseTree::List:
+ {
auto list = static_cast<const AST::UseTreeList *> (tree);
flatten_list (*list, paths, glob_paths, rebind_paths, ctx);
break;
}
- case AST::UseTree::Glob: {
+ case AST::UseTree::Glob:
+ {
auto glob = static_cast<const AST::UseTreeGlob *> (tree);
flatten_glob (*glob, glob_paths, ctx);
break;
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index 3ff37ed..0dfd654 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -160,8 +160,7 @@ private:
void visit (AST::Module &module) override;
void visit (AST::Trait &trait) override;
- void visit (AST::InherentImpl &impl) override;
- void visit (AST::TraitImpl &impl) override;
+ void maybe_insert_big_self (AST::Impl &impl) override;
void visit (AST::TraitItemType &trait_item) override;
void visit (AST::MacroRulesDefinition &macro) override;
void visit (AST::Function &function) override;
diff --git a/gcc/rust/rust-attribs.cc b/gcc/rust/rust-attribs.cc
index 74cb2af..a98c1fa 100644
--- a/gcc/rust/rust-attribs.cc
+++ b/gcc/rust/rust-attribs.cc
@@ -38,35 +38,27 @@ along with GCC; see the file COPYING3. If not see
* future.
*/
-extern const attribute_spec grs_langhook_common_attribute_table[];
+extern const struct scoped_attribute_specs grs_langhook_gnu_attribute_table;
+extern const struct scoped_attribute_specs grs_langhook_common_attribute_table;
/* Internal attribute handlers for built-in functions. */
-static tree
-handle_noreturn_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_leaf_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_const_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_malloc_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_pure_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_novops_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_nonnull_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_nothrow_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_type_generic_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_fnspec_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *);
+static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
+static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
+static tree handle_const_attribute (tree *, tree, tree, int, bool *);
+static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
+static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
+static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
+static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
+static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
+static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
+static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
+static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
+static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
+static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *);
+
+/* Rust attribute handlers for user defined attributes. */
+static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
+static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
/* Helper to define attribute exclusions. */
#define ATTR_EXCL(name, function, type, variable) \
@@ -74,6 +66,10 @@ handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *);
name, function, type, variable \
}
+// clang-format off
+// Disabling clang-format because it insists in having several ATTR_EXCL() on a
+// single line.
+
static const struct attribute_spec::exclusions attr_noreturn_exclusions[] = {
// ATTR_EXCL ("alloc_size", true, true, true),
ATTR_EXCL ("const", true, true, true),
@@ -89,11 +85,22 @@ static const struct attribute_spec::exclusions attr_returns_twice_exclusions[]
ATTR_EXCL (NULL, false, false, false),
};
+extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] = {
+
+ ATTR_EXCL ("cold", true, true, true),
+ ATTR_EXCL ("hot", true, true, true),
+ ATTR_EXCL (NULL, false, false, false)
+};
+
static const struct attribute_spec::exclusions attr_const_pure_exclusions[] = {
// ATTR_EXCL ("alloc_size", true, true, true),
ATTR_EXCL ("const", true, true, true),
ATTR_EXCL ("noreturn", true, true, true),
- ATTR_EXCL ("pure", true, true, true), ATTR_EXCL (NULL, false, false, false)};
+ ATTR_EXCL ("pure", true, true, true),
+ ATTR_EXCL (NULL, false, false, false)
+};
+
+// clang-format on
/* Helper to define an attribute. */
#define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \
@@ -105,7 +112,7 @@ static const struct attribute_spec::exclusions attr_const_pure_exclusions[] = {
/* Table of machine-independent attributes.
For internal use (marking of built-ins) only. */
-const attribute_spec grs_langhook_common_attribute_table[] = {
+static const attribute_spec grs_langhook_common_attributes[] = {
ATTR_SPEC ("noreturn", 0, 0, true, false, false, false,
handle_noreturn_attribute, attr_noreturn_exclusions),
ATTR_SPEC ("leaf", 0, 0, true, false, false, false, handle_leaf_attribute,
@@ -132,9 +139,21 @@ const attribute_spec grs_langhook_common_attribute_table[] = {
NULL),
ATTR_SPEC ("omp declare simd", 0, -1, true, false, false, false,
handle_omp_declare_simd_attribute, NULL),
- ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
};
+const scoped_attribute_specs grs_langhook_common_attribute_table
+ = {"gnu", {grs_langhook_common_attributes}};
+
+static const attribute_spec grs_langhook_gnu_attributes[] = {
+ ATTR_SPEC ("cold", 0, 0, true, false, false, false, handle_cold_attribute,
+ attr_cold_hot_exclusions),
+ ATTR_SPEC ("hot", 0, 0, true, false, false, false, handle_hot_attribute,
+ attr_cold_hot_exclusions),
+};
+
+const scoped_attribute_specs grs_langhook_gnu_attribute_table
+ = {"gnu", {grs_langhook_gnu_attributes}};
+
/* Built-in attribute handlers.
These functions take the arguments:
(tree *node, tree name, tree args, int flags, bool *no_add_attrs) */
@@ -204,7 +223,7 @@ handle_const_attribute (tree *node, tree, tree, int, bool *)
/* Handle a "malloc" attribute; arguments as in
struct attribute_spec.handler. */
-tree
+static tree
handle_malloc_attribute (tree *node, tree, tree, int, bool *)
{
gcc_assert (TREE_CODE (*node) == FUNCTION_DECL
@@ -217,9 +236,14 @@ handle_malloc_attribute (tree *node, tree, tree, int, bool *)
struct attribute_spec.handler. */
static tree
-handle_pure_attribute (tree *node, tree, tree, int, bool *)
+handle_pure_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
{
- gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
DECL_PURE_P (*node) = 1;
return NULL_TREE;
}
@@ -228,9 +252,14 @@ handle_pure_attribute (tree *node, tree, tree, int, bool *)
struct attribute_spec.handler. */
static tree
-handle_novops_attribute (tree *node, tree, tree, int, bool *)
+handle_novops_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
{
- gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
DECL_IS_NOVOPS (*node) = 1;
return NULL_TREE;
}
@@ -301,9 +330,14 @@ handle_nonnull_attribute (tree *node, tree, tree args, int, bool *)
struct attribute_spec.handler. */
static tree
-handle_nothrow_attribute (tree *node, tree, tree, int, bool *)
+handle_nothrow_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
{
- gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
TREE_NOTHROW (*node) = 1;
return NULL_TREE;
}
@@ -339,9 +373,14 @@ handle_transaction_pure_attribute (tree *node, tree, tree, int, bool *)
struct attribute_spec.handler. */
static tree
-handle_returns_twice_attribute (tree *node, tree, tree, int, bool *)
+handle_returns_twice_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
{
- gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
DECL_IS_RETURNS_TWICE (*node) = 1;
@@ -351,7 +390,7 @@ handle_returns_twice_attribute (tree *node, tree, tree, int, bool *)
/* Handle a "fn spec" attribute; arguments as in
struct attribute_spec.handler. */
-tree
+static tree
handle_fnspec_attribute (tree *, tree, tree args, int, bool *)
{
gcc_assert (args && TREE_CODE (TREE_VALUE (args)) == STRING_CST
@@ -362,9 +401,46 @@ handle_fnspec_attribute (tree *, tree, tree args, int, bool *)
/* Handle an "omp declare simd" attribute; arguments as in
struct attribute_spec.handler. */
-tree
-handle_omp_declare_simd_attribute (tree *node, tree, tree, int, bool *)
+static tree
+handle_omp_declare_simd_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
{
- gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
+/* Language specific attribute handlers.
+ These functions take the arguments:
+ (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */
+
+/* Handle a "cold" and attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_cold_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
+static tree
+handle_hot_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
return NULL_TREE;
}
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 414799e..a0df217 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -42,8 +42,7 @@ class Bvariable;
namespace Backend {
-void
-init ();
+void init ();
// Name/type/location. Used for function parameters, struct fields,
// interface methods.
@@ -64,47 +63,37 @@ struct typed_identifier
// debug
void debug (tree);
-void
-debug (Bvariable *);
+void debug (Bvariable *);
-tree
-get_identifier_node (const std::string &str);
+tree get_identifier_node (const std::string &str);
// Types.
// Get the wchar type
-tree
-wchar_type ();
+tree wchar_type ();
// Get the Host pointer size in bits
-int
-get_pointer_size ();
+int get_pointer_size ();
// Get the raw str type const char*
-tree
-raw_str_type ();
+tree raw_str_type ();
// Get an unnamed integer type with the given signedness and number
// of bits.
-tree
-integer_type (bool is_unsigned, int bits);
+tree integer_type (bool is_unsigned, int bits);
// Get an unnamed floating point type with the given number of bits
// (32 or 64).
-tree
-float_type (int bits);
+tree float_type (int bits);
// Get a pointer type.
-tree
-pointer_type (tree to_type);
+tree pointer_type (tree to_type);
// Get a reference type.
-tree
-reference_type (tree to_type);
+tree reference_type (tree to_type);
// make type immutable
-tree
-immutable_type (tree base);
+tree immutable_type (tree base);
// Get a function type. The receiver, parameter, and results are
// generated from the types in the Function_type. The Function_type
@@ -115,41 +104,36 @@ immutable_type (tree base);
// one result, RESULT_STRUCT is a struct type to hold the results,
// and RESULTS may be ignored; if there are zero or one results,
// RESULT_STRUCT is NULL.
-tree
-function_type (const typed_identifier &receiver,
- const std::vector<typed_identifier> &parameters,
- const std::vector<typed_identifier> &results, tree result_struct,
- location_t location);
-
-tree
-function_type_variadic (const typed_identifier &receiver,
- const std::vector<typed_identifier> &parameters,
- const std::vector<typed_identifier> &results,
- tree result_struct, location_t location);
-
-tree
-function_ptr_type (tree result, const std::vector<tree> &praameters,
- location_t location);
+tree function_type (const typed_identifier &receiver,
+ const std::vector<typed_identifier> &parameters,
+ const std::vector<typed_identifier> &results,
+ tree result_struct, location_t location);
+
+tree function_type_variadic (const typed_identifier &receiver,
+ const std::vector<typed_identifier> &parameters,
+ const std::vector<typed_identifier> &results,
+ tree result_struct, location_t location);
+
+tree function_ptr_type (tree result, const std::vector<tree> &praameters,
+ location_t location);
// Get a struct type.
-tree
-struct_type (const std::vector<typed_identifier> &fields, bool layout = true);
+tree struct_type (const std::vector<typed_identifier> &fields,
+ bool layout = true);
// Get a union type.
-tree
-union_type (const std::vector<typed_identifier> &fields, bool layout = true);
+tree union_type (const std::vector<typed_identifier> &fields,
+ bool layout = true);
// Get an array type.
-tree
-array_type (tree element_type, tree length);
+tree array_type (tree element_type, tree length);
// Return a named version of a type. The location is the location
// of the type definition. This will not be called for a type
// created via placeholder_pointer_type, placeholder_struct_type, or
// placeholder_array_type.. (It may be called for a pointer,
// struct, or array type in a case like "type P *byte; type Q P".)
-tree
-named_type (const std::string &name, tree, location_t);
+tree named_type (const std::string &name, tree, location_t);
// Return the size of a type.
int64_t type_size (tree);
@@ -164,8 +148,7 @@ int64_t type_field_alignment (tree);
// Return the offset of field INDEX in a struct type. INDEX is the
// entry in the FIELDS std::vector parameter of struct_type or
// set_placeholder_struct_type.
-int64_t
-type_field_offset (tree, size_t index);
+int64_t type_field_offset (tree, size_t index);
// Expressions.
@@ -175,155 +158,128 @@ type_field_offset (tree, size_t index);
tree zero_expression (tree);
// Create a reference to a variable.
-tree
-var_expression (Bvariable *var, location_t);
+tree var_expression (Bvariable *var, location_t);
// Return an expression for the floating point value VAL in BTYPE.
-tree
-float_constant_expression (tree btype, mpfr_t val);
+tree float_constant_expression (tree btype, mpfr_t val);
// Return an expression for the string value VAL.
-tree
-string_constant_expression (const std::string &val);
+tree string_constant_expression (const std::string &val);
// Get a char literal
-tree
-char_constant_expression (char c);
+tree char_constant_expression (char c);
// Get a char literal
-tree
-wchar_constant_expression (wchar_t c);
+tree wchar_constant_expression (wchar_t c);
// Return an expression for the boolean value VAL.
-tree
-boolean_constant_expression (bool val);
+tree boolean_constant_expression (bool val);
// Return an expression that converts EXPR to TYPE.
-tree
-convert_expression (tree type, tree expr, location_t);
+tree convert_expression (tree type, tree expr, location_t);
// Return an expression for the field at INDEX in BSTRUCT.
-tree
-struct_field_expression (tree bstruct, size_t index, location_t);
+tree struct_field_expression (tree bstruct, size_t index, location_t);
// Create an expression that executes BSTAT before BEXPR.
-tree
-compound_expression (tree bstat, tree bexpr, location_t);
+tree compound_expression (tree bstat, tree bexpr, location_t);
// Return an expression that executes THEN_EXPR if CONDITION is true, or
// ELSE_EXPR otherwise and returns the result as type BTYPE, within the
// specified function FUNCTION. ELSE_EXPR may be NULL. BTYPE may be NULL.
-tree
-conditional_expression (tree function, tree btype, tree condition,
- tree then_expr, tree else_expr, location_t);
+tree conditional_expression (tree function, tree btype, tree condition,
+ tree then_expr, tree else_expr, location_t);
// Return an expression for the negation operation OP EXPR.
// Supported values of OP are enumerated in NegationOperator.
-tree
-negation_expression (NegationOperator op, tree expr, location_t);
+tree negation_expression (NegationOperator op, tree expr, location_t);
// Return an expression for the operation LEFT OP RIGHT.
// Supported values of OP are enumerated in ArithmeticOrLogicalOperator.
-tree
-arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op, tree left,
- tree right, location_t loc);
+tree arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op,
+ tree left, tree right, location_t loc);
// Return an expression for the operation LEFT OP RIGHT.
// Supported values of OP are enumerated in ArithmeticOrLogicalOperator.
// This function adds overflow checking and returns a list of statements to
// add to the current function context. The `receiver` variable refers to the
// variable which will contain the result of that operation.
-tree
-arithmetic_or_logical_expression_checked (ArithmeticOrLogicalOperator op,
- tree left, tree right, location_t loc,
- Bvariable *receiver);
+tree arithmetic_or_logical_expression_checked (ArithmeticOrLogicalOperator op,
+ tree left, tree right,
+ location_t loc,
+ Bvariable *receiver);
// Return an expression for the operation LEFT OP RIGHT.
// Supported values of OP are enumerated in ComparisonOperator.
-tree
-comparison_expression (ComparisonOperator op, tree left, tree right,
- location_t loc);
+tree comparison_expression (ComparisonOperator op, tree left, tree right,
+ location_t loc);
// Return an expression for the operation LEFT OP RIGHT.
// Supported values of OP are enumerated in LazyBooleanOperator.
-tree
-lazy_boolean_expression (LazyBooleanOperator op, tree left, tree right,
- location_t);
+tree lazy_boolean_expression (LazyBooleanOperator op, tree left, tree right,
+ location_t);
// Return an expression that constructs BTYPE with VALS. BTYPE must be the
// backend representation a of struct. VALS must be in the same order as the
// corresponding fields in BTYPE.
-tree
-constructor_expression (tree btype, bool is_variant,
- const std::vector<tree> &vals, int, location_t);
+tree constructor_expression (tree btype, bool is_variant,
+ const std::vector<tree> &vals, int, location_t);
// Return an expression that constructs an array of BTYPE with INDEXES and
// VALS. INDEXES and VALS must have the same amount of elements. Each index
// in INDEXES must be in the same order as the corresponding value in VALS.
-tree
-array_constructor_expression (tree btype,
- const std::vector<unsigned long> &indexes,
- const std::vector<tree> &vals, location_t);
+tree array_constructor_expression (tree btype,
+ const std::vector<unsigned long> &indexes,
+ const std::vector<tree> &vals, location_t);
-tree
-array_initializer (tree, tree, tree, tree, tree, tree *, location_t);
+tree array_initializer (tree, tree, tree, tree, tree, tree *, location_t);
// Return an expression for ARRAY[INDEX] as an l-value. ARRAY is a valid
// fixed-length array, not a slice.
-tree
-array_index_expression (tree array, tree index, location_t);
+tree array_index_expression (tree array, tree index, location_t);
// Create an expression for a call to FN with ARGS, taking place within
// caller CALLER.
-tree
-call_expression (tree fn, const std::vector<tree> &args, tree static_chain,
- location_t);
+tree call_expression (tree fn, const std::vector<tree> &args, tree static_chain,
+ location_t);
// Statements.
// Create a variable initialization statement in the specified
// function. This initializes a local variable at the point in the
// program flow where it is declared.
-tree
-init_statement (tree, Bvariable *var, tree init);
+tree init_statement (tree, Bvariable *var, tree init);
// Create an assignment statement within the specified function.
-tree
-assignment_statement (tree lhs, tree rhs, location_t);
+tree assignment_statement (tree lhs, tree rhs, location_t);
// Create return statement for an decl for a value (can be NULL_TREE) at a
// location
-tree
-return_statement (tree fndecl, tree val, location_t);
+tree return_statement (tree fndecl, tree val, location_t);
// Create an if statement within a function. ELSE_BLOCK may be NULL.
-tree
-if_statement (tree, tree condition, tree then_block, tree else_block,
- location_t);
+tree if_statement (tree, tree condition, tree then_block, tree else_block,
+ location_t);
// infinite loop expressions
-tree
-loop_expression (tree body, location_t);
+tree loop_expression (tree body, location_t);
// exit expressions
-tree
-exit_expression (tree condition, location_t);
+tree exit_expression (tree condition, location_t);
// Create a single statement from two statements.
tree compound_statement (tree, tree);
// Create a single statement from a list of statements.
-tree
-statement_list (const std::vector<tree> &);
+tree statement_list (const std::vector<tree> &);
// Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if
// an exception occurs. EXCEPT_STMT may be NULL. FINALLY_STMT may be NULL and
// if not NULL, it will always be executed. This is used for handling defers
// in Go functions. In C++, the resulting code is of this form:
// try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
-tree
-exception_handler_statement (tree bstat, tree except_stmt, tree finally_stmt,
- location_t);
+tree exception_handler_statement (tree bstat, tree except_stmt,
+ tree finally_stmt, location_t);
// Blocks.
@@ -337,16 +293,14 @@ exception_handler_statement (tree bstat, tree except_stmt, tree finally_stmt,
// the initial curly brace. END_LOCATION is the location of the end
// of the block, more or less the location of the final curly brace.
// The statements will be added after the block is created.
-tree
-block (tree function, tree enclosing, const std::vector<Bvariable *> &vars,
- location_t start_location, location_t end_location);
+tree block (tree function, tree enclosing, const std::vector<Bvariable *> &vars,
+ location_t start_location, location_t end_location);
// Add the statements to a block. The block is created first. Then
// the statements are created. Then the statements are added to the
// block. This will called exactly once per block. The vector may
// be empty if there are no statements.
-void
-block_add_statements (tree, const std::vector<tree> &);
+void block_add_statements (tree, const std::vector<tree> &);
// Variables.
@@ -360,10 +314,10 @@ block_add_statements (tree, const std::vector<tree> &);
// be put into a unique section if possible; this is intended to
// permit the linker to garbage collect the variable if it is not
// referenced. LOCATION is where the variable was defined.
-Bvariable *
-global_variable (const std::string &name, const std::string &asm_name,
- tree btype, bool is_external, bool is_hidden,
- bool in_unique_section, location_t location);
+Bvariable *global_variable (const std::string &name,
+ const std::string &asm_name, tree btype,
+ bool is_external, bool is_hidden,
+ bool in_unique_section, location_t location);
// A global variable will 1) be initialized to zero, or 2) be
// initialized to a constant value, or 3) be initialized in the init
@@ -371,8 +325,7 @@ global_variable (const std::string &name, const std::string &asm_name,
// global_variable_set_init to set the initial value. If this is
// not called, the backend should initialize a global variable to 0.
// The init function may then assign a value to it.
-void
-global_variable_set_init (Bvariable *, tree);
+void global_variable_set_init (Bvariable *, tree);
// Create a local variable. The frontend will create the local
// variables first, and then create the block which contains them.
@@ -386,21 +339,18 @@ global_variable_set_init (Bvariable *, tree);
// the function, as otherwise the variable would be on the heap).
// LOCATION is where the variable is defined. For each local variable
// the frontend will call init_statement to set the initial value.
-Bvariable *
-local_variable (tree function, const std::string &name, tree type,
- Bvariable *decl_var, location_t location);
+Bvariable *local_variable (tree function, const std::string &name, tree type,
+ Bvariable *decl_var, location_t location);
// Create a function parameter. This is an incoming parameter, not
// a result parameter (result parameters are treated as local
// variables). The arguments are as for local_variable.
-Bvariable *
-parameter_variable (tree function, const std::string &name, tree type,
- location_t location);
+Bvariable *parameter_variable (tree function, const std::string &name,
+ tree type, location_t location);
// Create a static chain parameter. This is the closure parameter.
-Bvariable *
-static_chain_variable (tree function, const std::string &name, tree type,
- location_t location);
+Bvariable *static_chain_variable (tree function, const std::string &name,
+ tree type, location_t location);
// Create a temporary variable. A temporary variable has no name,
// just a type. We pass in FUNCTION and BLOCK in case they are
@@ -413,18 +363,16 @@ static_chain_variable (tree function, const std::string &name, tree type,
// variable, and may not be very useful. This function should
// return a variable which can be referenced later and should set
// *PSTATEMENT to a statement which initializes the variable.
-Bvariable *
-temporary_variable (tree fndecl, tree bind_tree, tree type, tree init,
- bool address_is_taken, location_t location,
- tree *pstatement);
+Bvariable *temporary_variable (tree fndecl, tree bind_tree, tree type,
+ tree init, bool address_is_taken,
+ location_t location, tree *pstatement);
// Labels.
// Create a new label. NAME will be empty if this is a label
// created by the frontend for a loop construct. The location is
// where the label is defined.
-tree
-label (tree, const std::string &name, location_t);
+tree label (tree, const std::string &name, location_t);
// Create a statement which defines a label. This statement will be
// put into the codestream at the point where the label should be
@@ -464,39 +412,34 @@ static const unsigned int function_in_unique_section = 1 << 3;
// string, is the name that should be used in the symbol table; this
// will be non-empty if a magic extern comment is used. FLAGS is
// bit flags described above.
-tree
-function (tree fntype, const std::string &name, const std::string &asm_name,
- unsigned int flags, location_t);
+tree function (tree fntype, const std::string &name,
+ const std::string &asm_name, unsigned int flags, location_t);
// Create a statement that runs all deferred calls for FUNCTION. This should
// be a statement that looks like this in C++:
// finish:
// try { DEFER_RETURN; } catch { CHECK_DEFER; goto finish; }
-tree
-function_defer_statement (tree function, tree undefer, tree check_defer,
- location_t);
+tree function_defer_statement (tree function, tree undefer, tree check_defer,
+ location_t);
// Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
// This will only be called for a function definition. Returns true on
// success, false on failure.
-bool
-function_set_parameters (tree function,
- const std::vector<Bvariable *> &param_vars);
+bool function_set_parameters (tree function,
+ const std::vector<Bvariable *> &param_vars);
// Utility.
// Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
// FUNCTION_DECLS, and VARIABLE_DECLS declared globally.
-void
-write_global_definitions (const std::vector<tree> &type_decls,
- const std::vector<tree> &constant_decls,
- const std::vector<tree> &function_decls,
- const std::vector<Bvariable *> &variable_decls);
+void write_global_definitions (const std::vector<tree> &type_decls,
+ const std::vector<tree> &constant_decls,
+ const std::vector<tree> &function_decls,
+ const std::vector<Bvariable *> &variable_decls);
// TODO: make static
-tree
-fill_in_fields (tree, const std::vector<typed_identifier> &, bool);
+tree fill_in_fields (tree, const std::vector<typed_identifier> &, bool);
tree fill_in_array (tree, tree, tree);
diff --git a/gcc/rust/rust-diagnostics.cc b/gcc/rust/rust-diagnostics.cc
index 702da71..5965bb4 100644
--- a/gcc/rust/rust-diagnostics.cc
+++ b/gcc/rust/rust-diagnostics.cc
@@ -48,27 +48,33 @@ expand_format (const char *fmt)
c++;
switch (*c)
{
- case '\0': {
+ case '\0':
+ {
// malformed format string
rust_unreachable ();
}
- case '%': {
+ case '%':
+ {
ss << "%";
break;
}
- case 'm': {
+ case 'm':
+ {
ss << mformat_value ();
break;
}
- case '<': {
+ case '<':
+ {
ss << rust_open_quote ();
break;
}
- case '>': {
+ case '>':
+ {
ss << rust_close_quote ();
break;
}
- case 'q': {
+ case 'q':
+ {
ss << rust_open_quote ();
c++;
if (*c == 'm')
@@ -82,7 +88,8 @@ expand_format (const char *fmt)
ss << rust_close_quote ();
break;
}
- default: {
+ default:
+ {
ss << "%" << *c;
}
}
@@ -104,8 +111,8 @@ expand_format (const char *fmt)
// calling function must need to have attribute gnu_printf as well, even
// though there is already an attribute declaration for it.
-static std::string
-expand_message (const char *fmt, va_list ap) RUST_ATTRIBUTE_GCC_DIAG (1, 0);
+static std::string expand_message (const char *fmt, va_list ap)
+ RUST_ATTRIBUTE_GCC_DIAG (1, 0);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
@@ -420,24 +427,24 @@ namespace Rust {
*/
// simple location
-static Error
-va_constructor (Error::Kind kind, location_t locus, const char *fmt,
- va_list args) RUST_ATTRIBUTE_GCC_DIAG (3, 0);
+static Error va_constructor (Error::Kind kind, location_t locus,
+ const char *fmt, va_list args)
+ RUST_ATTRIBUTE_GCC_DIAG (3, 0);
// simple location + error code
-static Error
-va_constructor (Error::Kind kind, location_t locus, const ErrorCode code,
- const char *fmt, va_list args) RUST_ATTRIBUTE_GCC_DIAG (4, 0);
+static Error va_constructor (Error::Kind kind, location_t locus,
+ const ErrorCode code, const char *fmt,
+ va_list args) RUST_ATTRIBUTE_GCC_DIAG (4, 0);
// rich location
-static Error
-va_constructor (Error::Kind kind, rich_location *r_locus, const char *fmt,
- va_list args) RUST_ATTRIBUTE_GCC_DIAG (3, 0);
+static Error va_constructor (Error::Kind kind, rich_location *r_locus,
+ const char *fmt, va_list args)
+ RUST_ATTRIBUTE_GCC_DIAG (3, 0);
// rich location + error code
-static Error
-va_constructor (Error::Kind kind, rich_location *r_locus, const ErrorCode code,
- const char *fmt, va_list args) RUST_ATTRIBUTE_GCC_DIAG (4, 0);
+static Error va_constructor (Error::Kind kind, rich_location *r_locus,
+ const ErrorCode code, const char *fmt,
+ va_list args) RUST_ATTRIBUTE_GCC_DIAG (4, 0);
// simple location
static Error
diff --git a/gcc/rust/rust-diagnostics.h b/gcc/rust/rust-diagnostics.h
index a13dc6a2..0b83e8c 100644
--- a/gcc/rust/rust-diagnostics.h
+++ b/gcc/rust/rust-diagnostics.h
@@ -31,7 +31,7 @@
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
#define RUST_ATTRIBUTE_GCC_DIAG(m, n) \
__attribute__ ((__format__ (__gcc_tdiag__, m, n))) \
- __attribute__ ((__nonnull__ (m)))
+ __attribute__ ((__nonnull__ (m)))
#else
#define RUST_ATTRIBUTE_GCC_DIAG(m, n)
#endif
@@ -119,10 +119,8 @@ rust_error_at(rich_location *richloc, const ErrorCode, const char *fmt, ...)
// These interfaces provide a way for the front end to ask for
// the open/close quote characters it should use when formatting
// diagnostics (warnings, errors).
-extern const char *
-rust_open_quote ();
-extern const char *
-rust_close_quote ();
+extern const char *rust_open_quote ();
+extern const char *rust_close_quote ();
// These interfaces are used by utilities above to pass warnings and
// errors (once format specifiers have been expanded) to the back end,
@@ -306,8 +304,7 @@ struct Error
#define rust_sorry_at(location, ...) sorry_at (location, __VA_ARGS__)
-void
-rust_debug_loc (const location_t location, const char *fmt,
- ...) ATTRIBUTE_PRINTF_2;
+void rust_debug_loc (const location_t location, const char *fmt,
+ ...) ATTRIBUTE_PRINTF_2;
#endif // !defined(RUST_DIAGNOSTICS_H)
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index e5319d3..f440f79 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1876,7 +1876,8 @@ non_zero_size_type (tree type)
}
return rust_non_zero_struct;
- case ARRAY_TYPE: {
+ case ARRAY_TYPE:
+ {
tree element_type = non_zero_size_type (TREE_TYPE (type));
return build_array_type_nelts (element_type, 1);
}
diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index f3a155d..35003ab 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -373,7 +373,13 @@ rust_localize_identifier (const char *ident)
return identifier_to_locale (ident);
}
-extern const attribute_spec grs_langhook_common_attribute_table[];
+extern const struct scoped_attribute_specs grs_langhook_gnu_attribute_table;
+extern const struct scoped_attribute_specs grs_langhook_common_attribute_table;
+
+const scoped_attribute_specs *const grs_langhook_attribute_table[] = {
+ &grs_langhook_gnu_attribute_table,
+ &grs_langhook_common_attribute_table,
+};
/* The language hooks data structure. This is the main interface between the GCC
* front-end and the GCC middle-end/back-end. A list of language hooks could be
@@ -394,8 +400,7 @@ extern const attribute_spec grs_langhook_common_attribute_table[];
#undef LANG_HOOKS_WRITE_GLOBALS
#undef LANG_HOOKS_GIMPLIFY_EXPR
#undef LANG_HOOKS_EH_PERSONALITY
-
-#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
+#undef LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_NAME "GNU Rust"
#define LANG_HOOKS_INIT grs_langhook_init
@@ -417,7 +422,7 @@ extern const attribute_spec grs_langhook_common_attribute_table[];
#define LANG_HOOKS_GIMPLIFY_EXPR grs_langhook_gimplify_expr
#define LANG_HOOKS_EH_PERSONALITY grs_langhook_eh_personality
-#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE grs_langhook_common_attribute_table
+#define LANG_HOOKS_ATTRIBUTE_TABLE grs_langhook_attribute_table
#if CHECKING_P
diff --git a/gcc/rust/rust-object-export.h b/gcc/rust/rust-object-export.h
index fe055c3..784fef3 100644
--- a/gcc/rust/rust-object-export.h
+++ b/gcc/rust/rust-object-export.h
@@ -21,13 +21,10 @@
#include "rust-system.h"
-extern unsigned int
-rust_field_alignment (tree t);
-
-extern const char *
-rust_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
- int *perr);
-extern void
-rust_write_export_data (const char *bytes, unsigned int size);
+extern unsigned int rust_field_alignment (tree t);
+
+extern const char *rust_read_export_data (int fd, off_t offset, char **pbuf,
+ size_t *plen, int *perr);
+extern void rust_write_export_data (const char *bytes, unsigned int size);
#endif // RUST_OBJECT_EXPORT_H
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 48acbf34..d42ae6a 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -20,6 +20,7 @@
#include "rust-collect-lang-items.h"
#include "rust-desugar-for-loops.h"
#include "rust-desugar-question-mark.h"
+#include "rust-desugar-apit.h"
#include "rust-diagnostics.h"
#include "rust-hir-pattern-analysis.h"
#include "rust-immutable-name-resolution-context.h"
@@ -61,11 +62,9 @@
#include "tm.h"
#include "rust-target.h"
-extern bool
-saw_errors (void);
+extern bool saw_errors (void);
-extern Linemap *
-rust_get_linemap ();
+extern Linemap *rust_get_linemap ();
namespace Rust {
@@ -150,9 +149,9 @@ validate_crate_name (const std::string &crate_name, Error &error)
{
if (!(is_alphabetic (c.value) || is_numeric (c.value) || c.value == '_'))
{
- error = Error (UNDEF_LOCATION,
- "invalid character %qs in crate name: %qs",
- c.as_string ().c_str (), crate_name.c_str ());
+ error
+ = Error (UNDEF_LOCATION, "invalid character %qs in crate name: %qs",
+ c.as_string ().c_str (), crate_name.c_str ());
return false;
}
}
@@ -203,14 +202,16 @@ Session::handle_option (
switch (code)
{
case OPT_I:
- case OPT_L: {
+ case OPT_L:
+ {
// TODO: add search path
const std::string p = std::string (arg);
add_search_path (p);
}
break;
- case OPT_frust_extern_: {
+ case OPT_frust_extern_:
+ {
std::string input (arg);
ret = handle_extern_option (input);
}
@@ -251,7 +252,8 @@ Session::handle_option (
Compile::Mangler::set_mangling (flag_rust_mangling);
break;
- case OPT_frust_cfg_: {
+ case OPT_frust_cfg_:
+ {
auto string_arg = std::string (arg);
ret = handle_cfg_option (string_arg);
break;
@@ -619,6 +621,7 @@ Session::compile_crate (const char *filename)
AST::DesugarForLoops ().go (parsed_crate);
AST::DesugarQuestionMark ().go (parsed_crate);
+ AST::DesugarApit ().go (parsed_crate);
rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
@@ -1108,8 +1111,7 @@ Session::load_extern_crate (const std::string &crate_name, location_t locus)
if (stream == NULL // No stream and
&& proc_macros.empty ()) // no proc macros
{
- rust_error_at (locus, "failed to locate crate %qs",
- import_name.c_str ());
+ rust_error_at (locus, "failed to locate crate %qs", import_name.c_str ());
return UNKNOWN_NODEID;
}
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 83ba121..9af103c 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -441,8 +441,7 @@ private:
#if CHECKING_P
namespace selftest {
-extern void
-rust_crate_name_validation_test (void);
+extern void rust_crate_name_validation_test (void);
}
#endif // CHECKING_P
diff --git a/gcc/rust/rust-system.h b/gcc/rust/rust-system.h
index 986428b..a455123 100644
--- a/gcc/rust/rust-system.h
+++ b/gcc/rust/rust-system.h
@@ -88,10 +88,8 @@ constexpr static const char *file_separator = "/";
*/
#define rust_unreachable() (fancy_abort (__FILE__, __LINE__, __FUNCTION__))
-extern void
-rust_preserve_from_gc (tree t);
+extern void rust_preserve_from_gc (tree t);
-extern const char *
-rust_localize_identifier (const char *ident);
+extern const char *rust_localize_identifier (const char *ident);
#endif // !defined(RUST_SYSTEM_H)
diff --git a/gcc/rust/rust-target.h b/gcc/rust/rust-target.h
index dbc2baf..e61ea51 100644
--- a/gcc/rust/rust-target.h
+++ b/gcc/rust/rust-target.h
@@ -26,8 +26,7 @@
#include "rust-target.def"
/* Used by target to add target-related info. */
-extern void
-rust_add_target_info (const char *, const char *);
+extern void rust_add_target_info (const char *, const char *);
/* Each target can provide their own. */
extern struct gcc_targetrustm targetrustm;
diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc
index 6aa20a8..8256074 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -26,8 +26,7 @@
namespace Rust {
namespace Resolver {
-static bool
-resolve_operator_overload_fn (
+static bool resolve_operator_overload_fn (
LangItem::Kind lang_item_type, TyTy::BaseType *ty, TyTy::FnType **resolved_fn,
Adjustment::AdjustmentType *requires_ref_adjustment);
diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc
index 90bdef1..d0a9f5d 100644
--- a/gcc/rust/typecheck/rust-casts.cc
+++ b/gcc/rust/typecheck/rust-casts.cc
@@ -73,7 +73,8 @@ TypeCastRules::cast_rules ()
to.get_ty ()->debug_str ().c_str ());
switch (from_type->get_kind ())
{
- case TyTy::TypeKind::INFER: {
+ case TyTy::TypeKind::INFER:
+ {
TyTy::InferType *from_infer
= static_cast<TyTy::InferType *> (from_type);
switch (from_infer->get_infer_kind ())
@@ -85,7 +86,8 @@ TypeCastRules::cast_rules ()
case TyTy::InferType::InferTypeKind::INTEGRAL:
switch (to.get_ty ()->get_kind ())
{
- case TyTy::TypeKind::CHAR: {
+ case TyTy::TypeKind::CHAR:
+ {
// only u8 and char
bool was_uint
= from.get_ty ()->get_kind () == TyTy::TypeKind::UINT;
@@ -108,7 +110,8 @@ TypeCastRules::cast_rules ()
return TypeCoercionRules::CoercionResult{
{}, to.get_ty ()->clone ()};
- case TyTy::TypeKind::INFER: {
+ case TyTy::TypeKind::INFER:
+ {
TyTy::InferType *to_infer
= static_cast<TyTy::InferType *> (to.get_ty ());
@@ -140,7 +143,8 @@ TypeCastRules::cast_rules ()
return TypeCoercionRules::CoercionResult{
{}, to.get_ty ()->clone ()};
- case TyTy::TypeKind::INFER: {
+ case TyTy::TypeKind::INFER:
+ {
TyTy::InferType *to_infer
= static_cast<TyTy::InferType *> (to.get_ty ());
@@ -187,7 +191,8 @@ TypeCastRules::cast_rules ()
case TyTy::TypeKind::INT:
switch (to.get_ty ()->get_kind ())
{
- case TyTy::TypeKind::CHAR: {
+ case TyTy::TypeKind::CHAR:
+ {
// only u8 and char
bool was_uint = from.get_ty ()->get_kind () == TyTy::TypeKind::UINT;
bool was_u8 = was_uint
@@ -200,7 +205,8 @@ TypeCastRules::cast_rules ()
}
break;
- case TyTy::TypeKind::FLOAT: {
+ case TyTy::TypeKind::FLOAT:
+ {
// can only do this for number types not char
bool from_char
= from.get_ty ()->get_kind () == TyTy::TypeKind::CHAR;
@@ -210,7 +216,8 @@ TypeCastRules::cast_rules ()
}
break;
- case TyTy::TypeKind::POINTER: {
+ case TyTy::TypeKind::POINTER:
+ {
// char can't be casted as a ptr
bool from_char
= from.get_ty ()->get_kind () == TyTy::TypeKind::CHAR;
@@ -244,7 +251,8 @@ TypeCastRules::cast_rules ()
case TyTy::TypeKind::FLOAT:
return TypeCoercionRules::CoercionResult{{}, to.get_ty ()->clone ()};
- case TyTy::TypeKind::INFER: {
+ case TyTy::TypeKind::INFER:
+ {
TyTy::InferType *to_infer
= static_cast<TyTy::InferType *> (to.get_ty ());
@@ -273,7 +281,8 @@ TypeCastRules::cast_rules ()
case TyTy::TypeKind::USIZE:
case TyTy::TypeKind::ISIZE:
case TyTy::TypeKind::UINT:
- case TyTy::TypeKind::INT: {
+ case TyTy::TypeKind::INT:
+ {
// refs should not cast to numeric type
bool from_ptr
= from.get_ty ()->get_kind () == TyTy::TypeKind::POINTER;
diff --git a/gcc/rust/typecheck/rust-coercion.cc b/gcc/rust/typecheck/rust-coercion.cc
index 5905992..50c74ed 100644
--- a/gcc/rust/typecheck/rust-coercion.cc
+++ b/gcc/rust/typecheck/rust-coercion.cc
@@ -125,13 +125,15 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
// pointers
switch (expected->get_kind ())
{
- case TyTy::TypeKind::POINTER: {
+ case TyTy::TypeKind::POINTER:
+ {
TyTy::PointerType *ptr = static_cast<TyTy::PointerType *> (expected);
try_result = coerce_unsafe_ptr (receiver, ptr, ptr->mutability ());
return !try_result.is_error ();
}
- case TyTy::TypeKind::REF: {
+ case TyTy::TypeKind::REF:
+ {
TyTy::ReferenceType *ptr
= static_cast<TyTy::ReferenceType *> (expected);
try_result
@@ -147,7 +149,8 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L210
switch (receiver->get_kind ())
{
- default: {
+ default:
+ {
rust_debug (
"do_coercion default unify and infer expected: %s receiver %s",
receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
@@ -182,7 +185,8 @@ TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
TyTy::BaseType *element = nullptr;
switch (receiver->get_kind ())
{
- case TyTy::TypeKind::REF: {
+ case TyTy::TypeKind::REF:
+ {
TyTy::ReferenceType *ref
= static_cast<TyTy::ReferenceType *> (receiver);
from_mutbl = ref->mutability ();
@@ -190,14 +194,16 @@ TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
}
break;
- case TyTy::TypeKind::POINTER: {
+ case TyTy::TypeKind::POINTER:
+ {
TyTy::PointerType *ref = static_cast<TyTy::PointerType *> (receiver);
from_mutbl = ref->mutability ();
element = ref->get_base ();
}
break;
- default: {
+ default:
+ {
// FIXME this can probably turn into a unify_and
if (receiver->can_eq (expected, false))
return CoercionResult{{}, expected->clone ()};
@@ -264,14 +270,16 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver,
Mutability from_mutbl = Mutability::Imm;
switch (receiver->get_kind ())
{
- case TyTy::TypeKind::REF: {
+ case TyTy::TypeKind::REF:
+ {
TyTy::ReferenceType *from
= static_cast<TyTy::ReferenceType *> (receiver);
from_mutbl = from->mutability ();
}
break;
- default: {
+ default:
+ {
// FIXME
// we might be able to replace this with a can_eq because we default
// back to a final unity anyway
@@ -393,7 +401,7 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
if (expect_dyn && need_unsize)
{
- bool bounds_compatible = b->bounds_compatible (*a, locus, true);
+ bool bounds_compatible = b->bounds_compatible (*a, locus, false);
if (!bounds_compatible)
{
unsafe_error = true;
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 032bb58..35c9b0a 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -224,7 +224,8 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
// handling.
break;
- case HIR::GenericParam::GenericKind::TYPE: {
+ case HIR::GenericParam::GenericKind::TYPE:
+ {
auto &typaram = static_cast<HIR::TypeParam &> (*generic_param);
bool is_self
= typaram.get_type_representation ().as_string ().compare ("Self")
@@ -543,7 +544,8 @@ AssociatedImplTrait::setup_associated_types (
// handling.
break;
- case HIR::GenericParam::GenericKind::TYPE: {
+ case HIR::GenericParam::GenericKind::TYPE:
+ {
TyTy::BaseType *l = nullptr;
bool ok = context->lookup_type (
generic_param->get_mappings ().get_hirid (), &l);
@@ -753,7 +755,8 @@ TraitItemReference::is_object_safe () const
// https://doc.rust-lang.org/reference/items/traits.html#object-safety
switch (get_trait_item_type ())
{
- case TraitItemReference::TraitItemType::FN: {
+ case TraitItemReference::TraitItemType::FN:
+ {
// lets be boring and just check that this is indeed a method will do
// for now
const HIR::TraitItem *item = get_hir_trait_item ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 14b8ab8..6d5806f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -124,7 +124,8 @@ TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
TyTy::BaseType *infered = nullptr;
switch (literal.get_lit_type ())
{
- case HIR::Literal::LitType::INT: {
+ case HIR::Literal::LitType::INT:
+ {
bool ok = false;
switch (literal.get_type_hint ())
@@ -191,7 +192,8 @@ TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
}
break;
- case HIR::Literal::LitType::FLOAT: {
+ case HIR::Literal::LitType::FLOAT:
+ {
bool ok = false;
switch (literal.get_type_hint ())
@@ -216,25 +218,29 @@ TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
}
break;
- case HIR::Literal::LitType::BOOL: {
+ case HIR::Literal::LitType::BOOL:
+ {
auto ok = context->lookup_builtin ("bool", &infered);
rust_assert (ok);
}
break;
- case HIR::Literal::LitType::CHAR: {
+ case HIR::Literal::LitType::CHAR:
+ {
auto ok = context->lookup_builtin ("char", &infered);
rust_assert (ok);
}
break;
- case HIR::Literal::LitType::BYTE: {
+ case HIR::Literal::LitType::BYTE:
+ {
auto ok = context->lookup_builtin ("u8", &infered);
rust_assert (ok);
}
break;
- case HIR::Literal::LitType::STRING: {
+ case HIR::Literal::LitType::STRING:
+ {
TyTy::BaseType *base = nullptr;
auto ok = context->lookup_builtin ("str", &base);
rust_assert (ok);
@@ -246,7 +252,8 @@ TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
}
break;
- case HIR::Literal::LitType::BYTE_STRING: {
+ case HIR::Literal::LitType::BYTE_STRING:
+ {
/* This is an arraytype of u8 reference (&[u8;size]). It isn't in
UTF-8, but really just a byte array. Code to construct the array
reference copied from ArrayElemsValues and ArrayType. */
@@ -440,7 +447,8 @@ TypeCheckBase::resolve_generic_params (
{
switch (generic_param->get_kind ())
{
- case HIR::GenericParam::GenericKind::LIFETIME: {
+ case HIR::GenericParam::GenericKind::LIFETIME:
+ {
auto lifetime_param
= static_cast<HIR::LifetimeParam &> (*generic_param);
auto lifetime = lifetime_param.get_lifetime ();
@@ -449,7 +457,8 @@ TypeCheckBase::resolve_generic_params (
}
break;
- case HIR::GenericParam::GenericKind::CONST: {
+ case HIR::GenericParam::GenericKind::CONST:
+ {
if (is_foreign && abi != Rust::ABI::INTRINSIC)
{
rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
@@ -478,7 +487,8 @@ TypeCheckBase::resolve_generic_params (
}
break;
- case HIR::GenericParam::GenericKind::TYPE: {
+ case HIR::GenericParam::GenericKind::TYPE:
+ {
if (is_foreign && abi != Rust::ABI::INTRINSIC)
{
rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
index c80a12f..2dbd84d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
@@ -87,7 +87,7 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
- = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
+ = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
}
else
{
@@ -131,7 +131,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
- = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
+ = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
}
else
{
@@ -193,7 +193,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
- = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
+ = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
}
else
{
@@ -253,7 +253,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
- = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
+ = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
}
else
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index cbf529a7..81d95c8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -373,7 +373,8 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
switch (expr.get_expr_type ())
{
case ArithmeticOrLogicalOperator::LEFT_SHIFT:
- case ArithmeticOrLogicalOperator::RIGHT_SHIFT: {
+ case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
+ {
TyTy::TyWithLocation from (rhs, expr.get_rhs ().get_locus ());
TyTy::TyWithLocation to (lhs, expr.get_lhs ().get_locus ());
infered = cast_site (expr.get_mappings ().get_hirid (), from, to,
@@ -381,7 +382,8 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
}
break;
- default: {
+ default:
+ {
infered = unify_site (
expr.get_mappings ().get_hirid (),
TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
@@ -470,7 +472,8 @@ TypeCheckExpr::visit (HIR::NegationExpr &expr)
// https://doc.rust-lang.org/reference/expressions/operator-expr.html#negation-operators
switch (expr.get_expr_type ())
{
- case NegationOperator::NEGATE: {
+ case NegationOperator::NEGATE:
+ {
bool valid
= (negated_expr_ty->get_kind () == TyTy::TypeKind::INT)
|| (negated_expr_ty->get_kind () == TyTy::TypeKind::UINT)
@@ -492,7 +495,8 @@ TypeCheckExpr::visit (HIR::NegationExpr &expr)
}
break;
- case NegationOperator::NOT: {
+ case NegationOperator::NOT:
+ {
bool valid
= (negated_expr_ty->get_kind () == TyTy::TypeKind::BOOL)
|| (negated_expr_ty->get_kind () == TyTy::TypeKind::INT)
@@ -643,6 +647,18 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
}
void
+TypeCheckExpr::visit (HIR::AnonConst &expr)
+{
+ infered = TypeCheckExpr::Resolve (expr.get_inner_expr ());
+}
+
+void
+TypeCheckExpr::visit (HIR::ConstBlock &expr)
+{
+ infered = TypeCheckExpr::Resolve (expr.get_const_expr ());
+}
+
+void
TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
{
auto lang_item_type = LangItem::Kind::RANGE;
@@ -790,38 +806,45 @@ typecheck_inline_asm_operand (HIR::InlineAsm &expr)
{
switch (operand.get_register_type ())
{
- case RegisterType::In: {
+ case RegisterType::In:
+ {
auto in = operand.get_in ();
TypeCheckExpr::Resolve (*in.expr);
break;
}
- case RegisterType::Out: {
+ case RegisterType::Out:
+ {
auto out = operand.get_out ();
TypeCheckExpr::Resolve (*out.expr);
break;
}
- case RegisterType::InOut: {
+ case RegisterType::InOut:
+ {
auto in_out = operand.get_in_out ();
TypeCheckExpr::Resolve (*in_out.expr);
break;
}
- case RegisterType::SplitInOut: {
+ case RegisterType::SplitInOut:
+ {
auto split_in_out = operand.get_split_in_out ();
TypeCheckExpr::Resolve (*split_in_out.in_expr);
TypeCheckExpr::Resolve (*split_in_out.out_expr);
break;
}
- case RegisterType::Const: {
+ case RegisterType::Const:
+ {
auto anon_const = operand.get_const ().anon_const;
- TypeCheckExpr::Resolve (*anon_const.expr);
+ TypeCheckExpr::Resolve (anon_const.get_inner_expr ());
break;
}
- case RegisterType::Sym: {
+ case RegisterType::Sym:
+ {
auto sym = operand.get_sym ();
TypeCheckExpr::Resolve (*sym.expr);
break;
}
- case RegisterType::Label: {
+ case RegisterType::Label:
+ {
auto label = operand.get_label ();
TypeCheckExpr::Resolve (*label.expr);
break;
@@ -837,7 +860,7 @@ TypeCheckExpr::visit (HIR::InlineAsm &expr)
// NOTE: Hoise out if we have noreturn as an option
// to return a never type
// TODO : new keyword for memory seems sooooo shaky
- if (expr.options.count (AST::InlineAsmOption::NORETURN) == 1)
+ if (expr.options.count (AST::InlineAsm::Option::NORETURN) == 1)
infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ());
else
infered = TyTy::TupleType::get_unit_type ();
@@ -996,8 +1019,7 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
rich_location r (line_table, expr.get_locus ());
r.add_range (expr.get_array_expr ().get_locus ());
r.add_range (expr.get_index_expr ().get_locus ());
- rust_error_at (r, ErrorCode::E0277,
- "the type %qs cannot be indexed by %qs",
+ rust_error_at (r, ErrorCode::E0277, "the type %qs cannot be indexed by %qs",
array_expr_ty->get_name ().c_str (),
index_expr_ty->get_name ().c_str ());
}
@@ -1011,7 +1033,8 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
TyTy::BaseType *element_type = nullptr;
switch (elements.get_array_expr_type ())
{
- case HIR::ArrayElems::ArrayExprType::COPIED: {
+ case HIR::ArrayElems::ArrayExprType::COPIED:
+ {
HIR::ArrayElemsCopied &elems
= static_cast<HIR::ArrayElemsCopied &> (elements);
element_type = TypeCheckExpr::Resolve (elems.get_elem_to_copy ());
@@ -1035,7 +1058,8 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
}
break;
- case HIR::ArrayElems::ArrayExprType::VALUES: {
+ case HIR::ArrayElems::ArrayExprType::VALUES:
+ {
HIR::ArrayElemsValues &elems
= static_cast<HIR::ArrayElemsValues &> (elements);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 79121b3..e0a3278 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -46,6 +46,8 @@ public:
void visit (HIR::IfExpr &expr) override;
void visit (HIR::IfExprConseqElse &expr) override;
void visit (HIR::BlockExpr &expr) override;
+ void visit (HIR::AnonConst &expr) override;
+ void visit (HIR::ConstBlock &expr) override;
void visit (HIR::UnsafeBlockExpr &expr) override;
void visit (HIR::ArrayIndexExpr &expr) override;
void visit (HIR::ArrayExpr &expr) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index bc7f6dc..00f0cc6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -266,7 +266,8 @@ TypeCheckImplItem::visit (HIR::Function &function)
self_type = self->clone ();
break;
- case HIR::SelfParam::IMM_REF: {
+ case HIR::SelfParam::IMM_REF:
+ {
tl::optional<TyTy::Region> region;
if (self_param.has_lifetime ())
{
@@ -290,7 +291,8 @@ TypeCheckImplItem::visit (HIR::Function &function)
}
break;
- case HIR::SelfParam::MUT_REF: {
+ case HIR::SelfParam::MUT_REF:
+ {
tl::optional<TyTy::Region> region;
if (self_param.has_lifetime ())
{
@@ -343,8 +345,8 @@ TypeCheckImplItem::visit (HIR::Function &function)
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- canonical_path = nr_ctx.values.to_canonical_path (
- function.get_mappings ().get_nodeid ());
+ canonical_path
+ = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
}
else
{
@@ -494,10 +496,9 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
rich_location r (line_table, constant.get_locus ());
r.add_range (resolved_trait_item.get_locus ());
- rust_error_at (
- r, "constant %qs has an incompatible type for trait %qs",
- constant.get_identifier ().as_string ().c_str (),
- trait_reference.get_name ().c_str ());
+ rust_error_at (r, "constant %qs has an incompatible type for trait %qs",
+ constant.get_identifier ().as_string ().c_str (),
+ trait_reference.get_name ().c_str ());
}
}
@@ -545,10 +546,9 @@ TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
rich_location r (line_table, type.get_locus ());
r.add_range (resolved_trait_item.get_locus ());
- rust_error_at (
- r, "type alias %qs has an incompatible type for trait %qs",
- type.get_new_type_name ().as_string ().c_str (),
- trait_reference.get_name ().c_str ());
+ rust_error_at (r, "type alias %qs has an incompatible type for trait %qs",
+ type.get_new_type_name ().as_string ().c_str (),
+ trait_reference.get_name ().c_str ());
}
// its actually a projection, since we need a way to actually bind the
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index aaa04af..5595dad 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -203,9 +203,8 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- path = nr_ctx.values
- .to_canonical_path (struct_decl.get_mappings ().get_nodeid ())
- .value ();
+ path
+ = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid ());
}
else
{
@@ -283,12 +282,8 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
{
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto canonical_path = nr_ctx.types.to_canonical_path (
- struct_decl.get_mappings ().get_nodeid ());
-
- if (!canonical_path.has_value ())
- rust_unreachable ();
- path = canonical_path.value ();
+ path
+ = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid ());
}
else
{
@@ -375,8 +370,8 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- canonical_path = nr_ctx.types.to_canonical_path (
- enum_decl.get_mappings ().get_nodeid ());
+ canonical_path
+ = nr_ctx.to_canonical_path (enum_decl.get_mappings ().get_nodeid ());
}
else
{
@@ -439,8 +434,8 @@ TypeCheckItem::visit (HIR::Union &union_decl)
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- canonical_path = nr_ctx.types.to_canonical_path (
- union_decl.get_mappings ().get_nodeid ());
+ canonical_path
+ = nr_ctx.to_canonical_path (union_decl.get_mappings ().get_nodeid ());
}
else
{
@@ -614,10 +609,7 @@ TypeCheckItem::visit (HIR::Function &function)
{
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
- auto canonical_path = nr_ctx.values.to_canonical_path (
- function.get_mappings ().get_nodeid ());
-
- path = canonical_path.value ();
+ path = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
}
else
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index bd13f7a..15d8620 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -213,13 +213,15 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
auto &items = pattern.get_items ();
switch (items.get_item_type ())
{
- case HIR::TupleStructItems::RANGED: {
+ case HIR::TupleStructItems::RANGED:
+ {
// TODO
rust_unreachable ();
}
break;
- case HIR::TupleStructItems::MULTIPLE: {
+ case HIR::TupleStructItems::MULTIPLE:
+ {
HIR::TupleStructItemsNoRange &items_no_range
= static_cast<HIR::TupleStructItemsNoRange &> (items);
@@ -333,13 +335,15 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
{
switch (field->get_item_type ())
{
- case HIR::StructPatternField::ItemType::TUPLE_PAT: {
+ case HIR::StructPatternField::ItemType::TUPLE_PAT:
+ {
// TODO
rust_unreachable ();
}
break;
- case HIR::StructPatternField::ItemType::IDENT_PAT: {
+ case HIR::StructPatternField::ItemType::IDENT_PAT:
+ {
HIR::StructPatternFieldIdentPat &ident
= static_cast<HIR::StructPatternFieldIdentPat &> (*field);
@@ -358,7 +362,8 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
}
break;
- case HIR::StructPatternField::ItemType::IDENT: {
+ case HIR::StructPatternField::ItemType::IDENT:
+ {
HIR::StructPatternFieldIdent &ident
= static_cast<HIR::StructPatternFieldIdent &> (*field);
@@ -397,7 +402,8 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
case HIR::StructPatternField::ItemType::IDENT:
case HIR::StructPatternField::ItemType::IDENT_PAT:
break;
- default: {
+ default:
+ {
auto first_elem
= struct_pattern_elems.get_struct_pattern_fields ()
.at (0)
@@ -459,7 +465,8 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
std::unique_ptr<HIR::TuplePatternItems> items;
switch (pattern.get_items ().get_item_type ())
{
- case HIR::TuplePatternItems::ItemType::MULTIPLE: {
+ case HIR::TuplePatternItems::ItemType::MULTIPLE:
+ {
auto &ref = static_cast<HIR::TuplePatternItemsMultiple &> (
pattern.get_items ());
@@ -498,7 +505,8 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
}
break;
- case HIR::TuplePatternItems::ItemType::RANGED: {
+ case HIR::TuplePatternItems::ItemType::RANGED:
+ {
// HIR::TuplePatternItemsRanged &ref
// = *static_cast<HIR::TuplePatternItemsRanged *> (
// pattern.get_items ().get ());
@@ -538,6 +546,11 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern)
void
TypeCheckPattern::visit (HIR::IdentifierPattern &pattern)
{
+ if (pattern.has_subpattern ())
+ {
+ TypeCheckPattern::Resolve (pattern.get_subpattern (), parent);
+ }
+
if (!pattern.get_is_ref ())
{
infered = parent;
@@ -608,7 +621,8 @@ TypeCheckPattern::typecheck_range_pattern_bound (
TyTy::BaseType *resolved_bound = nullptr;
switch (bound.get_bound_type ())
{
- case HIR::RangePatternBound::RangePatternBoundType::LITERAL: {
+ case HIR::RangePatternBound::RangePatternBoundType::LITERAL:
+ {
auto &ref = static_cast<HIR::RangePatternBoundLiteral &> (bound);
HIR::Literal lit = ref.get_literal ();
@@ -617,14 +631,16 @@ TypeCheckPattern::typecheck_range_pattern_bound (
}
break;
- case HIR::RangePatternBound::RangePatternBoundType::PATH: {
+ case HIR::RangePatternBound::RangePatternBoundType::PATH:
+ {
auto &ref = static_cast<HIR::RangePatternBoundPath &> (bound);
resolved_bound = TypeCheckExpr::Resolve (ref.get_path ());
}
break;
- case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: {
+ case HIR::RangePatternBound::RangePatternBoundType::QUALPATH:
+ {
auto &ref = static_cast<HIR::RangePatternBoundQualPath &> (bound);
resolved_bound = TypeCheckExpr::Resolve (ref.get_qualified_path ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index df1636a..e3a08e6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -329,8 +329,7 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field)
repeat_location.add_range (prev_field_locus);
rust_error_at (repeat_location, ErrorCode::E0062,
- "field %qs specified more than once",
- field_name.c_str ());
+ "field %qs specified more than once", field_name.c_str ());
return false;
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 6919093..18e0458 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -908,7 +908,8 @@ TypeResolveGenericParam::apply_trait_bounds (HIR::TypeParam &param,
{
switch (bound->get_bound_type ())
{
- case HIR::TypeParamBound::BoundType::TRAITBOUND: {
+ case HIR::TypeParamBound::BoundType::TRAITBOUND:
+ {
HIR::TraitBound &b = static_cast<HIR::TraitBound &> (*bound);
TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
@@ -920,7 +921,8 @@ TypeResolveGenericParam::apply_trait_bounds (HIR::TypeParam &param,
{
switch (predicate.get_polarity ())
{
- case BoundPolarity::AntiBound: {
+ case BoundPolarity::AntiBound:
+ {
bool found = predicates.find (predicate.get_id ())
!= predicates.end ();
if (found)
@@ -937,7 +939,8 @@ TypeResolveGenericParam::apply_trait_bounds (HIR::TypeParam &param,
}
break;
- default: {
+ default:
+ {
if (predicates.find (predicate.get_id ())
== predicates.end ())
{
@@ -1033,7 +1036,8 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
{
switch (bound->get_bound_type ())
{
- case HIR::TypeParamBound::BoundType::TRAITBOUND: {
+ case HIR::TypeParamBound::BoundType::TRAITBOUND:
+ {
auto *b = static_cast<HIR::TraitBound *> (bound.get ());
TyTy::TypeBoundPredicate predicate
@@ -1042,7 +1046,8 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
specified_bounds.push_back (std::move (predicate));
}
break;
- case HIR::TypeParamBound::BoundType::LIFETIME: {
+ case HIR::TypeParamBound::BoundType::LIFETIME:
+ {
if (auto param = binding->try_as<TyTy::ParamType> ())
{
auto *b = static_cast<HIR::Lifetime *> (bound.get ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index fbaf323..27879e3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -29,8 +29,7 @@
// for flag_name_resolution_2_0
#include "options.h"
-extern bool
-saw_errors (void);
+extern bool saw_errors (void);
namespace Rust {
namespace Resolver {
@@ -231,7 +230,8 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
break;
case HIR::SelfParam::IMM_REF:
- case HIR::SelfParam::MUT_REF: {
+ case HIR::SelfParam::MUT_REF:
+ {
auto mutability
= self_param.get_self_kind () == HIR::SelfParam::IMM_REF
? Mutability::Imm
@@ -284,7 +284,7 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
canonical_path
- = nr_ctx.values.to_canonical_path (fn.get_mappings ().get_nodeid ());
+ = nr_ctx.to_canonical_path (fn.get_mappings ().get_nodeid ());
}
else
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 18a65fe..356c558 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -263,13 +263,15 @@ public:
WARN_UNUSED_RESULT std::vector<TyTy::Region>
regions_from_generic_args (const HIR::GenericArgs &args) const;
- void compute_inference_variables (bool error);
+ void compute_inference_variables (bool emit_error);
TyTy::VarianceAnalysis::CrateCtx &get_variance_analysis_ctx ();
private:
TypeCheckContext ();
+ bool compute_infer_var (HirId id, TyTy::BaseType *ty, bool emit_error);
+
std::map<NodeId, HirId> node_id_refs;
std::map<HirId, TyTy::BaseType *> resolved;
std::vector<std::unique_ptr<TyTy::BaseType>> builtins;
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
index f0bd1f8..bdfde55 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -374,7 +374,7 @@ SubstMapperInternal::visit (TyTy::DynamicObjectType &type)
void
SubstMapperInternal::visit (TyTy::OpaqueType &type)
{
- resolved = type.handle_substitions (mappings);
+ resolved = type.clone ();
}
// SubstMapperFromExisting
diff --git a/gcc/rust/typecheck/rust-type-util.cc b/gcc/rust/typecheck/rust-type-util.cc
index c6c5b4b..a549449 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -40,12 +40,12 @@ query_type (HirId reference, TyTy::BaseType **result)
auto &resolver = *Resolver::get ();
TypeCheckContext *context = TypeCheckContext::get ();
- if (context->query_in_progress (reference))
- return false;
-
if (context->lookup_type (reference, result))
return true;
+ if (context->query_in_progress (reference))
+ return false;
+
context->insert_query (reference);
std::pair<HIR::Enum *, HIR::EnumItem *> enum_candidiate
diff --git a/gcc/rust/typecheck/rust-type-util.h b/gcc/rust/typecheck/rust-type-util.h
index 03874a4..dd97f1e 100644
--- a/gcc/rust/typecheck/rust-type-util.h
+++ b/gcc/rust/typecheck/rust-type-util.h
@@ -25,33 +25,30 @@
namespace Rust {
namespace Resolver {
-bool
-query_type (HirId reference, TyTy::BaseType **result);
+bool query_type (HirId reference, TyTy::BaseType **result);
-bool
-types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
- location_t unify_locus, bool emit_errors);
+bool types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
+ location_t unify_locus, bool emit_errors);
-TyTy::BaseType *
-unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
- location_t unify_locus);
+TyTy::BaseType *unify_site (HirId id, TyTy::TyWithLocation lhs,
+ TyTy::TyWithLocation rhs, location_t unify_locus);
-TyTy::BaseType *
-unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
- location_t unify_locus, bool emit_errors, bool commit_if_ok,
- bool implicit_infer_vars, bool cleanup);
+TyTy::BaseType *unify_site_and (HirId id, TyTy::TyWithLocation lhs,
+ TyTy::TyWithLocation rhs,
+ location_t unify_locus, bool emit_errors,
+ bool commit_if_ok, bool implicit_infer_vars,
+ bool cleanup);
-TyTy::BaseType *
-coercion_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
- location_t coercion_locus);
+TyTy::BaseType *coercion_site (HirId id, TyTy::TyWithLocation lhs,
+ TyTy::TyWithLocation rhs,
+ location_t coercion_locus);
-TyTy::BaseType *
-try_coercion (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
- location_t coercion_locus);
+TyTy::BaseType *try_coercion (HirId id, TyTy::TyWithLocation lhs,
+ TyTy::TyWithLocation rhs,
+ location_t coercion_locus);
-TyTy::BaseType *
-cast_site (HirId id, TyTy::TyWithLocation from, TyTy::TyWithLocation to,
- location_t cast_locus);
+TyTy::BaseType *cast_site (HirId id, TyTy::TyWithLocation from,
+ TyTy::TyWithLocation to, location_t cast_locus);
AssociatedImplTrait *
lookup_associated_impl_block (const TyTy::TypeBoundPredicate &bound,
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index 9112b99..7b35848 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -575,43 +575,48 @@ TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
}
void
-TypeCheckContext::compute_inference_variables (bool error)
+TypeCheckContext::compute_inference_variables (bool emit_error)
{
- auto &mappings = Analysis::Mappings::get ();
-
// default inference variables if possible
iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
- // nothing to do
- if (ty->get_kind () != TyTy::TypeKind::INFER)
- return true;
+ return compute_infer_var (id, ty, emit_error);
+ });
+}
- TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
- TyTy::BaseType *default_type;
-
- rust_debug_loc (mappings.lookup_location (id),
- "trying to default infer-var: %s",
- infer_var->as_string ().c_str ());
- bool ok = infer_var->default_type (&default_type);
- if (!ok)
- {
- if (error)
- rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
- "type annotations needed");
- return true;
- }
-
- auto result
- = unify_site (id, TyTy::TyWithLocation (ty),
- TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
- rust_assert (result);
- rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
- result->set_ref (id);
- insert_type (Analysis::NodeMapping (mappings.get_current_crate (), 0, id,
- UNKNOWN_LOCAL_DEFID),
- result);
+bool
+TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
+ bool emit_error)
+{
+ auto &mappings = Analysis::Mappings::get ();
+ // nothing to do
+ if (ty->get_kind () != TyTy::TypeKind::INFER)
return true;
- });
+
+ TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
+ TyTy::BaseType *default_type;
+
+ rust_debug_loc (mappings.lookup_location (id),
+ "trying to default infer-var: %s",
+ infer_var->as_string ().c_str ());
+ bool ok = infer_var->default_type (&default_type);
+ if (!ok)
+ {
+ if (emit_error)
+ rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
+ "type annotations needed");
+ return true;
+ }
+
+ auto result
+ = unify_site (id, TyTy::TyWithLocation (ty),
+ TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
+ rust_assert (result);
+ rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
+ result->set_ref (id);
+ insert_implicit_type (id, result);
+
+ return true;
}
TyTy::VarianceAnalysis::CrateCtx &
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index e028a0a..5d42f80 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -226,7 +226,8 @@ TypeCheckBase::get_predicate_from_bound (
auto &final_seg = type_path.get_final_segment ();
switch (final_seg.get_type ())
{
- case HIR::TypePathSegment::SegmentType::GENERIC: {
+ case HIR::TypePathSegment::SegmentType::GENERIC:
+ {
auto &final_generic_seg
= static_cast<HIR::TypePathSegmentGeneric &> (final_seg);
if (final_generic_seg.has_generic_args ())
@@ -251,7 +252,8 @@ TypeCheckBase::get_predicate_from_bound (
}
break;
- case HIR::TypePathSegment::SegmentType::FUNCTION: {
+ case HIR::TypePathSegment::SegmentType::FUNCTION:
+ {
auto &final_function_seg
= static_cast<HIR::TypePathSegmentFunction &> (final_seg);
auto &fn = final_function_seg.get_function_path ();
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index 2e0830e..63bb1ff 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -171,7 +171,8 @@ TypeCheckCallExpr::visit (FnType &type)
{
case TyTy::TypeKind::ERROR:
return;
- case TyTy::TypeKind::INT: {
+ case TyTy::TypeKind::INT:
+ {
auto &int_ty
= static_cast<TyTy::IntType &> (*argument_expr_tyty);
if ((int_ty.get_int_kind () == TyTy::IntType::IntKind::I8)
@@ -186,7 +187,8 @@ TypeCheckCallExpr::visit (FnType &type)
}
break;
}
- case TyTy::TypeKind::UINT: {
+ case TyTy::TypeKind::UINT:
+ {
auto &uint_ty
= static_cast<TyTy::UintType &> (*argument_expr_tyty);
if ((uint_ty.get_uint_kind () == TyTy::UintType::UintKind::U8)
@@ -202,7 +204,8 @@ TypeCheckCallExpr::visit (FnType &type)
}
break;
}
- case TyTy::TypeKind::FLOAT: {
+ case TyTy::TypeKind::FLOAT:
+ {
if (static_cast<TyTy::FloatType &> (*argument_expr_tyty)
.get_float_kind ()
== TyTy::FloatType::FloatKind::F32)
@@ -216,14 +219,16 @@ TypeCheckCallExpr::visit (FnType &type)
}
break;
}
- case TyTy::TypeKind::BOOL: {
+ case TyTy::TypeKind::BOOL:
+ {
rich_location richloc (line_table, arg_locus);
richloc.add_fixit_replace ("cast the value to c_int: as c_int");
rust_error_at (arg_locus, ErrorCode::E0617,
"expected %<c_int%> variadic argument");
return;
}
- case TyTy::TypeKind::FNDEF: {
+ case TyTy::TypeKind::FNDEF:
+ {
rust_error_at (
arg_locus, ErrorCode::E0617,
"unexpected function definition type as variadic "
@@ -246,7 +251,7 @@ TypeCheckCallExpr::visit (FnType &type)
}
type.monomorphize ();
- resolved = type.get_return_type ()->clone ();
+ resolved = type.get_return_type ()->monomorphized_clone ();
}
void
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
index c897c13..aeefaa9 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -621,7 +621,8 @@ public:
ok = true;
return;
- case InferType::InferTypeKind::INTEGRAL: {
+ case InferType::InferTypeKind::INTEGRAL:
+ {
if (type.get_infer_kind () == InferType::InferTypeKind::INTEGRAL)
{
ok = true;
@@ -635,7 +636,8 @@ public:
}
break;
- case InferType::InferTypeKind::FLOAT: {
+ case InferType::InferTypeKind::FLOAT:
+ {
if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
{
ok = true;
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index bdb6474..28d311a 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -72,6 +72,12 @@ SubstitutionParamMapping::get_generic_param ()
return generic;
}
+const HIR::TypeParam &
+SubstitutionParamMapping::get_generic_param () const
+{
+ return generic;
+}
+
bool
SubstitutionParamMapping::needs_substitution () const
{
@@ -618,7 +624,6 @@ SubstitutionRef::get_mappings_from_generic_args (
if (args.get_binding_args ().size () > get_num_associated_bindings ())
{
rich_location r (line_table, args.get_locus ());
-
rust_error_at (r,
"generic item takes at most %lu type binding "
"arguments but %lu were supplied",
@@ -702,7 +707,19 @@ SubstitutionRef::get_mappings_from_generic_args (
return SubstitutionArgumentMappings::error ();
}
- SubstitutionArg subst_arg (&substitutions.at (offs), resolved);
+ const auto &param_mapping = substitutions.at (offs);
+ const auto &type_param = param_mapping.get_generic_param ();
+ if (type_param.from_impl_trait ())
+ {
+ rich_location r (line_table, arg->get_locus ());
+ r.add_fixit_remove (arg->get_locus ());
+ rust_error_at (r, ErrorCode::E0632,
+ "cannot provide explicit generic arguments when "
+ "%<impl Trait%> is used in argument position");
+ return SubstitutionArgumentMappings::error ();
+ }
+
+ SubstitutionArg subst_arg (&param_mapping, resolved);
offs++;
mappings.push_back (std::move (subst_arg));
}
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index e6ed1fc..2f5de23 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -60,6 +60,7 @@ public:
const ParamType *get_param_ty () const;
HIR::TypeParam &get_generic_param ();
+ const HIR::TypeParam &get_generic_param () const;
// this is used for the backend to override the HirId ref of the param to
// what the concrete type is for the rest of the context
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis.h b/gcc/rust/typecheck/rust-tyty-variance-analysis.h
index 9059a2f..282c6f3 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis.h
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis.h
@@ -41,9 +41,10 @@ private:
std::unique_ptr<GenericTyPerCrateCtx> private_ctx;
};
-std::vector<size_t>
-query_field_regions (const ADTType *parent, size_t variant_index,
- size_t field_index, const FreeRegions &parent_regions);
+std::vector<size_t> query_field_regions (const ADTType *parent,
+ size_t variant_index,
+ size_t field_index,
+ const FreeRegions &parent_regions);
/** Variance semilattice */
class Variance
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index f0f4a07..91c68ef 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -230,11 +230,13 @@ BaseType::is_unit () const
case NEVER:
return true;
- case TUPLE: {
+ case TUPLE:
+ {
return x->as<const TupleType> ()->num_fields () == 0;
}
- case ADT: {
+ case ADT:
+ {
auto adt = x->as<const ADTType> ();
if (adt->is_enum ())
return false;
@@ -546,17 +548,14 @@ BaseType::destructure () const
{
x = p->get ();
}
- // else if (auto p = x->try_as<const OpaqueType> ())
- // {
- // auto pr = p->resolve ();
-
- // rust_debug ("XXXXXX")
-
- // if (pr == x)
- // return pr;
+ else if (auto p = x->try_as<const OpaqueType> ())
+ {
+ auto pr = p->resolve ();
+ if (pr == x)
+ return pr;
- // x = pr;
- // }
+ x = pr;
+ }
else
{
return x;
@@ -894,28 +893,32 @@ BaseType::has_substitutions_defined () const
case OPAQUE:
return false;
- case PROJECTION: {
+ case PROJECTION:
+ {
const ProjectionType &p = *static_cast<const ProjectionType *> (x);
const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (p);
return ref.has_substitutions ();
}
break;
- case FNDEF: {
+ case FNDEF:
+ {
const FnType &fn = *static_cast<const FnType *> (x);
const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (fn);
return ref.has_substitutions ();
}
break;
- case ADT: {
+ case ADT:
+ {
const ADTType &adt = *static_cast<const ADTType *> (x);
const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (adt);
return ref.has_substitutions ();
}
break;
- case CLOSURE: {
+ case CLOSURE:
+ {
const ClosureType &closure = *static_cast<const ClosureType *> (x);
const SubstitutionRef &ref
= static_cast<const SubstitutionRef &> (closure);
@@ -956,28 +959,32 @@ BaseType::needs_generic_substitutions () const
case OPAQUE:
return false;
- case PROJECTION: {
+ case PROJECTION:
+ {
const ProjectionType &p = *static_cast<const ProjectionType *> (x);
const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (p);
return ref.needs_substitution ();
}
break;
- case FNDEF: {
+ case FNDEF:
+ {
const FnType &fn = *static_cast<const FnType *> (x);
const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (fn);
return ref.needs_substitution ();
}
break;
- case ADT: {
+ case ADT:
+ {
const ADTType &adt = *static_cast<const ADTType *> (x);
const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (adt);
return ref.needs_substitution ();
}
break;
- case CLOSURE: {
+ case CLOSURE:
+ {
const ClosureType &closure = *static_cast<const ClosureType *> (x);
const SubstitutionRef &ref
= static_cast<const SubstitutionRef &> (closure);
@@ -996,28 +1003,32 @@ BaseType::get_subst_argument_mappings () const
const TyTy::BaseType *x = destructure ();
switch (x->get_kind ())
{
- case PROJECTION: {
+ case PROJECTION:
+ {
const auto &p = *static_cast<const ProjectionType *> (x);
const auto &ref = static_cast<const SubstitutionRef &> (p);
return ref.get_substitution_arguments ();
}
break;
- case FNDEF: {
+ case FNDEF:
+ {
const auto &fn = *static_cast<const FnType *> (x);
const auto &ref = static_cast<const SubstitutionRef &> (fn);
return ref.get_substitution_arguments ();
}
break;
- case ADT: {
+ case ADT:
+ {
const auto &adt = *static_cast<const ADTType *> (x);
const auto &ref = static_cast<const SubstitutionRef &> (adt);
return ref.get_substitution_arguments ();
}
break;
- case CLOSURE: {
+ case CLOSURE:
+ {
const auto &closure = *static_cast<const ClosureType *> (x);
const auto &ref = static_cast<const SubstitutionRef &> (closure);
return ref.get_substitution_arguments ();
@@ -1140,13 +1151,15 @@ InferType::default_type (BaseType **type) const
case GENERAL:
return false;
- case INTEGRAL: {
+ case INTEGRAL:
+ {
ok = context->lookup_builtin ("i32", type);
rust_assert (ok);
return ok;
}
- case FLOAT: {
+ case FLOAT:
+ {
ok = context->lookup_builtin ("f64", type);
rust_assert (ok);
return ok;
@@ -1269,7 +1282,8 @@ InferType::apply_primitive_type_hint (const BaseType &hint)
default_hint.kind = hint.get_kind ();
break;
- case INT: {
+ case INT:
+ {
infer_kind = INTEGRAL;
default_hint.kind = hint.get_kind ();
default_hint.shint = TypeHint::SignedHint::SIGNED;
@@ -1294,7 +1308,8 @@ InferType::apply_primitive_type_hint (const BaseType &hint)
}
break;
- case UINT: {
+ case UINT:
+ {
infer_kind = INTEGRAL;
default_hint.kind = hint.get_kind ();
default_hint.shint = TypeHint::SignedHint::UNSIGNED;
@@ -1319,7 +1334,8 @@ InferType::apply_primitive_type_hint (const BaseType &hint)
}
break;
- case TypeKind::FLOAT: {
+ case TypeKind::FLOAT:
+ {
infer_kind = FLOAT;
default_hint.shint = TypeHint::SignedHint::SIGNED;
default_hint.kind = hint.get_kind ();
@@ -1992,7 +2008,7 @@ TupleType::get_name () const
std::string fields_buffer;
for (const TyVar &field : get_fields ())
{
- fields_buffer += field.get_tyty ()->as_string ();
+ fields_buffer += field.get_tyty ()->get_name ();
bool has_next = (i + 1) < get_fields ().size ();
fields_buffer += has_next ? ", " : "";
i++;
@@ -3624,28 +3640,7 @@ BaseType *
OpaqueType::resolve () const
{
TyVar var (get_ty_ref ());
- BaseType *r = var.get_tyty ();
-
- while (r->get_kind () == TypeKind::OPAQUE)
- {
- OpaqueType *rr = static_cast<OpaqueType *> (r);
- if (!rr->can_resolve ())
- break;
-
- TyVar v (rr->get_ty_ref ());
- BaseType *n = v.get_tyty ();
-
- // fix infinite loop
- if (r == n)
- break;
-
- r = n;
- }
-
- if (r->get_kind () == TypeKind::OPAQUE && (r->get_ref () == r->get_ty_ref ()))
- return TyVar (r->get_ty_ref ()).get_tyty ();
-
- return r;
+ return var.get_tyty ();
}
bool
@@ -3655,41 +3650,9 @@ OpaqueType::is_equal (const BaseType &other) const
if (can_resolve () != other2.can_resolve ())
return false;
- if (can_resolve ())
- return resolve ()->can_eq (other2.resolve (), false);
-
return bounds_compatible (other, UNDEF_LOCATION, false);
}
-OpaqueType *
-OpaqueType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
-{
- // SubstitutionArg arg = SubstitutionArg::error ();
- // bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
- // if (!ok || arg.is_error ())
- // return this;
-
- // OpaqueType *p = static_cast<OpaqueType *> (clone ());
- // subst_mappings.on_param_subst (*p, arg);
-
- // // there are two cases one where we substitute directly to a new PARAM and
- // // otherwise
- // if (arg.get_tyty ()->get_kind () == TyTy::TypeKind::PARAM)
- // {
- // p->set_ty_ref (arg.get_tyty ()->get_ref ());
- // return p;
- // }
-
- // // this is the new subst that this needs to pass
- // p->set_ref (mappings.get_next_hir_id ());
- // p->set_ty_ref (arg.get_tyty ()->get_ref ());
-
- // return p;
-
- rust_unreachable ();
- return nullptr;
-}
-
// StrType
StrType::StrType (HirId ref, std::set<HirId> refs)
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 1cada9a..c759521 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -78,8 +78,7 @@ enum TypeKind
ERROR
};
-extern bool
-is_primitive_type_kind (TypeKind kind);
+extern bool is_primitive_type_kind (TypeKind kind);
class TypeKindFormat
{
@@ -268,8 +267,8 @@ public:
{}
WARN_UNUSED_RESULT virtual size_t get_num_params () const = 0;
- WARN_UNUSED_RESULT virtual BaseType *
- get_param_type_at (size_t index) const = 0;
+ WARN_UNUSED_RESULT virtual BaseType *get_param_type_at (size_t index) const
+ = 0;
WARN_UNUSED_RESULT virtual BaseType *get_return_type () const = 0;
};
@@ -441,8 +440,6 @@ public:
std::string get_name () const override final;
bool is_equal (const BaseType &other) const override;
-
- OpaqueType *handle_substitions (SubstitutionArgumentMappings &mappings);
};
class StructFieldType
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 294b677..9144f2e 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -53,6 +53,22 @@ UnifyRules::Resolve (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
}
TyTy::BaseType *
+UnifyRules::resolve_subtype (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs)
+{
+ TyTy::BaseType *result
+ = UnifyRules::Resolve (lhs, rhs, locus, commit_flag, emit_error, infer_flag,
+ commits, infers);
+
+ // If the recursive call resulted in an error and would have emitted an error
+ // message, disable error emission for the current level to avoid duplicate
+ // errors
+ if (result->get_kind () == TyTy::TypeKind::ERROR && emit_error)
+ emit_error = false;
+
+ return result;
+}
+
+TyTy::BaseType *
UnifyRules::get_base ()
{
return lhs.get_ty ()->destructure ();
@@ -69,7 +85,6 @@ UnifyRules::commit (TyTy::BaseType *base, TyTy::BaseType *other,
TyTy::BaseType *resolved)
{
TypeCheckContext &context = *TypeCheckContext::get ();
- Analysis::Mappings &mappings = Analysis::Mappings::get ();
TyTy::BaseType *b = base->destructure ();
TyTy::BaseType *o = other->destructure ();
@@ -102,13 +117,8 @@ UnifyRules::commit (TyTy::BaseType *base, TyTy::BaseType *other,
continue;
// if any of the types are inference variables lets fix them
- if (ref_tyty->get_kind () == TyTy::TypeKind::INFER)
- {
- auto node = Analysis::NodeMapping (mappings.get_current_crate (),
- UNKNOWN_NODEID, ref,
- UNKNOWN_LOCAL_DEFID);
- context.insert_type (node, resolved->clone ());
- }
+ if (ref_tyty->is<TyTy::InferType> ())
+ context.insert_implicit_type (ref, resolved);
}
}
}
@@ -328,30 +338,33 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
switch (ltype->get_infer_kind ())
{
case TyTy::InferType::InferTypeKind::GENERAL:
return rtype->clone ();
- case TyTy::InferType::InferTypeKind::INTEGRAL: {
+ case TyTy::InferType::InferTypeKind::INTEGRAL:
+ {
bool is_valid = r->get_infer_kind ()
== TyTy::InferType::InferTypeKind::INTEGRAL
|| r->get_infer_kind ()
== TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return rtype->clone ();
+ return rtype;
}
break;
- case TyTy::InferType::InferTypeKind::FLOAT: {
+ case TyTy::InferType::InferTypeKind::FLOAT:
+ {
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
|| r->get_infer_kind ()
== TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return rtype->clone ();
+ return rtype;
}
break;
}
@@ -361,7 +374,8 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
case TyTy::INT:
case TyTy::UINT:
case TyTy::USIZE:
- case TyTy::ISIZE: {
+ case TyTy::ISIZE:
+ {
bool is_valid = (ltype->get_infer_kind ()
== TyTy::InferType::InferTypeKind::GENERAL)
|| (ltype->get_infer_kind ()
@@ -369,12 +383,13 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
if (is_valid)
{
ltype->apply_primitive_type_hint (*rtype);
- return rtype->clone ();
+ return rtype;
}
}
break;
- case TyTy::FLOAT: {
+ case TyTy::FLOAT:
+ {
bool is_valid = (ltype->get_infer_kind ()
== TyTy::InferType::InferTypeKind::GENERAL)
|| (ltype->get_infer_kind ()
@@ -382,7 +397,7 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
if (is_valid)
{
ltype->apply_primitive_type_hint (*rtype);
- return rtype->clone ();
+ return rtype;
}
}
break;
@@ -404,7 +419,8 @@ UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
- case TyTy::OPAQUE: {
+ case TyTy::OPAQUE:
+ {
bool is_valid = (ltype->get_infer_kind ()
== TyTy::InferType::InferTypeKind::GENERAL);
if (is_valid)
@@ -424,7 +440,8 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -433,7 +450,8 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::ADT: {
+ case TyTy::ADT:
+ {
TyTy::ADTType &type = *static_cast<TyTy::ADTType *> (rtype);
if (ltype->get_adt_kind () != type.get_adt_kind ())
{
@@ -469,11 +487,8 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
TyTy::BaseType *other_field_ty = other_field->get_field_type ();
TyTy::BaseType *unified_ty
- = UnifyRules::Resolve (TyTy::TyWithLocation (this_field_ty),
- TyTy::TyWithLocation (other_field_ty),
- locus, commit_flag,
- false /* emit_error */, infer_flag,
- commits, infers);
+ = resolve_subtype (TyTy::TyWithLocation (this_field_ty),
+ TyTy::TyWithLocation (other_field_ty));
if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -495,11 +510,8 @@ UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
auto pa = a.get_param_ty ();
auto pb = b.get_param_ty ();
- auto res
- = UnifyRules::Resolve (TyTy::TyWithLocation (pa),
- TyTy::TyWithLocation (pb), locus,
- commit_flag, false /* emit_error */,
- infer_flag, commits, infers);
+ auto res = resolve_subtype (TyTy::TyWithLocation (pa),
+ TyTy::TyWithLocation (pb));
if (res->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -544,7 +556,8 @@ UnifyRules::expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -589,7 +602,8 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -598,16 +612,15 @@ UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::REF: {
+ case TyTy::REF:
+ {
TyTy::ReferenceType &type = *static_cast<TyTy::ReferenceType *> (rtype);
auto base_type = ltype->get_base ();
auto other_base_type = type.get_base ();
TyTy::BaseType *base_resolved
- = UnifyRules::Resolve (TyTy::TyWithLocation (base_type),
- TyTy::TyWithLocation (other_base_type), locus,
- commit_flag, false /* emit_error */,
- infer_flag, commits, infers);
+ = resolve_subtype (TyTy::TyWithLocation (base_type),
+ TyTy::TyWithLocation (other_base_type));
if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -660,7 +673,8 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -669,16 +683,15 @@ UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::POINTER: {
+ case TyTy::POINTER:
+ {
TyTy::PointerType &type = *static_cast<TyTy::PointerType *> (rtype);
auto base_type = ltype->get_base ();
auto other_base_type = type.get_base ();
TyTy::BaseType *base_resolved
- = UnifyRules::Resolve (TyTy::TyWithLocation (base_type),
- TyTy::TyWithLocation (other_base_type), locus,
- commit_flag, false /* emit_error */,
- infer_flag, commits, infers);
+ = resolve_subtype (TyTy::TyWithLocation (base_type),
+ TyTy::TyWithLocation (other_base_type));
if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -731,7 +744,8 @@ UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -740,7 +754,8 @@ UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::PARAM: {
+ case TyTy::PARAM:
+ {
TyTy::ParamType &type = *static_cast<TyTy::ParamType *> (rtype);
// bool symbol_matches
// = ltype->get_symbol ().compare (type.get_symbol ()) == 0;
@@ -793,7 +808,8 @@ UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -802,12 +818,12 @@ UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::ARRAY: {
+ case TyTy::ARRAY:
+ {
TyTy::ArrayType &type = *static_cast<TyTy::ArrayType *> (rtype);
- TyTy::BaseType *element_unify = UnifyRules::Resolve (
- TyTy::TyWithLocation (ltype->get_element_type ()),
- TyTy::TyWithLocation (type.get_element_type ()), locus, commit_flag,
- false /* emit_error*/, infer_flag, commits, infers);
+ TyTy::BaseType *element_unify
+ = resolve_subtype (TyTy::TyWithLocation (ltype->get_element_type ()),
+ TyTy::TyWithLocation (type.get_element_type ()));
if (element_unify->get_kind () != TyTy::TypeKind::ERROR)
{
@@ -853,7 +869,8 @@ UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -862,12 +879,12 @@ UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::SLICE: {
+ case TyTy::SLICE:
+ {
TyTy::SliceType &type = *static_cast<TyTy::SliceType *> (rtype);
- TyTy::BaseType *element_unify = UnifyRules::Resolve (
- TyTy::TyWithLocation (ltype->get_element_type ()),
- TyTy::TyWithLocation (type.get_element_type ()), locus, commit_flag,
- false /* emit_error*/, infer_flag, commits, infers);
+ TyTy::BaseType *element_unify
+ = resolve_subtype (TyTy::TyWithLocation (ltype->get_element_type ()),
+ TyTy::TyWithLocation (type.get_element_type ()));
if (element_unify->get_kind () != TyTy::TypeKind::ERROR)
{
@@ -912,7 +929,8 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -921,7 +939,8 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::FNDEF: {
+ case TyTy::FNDEF:
+ {
TyTy::FnType &type = *static_cast<TyTy::FnType *> (rtype);
if (ltype->num_params () != type.num_params ())
{
@@ -933,21 +952,17 @@ UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
auto a = ltype->param_at (i).get_type ();
auto b = type.param_at (i).get_type ();
- auto unified_param
- = UnifyRules::Resolve (TyTy::TyWithLocation (a),
- TyTy::TyWithLocation (b), locus,
- commit_flag, false /* emit_errors */,
- infer_flag, commits, infers);
+ auto unified_param = resolve_subtype (TyTy::TyWithLocation (a),
+ TyTy::TyWithLocation (b));
if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
}
}
- auto unified_return = UnifyRules::Resolve (
- TyTy::TyWithLocation (ltype->get_return_type ()),
- TyTy::TyWithLocation (type.get_return_type ()), locus, commit_flag,
- false /* emit_errors */, infer_flag, commits, infers);
+ auto unified_return
+ = resolve_subtype (TyTy::TyWithLocation (ltype->get_return_type ()),
+ TyTy::TyWithLocation (type.get_return_type ()));
if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -1003,7 +1018,8 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1012,7 +1028,8 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::FNPTR: {
+ case TyTy::FNPTR:
+ {
TyTy::FnPtr &type = *static_cast<TyTy::FnPtr *> (rtype);
if (ltype->num_params () != type.num_params ())
{
@@ -1024,21 +1041,17 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
auto a = ltype->get_param_type_at (i);
auto b = type.get_param_type_at (i);
- auto unified_param
- = UnifyRules::Resolve (TyTy::TyWithLocation (a),
- TyTy::TyWithLocation (b), locus,
- commit_flag, false /* emit_errors */,
- infer_flag, commits, infers);
+ auto unified_param = resolve_subtype (TyTy::TyWithLocation (a),
+ TyTy::TyWithLocation (b));
if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
}
}
- auto unified_return = UnifyRules::Resolve (
- TyTy::TyWithLocation (ltype->get_return_type ()),
- TyTy::TyWithLocation (type.get_return_type ()), locus, commit_flag,
- false /* emit_errors */, infer_flag, commits, infers);
+ auto unified_return
+ = resolve_subtype (TyTy::TyWithLocation (ltype->get_return_type ()),
+ TyTy::TyWithLocation (type.get_return_type ()));
if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -1048,16 +1061,15 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::FNDEF: {
+ case TyTy::FNDEF:
+ {
TyTy::FnType &type = *static_cast<TyTy::FnType *> (rtype);
auto this_ret_type = ltype->get_return_type ();
auto other_ret_type = type.get_return_type ();
auto unified_result
- = UnifyRules::Resolve (TyTy::TyWithLocation (this_ret_type),
- TyTy::TyWithLocation (other_ret_type), locus,
- commit_flag, false /*emit_errors*/, infer_flag,
- commits, infers);
+ = resolve_subtype (TyTy::TyWithLocation (this_ret_type),
+ TyTy::TyWithLocation (other_ret_type));
if (unified_result->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -1074,10 +1086,8 @@ UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
auto other_param = type.param_at (i).get_type ();
auto unified_param
- = UnifyRules::Resolve (TyTy::TyWithLocation (this_param),
- TyTy::TyWithLocation (other_param), locus,
- commit_flag, false /* emit_errors */,
- infer_flag, commits, infers);
+ = resolve_subtype (TyTy::TyWithLocation (this_param),
+ TyTy::TyWithLocation (other_param));
if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -1120,7 +1130,8 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1129,7 +1140,8 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::TUPLE: {
+ case TyTy::TUPLE:
+ {
TyTy::TupleType &type = *static_cast<TyTy::TupleType *> (rtype);
if (ltype->num_fields () != type.num_fields ())
{
@@ -1143,10 +1155,8 @@ UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
TyTy::BaseType *fo = type.get_field (i);
TyTy::BaseType *unified_ty
- = UnifyRules::Resolve (TyTy::TyWithLocation (bo),
- TyTy::TyWithLocation (fo), locus,
- commit_flag, false /* emit_errors */,
- infer_flag, commits, infers);
+ = resolve_subtype (TyTy::TyWithLocation (bo),
+ TyTy::TyWithLocation (fo));
if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (0);
@@ -1191,7 +1201,8 @@ UnifyRules::expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1239,7 +1250,8 @@ UnifyRules::expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1287,7 +1299,8 @@ UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
@@ -1300,7 +1313,8 @@ UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::INT: {
+ case TyTy::INT:
+ {
TyTy::IntType &type = *static_cast<TyTy::IntType *> (rtype);
bool is_valid = ltype->get_int_kind () == type.get_int_kind ();
if (is_valid)
@@ -1342,7 +1356,8 @@ UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
@@ -1355,7 +1370,8 @@ UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::UINT: {
+ case TyTy::UINT:
+ {
TyTy::UintType &type = *static_cast<TyTy::UintType *> (rtype);
bool is_valid = ltype->get_uint_kind () == type.get_uint_kind ();
if (is_valid)
@@ -1397,7 +1413,8 @@ UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
@@ -1410,7 +1427,8 @@ UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::FLOAT: {
+ case TyTy::FLOAT:
+ {
TyTy::FloatType &type = *static_cast<TyTy::FloatType *> (rtype);
bool is_valid = ltype->get_float_kind () == type.get_float_kind ();
if (is_valid)
@@ -1452,7 +1470,8 @@ UnifyRules::expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
@@ -1500,7 +1519,8 @@ UnifyRules::expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
@@ -1548,7 +1568,8 @@ UnifyRules::expect_never (TyTy::NeverType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1569,7 +1590,8 @@ UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1619,7 +1641,8 @@ UnifyRules::expect_projection (TyTy::ProjectionType *ltype,
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1666,7 +1689,8 @@ UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1675,7 +1699,8 @@ UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::DYNAMIC: {
+ case TyTy::DYNAMIC:
+ {
TyTy::DynamicObjectType &type
= *static_cast<TyTy::DynamicObjectType *> (rtype);
if (ltype->num_specified_bounds () != type.num_specified_bounds ())
@@ -1725,7 +1750,8 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
{
switch (rtype->get_kind ())
{
- case TyTy::INFER: {
+ case TyTy::INFER:
+ {
TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
@@ -1734,26 +1760,25 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
}
break;
- case TyTy::CLOSURE: {
+ case TyTy::CLOSURE:
+ {
TyTy::ClosureType &type = *static_cast<TyTy::ClosureType *> (rtype);
if (ltype->get_def_id () != type.get_def_id ())
{
return new TyTy::ErrorType (0);
}
- TyTy::BaseType *args_res = UnifyRules::Resolve (
- TyTy::TyWithLocation (&ltype->get_parameters ()),
- TyTy::TyWithLocation (&type.get_parameters ()), locus, commit_flag,
- false /* emit_error */, infer_flag, commits, infers);
+ TyTy::BaseType *args_res
+ = resolve_subtype (TyTy::TyWithLocation (&ltype->get_parameters ()),
+ TyTy::TyWithLocation (&type.get_parameters ()));
if (args_res->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
}
- TyTy::BaseType *res = UnifyRules::Resolve (
- TyTy::TyWithLocation (&ltype->get_result_type ()),
- TyTy::TyWithLocation (&type.get_result_type ()), locus, commit_flag,
- false /* emit_error */, infer_flag, commits, infers);
+ TyTy::BaseType *res
+ = resolve_subtype (TyTy::TyWithLocation (&ltype->get_result_type ()),
+ TyTy::TyWithLocation (&type.get_result_type ()));
if (res == nullptr || res->get_kind () == TyTy::TypeKind::ERROR)
{
return new TyTy::ErrorType (0);
@@ -1794,59 +1819,47 @@ UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
TyTy::BaseType *
UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
{
- switch (rtype->get_kind ())
+ if (rtype->is<TyTy::OpaqueType> ())
{
- case TyTy::INFER: {
- TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
- bool is_valid
- = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
- if (is_valid)
- return ltype->clone ();
- }
- break;
+ TyTy::OpaqueType *ro = rtype->as<TyTy::OpaqueType> ();
+ if (!ltype->is_equal (*ro))
+ return new TyTy::ErrorType (0);
- case TyTy::OPAQUE: {
- auto &type = *static_cast<TyTy::OpaqueType *> (rtype);
- if (ltype->num_specified_bounds () != type.num_specified_bounds ())
- {
- return new TyTy::ErrorType (0);
- }
+ if (ltype->can_resolve () && ro->can_resolve ())
+ {
+ auto lr = ltype->resolve ();
+ auto rr = ro->resolve ();
- if (!ltype->bounds_compatible (type, locus, true))
- {
+ auto res = resolve_subtype (TyTy::TyWithLocation (lr),
+ TyTy::TyWithLocation (rr));
+ if (res->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (0);
- }
-
- return ltype->clone ();
- }
- break;
-
- case TyTy::CLOSURE:
- case TyTy::SLICE:
- case TyTy::PARAM:
- case TyTy::POINTER:
- case TyTy::STR:
- case TyTy::ADT:
- case TyTy::REF:
- case TyTy::ARRAY:
- case TyTy::FNDEF:
- case TyTy::FNPTR:
- case TyTy::TUPLE:
- case TyTy::BOOL:
- case TyTy::CHAR:
- case TyTy::INT:
- case TyTy::UINT:
- case TyTy::FLOAT:
- case TyTy::USIZE:
- case TyTy::ISIZE:
- case TyTy::NEVER:
- case TyTy::PLACEHOLDER:
- case TyTy::PROJECTION:
- case TyTy::DYNAMIC:
- case TyTy::ERROR:
- return new TyTy::ErrorType (0);
+ }
+ else if (ltype->can_resolve ())
+ {
+ auto lr = ltype->resolve ();
+ ro->set_ty_ref (lr->get_ref ());
+ }
+ else if (ro->can_resolve ())
+ {
+ auto rr = ro->resolve ();
+ ltype->set_ty_ref (rr->get_ref ());
+ }
}
- return new TyTy::ErrorType (0);
+ else if (ltype->can_resolve ())
+ {
+ auto underly = ltype->resolve ();
+ auto res = resolve_subtype (TyTy::TyWithLocation (underly),
+ TyTy::TyWithLocation (rtype));
+ if (res->get_kind () == TyTy::TypeKind::ERROR)
+ return new TyTy::ErrorType (0);
+ }
+ else
+ {
+ ltype->set_ty_ref (rtype->get_ref ());
+ }
+
+ return ltype;
}
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-unify.h b/gcc/rust/typecheck/rust-unify.h
index 5ff3b7c..f64f0ed 100644
--- a/gcc/rust/typecheck/rust-unify.h
+++ b/gcc/rust/typecheck/rust-unify.h
@@ -91,6 +91,9 @@ private:
std::vector<CommitSite> &commits,
std::vector<InferenceSite> &infers);
+ TyTy::BaseType *resolve_subtype (TyTy::TyWithLocation lhs,
+ TyTy::TyWithLocation rhs);
+
void emit_type_mismatch () const;
void emit_abi_mismatch (const TyTy::FnType &expected,
const TyTy::FnType &got) const;
diff --git a/gcc/rust/util/rust-abi.h b/gcc/rust/util/rust-abi.h
index a0180ed..357a5db 100644
--- a/gcc/rust/util/rust-abi.h
+++ b/gcc/rust/util/rust-abi.h
@@ -34,11 +34,9 @@ enum ABI
SYSV64
};
-extern Rust::ABI
-get_abi_from_string (const std::string &abi);
+extern Rust::ABI get_abi_from_string (const std::string &abi);
-extern std::string
-get_string_from_abi (Rust::ABI abi);
+extern std::string get_string_from_abi (Rust::ABI abi);
} // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index c77e99c..9bf4f77 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -221,7 +221,8 @@ check_doc_attribute (const AST::Attribute &attribute)
break;
// FIXME: Handle them as well
- case AST::AttrInput::TOKEN_TREE: {
+ case AST::AttrInput::TOKEN_TREE:
+ {
// FIXME: This doesn't check for #[doc(alias(...))]
const auto &option = static_cast<const AST::DelimTokenTree &> (
attribute.get_attr_input ());
diff --git a/gcc/rust/util/rust-base62.h b/gcc/rust/util/rust-base62.h
index e751c95..5fd7a37 100644
--- a/gcc/rust/util/rust-base62.h
+++ b/gcc/rust/util/rust-base62.h
@@ -26,8 +26,7 @@ namespace Rust {
/**
* Get the Base62 representation of an integer
*/
-std::string
-base62_integer (uint64_t value);
+std::string base62_integer (uint64_t value);
} // namespace Rust
diff --git a/gcc/rust/util/rust-canonical-path.h b/gcc/rust/util/rust-canonical-path.h
index 4d8f954..079ae76 100644
--- a/gcc/rust/util/rust-canonical-path.h
+++ b/gcc/rust/util/rust-canonical-path.h
@@ -57,10 +57,11 @@ public:
return *this;
}
- static CanonicalPath new_seg (NodeId id, const std::string &path)
+ static CanonicalPath new_seg (NodeId id, std::string path)
{
rust_assert (!path.empty ());
- return CanonicalPath ({std::pair<NodeId, std::string> (id, path)},
+ return CanonicalPath ({std::pair<NodeId, std::string> (id,
+ std::move (path))},
UNKNOWN_CRATENUM);
}
@@ -68,14 +69,18 @@ public:
trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg,
const CanonicalPath &impl_type_seg)
{
- return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + " as "
+ // https://doc.rust-lang.org/reference/paths.html#canonical-paths
+ // should be "<X>"?
+ return CanonicalPath::new_seg (id, "<impl " + impl_type_seg.get () + " as "
+ trait_seg.get () + ">");
}
static CanonicalPath inherent_impl_seg (NodeId id,
const CanonicalPath &impl_type_seg)
{
- return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + ">");
+ // https://doc.rust-lang.org/reference/paths.html#canonical-paths
+ // should be "<X as Y>"?
+ return CanonicalPath::new_seg (id, "<impl " + impl_type_seg.get () + ">");
}
std::string get () const
diff --git a/gcc/rust/util/rust-dir-owner.h b/gcc/rust/util/rust-dir-owner.h
index dcb45d8..fb72bb1 100644
--- a/gcc/rust/util/rust-dir-owner.h
+++ b/gcc/rust/util/rust-dir-owner.h
@@ -26,8 +26,7 @@
namespace Rust {
// extracts the owned subdirectory name from a file name
-bool
-get_file_subdir (const std::string &filename, std::string &subdir);
+bool get_file_subdir (const std::string &filename, std::string &subdir);
} // namespace Rust
diff --git a/gcc/rust/util/rust-edition.h b/gcc/rust/util/rust-edition.h
index d034ea0..532fedb 100644
--- a/gcc/rust/util/rust-edition.h
+++ b/gcc/rust/util/rust-edition.h
@@ -33,8 +33,7 @@ enum class Edition
E2021
};
-Edition
-get_rust_edition ();
+Edition get_rust_edition ();
} // namespace Rust
diff --git a/gcc/rust/util/rust-punycode.h b/gcc/rust/util/rust-punycode.h
index a939f05..75260ce 100644
--- a/gcc/rust/util/rust-punycode.h
+++ b/gcc/rust/util/rust-punycode.h
@@ -27,8 +27,7 @@ namespace Rust {
/* Encode a string as punycode. Returns a string if encoding is successful.
* Returns nullopt otherwise. Note that a returned string contains only ASCII
* characters and does not start with `xn--`. */
-tl::optional<std::string>
-encode_punycode (const Utf8String &src);
+tl::optional<std::string> encode_punycode (const Utf8String &src);
} // namespace Rust
@@ -36,8 +35,7 @@ encode_punycode (const Utf8String &src);
namespace selftest {
-void
-rust_punycode_encode_test ();
+void rust_punycode_encode_test ();
} // namespace selftest
diff --git a/gcc/rust/util/rust-token-converter.cc b/gcc/rust/util/rust-token-converter.cc
index fc34adb..52172f4 100644
--- a/gcc/rust/util/rust-token-converter.cc
+++ b/gcc/rust/util/rust-token-converter.cc
@@ -202,7 +202,8 @@ convert (const std::vector<const_TokenPtr> &tokens)
case PERCENT_EQ:
case SCOPE_RESOLUTION:
case NOT_EQUAL:
- case EQUAL_EQUAL: {
+ case EQUAL_EQUAL:
+ {
auto str = token->as_string ();
auto it = str.cbegin ();
for (; it != str.cend () - 1; it++)
@@ -260,9 +261,8 @@ convert (const std::vector<const_TokenPtr> &tokens)
return trees.back ();
}
-static void
-from_tokenstream (const ProcMacro::TokenStream &ts,
- std::vector<const_TokenPtr> &result);
+static void from_tokenstream (const ProcMacro::TokenStream &ts,
+ std::vector<const_TokenPtr> &result);
/**
* Append the token corresponding to a given Ident to a vector.
diff --git a/gcc/rust/util/rust-token-converter.h b/gcc/rust/util/rust-token-converter.h
index 5405d6e..6e4af50 100644
--- a/gcc/rust/util/rust-token-converter.h
+++ b/gcc/rust/util/rust-token-converter.h
@@ -23,14 +23,11 @@
namespace Rust {
-ProcMacro::TokenStream
-convert (const std::vector<const_TokenPtr> &tokens);
+ProcMacro::TokenStream convert (const std::vector<const_TokenPtr> &tokens);
-std::vector<const_TokenPtr>
-convert (const ProcMacro::TokenStream &ts);
+std::vector<const_TokenPtr> convert (const ProcMacro::TokenStream &ts);
-ProcMacro::Literal
-convert_literal (const_TokenPtr lit);
+ProcMacro::Literal convert_literal (const_TokenPtr lit);
} // namespace Rust
diff --git a/gcc/rust/util/rust-unicode.h b/gcc/rust/util/rust-unicode.h
index 6a6526d..6579b80 100644
--- a/gcc/rust/util/rust-unicode.h
+++ b/gcc/rust/util/rust-unicode.h
@@ -59,20 +59,15 @@ public:
Utf8String nfc_normalize () const;
};
-bool
-is_alphabetic (uint32_t codepoint);
+bool is_alphabetic (uint32_t codepoint);
-bool
-is_ascii_only (const std::string &str);
+bool is_ascii_only (const std::string &str);
-bool
-is_numeric (uint32_t codepoint);
+bool is_numeric (uint32_t codepoint);
-bool
-is_nfc_qc_no (uint32_t codepoint);
+bool is_nfc_qc_no (uint32_t codepoint);
-bool
-is_nfc_qc_maybe (uint32_t codepoint);
+bool is_nfc_qc_maybe (uint32_t codepoint);
enum class QuickCheckResult
{
@@ -81,8 +76,7 @@ enum class QuickCheckResult
MAYBE
};
-QuickCheckResult
-nfc_quick_check (const std::vector<Codepoint> &s);
+QuickCheckResult nfc_quick_check (const std::vector<Codepoint> &s);
} // namespace Rust
@@ -90,14 +84,11 @@ nfc_quick_check (const std::vector<Codepoint> &s);
namespace selftest {
-void
-rust_nfc_qc_test ();
+void rust_nfc_qc_test ();
-void
-rust_utf8_normalize_test ();
+void rust_utf8_normalize_test ();
-void
-rust_utf8_property_test ();
+void rust_utf8_property_test ();
} // namespace selftest
diff --git a/gcc/rust/util/rust-unwrap-segment.h b/gcc/rust/util/rust-unwrap-segment.h
index bebdc3a..af3a237 100644
--- a/gcc/rust/util/rust-unwrap-segment.h
+++ b/gcc/rust/util/rust-unwrap-segment.h
@@ -83,14 +83,11 @@ public:
/*
* Used to get the node id of a path segment object
*/
-NodeId
-unwrap_segment_node_id (const AST::TypePathSegment &seg);
+NodeId unwrap_segment_node_id (const AST::TypePathSegment &seg);
-NodeId
-unwrap_segment_node_id (const AST::SimplePathSegment &seg);
+NodeId unwrap_segment_node_id (const AST::SimplePathSegment &seg);
-NodeId
-unwrap_segment_node_id (const AST::PathExprSegment &seg);
+NodeId unwrap_segment_node_id (const AST::PathExprSegment &seg);
template <class T>
NodeId
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b43cbb7..f9f3de6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,193 @@
+2025-08-04 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/121351
+ * g++.dg/cpp2a/concepts-using6.C: New test.
+
+2025-08-04 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/121351
+ PR c++/119859
+ * g++.dg/cpp2a/concepts-using5.C: New test.
+ * g++.dg/cpp2a/concepts-using5a.C: New test.
+
+2025-08-04 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/120620
+ * g++.dg/cpp2a/constexpr-dynamic19.C: New test.
+ * g++.dg/cpp2a/constexpr-dynamic1a.C: New test.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ PR diagnostics/116253
+ * gcc.dg/plugin/diagnostic-test-nesting-html.c: New test.
+ * gcc.dg/plugin/diagnostic-test-nesting-html.py: New test script.
+ * gcc.dg/plugin/plugin.exp: Add it.
+ * libgdiagnostics.dg/test-multiple-lines.c: Update expected output
+ to show fix-it hint.
+ * sarif-replay.dg/2.1.0-valid/nested-diagnostics-1.sarif: New test.
+
+2025-08-04 David Malcolm <dmalcolm@redhat.com>
+
+ PR diagnostics/116792
+ * gcc.dg/plugin/diagnostic-test-graphs-html.py: Remove trailing
+ space from expected text of message.
+ * sarif-replay.dg/2.1.0-valid/embedded-links-check-html.py:
+ Likewise.
+ * sarif-replay.dg/2.1.0-valid/graphs-check-html.py: Likewise.
+
+2025-08-04 Konstantinos Eleftheriou <konstantinos.eleftheriou@vrull.eu>
+
+ PR rtl-optimization/121303
+ * gcc.target/i386/pr121303.c: New test.
+
+2025-08-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * g++.dg/DRs/dr2580.C: New test.
+
+2025-08-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * g++.dg/DRs/dr2578.C: New test.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/dupq_13.c: New test.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/dup_1.c: New test.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/pnext_3.c: New test.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve2/acle/general/match_4.c: New test.
+ * gcc.target/aarch64/sve2/acle/general/nmatch_1.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/acge_1.c: New test.
+ * gcc.target/aarch64/sve/acle/general/acgt_1.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/acle_1.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/aclt_1.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/cmpeq_6.c: New test.
+ * gcc.target/aarch64/sve/acle/general/cmpge_9.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_9.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_9.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_9.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpne_5.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpuo_1.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/cmpeq_5.c: New test.
+ * gcc.target/aarch64/sve/acle/general/cmpge_7.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpge_8.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_7.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_8.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_7.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_8.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_7.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_8.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpne_4.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/cmpeq_1.c: Check the number
+ of PTRUEs.
+ * gcc.target/aarch64/sve/acle/general/cmpge_5.c: New test.
+ * gcc.target/aarch64/sve/acle/general/cmpge_6.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_5.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_6.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_5.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_6.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_5.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_6.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpne_3.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/cmpeq_1.c: Add more tests.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/pred_clobber_1.c: Disable combine.
+ * gcc.target/aarch64/sve/pred_clobber_2.c: Likewise.
+ * gcc.target/aarch64/sve/pred_clobber_3.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpeq_2.c: Add more cases.
+ * gcc.target/aarch64/sve/acle/general/cmpeq_4.c: New test.
+ * gcc.target/aarch64/sve/acle/general/cmpge_1.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpge_2.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpge_3.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpge_4.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_1.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_2.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_3.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpgt_4.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_1.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_2.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_3.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmple_4.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_1.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_2.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_3.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmplt_4.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpne_1.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/cmpne_2.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/general/unpkhi_1.c: New test.
+ * gcc.target/aarch64/sve/acle/general/unpklo_1.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/121294
+ * gcc.target/aarch64/sve/acle/general/rev_2.c: New test.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/121294
+ * gcc.target/aarch64/sve/acle/general/perm_2.c: New test.
+ * gcc.target/aarch64/sve/acle/general/perm_3.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/perm_4.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/perm_5.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/perm_6.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/perm_7.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR testsuite/121118
+ * gcc.target/aarch64/sve/acle/general/pr121118_1.c: New test.
+ * gcc.target/aarch64/sve/acle/general/whilele_13.c: Likewise.
+ * gcc.target/aarch64/sve/acle/general/whilelt_6.c: Likewise.
+ * gcc.target/aarch64/sve2/acle/general/whilege_1.c: Likewise.
+ * gcc.target/aarch64/sve2/acle/general/whilegt_1.c: Likewise.
+ * gcc.target/aarch64/sve2/acle/general/whilerw_5.c: Likewise.
+ * gcc.target/aarch64/sve2/acle/general/whilewr_5.c: Likewise.
+
+2025-08-04 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/121293
+ * gcc.target/aarch64/sve/acle/general/dupq_lane_9.c: New test.
+
+2025-08-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/121362
+ * gcc.dg/tree-ssa/ssa-fre-105.c: New testcase.
+ * gcc.dg/tree-ssa/ssa-fre-106.c: Likewise.
+
+2025-08-04 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/120941
+ * gcc.target/i386/pr120941-1.c: New test.
+
2025-08-03 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/120778
diff --git a/gcc/testsuite/c-c++-common/cpp/va-opt-6.c b/gcc/testsuite/c-c++-common/cpp/va-opt-6.c
index 8a7761b..9a92431 100644
--- a/gcc/testsuite/c-c++-common/cpp/va-opt-6.c
+++ b/gcc/testsuite/c-c++-common/cpp/va-opt-6.c
@@ -3,15 +3,15 @@
/* { dg-options "-std=c++20" { target c++ } } */
#define a ""
-#define b(...) a ## #__VA_OPT__(1) /* { dg-error "pasting \"a\" and \"\"\"\" does not give a valid preprocessing token" } */
-#define c(...) a ## #__VA_OPT__(1) /* { dg-error "pasting \"a\" and \"\"1\"\" does not give a valid preprocessing token" } */
+#define b(...) a ## #__VA_OPT__(1) /* { dg-error "pasting 'a' and '\"\"' does not give a valid preprocessing token" } */
+#define c(...) a ## #__VA_OPT__(1) /* { dg-error "pasting 'a' and '\"1\"' does not give a valid preprocessing token" } */
#define d(...) #__VA_OPT__(1) ## !
#define e(...) #__VA_OPT__(1) ## !
#define f(...) #__VA_OPT__(. ## !)
#define g(...) #__VA_OPT__(. ## !)
b()
c(1)
-d( ) /* { dg-error "pasting \"\"\"\" and \"!\" does not give a valid preprocessing token" } */
-e( 1 ) /* { dg-error "pasting \"\"1\"\" and \"!\" does not give a valid preprocessing token" } */
+d( ) /* { dg-error "pasting '\"\"' and '!' does not give a valid preprocessing token" } */
+e( 1 ) /* { dg-error "pasting '\"1\"' and '!' does not give a valid preprocessing token" } */
f()
-g(0) /* { dg-error "pasting \".\" and \"!\" does not give a valid preprocessing token" } */
+g(0) /* { dg-error "pasting '.' and '!' does not give a valid preprocessing token" } */
diff --git a/gcc/testsuite/g++.dg/DRs/dr2579.C b/gcc/testsuite/g++.dg/DRs/dr2579.C
new file mode 100644
index 0000000..dda3643
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2579.C
@@ -0,0 +1,9 @@
+// DR 2579 - Undefined behavior when token pasting does not create a preprocessing token
+// { dg-do preprocess }
+// { dg-options "-pedantic-errors" }
+
+#define A(a, b) a ## b
+A(5,6)
+A(-,32) // { dg-error "pasting '-' and '32' does not give a valid preprocessing token" }
+A("","") // { dg-error "pasting '\"\"' and '\"\"' does not give a valid preprocessing token" }
+A(\,u0393)
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-using6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-using6.C
new file mode 100644
index 0000000..a40519a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-using6.C
@@ -0,0 +1,20 @@
+// PR c++/121351
+// { dg-do compile { target c++20 } }
+
+template<class T> concept C = true;
+
+template<class T>
+struct A {
+ template<class U> void f(U) requires C<T>; // #1
+};
+
+template<class T>
+struct B : A<T*> {
+ using A<T*>::f;
+ template<class U> void f(U) requires C<T>; // #2
+};
+
+int main() {
+ B<int> b;
+ b.f(42); // { dg-error "ambiguous" } #1 and #2 don't correspond
+}
diff --git a/gcc/testsuite/gcc.dg/bitintext.h b/gcc/testsuite/gcc.dg/bitintext.h
index 99fedb3..d5f2689d 100644
--- a/gcc/testsuite/gcc.dg/bitintext.h
+++ b/gcc/testsuite/gcc.dg/bitintext.h
@@ -4,6 +4,24 @@ do_copy (void *p, const void *q, __SIZE_TYPE__ r)
__builtin_memcpy (p, q, r);
}
+/* Obtain the value of N from a _BitInt(N)-typed expression X
+ at compile time. */
+#define S(x) \
+ ((typeof (x)) -1 < 0 \
+ ? __builtin_clrsbg (__builtin_choose_expr ((typeof (x)) -1 < 0, \
+ (typeof (x)) -1, -1)) + 1 \
+ : __builtin_popcountg (__builtin_choose_expr ((typeof (x)) -1 < 0, \
+ 0U, (typeof (x)) -1)))
+
+#define CEIL(x,y) (((x) + (y) - 1) / (y))
+
+/* Promote a _BitInt type to include its padding bits. */
+#if defined (__s390x__) || defined(__arm__)
+#define PROMOTED_SIZE(x) sizeof (x)
+#elif defined(__loongarch__)
+#define PROMOTED_SIZE(x) (sizeof (x) > 8 ? CEIL (S (x), 64) * 8 : sizeof (x))
+#endif
+
/* Macro to test whether (on targets where psABI requires it) _BitInt
with padding bits have those filled with sign or zero extension. */
#if defined(__s390x__) || defined(__arm__) || defined(__loongarch__)
@@ -11,14 +29,14 @@ do_copy (void *p, const void *q, __SIZE_TYPE__ r)
do { \
if ((typeof (x)) -1 < 0) \
{ \
- _BitInt(sizeof (x) * __CHAR_BIT__) __x; \
+ _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \
do_copy (&__x, &(x), sizeof (__x)); \
if (__x != (x)) \
__builtin_abort (); \
} \
else \
{ \
- unsigned _BitInt(sizeof (x) * __CHAR_BIT__) __x; \
+ unsigned _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \
do_copy (&__x, &(x), sizeof (__x)); \
if (__x != (x)) \
__builtin_abort (); \
diff --git a/gcc/testsuite/gcc.dg/c23-attr-syntax-6.c b/gcc/testsuite/gcc.dg/c23-attr-syntax-6.c
index f8c5b0f..4e6b80b 100644
--- a/gcc/testsuite/gcc.dg/c23-attr-syntax-6.c
+++ b/gcc/testsuite/gcc.dg/c23-attr-syntax-6.c
@@ -45,7 +45,7 @@ typedef int [[__extension__ __extension__]] b2; /* { dg-error {'extension' attri
typedef int [[__extension__ unknown_attribute]] b3; /* { dg-error {'unknown_attribute' attribute ignored} } */
typedef int [[__extension__ gnu:vector_size(4)]] b4; /* { dg-error {expected '\]' before ':'} } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
-typedef int [[__extension__ gnu JOIN2(:,:) vector_size (4)]] b5; /* { dg-error {pasting ":" and ":" does not give a valid preprocessing token} } */
+typedef int [[__extension__ gnu JOIN2(:,:) vector_size (4)]] b5; /* { dg-error {pasting ':' and ':' does not give a valid preprocessing token} } */
/* { dg-error {expected '\]' before ':'} "" { target *-*-* } .-1 } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-2 } */
typedef int [[__extension__ gnu : : vector_size (4)]] b6; /* { dg-error {expected '\]' before ':'} } */
@@ -81,7 +81,7 @@ typedef int [[gnu :: vector_size (4)]] b18; /* { dg-error {attributes before C23
typedef int [[gnu FOO vector_size (4)]] b19; /* { dg-error {attributes before C23} } */
typedef int [[gnu :: vector_size (sizeof (void (*)(...)))]] b20; /* { dg-error {attributes before C23} } */
/* { dg-error {requires a named argument before} "" { target *-*-* } .-1 } */
-typedef int [[gnu JOIN2(:,:) vector_size (4)]] b21; /* { dg-error {pasting ":" and ":" does not give a valid preprocessing token} } */
+typedef int [[gnu JOIN2(:,:) vector_size (4)]] b21; /* { dg-error {pasting ':' and ':' does not give a valid preprocessing token} } */
/* { dg-error {expected '\]' before ':'} "" { target *-*-* } .-1 } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-2 } */
/* { dg-error {attributes before C23} "" { target *-*-* } .-3 } */
diff --git a/gcc/testsuite/gcc.dg/cpp/paste12-2.c b/gcc/testsuite/gcc.dg/cpp/paste12-2.c
index 6e2e4f1..f46645a 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste12-2.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste12-2.c
@@ -6,6 +6,6 @@
/* Test correct diagnostics when pasting in #include.
Source: PR preprocessor/6780. */
-#define inc2(a,b) <##a.b> /* { dg-error "pasting \"<\" and \"stdio\" does not" } */
+#define inc2(a,b) <##a.b> /* { dg-error "pasting '<' and 'stdio' does not" } */
#define INC(X) inc2(X,h)
#include INC(stdio)
diff --git a/gcc/testsuite/gcc.dg/cpp/paste12.c b/gcc/testsuite/gcc.dg/cpp/paste12.c
index 3e0f7b9..f6b3696 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste12.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste12.c
@@ -8,4 +8,4 @@
#define inc2(a,b) <##a.b>
#define INC(X) inc2(X,h)
-#include INC(stdio) /* { dg-error "pasting \"<\" and \"stdio\" does not" } */
+#include INC(stdio) /* { dg-error "pasting '<' and 'stdio' does not" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/paste14-2.c b/gcc/testsuite/gcc.dg/cpp/paste14-2.c
index 3b23ada..bb51999 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste14-2.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste14-2.c
@@ -4,8 +4,8 @@
{ dg-do preprocess }
*/
-#define foo - ## >> /* { dg-error "pasting \"-\" and \">>\"" } */
+#define foo - ## >> /* { dg-error "pasting '-' and '>>'" } */
foo
-#define bar = ## == /* { dg-error "pasting \"=\" and \"==\"" } */
+#define bar = ## == /* { dg-error "pasting '=' and '=='" } */
bar
diff --git a/gcc/testsuite/gcc.dg/cpp/paste14.c b/gcc/testsuite/gcc.dg/cpp/paste14.c
index 043d5e5..d60b328 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste14.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste14.c
@@ -5,6 +5,6 @@
*/
#define foo - ## >>
-foo /* { dg-error "pasting \"-\" and \">>\"" } */
+foo /* { dg-error "pasting '-' and '>>'" } */
#define bar = ## ==
-bar /* { dg-error "pasting \"=\" and \"==\"" } */
+bar /* { dg-error "pasting '=' and '=='" } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr121370.c b/gcc/testsuite/gcc.dg/torture/pr121370.c
new file mode 100644
index 0000000..d40f3b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121370.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+int a;
+int main()
+{
+ int c = -2147483647;
+ int d = -2147483647;
+ int e = 2147483647;
+ if (0)
+ f:
+ e = d + e - 2;
+g:
+ if (d - c - e > 0) {
+ a = -c;
+ if (a + d) {
+ d = 1;
+ goto g;
+ }
+ return 0;
+ }
+ if (e)
+ goto f;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr121382.c b/gcc/testsuite/gcc.dg/torture/pr121382.c
new file mode 100644
index 0000000..20b49b1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121382.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+int a, b, c;
+__attribute__((noipa))
+static void d(int e, int f)
+{
+ if (e != 5 && e != 2147483647)
+ __builtin_abort();
+ f = 2147483647;
+ do {
+ f = f - e;
+ if (c - 9 * f) {
+ __builtin_abort();
+ }
+ } while (c);
+}
+__attribute__((noipa))
+int main(void)
+{
+ d(2147483647, 2147483647);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr59984.c b/gcc/testsuite/gcc.dg/vect/pr59984.c
index c00c2267..8ca446e 100644
--- a/gcc/testsuite/gcc.dg/vect/pr59984.c
+++ b/gcc/testsuite/gcc.dg/vect/pr59984.c
@@ -64,3 +64,7 @@ main ()
return 0;
}
+/* { dg-final { scan-tree-dump "31:17: optimized: loop vectorized" "vect" } } */
+/* { dg-final { scan-tree-dump "37:7: optimized: loop vectorized" "vect" } } */
+/* { dg-final { scan-tree-dump "44:17: optimized: loop vectorized" "vect" } } */
+/* { dg-final { scan-tree-dump "50:7: optimized: loop vectorized" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr118591-1.c b/gcc/testsuite/gcc.target/avr/torture/pr118591-1.c
index 814f041..6f54c63 100644
--- a/gcc/testsuite/gcc.target/avr/torture/pr118591-1.c
+++ b/gcc/testsuite/gcc.target/avr/torture/pr118591-1.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { ! avr_tiny } } } */
-/* { dg-additional-options "-std=c99 -mlra" } */
+/* { dg-additional-options "-std=c99" } */
__attribute__((noipa))
void func2 (long long a1, long long a2, long b)
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr118591-2.c b/gcc/testsuite/gcc.target/avr/torture/pr118591-2.c
index 83d3606..222af09 100644
--- a/gcc/testsuite/gcc.target/avr/torture/pr118591-2.c
+++ b/gcc/testsuite/gcc.target/avr/torture/pr118591-2.c
@@ -1,6 +1,6 @@
/* Test case failed on avrtiny. */
/* { dg-do run } */
-/* { dg-additional-options "-std=c99 -mlra" } */
+/* { dg-additional-options "-std=c99" } */
__attribute__((noipa))
void func2 (long a, long b)
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c
index 8d5449b..fa3758a 100644
--- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c
@@ -9,3 +9,5 @@
DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT)
/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
+/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */
+/* { dg-final { scan-assembler-times "mulhu" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c
index d8a01d1..b1bf4fa 100644
--- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c
@@ -10,3 +10,4 @@ DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT)
/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
/* { dg-final { scan-assembler-not "\.L\[0-9\]+" } } */
+/* { dg-final { scan-assembler-times "mulhu" 1 } } */
diff --git a/gcc/testsuite/lib/rust.exp b/gcc/testsuite/lib/rust.exp
index 9513e1c..692030c 100644
--- a/gcc/testsuite/lib/rust.exp
+++ b/gcc/testsuite/lib/rust.exp
@@ -168,10 +168,7 @@ proc rust_target_compile { source dest type options } {
global gluefile wrap_flags
global ALWAYS_RUSTFLAGS
global RUST_UNDER_TEST
- global individual_timeout
-
- # HACK: guard against infinite loops in the compiler
- set individual_timeout 10
+
if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } {
lappend options "libs=${gluefile}"
diff --git a/gcc/testsuite/rust/compile/bad-rpit1.rs b/gcc/testsuite/rust/compile/bad-rpit1.rs
new file mode 100644
index 0000000..d8c21b1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad-rpit1.rs
@@ -0,0 +1,26 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct A;
+struct B;
+
+impl Foo for A {
+ fn id(&self) -> i32 {
+ 1
+ }
+}
+
+impl Foo for B {
+ fn id(&self) -> i32 {
+ 2
+ }
+}
+
+fn make_foo(cond: bool) -> impl Foo {
+ if cond { A } else { B }
+ // { dg-error "mismatched types, expected .A. but got .B. .E0308." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_3.rs b/gcc/testsuite/rust/compile/const_generics_3.rs
index 524d48d..bd91729 100644
--- a/gcc/testsuite/rust/compile/const_generics_3.rs
+++ b/gcc/testsuite/rust/compile/const_generics_3.rs
@@ -1,4 +1,4 @@
-// { dg-additional-options "-w -frust-name-resolution-2.0" }
+// { dg-additional-options "-w -frust-name-resolution-2.0 -frust-compile-until=compilation" }
#[lang = "sized"]
trait Sized {}
diff --git a/gcc/testsuite/rust/compile/impl_trait_diag.rs b/gcc/testsuite/rust/compile/impl_trait_diag.rs
new file mode 100644
index 0000000..54a0cd2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/impl_trait_diag.rs
@@ -0,0 +1,17 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+trait Foo {
+ fn method(&self);
+}
+
+struct Bar;
+impl Foo for Bar {}
+
+fn main() {
+ let x: impl Foo = Bar; // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+
+ struct Wrapper {
+ field: impl Foo, // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs b/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs
new file mode 100644
index 0000000..ecdb088
--- /dev/null
+++ b/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs
@@ -0,0 +1,24 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> u8;
+}
+
+struct Bar;
+
+impl Foo for Bar {
+ fn id(&self) -> u8 {
+ 1
+ }
+}
+
+fn takes(val: impl Foo) -> u8 {
+ val.id()
+}
+
+fn main() {
+ let b = Bar;
+ let x = takes::<Bar>(b);
+ // { dg-error "cannot provide explicit generic arguments when .impl Trait. is used in argument position .E0632." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1485.rs b/gcc/testsuite/rust/compile/issue-1485.rs
new file mode 100644
index 0000000..a0cd5a0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1485.rs
@@ -0,0 +1,16 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+struct BinOpInvalid {
+ lhs: i32,
+ rhs: i32,
+ f: impl FnOnce(i32) -> i32, // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1487.rs b/gcc/testsuite/rust/compile/issue-1487.rs
new file mode 100644
index 0000000..4a4d759
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1487.rs
@@ -0,0 +1,15 @@
+// { dg-options "-w" }
+#[lang = "sized"]
+trait Sized {}
+
+trait Printable {
+ fn print(&self);
+}
+
+struct Foo;
+
+impl Printable for Foo {
+ fn print(&self) {}
+}
+
+fn take_printable(_: impl Printable) {}
diff --git a/gcc/testsuite/rust/compile/issue-2015.rs b/gcc/testsuite/rust/compile/issue-2015.rs
index 7789ecd..7e03651 100644
--- a/gcc/testsuite/rust/compile/issue-2015.rs
+++ b/gcc/testsuite/rust/compile/issue-2015.rs
@@ -1,4 +1,5 @@
-// { dg-additional-options "-frust-compile-until=lowering" }
+#[lang = "sized"]
+trait Sized {}
macro_rules! impl_foo {
() => { impl Foo }
diff --git a/gcc/testsuite/rust/compile/issue-3454.rs b/gcc/testsuite/rust/compile/issue-3454.rs
new file mode 100644
index 0000000..2a3c0c7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3454.rs
@@ -0,0 +1,20 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+macro_rules! impl_foo {
+ () => { impl Foo }
+}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+pub fn foo(_value: impl Bar<Baz = impl_foo!()>) -> i32 {
+ 15
+}
+
+pub fn bar(_value: impl Bar<Baz = impl Foo>) -> i32 {
+ 16
+}
diff --git a/gcc/testsuite/rust/compile/issue-3618.rs b/gcc/testsuite/rust/compile/issue-3618.rs
new file mode 100644
index 0000000..9728613
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3618.rs
@@ -0,0 +1 @@
+static _X: () = loop {}; // { dg-error "loop iteration count exceeds limit" }
diff --git a/gcc/testsuite/rust/compile/issue-3660.rs b/gcc/testsuite/rust/compile/issue-3660.rs
new file mode 100644
index 0000000..1f1c583
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3660.rs
@@ -0,0 +1,3 @@
+pub static A: [u32; 2] = [1, 2];
+
+pub static B: [u8; 2] = [3, 4];
diff --git a/gcc/testsuite/rust/compile/issue-3661.rs b/gcc/testsuite/rust/compile/issue-3661.rs
new file mode 100644
index 0000000..8d03c36
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3661.rs
@@ -0,0 +1,10 @@
+pub macro m($inner_str:expr) {
+ #[m = $inner_str]
+ // { dg-error "macro not found" "" { target *-*-* } .-1 }
+
+ struct S;
+}
+
+fn main() {
+ m!(stringify!(foo));
+}
diff --git a/gcc/testsuite/rust/compile/issue-3671.rs b/gcc/testsuite/rust/compile/issue-3671.rs
index e800d53..8015653 100644
--- a/gcc/testsuite/rust/compile/issue-3671.rs
+++ b/gcc/testsuite/rust/compile/issue-3671.rs
@@ -1,2 +1,2 @@
-impl Self<0> {}
+impl Foo<0> {}
// { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs b/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs
new file mode 100644
index 0000000..ed6e100
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs
@@ -0,0 +1,7 @@
+macro_rules! foo {
+ ($x:meta) => {0}
+}
+
+pub fn main() -> i32 {
+ foo!(Clone)
+}
diff --git a/gcc/testsuite/rust/compile/match-identifierpattern.rs b/gcc/testsuite/rust/compile/match-identifierpattern.rs
new file mode 100644
index 0000000..6c558ac
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-identifierpattern.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let x = 1;
+
+ match x {
+ 2 => {},
+ a @ 3 => {},
+ _ => {},
+ }
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index c020e36..31d7a26 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,17 +1,9 @@
-canonical_paths1.rs
issue-3315-2.rs
-privacy5.rs
-privacy8.rs
-pub_restricted_1.rs
-pub_restricted_2.rs
-pub_restricted_3.rs
-issue-2905-2.rs
-derive-default1.rs
-derive-eq-invalid.rs
torture/alt_patterns1.rs
torture/name_resolve1.rs
-issue-3663.rs
-issue-3671.rs
issue-3652.rs
-issue-3649.rs
+issue-1487.rs
+issue-2015.rs
+issue-3454.rs
+impl_trait_generic_arg.rs
# please don't delete the trailing newline
diff --git a/gcc/testsuite/rust/compile/pub_restricted_1.rs b/gcc/testsuite/rust/compile/pub_restricted_1.rs
index 9bda968..44989a8 100644
--- a/gcc/testsuite/rust/compile/pub_restricted_1.rs
+++ b/gcc/testsuite/rust/compile/pub_restricted_1.rs
@@ -1,3 +1,5 @@
+// { dg-additional-options "-frust-name-resolution-2.0" }
+
pub mod foo {
pub mod bar {
pub fn baz() {}
@@ -6,8 +8,8 @@ pub mod foo {
}
}
-pub(in foo::fah::baz) struct A1; // { dg-error "cannot find simple path segment .fah." }
-pub(in fro::bulator::saindoux) struct A2; // { dg-error "cannot find simple path segment .fro." }
-pub(in foo::bar::saindoux) struct A3; // { dg-error "cannot find simple path segment .saindoux." }
+pub(in foo::fah::baz) struct A1; // { dg-error "could not resolve path .foo::fah::baz." }
+pub(in fro::bulator::saindoux) struct A2; // { dg-error "could not resolve path .fro::bulator::saindoux." }
+pub(in foo::bar::saindoux) struct A3; // { dg-error "could not resolve path .foo::bar::saindoux." }
fn main() {}
diff --git a/gcc/testsuite/rust/compile/pub_restricted_2.rs b/gcc/testsuite/rust/compile/pub_restricted_2.rs
index 8588f27..91f072e 100644
--- a/gcc/testsuite/rust/compile/pub_restricted_2.rs
+++ b/gcc/testsuite/rust/compile/pub_restricted_2.rs
@@ -1,18 +1,18 @@
-// { dg-additional-options "-w" }
+// { dg-additional-options "-w -frust-name-resolution-2.0" }
mod foo {
mod bar {
mod baz {
- pub(in baz) struct A0;
- pub(in bar::baz) struct A1;
+ pub(in super::baz) struct A0;
+ pub(in super::super::bar::baz) struct A1;
pub(in foo::bar::baz) struct A2;
mod sain {
mod doux {}
}
- pub(in sain) struct A3; // { dg-error "restricted path is not an ancestor of the current module" }
- pub(in sain::doux) struct A4; // { dg-error "restricted path is not an ancestor of the current module" }
+ pub(in self::sain) struct A3; // { dg-error "restricted path is not an ancestor of the current module" }
+ pub(in self::sain::doux) struct A4; // { dg-error "restricted path is not an ancestor of the current module" }
}
}
}
diff --git a/gcc/testsuite/rust/execute/same_field_name.rs b/gcc/testsuite/rust/compile/same_field_name.rs
index d57562b..8e5b78c 100644
--- a/gcc/testsuite/rust/execute/same_field_name.rs
+++ b/gcc/testsuite/rust/compile/same_field_name.rs
@@ -1,7 +1,7 @@
// https://doc.rust-lang.org/error_codes/E0124.html
fn main() {
struct Foo {
- field1: i32, // { dg-error "field .field1. is already declared" }
+ field1: i32,
field1: i32, // { dg-error "field .field1. is already declared" }
field1: i32, // { dg-error "field .field1. is already declared" }
}
diff --git a/gcc/testsuite/rust/compile/self-in-impl.rs b/gcc/testsuite/rust/compile/self-in-impl.rs
new file mode 100644
index 0000000..f888162
--- /dev/null
+++ b/gcc/testsuite/rust/compile/self-in-impl.rs
@@ -0,0 +1,17 @@
+// { dg-additional-options "-frust-name-resolution-2.0" }
+
+// the error message here is what rustc >=1.66 emits
+// rustc <1.66 emits a "cycle detected" error when
+// trying to calculate the impl type
+//
+// since we aren't trying to match error messages too closely
+// and the >=1.66 error message is nicer
+// we may as well mimic that
+
+impl ((Self, i32)) {}
+// { dg-error ".Self. is not valid in the self" "" { target *-*-* } .-1 }
+
+trait Foo {}
+
+impl Foo for ((Self, i32)) {}
+// { dg-error ".Self. is not valid in the self" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/torture/extern_mod2.rs b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
index 4984d5d..f3a4f79 100644
--- a/gcc/testsuite/rust/compile/torture/extern_mod2.rs
+++ b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
@@ -12,6 +12,12 @@ mod no_leading_equal;
#[path = "modules/valid_path.rs"]
mod extra_spaces;
+#[path = ""] // { dg-error "path attributes must contain a filename" }
+mod empty_path; // { dg-error "no candidate found" }
+
+#[path = " "] // { dg-error "path attributes must contain a filename" }
+mod path_with_spaces; // { dg-error "no candidate found" }
+
#[path] // { dg-error "path attributes must contain a filename" }
mod error; // { dg-error "no candidate found" }
diff --git a/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs b/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs
new file mode 100644
index 0000000..91a3c9a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs
@@ -0,0 +1,6 @@
+// { dg-excess-errors "...." }
+fn main() {
+ // { dg-error "unended raw byte string literal" "" { target *-*-* } .+1 }
+ let s = br##"123"#
+}
+
diff --git a/gcc/testsuite/rust/compile/traits9.rs b/gcc/testsuite/rust/compile/traits9.rs
index bb3034d..f4308e8 100644
--- a/gcc/testsuite/rust/compile/traits9.rs
+++ b/gcc/testsuite/rust/compile/traits9.rs
@@ -11,6 +11,5 @@ fn main() {
a = Foo(123);
let b: &dyn Bar = &a;
- // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied" "" { target *-*-* } .-1 }
- // { dg-error "expected" "" { target *-*-* } .-2 }
+ // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied .E0277." "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/unify-errors1.rs b/gcc/testsuite/rust/compile/unify-errors1.rs
new file mode 100644
index 0000000..0fe95ef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unify-errors1.rs
@@ -0,0 +1,49 @@
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+trait MyTrait {}
+
+struct Wrapper<T: MyTrait> {
+ value: T,
+}
+
+struct NotImpl;
+
+trait A {}
+trait B {}
+
+struct Wrapper2<T: A + B> {
+ value: T,
+}
+
+struct NotImpl2;
+
+impl A for NotImpl2 {}
+
+fn takes_tuple(x: (i32, bool)) {}
+
+fn requires_copy<T: Copy>(value: T) {}
+
+pub fn test() {
+ takes_tuple((1, 2));
+ // { dg-error "mismatched types, expected .bool. but got .<integer>. .E0308." "" { target *-*-* } .-1 }
+
+ takes_tuple((1, 2, 3));
+ // { dg-error "mismatched types, expected ..i32, bool.. but got ..<integer>, <integer>, <integer>.. .E0308." "" { target *-*-* } .-1 }
+
+ takes_tuple("hello");
+ // { dg-error "mismatched types, expected ..i32, bool.. but got .& str. .E0308." "" { target *-*-* } .-1 }
+
+ let x = &mut 5;
+ requires_copy(x);
+ // { dg-error "bounds not satisfied for &mut <integer> .Copy. is not satisfied .E0277." "" { target *-*-* } .-1 }
+
+ let _x = Wrapper { value: NotImpl };
+ // { dg-error "bounds not satisfied for NotImpl .MyTrait. is not satisfied .E0277." "" { target *-*-* } .-1 }
+
+ let _x = Wrapper2 { value: NotImpl2 };
+ // { dg-error "bounds not satisfied for NotImpl2 .B. is not satisfied .E0277." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs b/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs
new file mode 100644
index 0000000..efb825b
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs
@@ -0,0 +1,176 @@
+/* { dg-output "less\r*" }*/
+mod core {
+ mod option {
+ pub enum Option<T> {
+ None,
+ Some(T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {}
+
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {}
+
+ #[lang = "sized"]
+ pub trait Sized {}
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ pub enum Ordering {
+ Less = -1,
+ Equal = 0,
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ pub trait Eq: PartialEq<Self> {
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) | Option::Some(Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) | Option::Some(Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ pub trait Ord: Eq + PartialOrd<Self> {
+ fn cmp(&self, other: &Self) -> Ordering;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::option::Option;
+
+// Needed impls for primitives
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self < *other {
+ Option::Some(Ordering::Less)
+ } else if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+}
+
+impl Eq for i32 {}
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self < *other {
+ Ordering::Less
+ } else if *self > *other {
+ Ordering::Greater
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// Manual impl for struct Bar
+struct Bar {
+ a: i32,
+ b: i32,
+}
+
+impl PartialEq for Bar {
+ fn eq(&self, other: &Self) -> bool {
+ self.a.eq(&other.a) && self.b.eq(&other.b)
+ }
+}
+
+impl Eq for Bar {}
+
+impl PartialOrd for Bar {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ match self.a.partial_cmp(&other.a) {
+ Option::Some(Ordering::Equal) => self.b.partial_cmp(&other.b),
+ ord => ord,
+ }
+ }
+}
+
+impl Ord for Bar {
+ fn cmp(&self, other: &Self) -> Ordering {
+ match self.a.cmp(&other.a) {
+ Ordering::Equal => self.b.cmp(&other.b),
+ ord => ord,
+ }
+ }
+}
+
+// External print shim
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let x = Bar { a: 1, b: 2 };
+ let y = Bar { a: 1, b: 3 };
+
+ match x.partial_cmp(&y) {
+ Option::Some(Ordering::Less) => print("less"),
+ Option::Some(Ordering::Greater) => print("greater"),
+ Option::Some(Ordering::Equal) => print("equal"),
+ _ => print("none"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs b/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs
new file mode 100644
index 0000000..b8c3672
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs
@@ -0,0 +1,184 @@
+/* { dg-output "<><=>=\r*" } */
+/* { dg-options "-w" } */
+mod core {
+ mod option {
+ pub enum Option<T> {
+ None,
+ Some(T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {}
+
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {}
+
+ #[lang = "sized"]
+ pub trait Sized {}
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ pub enum Ordering {
+ Less = -1,
+ Equal = 0,
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ pub trait Eq: PartialEq<Self> {
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) | Option::Some(Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) | Option::Some(Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ pub trait Ord: Eq + PartialOrd<Self> {
+ fn cmp(&self, other: &Self) -> Ordering;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::option::Option;
+
+// Needed impls for primitives
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self < *other {
+ Option::Some(Ordering::Less)
+ } else if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+}
+
+impl Eq for i32 {}
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self < *other {
+ Ordering::Less
+ } else if *self > *other {
+ Ordering::Greater
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// Manual impl for struct Bar
+struct Bar {
+ a: i32,
+ b: i32,
+}
+
+impl PartialEq for Bar {
+ fn eq(&self, other: &Self) -> bool {
+ self.a.eq(&other.a) && self.b.eq(&other.b)
+ }
+}
+
+impl Eq for Bar {}
+
+impl PartialOrd for Bar {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ match self.a.partial_cmp(&other.a) {
+ Option::Some(Ordering::Equal) => self.b.partial_cmp(&other.b),
+ ord => ord,
+ }
+ }
+}
+
+impl Ord for Bar {
+ fn cmp(&self, other: &Self) -> Ordering {
+ match self.a.cmp(&other.a) {
+ Ordering::Equal => self.b.cmp(&other.b),
+ ord => ord,
+ }
+ }
+}
+
+// External print shim
+extern "C" {
+ fn printf(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ printf(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Bar { a: 1, b: 2 };
+ let b = Bar { a: 1, b: 3 };
+ let c = Bar { a: 1, b: 2 };
+
+ if a < b {
+ print("<");
+ }
+ if b > a {
+ print(">");
+ }
+ if a <= c {
+ print("<=");
+ }
+ if b >= c {
+ print(">=");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_abort.rs b/gcc/testsuite/rust/execute/torture/builtin_abort.rs
index 9f2d8c2..8c8259a 100644
--- a/gcc/testsuite/rust/execute/torture/builtin_abort.rs
+++ b/gcc/testsuite/rust/execute/torture/builtin_abort.rs
@@ -9,6 +9,6 @@ mod intrinsics {
}
pub fn main () -> i32 {
- abort();
+ intrinsics::abort();
0
}
diff --git a/gcc/testsuite/rust/execute/torture/const_block1.rs b/gcc/testsuite/rust/execute/torture/const_block1.rs
new file mode 100644
index 0000000..eaf3432
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const_block1.rs
@@ -0,0 +1,9 @@
+const X: i32 = const {
+ let a = 15;
+ let b = 14;
+ a + b
+};
+
+fn main() -> i32 {
+ X - 29
+}
diff --git a/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs b/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs
new file mode 100644
index 0000000..70ed7dc
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs
@@ -0,0 +1,66 @@
+// { dg-output "true\r*\nfalse\r*\nfalse\r*\nfalse\r*\nfalse\r*\n" }
+
+#![feature(intrinsics)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ /// This method tests for `!=`.
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+#[derive(PartialEq)]
+enum Foo {
+ A { a: i32, b: i32 },
+ B(i32, i32),
+ C,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(b: bool) {
+ if b {
+ unsafe { puts("true\0" as *const str as *const i8) }
+ } else {
+ unsafe { puts("false\0" as *const str as *const i8) }
+ }
+}
+
+fn main() -> i32 {
+ let x = Foo::A { a: 15, b: 14 };
+
+ let b1 = x == Foo::A { a: 15, b: 14 };
+ let b12 = x == Foo::A { a: 15, b: 19 };
+ let b13 = x == Foo::A { a: 19, b: 14 };
+ let b2 = x == Foo::B(15, 14);
+ let b3 = x == Foo::C;
+
+ print(b1);
+ print(b12);
+ print(b13);
+ print(b2);
+ print(b3);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/for-loop1.rs b/gcc/testsuite/rust/execute/torture/for-loop1.rs
index 5a6a70c..3342189 100644
--- a/gcc/testsuite/rust/execute/torture/for-loop1.rs
+++ b/gcc/testsuite/rust/execute/torture/for-loop1.rs
@@ -102,30 +102,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -133,12 +133,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -146,7 +146,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -155,31 +155,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -194,7 +194,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -204,7 +204,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
diff --git a/gcc/testsuite/rust/execute/torture/for-loop2.rs b/gcc/testsuite/rust/execute/torture/for-loop2.rs
index 5ba2cd1..4f5dfe1 100644
--- a/gcc/testsuite/rust/execute/torture/for-loop2.rs
+++ b/gcc/testsuite/rust/execute/torture/for-loop2.rs
@@ -101,30 +101,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -132,12 +132,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -145,7 +145,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -154,31 +154,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -193,7 +193,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -203,7 +203,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
diff --git a/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs b/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs
new file mode 100644
index 0000000..c73ea34
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs
@@ -0,0 +1,32 @@
+#[lang = "sized"]
+trait Sized {}
+
+macro_rules! impl_foo {
+ () => { impl Foo }
+}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+struct MyBaz; // { dg-warning "struct is never constructed" }
+impl Foo for MyBaz {}
+
+struct MyBar;
+
+impl Bar for MyBar {
+ type Baz = MyBaz;
+}
+
+pub fn foo(_value: impl Bar<Baz = impl_foo!()>) -> i32 {
+ 15
+}
+
+fn main() -> i32 {
+ let bar = MyBar;
+ let result: i32 = foo(bar);
+
+ result - 15
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_desugar.rs b/gcc/testsuite/rust/execute/torture/impl_desugar.rs
new file mode 100644
index 0000000..22d3951
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_desugar.rs
@@ -0,0 +1,32 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+struct MyBaz; // { dg-warning "struct is never constructed" }
+impl Foo for MyBaz {}
+
+struct MyBar;
+
+impl Bar for MyBar {
+ type Baz = MyBaz;
+}
+
+pub fn foo<T, U>(_value: T) -> i32
+where
+ T: Bar<Baz = U>,
+ U: Foo,
+{
+ 15
+}
+
+fn main() -> i32 {
+ let bar = MyBar;
+ let result: i32 = foo::<MyBar, MyBaz>(bar);
+
+ result - 15
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit1.rs b/gcc/testsuite/rust/execute/torture/impl_rpit1.rs
new file mode 100644
index 0000000..8ce5f21
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit1.rs
@@ -0,0 +1,28 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing(a: i32) -> impl Foo {
+ Thing(a)
+}
+
+fn use_foo(f: impl Foo) -> i32 {
+ f.id()
+}
+
+fn main() -> i32 {
+ let value = make_thing(42);
+ let val = use_foo(value);
+ val - 42
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit2.rs b/gcc/testsuite/rust/execute/torture/impl_rpit2.rs
new file mode 100644
index 0000000..f7cbbb6
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit2.rs
@@ -0,0 +1,36 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Thing {
+ fn double(&self) -> i32 {
+ // { dg-warning "associated function is never used: .double." "" { target *-*-* } .-1 }
+ self.0 * 2
+ }
+}
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing(a: i32) -> impl Foo {
+ Thing(a)
+}
+
+fn use_foo(f: impl Foo) -> i32 {
+ f.id()
+}
+
+fn main() -> i32 {
+ let value = make_thing(21);
+ let id = use_foo(value);
+
+ id - 21
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit3.rs b/gcc/testsuite/rust/execute/torture/impl_rpit3.rs
new file mode 100644
index 0000000..dd68eb2
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit3.rs
@@ -0,0 +1,25 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing() -> impl Foo {
+ Thing(99)
+}
+
+fn main() -> i32 {
+ let v = make_thing();
+ let r = &v;
+ let val = r.id();
+ val - 99
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait1.rs b/gcc/testsuite/rust/execute/torture/impl_trait1.rs
new file mode 100644
index 0000000..33a5c8c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait1.rs
@@ -0,0 +1,31 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Value {
+ fn get(&self) -> i32;
+}
+
+struct Foo(i32);
+struct Bar(i32);
+
+impl Value for Foo {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+impl Value for Bar {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+
+pub fn foo(a: impl Value, b: impl Value) -> i32 {
+ a.get() + b.get()
+}
+
+fn main() -> i32 {
+ let a = Foo(1);
+ let b = Bar(2);
+
+ foo(a, b) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait2.rs b/gcc/testsuite/rust/execute/torture/impl_trait2.rs
new file mode 100644
index 0000000..29f393d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait2.rs
@@ -0,0 +1,31 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Value {
+ fn get(&self) -> i32;
+}
+
+struct Foo(i32);
+struct Bar(i32);
+
+impl Value for Foo {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+impl Value for Bar {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+
+pub fn foo(a: &impl Value, b: &impl Value) -> i32 {
+ a.get() + b.get()
+}
+
+fn main() -> i32 {
+ let a = Foo(1);
+ let b = Bar(2);
+
+ foo(&a, &b) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait3.rs b/gcc/testsuite/rust/execute/torture/impl_trait3.rs
new file mode 100644
index 0000000..97e2972
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait3.rs
@@ -0,0 +1,46 @@
+/* { dg-output "Hello from Message\r*\n" } */
+#[lang = "sized"]
+pub trait Sized {}
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+trait Speak {
+ fn speak(&self) -> &'static str;
+}
+
+trait Printer {
+ fn print(&self, input: impl Speak);
+}
+
+struct Console;
+
+impl Printer for Console {
+ fn print(&self, input: impl Speak) {
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ unsafe {
+ let a = input.speak();
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+ }
+}
+
+struct Message(&'static str);
+
+impl Speak for Message {
+ fn speak(&self) -> &'static str {
+ self.0
+ }
+}
+
+fn main() -> i32 {
+ let c = Console;
+ let msg = Message("Hello from Message\n");
+ c.print(msg);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait4.rs b/gcc/testsuite/rust/execute/torture/impl_trait4.rs
new file mode 100644
index 0000000..67d0095
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait4.rs
@@ -0,0 +1,31 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct A(i32);
+struct B(i32);
+
+impl Foo for A {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+impl Foo for B {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn takes_tuple(pair: (impl Foo, impl Foo)) -> i32 {
+ pair.0.id() + pair.1.id()
+}
+
+fn main() -> i32 {
+ let a = A(1);
+ let b = B(2);
+ takes_tuple((a, b)) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1482.rs b/gcc/testsuite/rust/execute/torture/issue-1482.rs
new file mode 100644
index 0000000..ed8dc81
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1482.rs
@@ -0,0 +1,23 @@
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn takes_fn(a: i32, f: impl FnOnce(i32) -> i32) -> i32 {
+ f(a)
+}
+
+pub fn main() -> i32 {
+ let capture = 2;
+ let a = |i: i32| {
+ let b = i + capture;
+ b
+ };
+ takes_fn(1, a) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/iter1.rs b/gcc/testsuite/rust/execute/torture/iter1.rs
index c3b6c7b..233eb60 100644
--- a/gcc/testsuite/rust/execute/torture/iter1.rs
+++ b/gcc/testsuite/rust/execute/torture/iter1.rs
@@ -99,30 +99,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -130,12 +130,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -143,7 +143,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -152,31 +152,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -191,7 +191,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -201,7 +201,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
diff --git a/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs b/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs
new file mode 100644
index 0000000..b102ad1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs
@@ -0,0 +1,10 @@
+fn main() -> i32 {
+ let mut x = 2;
+
+ match x {
+ a @ 2 => { x = a + 1 },
+ _ => {}
+ }
+
+ x - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs b/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs
new file mode 100644
index 0000000..6aec51f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs
@@ -0,0 +1,13 @@
+enum Foo {
+ A { x: i32 },
+ B { y: i32 }
+}
+
+fn main() -> i32 {
+ let x = Foo::A { x: 12 };
+ match x {
+ Foo::A { x: 10 } => 1,
+ Foo::B { y: 11 } => 2,
+ Foo::A { x: abc } => { abc - 12 }
+ }
+}
diff --git a/gcc/testsuite/rust/execute/torture/struct_pattern1.rs b/gcc/testsuite/rust/execute/torture/struct_pattern1.rs
new file mode 100644
index 0000000..7a74092
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/struct_pattern1.rs
@@ -0,0 +1,19 @@
+struct A {
+ // the two warnings are invalid but this should be fixed by our lint rework
+ // with this year's GSoC so ok for now
+ a: i32, // { dg-warning "never read" }
+ b: i32, // { dg-warning "never read" }
+}
+
+fn main() -> i32 {
+ let a = A { a: 15, b: 14 };
+
+ let result = match a {
+ A {
+ a: self_a,
+ b: self_b,
+ } => self_a + self_b,
+ };
+
+ result - 29
+}
diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
index 413ca49..3b3748a 100644
--- a/gcc/tree-scalar-evolution.cc
+++ b/gcc/tree-scalar-evolution.cc
@@ -670,6 +670,17 @@ scev_dfs::add_to_evolution_1 (tree chrec_before, tree to_add, gimple *at_stmt)
to_add = chrec_convert (type, to_add, at_stmt);
right = chrec_convert_rhs (type, right, at_stmt);
right = chrec_fold_plus (chrec_type (right), right, to_add);
+ /* When we have an evolution in a non-wrapping type and
+ in the process of accumulating CHREC_RIGHT there was
+ overflow this indicates in the association that happened
+ in building the CHREC clearly involved UB. Avoid this.
+ In building a CHREC we basically turn (a + INCR1) + INCR2
+ into a + (INCR1 + INCR2) which is not always valid.
+ Note this check only catches few invalid cases. */
+ if ((INTEGRAL_TYPE_P (type) && ! TYPE_OVERFLOW_WRAPS (type))
+ && TREE_CODE (right) == INTEGER_CST
+ && TREE_OVERFLOW (right))
+ return chrec_dont_know;
return build_polynomial_chrec (var, left, right);
}
else
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 879668c..2fe2655 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -132,6 +132,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-vectorizer.h"
#include "dbgcnt.h"
#include "cfganal.h"
+#include "gimple-fold.h"
/* For lang_hooks.types.type_for_mode. */
#include "langhooks.h"
@@ -7252,7 +7253,24 @@ create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
base = unshare_expr (cand->iv->base);
- create_iv (base, PLUS_EXPR, unshare_expr (cand->iv->step),
+ /* The step computation could invoke UB when the loop does not iterate.
+ Avoid inserting it on the preheader in its native form but rewrite
+ it to a well-defined form. This also helps masking SCEV issues
+ which freely re-associates the IV computations when building up
+ CHRECs without much regard for signed overflow invoking UB. */
+ gimple_seq stmts = NULL;
+ tree step = force_gimple_operand (unshare_expr (cand->iv->step), &stmts,
+ true, NULL_TREE);
+ if (stmts)
+ {
+ for (auto gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
+ if (gimple_needing_rewrite_undefined (gsi_stmt (gsi)))
+ rewrite_to_defined_unconditional (&gsi);
+ gsi_insert_seq_on_edge_immediate
+ (loop_preheader_edge (data->current_loop), stmts);
+ }
+
+ create_iv (base, PLUS_EXPR, step,
cand->var_before, data->current_loop,
&incr_pos, after, &cand->var_before, &cand->var_after);
}
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index da700cd..dc82bf6 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -1856,21 +1856,14 @@ vect_get_data_access_cost (vec_info *vinfo, dr_vec_info *dr_info,
stmt_vector_for_cost *prologue_cost_vec)
{
stmt_vec_info stmt_info = dr_info->stmt;
- loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
- int ncopies;
-
- if (PURE_SLP_STMT (stmt_info))
- ncopies = 1;
- else
- ncopies = vect_get_num_copies (loop_vinfo, STMT_VINFO_VECTYPE (stmt_info));
if (DR_IS_READ (dr_info->dr))
- vect_get_load_cost (vinfo, stmt_info, NULL, ncopies,
+ vect_get_load_cost (vinfo, stmt_info, NULL, 1,
alignment_support_scheme, misalignment, true,
inside_cost, outside_cost, prologue_cost_vec,
body_cost_vec, false);
else
- vect_get_store_cost (vinfo,stmt_info, NULL, ncopies,
+ vect_get_store_cost (vinfo,stmt_info, NULL, 1,
alignment_support_scheme, misalignment, inside_cost,
body_cost_vec);
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 460de57..85f3e90 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -2512,9 +2512,8 @@ start_over:
if (!vect_make_slp_decision (loop_vinfo))
return opt_result::failure_at (vect_location, "no stmts to vectorize.\n");
- /* Find stmts that need to be both vectorized and SLPed. */
- if (!vect_detect_hybrid_slp (loop_vinfo))
- return opt_result::failure_at (vect_location, "needs non-SLP handling\n");
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location, "Loop contains only SLP stmts\n");
/* Determine the vectorization factor from the SLP decision. */
LOOP_VINFO_VECT_FACTOR (loop_vinfo)
@@ -2923,7 +2922,7 @@ again:
!gsi_end_p (si); gsi_next (&si))
{
stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si));
- STMT_SLP_TYPE (stmt_info) = loop_vect;
+ STMT_SLP_TYPE (stmt_info) = not_vect;
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def
|| STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def)
{
@@ -2942,7 +2941,7 @@ again:
if (is_gimple_debug (gsi_stmt (si)))
continue;
stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si));
- STMT_SLP_TYPE (stmt_info) = loop_vect;
+ STMT_SLP_TYPE (stmt_info) = not_vect;
if (STMT_VINFO_IN_PATTERN_P (stmt_info))
{
stmt_vec_info pattern_stmt_info
@@ -2951,11 +2950,11 @@ again:
STMT_VINFO_IN_PATTERN_P (stmt_info) = false;
gimple *pattern_def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info);
- STMT_SLP_TYPE (pattern_stmt_info) = loop_vect;
+ STMT_SLP_TYPE (pattern_stmt_info) = not_vect;
for (gimple_stmt_iterator pi = gsi_start (pattern_def_seq);
!gsi_end_p (pi); gsi_next (&pi))
STMT_SLP_TYPE (loop_vinfo->lookup_stmt (gsi_stmt (pi)))
- = loop_vect;
+ = not_vect;
}
}
}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 3f3a509..794a073 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -1140,7 +1140,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
soft_fail_nunits_vectype = nunits_vectype;
}
- gcc_assert (vectype);
+ gcc_assert (vectype || !gimple_get_lhs (first_stmt_info->stmt));
*node_vectype = vectype;
/* For every stmt in NODE find its def stmt/s. */
@@ -1187,10 +1187,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
gcall *call_stmt = dyn_cast <gcall *> (stmt);
tree lhs = gimple_get_lhs (stmt);
- if (lhs == NULL_TREE
- && (!call_stmt
- || !gimple_call_internal_p (stmt)
- || !internal_store_fn_p (gimple_call_internal_fn (stmt))))
+ if (lhs == NULL_TREE && !call_stmt)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -4917,6 +4914,22 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size,
return opt_result::failure_at (vect_location,
"SLP build failed.\n");
}
+
+ stmt_vec_info stmt_info;
+ FOR_EACH_VEC_ELT (LOOP_VINFO_ALTERNATE_DEFS (loop_vinfo), i, stmt_info)
+ {
+ vec<stmt_vec_info> stmts;
+ vec<stmt_vec_info> roots = vNULL;
+ vec<tree> remain = vNULL;
+ stmts.create (1);
+ stmts.quick_push (stmt_info);
+ if (! vect_build_slp_instance (vinfo, slp_inst_kind_store,
+ stmts, roots, remain, max_tree_size,
+ &limit, bst_map, NULL,
+ force_single_lane))
+ return opt_result::failure_at (vect_location,
+ "SLP build failed.\n");
+ }
}
if (bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo))
@@ -7634,7 +7647,8 @@ vect_make_slp_decision (loop_vec_info loop_vinfo)
/* If all instances ended up with vector(1) T roots make sure to
not vectorize. RVV for example relies on loop vectorization
when some instances are essentially kept scalar. See PR121048. */
- if (known_gt (TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (root)), 1U))
+ if (SLP_TREE_VECTYPE (root)
+ && known_gt (TYPE_VECTOR_SUBPARTS (SLP_TREE_VECTYPE (root)), 1U))
decided_to_slp++;
}
@@ -7652,232 +7666,6 @@ vect_make_slp_decision (loop_vec_info loop_vinfo)
return (decided_to_slp > 0);
}
-/* Private data for vect_detect_hybrid_slp. */
-struct vdhs_data
-{
- loop_vec_info loop_vinfo;
- vec<stmt_vec_info> *worklist;
-};
-
-/* Walker for walk_gimple_op. */
-
-static tree
-vect_detect_hybrid_slp (tree *tp, int *, void *data)
-{
- walk_stmt_info *wi = (walk_stmt_info *)data;
- vdhs_data *dat = (vdhs_data *)wi->info;
-
- if (wi->is_lhs)
- return NULL_TREE;
-
- stmt_vec_info def_stmt_info = dat->loop_vinfo->lookup_def (*tp);
- if (!def_stmt_info)
- return NULL_TREE;
- def_stmt_info = vect_stmt_to_vectorize (def_stmt_info);
- if (PURE_SLP_STMT (def_stmt_info))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location, "marking hybrid: %G",
- def_stmt_info->stmt);
- STMT_SLP_TYPE (def_stmt_info) = hybrid;
- dat->worklist->safe_push (def_stmt_info);
- }
-
- return NULL_TREE;
-}
-
-/* Look if STMT_INFO is consumed by SLP indirectly and mark it pure_slp
- if so, otherwise pushing it to WORKLIST. */
-
-static void
-maybe_push_to_hybrid_worklist (vec_info *vinfo,
- vec<stmt_vec_info> &worklist,
- stmt_vec_info stmt_info)
-{
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Processing hybrid candidate : %G", stmt_info->stmt);
- stmt_vec_info orig_info = vect_orig_stmt (stmt_info);
- imm_use_iterator iter2;
- ssa_op_iter iter1;
- use_operand_p use_p;
- def_operand_p def_p;
- bool any_def = false;
- FOR_EACH_PHI_OR_STMT_DEF (def_p, orig_info->stmt, iter1, SSA_OP_DEF)
- {
- any_def = true;
- FOR_EACH_IMM_USE_FAST (use_p, iter2, DEF_FROM_PTR (def_p))
- {
- if (is_gimple_debug (USE_STMT (use_p)))
- continue;
- stmt_vec_info use_info = vinfo->lookup_stmt (USE_STMT (use_p));
- /* An out-of loop use means this is a loop_vect sink. */
- if (!use_info)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Found loop_vect sink: %G", stmt_info->stmt);
- worklist.safe_push (stmt_info);
- return;
- }
- else if (!STMT_SLP_TYPE (vect_stmt_to_vectorize (use_info)))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Found loop_vect use: %G", use_info->stmt);
- worklist.safe_push (stmt_info);
- return;
- }
- }
- }
- /* No def means this is a loop_vect sink. Gimple conditionals also don't have a
- def but shouldn't be considered sinks. */
- if (!any_def && STMT_VINFO_DEF_TYPE (stmt_info) != vect_condition_def)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Found loop_vect sink: %G", stmt_info->stmt);
- worklist.safe_push (stmt_info);
- return;
- }
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Marked SLP consumed stmt pure: %G", stmt_info->stmt);
- STMT_SLP_TYPE (stmt_info) = pure_slp;
-}
-
-/* Find stmts that must be both vectorized and SLPed. */
-
-bool
-vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
-{
- DUMP_VECT_SCOPE ("vect_detect_hybrid_slp");
-
- /* All stmts participating in SLP are marked pure_slp, all other
- stmts are loop_vect.
- First collect all loop_vect stmts into a worklist.
- SLP patterns cause not all original scalar stmts to appear in
- SLP_TREE_SCALAR_STMTS and thus not all of them are marked pure_slp.
- Rectify this here and do a backward walk over the IL only considering
- stmts as loop_vect when they are used by a loop_vect stmt and otherwise
- mark them as pure_slp. */
- auto_vec<stmt_vec_info> worklist;
- for (int i = LOOP_VINFO_LOOP (loop_vinfo)->num_nodes - 1; i >= 0; --i)
- {
- basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i];
- for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
- gsi_next (&gsi))
- {
- gphi *phi = gsi.phi ();
- stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (phi);
- if (!STMT_SLP_TYPE (stmt_info) && STMT_VINFO_RELEVANT (stmt_info))
- maybe_push_to_hybrid_worklist (loop_vinfo,
- worklist, stmt_info);
- }
- for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
- gsi_prev (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- if (is_gimple_debug (stmt))
- continue;
- stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (stmt);
- if (STMT_VINFO_IN_PATTERN_P (stmt_info))
- {
- for (gimple_stmt_iterator gsi2
- = gsi_start (STMT_VINFO_PATTERN_DEF_SEQ (stmt_info));
- !gsi_end_p (gsi2); gsi_next (&gsi2))
- {
- stmt_vec_info patt_info
- = loop_vinfo->lookup_stmt (gsi_stmt (gsi2));
- if (!STMT_SLP_TYPE (patt_info)
- && STMT_VINFO_RELEVANT (patt_info))
- maybe_push_to_hybrid_worklist (loop_vinfo,
- worklist, patt_info);
- }
- stmt_info = STMT_VINFO_RELATED_STMT (stmt_info);
- }
- if (!STMT_SLP_TYPE (stmt_info) && STMT_VINFO_RELEVANT (stmt_info))
- maybe_push_to_hybrid_worklist (loop_vinfo,
- worklist, stmt_info);
- }
- }
-
- /* Now we have a worklist of non-SLP stmts, follow use->def chains and
- mark any SLP vectorized stmt as hybrid.
- ??? We're visiting def stmts N times (once for each non-SLP and
- once for each hybrid-SLP use). */
- walk_stmt_info wi;
- vdhs_data dat;
- dat.worklist = &worklist;
- dat.loop_vinfo = loop_vinfo;
- memset (&wi, 0, sizeof (wi));
- wi.info = (void *)&dat;
- while (!worklist.is_empty ())
- {
- stmt_vec_info stmt_info = worklist.pop ();
- /* Since SSA operands are not set up for pattern stmts we need
- to use walk_gimple_op. */
- wi.is_lhs = 0;
- walk_gimple_op (stmt_info->stmt, vect_detect_hybrid_slp, &wi);
- /* For gather/scatter make sure to walk the offset operand, that
- can be a scaling and conversion away. */
- gather_scatter_info gs_info;
- if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
- && vect_check_gather_scatter (stmt_info, loop_vinfo, &gs_info))
- {
- int dummy;
- vect_detect_hybrid_slp (&gs_info.offset, &dummy, &wi);
- }
- }
-
- /* Determine if all the stmts in the loop can be SLPed. */
- for (unsigned i = 0; i < LOOP_VINFO_LOOP (loop_vinfo)->num_nodes; i++)
- {
- basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i];
- for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
- gsi_next (&si))
- {
- stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (si.phi ());
- if (!stmt_info)
- continue;
- if ((STMT_VINFO_RELEVANT_P (stmt_info)
- || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
- && !PURE_SLP_STMT (stmt_info))
- {
- /* STMT needs both SLP and loop-based vectorization. */
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Loop contains SLP and non-SLP stmts\n");
- return false;
- }
- }
- for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
- gsi_next (&si))
- {
- if (is_gimple_debug (gsi_stmt (si)))
- continue;
- stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si));
- stmt_info = vect_stmt_to_vectorize (stmt_info);
- if ((STMT_VINFO_RELEVANT_P (stmt_info)
- || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
- && !PURE_SLP_STMT (stmt_info))
- {
- /* STMT needs both SLP and loop-based vectorization. */
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Loop contains SLP and non-SLP stmts\n");
- return false;
- }
- }
- }
-
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Loop contains only SLP stmts\n");
- return true;
-}
-
-
/* Initialize a bb_vec_info struct for the statements in BBS basic blocks. */
_bb_vec_info::_bb_vec_info (vec<basic_block> _bbs, vec_info_shared *shared)
@@ -7961,7 +7749,10 @@ vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node,
elements in a vector. For single-defuse-cycle, lane-reducing op, and
PHI statement that starts reduction comprised of only lane-reducing ops,
the number is more than effective vector statements actually required. */
- SLP_TREE_NUMBER_OF_VEC_STMTS (node) = vect_get_num_copies (vinfo, node);
+ if (SLP_TREE_VECTYPE (node))
+ SLP_TREE_NUMBER_OF_VEC_STMTS (node) = vect_get_num_copies (vinfo, node);
+ else
+ SLP_TREE_NUMBER_OF_VEC_STMTS (node) = 0;
/* Handle purely internal nodes. */
if (SLP_TREE_CODE (node) == VEC_PERM_EXPR)
@@ -11318,8 +11109,10 @@ vect_schedule_slp_node (vec_info *vinfo,
stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node);
- gcc_assert (SLP_TREE_NUMBER_OF_VEC_STMTS (node) != 0);
- SLP_TREE_VEC_DEFS (node).create (SLP_TREE_NUMBER_OF_VEC_STMTS (node));
+ gcc_assert (!SLP_TREE_VECTYPE (node)
+ || SLP_TREE_NUMBER_OF_VEC_STMTS (node) != 0);
+ if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) != 0)
+ SLP_TREE_VEC_DEFS (node).create (SLP_TREE_NUMBER_OF_VEC_STMTS (node));
if (SLP_TREE_CODE (node) != VEC_PERM_EXPR
&& STMT_VINFO_DATA_REF (stmt_info))
@@ -11564,8 +11357,6 @@ vect_remove_slp_scalar_calls (vec_info *vinfo,
{
if (!stmt_info)
continue;
- if (!PURE_SLP_STMT (stmt_info))
- continue;
stmt_info = vect_orig_stmt (stmt_info);
gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt);
if (!stmt || gimple_bb (stmt) == NULL)
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 97222f6..f7a052b 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -386,6 +386,9 @@ vect_stmt_relevant_p (stmt_vec_info stmt_info, loop_vec_info loop_vinfo,
dump_printf_loc (MSG_NOTE, vect_location,
"vec_stmt_relevant_p: stmt has vdefs.\n");
*relevant = vect_used_in_scope;
+ if (! STMT_VINFO_DATA_REF (stmt_info)
+ && zero_ssa_operands (stmt_info->stmt, SSA_OP_DEF))
+ LOOP_VINFO_ALTERNATE_DEFS (loop_vinfo).safe_push (stmt_info);
}
/* uses outside the loop. */
@@ -4752,7 +4755,8 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
}
}
- SLP_TREE_VEC_DEFS (slp_node).quick_push (gimple_get_lhs (new_stmt));
+ if (gimple_get_lhs (new_stmt))
+ SLP_TREE_VEC_DEFS (slp_node).quick_push (gimple_get_lhs (new_stmt));
}
for (i = 0; i < nargs; ++i)
@@ -7780,10 +7784,6 @@ vectorizable_store (vec_info *vinfo,
return false;
}
- /* Cannot have hybrid store SLP -- that would mean storing to the
- same location twice. */
- gcc_assert (PURE_SLP_STMT (stmt_info));
-
tree vectype = SLP_TREE_VECTYPE (stmt_info), rhs_vectype = NULL_TREE;
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
diff --git a/gcc/tree-vectorizer.cc b/gcc/tree-vectorizer.cc
index f992856..50985a6 100644
--- a/gcc/tree-vectorizer.cc
+++ b/gcc/tree-vectorizer.cc
@@ -733,7 +733,7 @@ vec_info::new_stmt_vec_info (gimple *stmt)
else
STMT_VINFO_DEF_TYPE (res) = vect_internal_def;
- STMT_SLP_TYPE (res) = loop_vect;
+ STMT_SLP_TYPE (res) = not_vect;
/* This is really "uninitialized" until vect_compute_data_ref_alignment. */
res->dr_aux.misalignment = DR_MISALIGNMENT_UNINITIALIZED;
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 0a75ee1..52e1075 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -947,6 +947,10 @@ public:
stmt in the chain. */
auto_vec<stmt_vec_info> reduction_chains;
+ /* Defs that could not be analyzed such as OMP SIMD calls without
+ a LHS. */
+ auto_vec<stmt_vec_info> alternate_defs;
+
/* Cost vector for a single scalar iteration. */
auto_vec<stmt_info_for_cost> scalar_cost_vec;
@@ -1186,6 +1190,7 @@ public:
#define LOOP_VINFO_INNER_LOOP_COST_FACTOR(L) (L)->inner_loop_cost_factor
#define LOOP_VINFO_INV_PATTERN_DEF_SEQ(L) (L)->inv_pattern_def_seq
#define LOOP_VINFO_DRS_ADVANCED_BY(L) (L)->drs_advanced_by
+#define LOOP_VINFO_ALTERNATE_DEFS(L) (L)->alternate_defs
#define LOOP_VINFO_FULLY_MASKED_P(L) \
(LOOP_VINFO_USING_PARTIAL_VECTORS_P (L) \
@@ -1288,26 +1293,12 @@ enum vect_relevant {
vect_used_in_scope
};
-/* The type of vectorization that can be applied to the stmt: regular loop-based
- vectorization; pure SLP - the stmt is a part of SLP instances and does not
- have uses outside SLP instances; or hybrid SLP and loop-based - the stmt is
- a part of SLP instance and also must be loop-based vectorized, since it has
- uses outside SLP sequences.
-
- In the loop context the meanings of pure and hybrid SLP are slightly
- different. By saying that pure SLP is applied to the loop, we mean that we
- exploit only intra-iteration parallelism in the loop; i.e., the loop can be
- vectorized without doing any conceptual unrolling, cause we don't pack
- together stmts from different iterations, only within a single iteration.
- Loop hybrid SLP means that we exploit both intra-iteration and
- inter-iteration parallelism (e.g., number of elements in the vector is 4
- and the slp-group-size is 2, in which case we don't have enough parallelism
- within an iteration, so we obtain the rest of the parallelism from subsequent
- iterations by unrolling the loop by 2). */
+/* The type of vectorization. pure_slp means the stmt is covered by the
+ SLP graph, not_vect means it is not. This is mostly used by BB
+ vectorization. */
enum slp_vect_type {
- loop_vect = 0,
+ not_vect = 0,
pure_slp,
- hybrid
};
/* Says whether a statement is a load, a store of a vectorized statement
@@ -1655,7 +1646,6 @@ struct gather_scatter_info {
#define STMT_VINFO_RELEVANT_P(S) ((S)->relevant != vect_unused_in_scope)
-#define HYBRID_SLP_STMT(S) ((S)->slp_type == hybrid)
#define PURE_SLP_STMT(S) ((S)->slp_type == pure_slp)
#define STMT_SLP_TYPE(S) (S)->slp_type
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index b5188fd..e58fad1 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,9 @@
+2025-08-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * macro.cc (stringify_arg): For C++26 emit a pedarn instead of warning
+ for \ at the end of stringification.
+
2025-08-03 Jakub Jelinek <jakub@redhat.com>
PR c++/120845
diff --git a/libcpp/macro.cc b/libcpp/macro.cc
index d869b02..158c821 100644
--- a/libcpp/macro.cc
+++ b/libcpp/macro.cc
@@ -1071,7 +1071,7 @@ paste_tokens (cpp_reader *pfile, location_t location,
/* Mandatory error for all apart from assembler. */
if (CPP_OPTION (pfile, lang) != CLK_ASM)
cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0,
- "pasting \"%.*s\" and \"%.*s\" does not give "
+ "pasting %<%.*s%> and %<%.*s%> does not give "
"a valid preprocessing token",
(int) (lhsend - buf), buf,
(int) (end - rhsstart), rhsstart);
diff --git a/libgrust/libproc_macro_internal/ffistring.h b/libgrust/libproc_macro_internal/ffistring.h
index e176bc2..b133b35 100644
--- a/libgrust/libproc_macro_internal/ffistring.h
+++ b/libgrust/libproc_macro_internal/ffistring.h
@@ -43,11 +43,9 @@ public:
};
extern "C" {
-FFIString
-FFIString__new (const unsigned char *data, std::uint64_t len);
+FFIString FFIString__new (const unsigned char *data, std::uint64_t len);
-void
-FFIString__drop (FFIString *str);
+void FFIString__drop (FFIString *str);
}
} // namespace ProcMacro
diff --git a/libgrust/libproc_macro_internal/ident.h b/libgrust/libproc_macro_internal/ident.h
index cdc9b0d..8394716 100644
--- a/libgrust/libproc_macro_internal/ident.h
+++ b/libgrust/libproc_macro_internal/ident.h
@@ -47,17 +47,13 @@ public:
extern "C" {
-Ident
-Ident__new (FFIString str, Span span);
+Ident Ident__new (FFIString str, Span span);
-Ident
-Ident__new_raw (FFIString str, Span span);
+Ident Ident__new_raw (FFIString str, Span span);
-void
-Ident__drop (Ident *ident);
+void Ident__drop (Ident *ident);
-Ident
-Ident__clone (const Ident *ident);
+Ident Ident__clone (const Ident *ident);
}
} // namespace ProcMacro
diff --git a/libgrust/libproc_macro_internal/literal.h b/libgrust/libproc_macro_internal/literal.h
index c857947..b30c69a 100644
--- a/libgrust/libproc_macro_internal/literal.h
+++ b/libgrust/libproc_macro_internal/literal.h
@@ -105,8 +105,7 @@ public:
};
extern "C" {
-bool
-Literal__from_string (FFIString str, Literal *lit);
+bool Literal__from_string (FFIString str, Literal *lit);
}
} // namespace ProcMacro
diff --git a/libgrust/libproc_macro_internal/proc_macro.h b/libgrust/libproc_macro_internal/proc_macro.h
index ce9adb2..d5f2e20 100644
--- a/libgrust/libproc_macro_internal/proc_macro.h
+++ b/libgrust/libproc_macro_internal/proc_macro.h
@@ -96,8 +96,7 @@ struct ProcmacroArray
Procmacro *macros;
};
-extern "C" bool
-bridge_is_available ();
+extern "C" bool bridge_is_available ();
} // namespace ProcMacro
diff --git a/libgrust/libproc_macro_internal/tokenstream.h b/libgrust/libproc_macro_internal/tokenstream.h
index 4e13ce7..f24d4ab 100644
--- a/libgrust/libproc_macro_internal/tokenstream.h
+++ b/libgrust/libproc_macro_internal/tokenstream.h
@@ -51,23 +51,17 @@ public:
static void drop (TokenStream *stream);
};
-extern "C" TokenStream
-TokenStream__new ();
+extern "C" TokenStream TokenStream__new ();
-extern "C" TokenStream
-TokenStream__with_capacity (std::uint64_t capacity);
+extern "C" TokenStream TokenStream__with_capacity (std::uint64_t capacity);
-extern "C" void
-TokenSream__push (TokenStream *stream, TokenTree tree);
+extern "C" void TokenSream__push (TokenStream *stream, TokenTree tree);
-extern "C" bool
-TokenStream__from_string (FFIString str, TokenStream *ts);
+extern "C" bool TokenStream__from_string (FFIString str, TokenStream *ts);
-extern "C" TokenStream
-TokenStream__clone (const TokenStream *ts);
+extern "C" TokenStream TokenStream__clone (const TokenStream *ts);
-extern "C" void
-TokenStream__drop (TokenStream *stream);
+extern "C" void TokenStream__drop (TokenStream *stream);
} // namespace ProcMacro
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index cd1f142..2dba9dc 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,27 @@
+2025-08-04 Jakub Jelinek <jakub@redhat.com>
+ hexne <printfne@gmail.com>
+
+ PR libstdc++/121373
+ * src/c++23/std.cc.in (std::ranges::shift_left,
+ std::ranges::shift_right): Only export for C++23 and later.
+ (std::ranges::fold_left_first_with_iter_result,
+ std::ranges::fold_left_with_iter_result): Export.
+ (std::byteswap): Export for C++23 and later.
+ (std::ranges::iter_move, std::ranges::iter_swap): Export.
+ (std::projected_value_t): Export for C++26 and later.
+ (std::out_ptr_t, std::inout_ptr_t): Export.
+ (std::ranges::iota_result): Export.
+ (std::regex_constants): Export a lot of constants.
+ (std::is_scoped_enum, std::is_scoped_enum_v): Export.
+
+2025-08-04 Tomasz KamiƄski <tkaminsk@redhat.com>
+
+ PR libstdc++/121128
+ * include/bits/indirect.h (indirect::operator*):
+ Cast __self to approparietly qualified indirect.
+ * testsuite/std/memory/indirect/access.cc: New test.
+ * testsuite/std/memory/polymorphic/access.cc: New test.
+
2025-08-03 Jakub Jelinek <jakub@redhat.com>
* src/c++23/std.cc.in (std::owner_equal, std::owner_hash): Export.
diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in
index 2300126..405bb6e 100644
--- a/libstdc++-v3/src/c++23/std.cc.in
+++ b/libstdc++-v3/src/c++23/std.cc.in
@@ -1697,8 +1697,6 @@ export namespace std
{
using std::ranges::advance;
using std::ranges::distance;
- using std::ranges::iter_move;
- using std::ranges::iter_swap;
using std::ranges::next;
using std::ranges::prev;
}